def create_packet(self, mt, chaddr, ciaddr, yiaddr, xid, server): req = DhcpPacket() req.SetOption('op', [1]) req.SetOption('htype',[1]) req.SetOption('hlen',[6]) req.SetOption('hops', [0]) req.SetOption('xid', xid) req.SetOption('giaddr', ipv4().list()) req.SetOption('chaddr', hwmac(chaddr).list() + [0] * 10) req.SetOption('ciaddr', ipv4(ciaddr).list()) if mt == DHCPRequest: req.SetOption('yiaddr', ipv4(yiaddr).list()) req.SetOption('request_ip_address', ipv4(yiaddr).list()) if mt == DHCPRelease: req.SetOption('siaddr', server) req.SetOption('server_identifier', ipv4(server).list()) if server == '255.255.255.255': req.SetOption('flags', [128, 0]) req.SetOption('dhcp_message_type',[mt]) req.SetOption("domain_name", strlist("catdamnit.com").list()) return req
def handle(self): ackCounter = 0 # self.request is the TCP socket connected to the client while True: # DHCP packet size is 244, HomeId size is 5 data_raw = self.request.recv(249, socket.MSG_WAITALL) if len(data_raw) < 249: #sleep(1) continue data, port = data_raw[:244], data_raw[-5:] packet = DhcpPacket() packet.DecodePacket(data) log(packet, port) if packet.IsDhcpDiscoverPacket(): packet.TransformToDhcpOfferPacket() packet.SetOption('yiaddr', ipv4(chooseIp(port, str(packet.GetOption("chaddr")))).list()) packet.SetOption('siaddr', ipv4(self.client_address[0]).list()) extPacket = packet.EncodePacket() + port self.request.send(extPacket) if packet.IsDhcpRequestPacket(): packet.TransformToDhcpAckPacket() extPacket = packet.EncodePacket() + port self.request.send(extPacket) ackCounter += 1 log(packet, port) if ackCounter % 100 == 0: print("-------> Ack Counter = " + str(ackCounter))
def preparePacket(xid=None, giaddr='0.0.0.0', chaddr='00:00:00:00:00:00', ciaddr='0.0.0.0', msgtype='discover', required_opts=[]): req = DhcpPacket() req.SetOption('op', [1]) req.SetOption('htype', [1]) req.SetOption('hlen', [6]) req.SetOption('hops', [0]) if not xid: xid = genxid() req.SetOption('xid', xid) req.SetOption('giaddr', ipv4(giaddr).list()) req.SetOption('chaddr', hwmac(chaddr).list() + [0] * 10) req.SetOption('ciaddr', ipv4(ciaddr).list()) if msgtype == 'request': mt = 3 elif msgtype == 'release': mt = 7 else: mt = 1 req.SetOption('dhcp_message_type', [mt]) # req.SetOption('parameter_request_list',1) return req
def prepare_packet(giaddr='0.0.0.0', chaddr='00:00:00:00:00:00', ciaddr='0.0.0.0', hostname=None): req = DhcpPacket() req.SetOption('op', [1]) req.SetOption('htype', [1]) req.SetOption('hlen', [6]) req.SetOption('hops', [0]) req.SetOption('xid', genxid()) req.SetOption('giaddr', ipv4(giaddr).list()) req.SetOption('chaddr', hwmac(chaddr).list() + [0] * 10) req.SetOption('ciaddr', ipv4('0.0.0.0').list()) req.SetOption('dhcp_message_type', [3]) # request req.SetOption('request_ip_address', ipv4(ciaddr).list()) if hostname: req.SetOption('host_name', strlist(hostname).list()) return req
def _send_release(self, mac, ip): print "Creating DHCPRelease" # Different xid should be generated for DHCPRelease. pkt = self.create_packet(DHCPRelease, mac, ip.str(), '0.0.0.0', self._generate_xid(), self.DHCP_SRV_IP) self.summary['release'] += 1 print "Sending DHCPRelease:" self.SendDhcpPacketTo(pkt, ipv4(self.DHCP_SRV_IP).str(), self.s_port)
def SendDhcpPacket(self, request, response): giaddr = ".".join(map(str, request.GetOption("giaddr"))) ciaddr = ".".join(map(str, request.GetOption("ciaddr"))) broadcast = (request.GetOption("flags")[0] & 0x80) != 0 if (giaddr != "0.0.0.0"): self.SendDhcpPacketTo(response, giaddr, self.listen_port) elif (response.IsDhcpNackPacket()): self.SendDhcpPacketTo(response, "255.255.255.255", self.emit_port) elif (ciaddr != "0.0.0.0"): self.SendDhcpPacketTo(response, ciaddr, self.emit_port) elif broadcast: #self.SendDhcpPacketTo( response, "255.255.255.255", self.emit_port ) chaddr = struct.pack(6 * "B", *request.GetOption("chaddr")[0:6]) ifconfig = interface.interface() ifindex = ifconfig.getIndex(self.ifname) ifaddr = ifconfig.getAddr(self.ifname) if (ifaddr is None): ifaddr = "0.0.0.0" _rawsocket.udp_send_packet(response.EncodePacket(), type_ipv4.ipv4(ifaddr).int(), self.listen_port, type_ipv4.ipv4("255.255.255.255").int(), self.emit_port, chaddr, ifindex) else: # unicast to yiaddr yiaddr = ".".join(map(str, response.GetOption("yiaddr"))) chaddr = struct.pack(6 * "B", *request.GetOption("chaddr")[0:6]) ifconfig = interface.interface() ifindex = ifconfig.getIndex(self.ifname) ifaddr = ifconfig.getAddr(self.ifname) if (ifaddr is None): ifaddr = "0.0.0.0" _rawsocket.udp_send_packet(response.EncodePacket(), type_ipv4.ipv4(ifaddr).int(), self.listen_port, type_ipv4.ipv4(yiaddr).int(), self.emit_port, chaddr, ifindex)
def HandleDhcpAck(self, packet): event.set() self.summary['ack'] += 1 ip = ipv4(packet.GetOption('yiaddr')) mac = packet.GetOption('chaddr')[:6] # Need to capture it to send a release. self.DHCP_SRV_IP = packet.GetOption('siaddr') print "Got DHCPAck, sending release" self._send_release(mac, ip)
def HandleDhcpRequest(self, packet): print 'New Request: ' + ipv4( packet.GetOption('request_ip_address')).str() print strlist(packet.GetOption('host_name')) print hwmac(packet.GetHardwareAddress()) print ipv4(packet.GetOption('request_ip_address')) time = strftime("%H:%M:%S", gmtime()) date = strftime("%Y-%m-%d", gmtime()) cur.execute("INSERT INTO data(name,mac,ip,date,time) VALUES ('" + strlist(packet.GetOption('host_name')).str() + "','" + hwmac(packet.GetHardwareAddress()).str() + "','" + ipv4(packet.GetOption('request_ip_address')).str() + "','" + date + "','" + time + "');") print "INSERT INTO data(name,mac,ip,date,time) VALUES ('" + strlist( packet.GetOption('host_name')).str() + "','" + hwmac( packet.GetHardwareAddress()).str() + "','" + ipv4( packet.GetOption('request_ip_address')).str( ) + "','" + date + "','" + time + "');" conn.commit()
def preparePacket(xid=None,giaddr='0.0.0.0',chaddr='00:00:00:00:00:00',ciaddr='0.0.0.0',msgtype='discover',required_opts=[]): req = DhcpPacket() req.SetOption('op',[1]) req.SetOption('htype',[1]) req.SetOption('hlen',[6]) req.SetOption('hops',[0]) if not xid: xid = genxid() req.SetOption('xid',xid) req.SetOption('giaddr',ipv4(giaddr).list()) req.SetOption('chaddr',hwmac(chaddr).list() + [0] * 10) req.SetOption('ciaddr',ipv4(ciaddr).list()) if msgtype == 'request': mt = 3 elif msgtype == 'release': mt = 7 else: mt = 1 req.SetOption('dhcp_message_type',[mt]) # req.SetOption('parameter_request_list',1) return req
def HandleDhcpRequest(self, packet): self.app.logger.info('REQUEST from %s', packet.str_mac) self.app.logger.debug(packet.str()) node = Node.query.get(packet.str_mac) renew_ip = self._list2long(packet.GetOption("ciaddr")) new_ip = self._list2long(packet.GetOption('request_ip_address')) server_id = self._list2long(packet.GetOption('server_identifier')) lease = None if not server_id: # INIT-REBOOT lease = node.lease(new_ip) elif ipv4(server_id) == self.listen_on_ip: # SELECT request_ip_address = renew_ip or new_ip if not request_ip_address: self.app.logger.error('Got DHCP REQUEST from %s with empty request_ip_address and ciaddr', packet.str_mac) else: lease = node.lease(request_ip_address, existen=renew_ip) else: self.app.logger.info('Node %s has accept offer from another server', packet.str_mac) node.cleanup_offers() return if not lease: self.nack(packet) return ack = DhcpPacket() ack.CreateDhcpAckPacketFrom(packet) if packet.str_user_class in ['gPXE', 'iPXE']: options = node.gpxe_options else: options = node.pxe_options for opt in options: ack.SetOption(opt.option, opt.binary) ack.SetOption("yiaddr", lease.yiaddr.words) ack.SetOption("siaddr", self.listen_on_ip.list()) events.PyBootstrapperEventDhcpLeasing.register(packet.str_mac, lease.yiaddr) node.commit_lease(lease) self.app.logger.debug(ack.str()) if self.SendDhcpPacketTo(ack, self.broadcast, self.emit_port) <= 0: self.app.logger.error('Could not send DHCP ACK to %s', packet.str_mac)
def __init__(self, app, listen_on_iface): self.app = app self.listen_on_iface = listen_on_iface self.kill = False DhcpServer.__init__(self) threading.Thread.__init__(self) listen_on = socket.inet_ntoa(fcntl.ioctl( self.dhcp_socket.fileno(), 0x8915, # SIOCGIFADDR struct.pack('256s', self.listen_on_iface[:15]) )[20:24]) self.listen_on_ip = ipv4(listen_on) self.broadcast = str(ipv4([255,255,255,255])) self.app.logger.info('DHCP listen on %s(%s)', self.listen_on_ip, self.listen_on_iface)
def preparePacket(xid=None,giaddr='0.0.0.0',chaddr='00:00:00:00:00:00',ciaddr='0.0.0.0', yiaddr='0.0.0.0', msgtype='discover'): req = DhcpPacket() req.SetOption('op',[1]) req.SetOption('htype',[1]) req.SetOption('hlen',[6]) req.SetOption('hops',[0]) req.SetOption('xid',xid) req.SetOption('giaddr',ipv4(giaddr).list()) req.SetOption('chaddr',hwmac(chaddr).list() + [0] * 10) req.SetOption('ciaddr',ipv4(ciaddr).list()) if msgtype == 'request': mt = 3 elif msgtype == 'release': mt = 7 else: mt = 1 if mt == 3: req.SetOption('yiaddr', ipv4(yiaddr).list()) req.SetOption('request_ip_address', ipv4(yiaddr).list()) req.SetOption('dhcp_message_type',[mt]) return req
def main(): parser = OptionParser() parser.add_option("-s", "--server", dest="server", default='0.0.0.0', help="DHCP server IP (default %default)") parser.add_option("-p", "--port", type="int", dest="port", default=67, help="DHCP server port (default (%default)") parser.add_option("-m", "--mac", "--chaddr", dest="chaddr", help="chaddr: Client's MAC address, default random") parser.add_option("-c", "--ciaddr", dest="ciaddr", default='0.0.0.0', help="ciaddr: Client's desired IP address") parser.add_option("-g", "--giaddr", dest="giaddr", default='0.0.0.0', help="giaddr: Gateway IP address (if any)") parser.add_option( "-t", "--type", dest="msgtype", type="choice", choices=["discover", "request", "release"], default="discover", help="DHCP message type: discover, request, release (default %default)" ) parser.add_option("-w", "--timeout", dest="timeout", type="int", default=4, help="UDP timeout (default %default)") parser.add_option("-r", "--require", action="append", type="int", default=[1, 3, 6, 51], dest="required_opts", help="Require options by its number") parser.add_option("-y", "--cycle", action="store_true", dest="docycle", help="Do full cycle: DISCOVERY, REQUEST, RELEASE") parser.add_option("-n", "--cycles", dest="cycles", type="int", default="1", help="Do number of cycles (default %default)") parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="Verbose operation") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", help="Quiet operation") parser.add_option("--nagios", action="store_true", dest="nagios", help="Nagios mode of operation") (opts, args) = parser.parse_args() if not opts.chaddr: chaddr = genmac() else: chaddr = opts.chaddr if opts.nagios: opts.verbose = False verbose = opts.verbose if opts.docycle: request_dhcp_message_type = "discover" else: request_dhcp_message_type = opts.msgtype request_ciaddr = opts.ciaddr serverip = opts.server cycleno = 1 xid = genxid() while True: if opts.cycles > 1 and opts.verbose is not False and ( not opts.docycle or request_dhcp_message_type == "discover"): print "=" * 100 print "| Cycle %s" % cycleno print "=" * 100 req = preparePacket(xid=xid, giaddr=opts.giaddr, chaddr=chaddr, ciaddr=request_ciaddr, msgtype=request_dhcp_message_type, required_opts=opts.required_opts) if verbose != False: print "Sending %s [%s] packet to %s" % ( request_dhcp_message_type.upper(), chaddr, opts.server) if verbose == True: print "-" * 100 #req.PrintHeaders() #req.PrintOptions() print "=" * 100 print "\n" try: res = receivePacket(serverip=serverip, serverport=opts.port, timeout=opts.timeout, req=req) except socket.timeout: res = None if opts.nagios: nagiosExit( 2, "%s request has been timed out." % request_dhcp_message_type.upper()) if verbose != False: print "Timed out." pass if res: dhcp_message_type = res.GetOption('dhcp_message_type')[0] server_identifier = ipv4(res.GetOption('server_identifier')) chaddr = hwmac(res.GetOption('chaddr')[:6]) yiaddr = ipv4(res.GetOption('yiaddr')) if opts.nagios and dhcp_message_type not in (2, 5): nagiosExit( 2, "Got %s response for our %s request" % (dhcpTypes.get(dhcp_message_type, 'UNKNOWN'), dhcpTypes.get(request_dhcp_message_type, 'UNKNOWN'))) if verbose != False: print "Received %s packet from %s; [%s] was bound to %s" % ( dhcpTypes.get(dhcp_message_type, 'UNKNOWN'), server_identifier, chaddr, yiaddr) if verbose == True: print "-" * 100 res.PrintHeaders() res.PrintOptions() print "=" * 100 print "\n" if opts.docycle: if dhcp_message_type == 2: request_dhcp_message_type = 'request' request_ciaddr = yiaddr.str() serverip = server_identifier.str() continue if dhcp_message_type == 5: request_dhcp_message_type = 'release' request_ciaddr = yiaddr.str() serverip = server_identifier.str() continue cycleno += 1 if cycleno > opts.cycles: if opts.nagios: if res: nagiosExit( 0, "%s finished successfully: %s. yiaddr: %s, chaddr: %s" % ( request_dhcp_message_type.upper(), dhcpTypes.get(dhcp_message_type, 'UNKNOWN'), yiaddr, chaddr, )) elif opts.docycle: nagiosExit( 0, "Cycle has been finished successfully. Got %s for %s" % (yiaddr, chaddr)) else: nagiosExit( 0, "%s has been finished without the answer" % (request_dhcp_message_type.upper())) break if opts.docycle: request_dhcp_message_type = "discover" request_ciaddr = opts.ciaddr serverip = opts.server xid = genxid() if not opts.chaddr: chaddr = genmac() else: chaddr = opts.chaddr
def str(self): # Process headers : printable_data = "# Header fields\n" op = self.packet_data[DhcpFields['op'][0]:DhcpFields['op'][0] + DhcpFields['op'][1]] printable_data += "op : " + DhcpFieldsName['op'][str(op[0])] + "\n" for opt in [ 'htype', 'hlen', 'hops', 'xid', 'secs', 'flags', 'ciaddr', 'yiaddr', 'siaddr', 'giaddr', 'chaddr', 'sname', 'file' ]: begin = DhcpFields[opt][0] end = DhcpFields[opt][0] + DhcpFields[opt][1] data = self.packet_data[begin:end] result = '' if DhcpFieldsTypes[opt] == "int": result = str(data[0]) elif DhcpFieldsTypes[opt] == "int2": result = str((data[0] << 8) + data[1]) elif DhcpFieldsTypes[opt] == "int4": result = str((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) elif DhcpFieldsTypes[opt] == "str": for each in data: if each != 0: result += chr(each) else: break elif DhcpFieldsTypes[opt] == "ipv4": result = ipv4(data).str() elif DhcpFieldsTypes[opt] == "hwmac": result = [] hexsym = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' ] for iterator in range(6): result += [ str(hexsym[int(data[iterator] / 16)] + hexsym[data[iterator] % 16]) ] result = ':'.join(result) printable_data += opt + " : " + result + "\n" # Process options : printable_data += "# Options fields\n" for opt in self.options_data.keys(): data = self.options_data[opt] result = "" optnum = DhcpOptions[opt] if opt == 'dhcp_message_type': result = DhcpFieldsName['dhcp_message_type'][str(data[0])] elif DhcpOptionsTypes[optnum] == "char": result = str(data[0]) elif DhcpOptionsTypes[optnum] == "16-bits": result = str((data[0] << 8) + data[1]) elif DhcpOptionsTypes[optnum] == "32-bits": result = str((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) elif DhcpOptionsTypes[optnum] == "string": for each in data: if each != 0: result += chr(each) else: break elif DhcpOptionsTypes[optnum] == "ipv4": result = ipv4(data).str() elif DhcpOptionsTypes[optnum] == "ipv4+": for i in range(0, len(data), 4): if len(data[i:i + 4]) == 4: result += ipv4(data[i:i + 4]).str() + " - " elif DhcpOptionsTypes[optnum] == "char+": if optnum == 55: # parameter_request_list result = ','.join([DhcpOptionsList[each] for each in data]) else: result += str(data) elif DhcpOptionsTypes[optnum] == "RFC3046": result = rfc3046(data).str() printable_data += opt + " : " + result + "\n" return printable_data
def OptionsToBinary(self, parameter, value): # Transform textual data into dhcp binary data p = parameter.strip() # 1- Search for header informations or specific parameter if p == 'op' or p == 'htype': value = value.strip() if value.isdigit(): return [int(value)] try: value = DhcpNames[value.strip()] return [value] except KeyError: return [0] elif p == 'hlen' or p == 'hops': try: value = int(value) return [value] except ValueError: return [0] elif p == 'secs' or p == 'flags': try: value = ipv4(int(value)).list() except ValueError: value = [0, 0, 0, 0] return value[2:] elif p == 'xid': try: value = ipv4(int(value)).list() except ValueError: value = [0, 0, 0, 0] return value elif p == 'ciaddr' or p == 'yiaddr' or p == 'siaddr' or p == 'giaddr': try: ip = ipv4(value).list() except ValueError: ip = [0, 0, 0, 0] return ip elif p == 'chaddr': try: value = hwmac(value).list() + [0] * 10 except (ValueError, TypeError): value = [0] * 16 return value elif p == 'sname': return elif p == 'file': return elif p == 'parameter_request_list': value = value.strip().split(',') tmp = [] for each in value: if each in DhcpOptions: tmp.append(DhcpOptions[each]) return tmp elif p == 'dhcp_message_type': try: return [DhcpNames[value]] except KeyError: return # 2- Search for options try: option_type = DhcpOptionsTypes[DhcpOptions[parameter]] except KeyError: return False if option_type == "ipv4": # this is a single ip address try: binary_value = map(int, value.split(".")) except ValueError: return False elif option_type == "ipv4+": # this is multiple ip address iplist = value.split(",") opt = [] for single in iplist: opt += (ipv4(single).list()) binary_value = opt elif option_type == "32-bits": # This is probably a number... try: digit = int(value) binary_value = [ digit >> 24 & 0xFF, (digit >> 16) & 0xFF, (digit >> 8) & 0xFF, digit & 0xFF ] except ValueError: return False elif option_type == "16-bits": try: digit = int(value) binary_value = [(digit >> 8) & 0xFF, digit & 0xFF] except ValueError: return False elif option_type == "char": try: digit = int(value) binary_value = [digit & 0xFF] except ValueError: return False elif option_type == "bool": if value == "False" or value == "false" or value == 0: binary_value = [0] else: binary_value = [1] elif option_type == "string": binary_value = strlist(value).list() else: binary_value = strlist(value).list() return binary_value
def convert_32bit_to_str(value): return str(ipv4(value).int())
def str(self): # Process headers : printable_data = "# Header fields\n" op = self.packet_data[ DhcpFields['op'][0]:DhcpFields['op'][0] + DhcpFields['op'][1]] printable_data += "op : " + DhcpFieldsName['op'][str(op[0])] + "\n" for opt in ['htype', 'hlen', 'hops', 'xid', 'secs', 'flags', 'ciaddr', 'yiaddr', 'siaddr', 'giaddr', 'chaddr', 'sname', 'file']: begin = DhcpFields[opt][0] end = DhcpFields[opt][0] + DhcpFields[opt][1] data = self.packet_data[begin:end] result = '' if DhcpFieldsTypes[opt] == "int": result = str(data[0]) elif DhcpFieldsTypes[opt] == "int2": result = str(data[0] * 256 + data[1]) elif DhcpFieldsTypes[opt] == "int4": result = str(ipv4(data).int()) elif DhcpFieldsTypes[opt] == "str": for each in data: if each != 0: result += chr(each) else: break elif DhcpFieldsTypes[opt] == "ipv4": result = ipv4(data).str() elif DhcpFieldsTypes[opt] == "hwmac": result = [] hexsym = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'] for iterator in range(6): result += [str(hexsym[data[iterator] / 16] + hexsym[ data[iterator] % 16])] result = ':'.join(result) printable_data += opt + " : " + result + "\n" # Process options : printable_data += "# Options fields\n" for opt in self.options_data.keys(): data = self.options_data[opt] result = "" optnum = DhcpOptions[opt] if opt == 'dhcp_message_type': result = DhcpFieldsName['dhcp_message_type'][str(data[0])] elif DhcpOptionsTypes[optnum] == "char": result = str(data[0]) elif DhcpOptionsTypes[optnum] == "16-bits": result = str(data[0] * 256 + data[0]) elif DhcpOptionsTypes[optnum] == "32-bits": result = str(ipv4(data).int()) elif DhcpOptionsTypes[optnum] == "string": for each in data: if each != 0: result += chr(each) else: break elif DhcpOptionsTypes[optnum] == "ipv4": result = ipv4(data).str() elif DhcpOptionsTypes[optnum] == "ipv4+": for i in range(0, len(data), 4): if len(data[i:i + 4]) == 4: result += ipv4(data[i:i + 4]).str() + " - " elif DhcpOptionsTypes[optnum] == "char+": if optnum == 55: # parameter_request_list result = ','.join([DhcpOptionsList[each] for each in data]) else: result += str(data) printable_data += opt + " : " + result + "\n" return printable_data
#!/usr/bin/python from pydhcplib.type_ipv4 import ipv4 address = ipv4() print("a0 : ", address) address1 = ipv4("192.168.0.1") print("a1 : ", address1) address2 = ipv4("10.0.0.1") print("a2 : ", address2) address3 = ipv4([192, 168, 0, 1]) print("a3 : ", address3) if address1 == address2: print("test 1 : ", address1, "==", address2) else: print("test 1 : " , address1, "!=", address2) if address1 == address3: print("test 2 : ", address1, "==", address3) else: print("test 2 : ", address1, "!=", address3)
#!/usr/bin/python from pydhcplib.dhcp_packet import DhcpPacket from pydhcplib.type_strlist import strlist from pydhcplib.type_ipv4 import ipv4 packet = DhcpPacket() packet.SetOption("domain_name",strlist("anemon.org").list()) packet.SetOption("router",ipv4("192.168.0.1").list()+[6,4,2,1]) packet.SetOption("time_server",[100,100,100,7,6,4,2,1]) packet.SetOption("yiaddr",[192,168,0,18]) packet.PrintHeaders() packet.PrintOptions()
def OptionsToBinary(self, parameter, value): # Transform textual data into dhcp binary data p = parameter.strip() # 1- Search for header informations or specific parameter if p == 'op' or p == 'htype': value = value.strip() if value.isdigit(): return [int(value)] try: value = DhcpNames[value.strip()] return [value] except KeyError: return [0] elif p == 'hlen' or p == 'hops': try: value = int(value) return [value] except ValueError: return [0] elif p == 'secs' or p == 'flags': try: value = ipv4(int(value)).list() except ValueError: value = [0, 0, 0, 0] return value[2:] elif p == 'xid': try: value = ipv4(int(value)).list() except ValueError: value = [0, 0, 0, 0] return value elif p == 'ciaddr' or p == 'yiaddr' or p == 'siaddr' or p == 'giaddr': try: ip = ipv4(value).list() except ValueError: ip = [0, 0, 0, 0] return ip elif p == 'chaddr': try: value = hwmac(value).list() + [0] * 10 except (ValueError, TypeError): value = [0] * 16 return value elif p == 'sname': return elif p == 'file': return elif p == 'parameter_request_list': value = value.strip().split(',') tmp = [] for each in value: if each in DhcpOptions: tmp.append(DhcpOptions[each]) return tmp elif p == 'dhcp_message_type': try: return [DhcpNames[value]] except KeyError: return # 2- Search for options try: option_type = DhcpOptionsTypes[DhcpOptions[parameter]] except KeyError: return False if option_type == "ipv4": # this is a single ip address try: binary_value = map(int, value.split(".")) except ValueError: return False elif option_type == "ipv4+": # this is multiple ip address iplist = value.split(",") opt = [] for single in iplist: opt += (ipv4(single).list()) binary_value = opt elif option_type == "32-bits": # This is probably a number... try: digit = int(value) binary_value = [digit >> 24 & 0xFF, (digit >> 16) & 0xFF, (digit >> 8) & 0xFF, digit & 0xFF] except ValueError: return False elif option_type == "16-bits": try: digit = int(value) binary_value = [(digit >> 8) & 0xFF, digit & 0xFF] except ValueError: return False elif option_type == "char": try: digit = int(value) binary_value = [digit & 0xFF] except ValueError: return False elif option_type == "bool": if value == "False" or value == "false" or value == 0: binary_value = [0] else: binary_value = [1] elif option_type == "string": binary_value = strlist(value).list() else: binary_value = strlist(value).list() return binary_value
#!/usr/bin/python from pydhcplib.dhcp_packet import DhcpPacket from pydhcplib.type_strlist import strlist from pydhcplib.type_ipv4 import ipv4 packet = DhcpPacket() packet.SetOption("op",[1]) #packet.SetOption("domain_name",strlist("anemon.org").list()) packet.SetOption("router",ipv4("1.1.1.1").list()+[6,4,2,1]) packet.SetOption("time_server",[100,100,100,7,6,4,2,1]) packet.SetOption("yiaddr",[0,0,0,0]) packet.SetOption("dhcp_message_type",[1]) packet.SetOption("hlen",[6]) packet.SetOption("chaddr",[1,02,3,4,5,6,0,0,0,0,0,0,0,0,0,0,]) packet.SetOption("htype",[1]) print packet.str() p = packet.EncodePacket() import socket as S s = S.socket(S.AF_INET, S.SOCK_DGRAM, 0) s.setsockopt( S.SOL_SOCKET, S.SO_BROADCAST, 1) s.setsockopt(S.SOL_SOCKET,S.SO_REUSEADDR,1) s.bind( ('1.1.1.106',68) )
def main(): parser = OptionParser() parser.add_option("-s","--server", dest="server", default='0.0.0.0', help="DHCP server IP (default %default)") parser.add_option("-p","--port", type="int", dest="port", default=67, help="DHCP server port (default (%default)") parser.add_option("-m","--mac","--chaddr", dest="chaddr", help="chaddr: Client's MAC address, default random") parser.add_option("-c","--ciaddr", dest="ciaddr", default='0.0.0.0', help="ciaddr: Client's desired IP address") parser.add_option("-g","--giaddr", dest="giaddr", default='0.0.0.0', help="giaddr: Gateway IP address (if any)") parser.add_option("-t","--type", dest="msgtype", type="choice", choices=["discover","request","release"], default="discover", help="DHCP message type: discover, request, release (default %default)") parser.add_option("-w","--timeout", dest="timeout", type="int", default=4, help="UDP timeout (default %default)") parser.add_option("-r","--require", action="append", type="int", default=[1,3,6,51], dest="required_opts", help="Require options by its number") parser.add_option("-y","--cycle", action="store_true", dest="docycle", help="Do full cycle: DISCOVERY, REQUEST, RELEASE") parser.add_option("-n","--cycles", dest="cycles", type="int", default="1", help="Do number of cycles (default %default)") parser.add_option("-v","--verbose", action="store_true", dest="verbose", help="Verbose operation") parser.add_option("-q","--quiet", action="store_false", dest="verbose", help="Quiet operation") parser.add_option("--nagios", action="store_true", dest="nagios", help="Nagios mode of operation") (opts, args) = parser.parse_args() if not opts.chaddr: chaddr = genmac() else: chaddr = opts.chaddr if opts.nagios: opts.verbose = False verbose = opts.verbose if opts.docycle: request_dhcp_message_type = "discover" else: request_dhcp_message_type = opts.msgtype request_ciaddr = opts.ciaddr serverip = opts.server cycleno = 1 xid = genxid() while True: if opts.cycles > 1 and opts.verbose is not False and (not opts.docycle or request_dhcp_message_type == "discover"): print "="*100 print "| Cycle %s"%cycleno print "="*100 req = preparePacket(xid=xid, giaddr=opts.giaddr, chaddr=chaddr, ciaddr=request_ciaddr, msgtype=request_dhcp_message_type, required_opts=opts.required_opts) if verbose != False: print "Sending %s [%s] packet to %s"%(request_dhcp_message_type.upper(),chaddr, opts.server) if verbose == True: print "-"*100 #req.PrintHeaders() #req.PrintOptions() print "="*100 print "\n" try: res = receivePacket(serverip=serverip, serverport=opts.port, timeout=opts.timeout, req=req) except socket.timeout: res = None if opts.nagios: nagiosExit(2,"%s request has been timed out."%request_dhcp_message_type.upper()) if verbose != False: print "Timed out." pass if res: dhcp_message_type = res.GetOption('dhcp_message_type')[0] server_identifier = ipv4(res.GetOption('server_identifier')) chaddr = hwmac(res.GetOption('chaddr')[:6]) yiaddr = ipv4(res.GetOption('yiaddr')) if opts.nagios and dhcp_message_type not in (2, 5): nagiosExit(2,"Got %s response for our %s request"%(dhcpTypes.get(dhcp_message_type,'UNKNOWN'),dhcpTypes.get(request_dhcp_message_type,'UNKNOWN'))) if verbose != False: print "Received %s packet from %s; [%s] was bound to %s"%(dhcpTypes.get(dhcp_message_type,'UNKNOWN'), server_identifier, chaddr, yiaddr ) if verbose == True: print "-"*100 res.PrintHeaders() res.PrintOptions() print "="*100 print "\n" if opts.docycle: if dhcp_message_type == 2: request_dhcp_message_type = 'request' request_ciaddr = yiaddr.str() serverip = server_identifier.str() continue if dhcp_message_type == 5: request_dhcp_message_type = 'release' request_ciaddr = yiaddr.str() serverip = server_identifier.str() continue cycleno += 1 if cycleno > opts.cycles: if opts.nagios: if res: nagiosExit(0,"%s finished successfully: %s. yiaddr: %s, chaddr: %s"%( request_dhcp_message_type.upper(), dhcpTypes.get(dhcp_message_type,'UNKNOWN'), yiaddr, chaddr, )) elif opts.docycle: nagiosExit(0,"Cycle has been finished successfully. Got %s for %s"%(yiaddr,chaddr)) else: nagiosExit(0,"%s has been finished without the answer"%(request_dhcp_message_type.upper())) break if opts.docycle: request_dhcp_message_type = "discover" request_ciaddr = opts.ciaddr serverip = opts.server xid = genxid() if not opts.chaddr: chaddr = genmac() else: chaddr = opts.chaddr
def convert_ipv4_to_str(value): return str(ipv4(value).int())
#!/usr/bin/python from pydhcplib.dhcp_packet import DhcpPacket from pydhcplib.type_strlist import strlist from pydhcplib.type_ipv4 import ipv4 packet = DhcpPacket() packet.SetOption("domain_name", strlist("anemon.org").list()) packet.SetOption("router", ipv4("192.168.0.1").list() + [6, 4, 2, 1]) packet.SetOption("time_server", [100, 100, 100, 7, 6, 4, 2, 1]) packet.SetOption("yiaddr", [192, 168, 0, 18]) packet.PrintHeaders() packet.PrintOptions()
#!/usr/bin/python from pydhcplib.dhcp_packet import DhcpPacket from pydhcplib.type_strlist import strlist from pydhcplib.type_ipv4 import ipv4 packet = DhcpPacket() packet.SetOption("op", [1]) #packet.SetOption("domain_name",strlist("anemon.org").list()) packet.SetOption("router", ipv4("1.1.1.1").list() + [6, 4, 2, 1]) packet.SetOption("time_server", [100, 100, 100, 7, 6, 4, 2, 1]) packet.SetOption("yiaddr", [0, 0, 0, 0]) packet.SetOption("dhcp_message_type", [1]) packet.SetOption("hlen", [6]) packet.SetOption("chaddr", [ 1, 02, 3, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,