Example #1
0
class Dot11EltMicrosoftWPA(Dot11Elt):
    name = "802.11 Microsoft WPA"
    match_subclass = True
    fields_desc = [
        ByteField("ID", 221),
        ByteField("len", None),
        X3BytesField("oui", 0x0050f2),
        XByteField("type", 0x01),
        LEShortField("version", 1),
        PacketField("group_cipher_suite", RSNCipherSuite(), RSNCipherSuite),
        LEFieldLenField("nb_pairwise_cipher_suites",
                        1,
                        count_of="pairwise_cipher_suites"),
        PacketListField("pairwise_cipher_suites",
                        RSNCipherSuite(),
                        RSNCipherSuite,
                        count_from=lambda p: p.nb_pairwise_cipher_suites),
        LEFieldLenField("nb_akm_suites", 1, count_of="akm_suites"),
        PacketListField("akm_suites",
                        AKMSuite(),
                        AKMSuite,
                        count_from=lambda p: p.nb_akm_suites)
    ]
Example #2
0
class NSH(Packet):
    """Network Service Header.
       NSH MD-type 1 if there is no ContextHeaders"""
    name = "NSH"

    fields_desc = [
        BitField('Ver', 0, 2),
        BitField('OAM', 0, 1),
        BitField('Critical', 0, 1),
        BitField('Reserved', 0, 6),
        BitField('Len', 0, 6),
        ByteEnumField('MDType', 1, {
            1: 'Fixed Length',
            2: 'Variable Length'
        }),
        ByteEnumField('NextProto', 3, {
            1: 'IPv4',
            2: 'IPv6',
            3: 'Ethernet',
            4: 'NSH',
            5: 'MPLS'
        }),
        X3BytesField('NSP', 0),
        ByteField('NSI', 1),
        ConditionalField(XIntField('NPC', 0), lambda pkt: pkt.MDType == 1),
        ConditionalField(XIntField('NSC', 0), lambda pkt: pkt.MDType == 1),
        ConditionalField(XIntField('SPC', 0), lambda pkt: pkt.MDType == 1),
        ConditionalField(XIntField('SSC', 0), lambda pkt: pkt.MDType == 1),
        ConditionalField(
            PacketListField("ContextHeaders",
                            None,
                            NSHTLV,
                            count_from="Length"), lambda pkt: pkt.MDType == 2)
    ]

    def mysummary(self):
        return self.sprintf("NSP: %NSP% - NSI: %NSI%")
Example #3
0
class RSNCipherSuite(Packet):
    name = "Cipher suite"
    fields_desc = [
        X3BytesField("oui", 0x000fac),
        ByteEnumField("cipher", 0x04, {
            0x00: "Use group cipher suite",
            0x01: "WEP-40",
            0x02: "TKIP",
            0x03: "OCB",
            0x04: "CCMP",
            0x05: "WEP-104",
            0x06: "BIP-128",
            0x07: "Group addressed traffic not allowed",
            0x08: "GCMP-128",
            0x09: "GCMP-256",
            0x0A: "CCMP-256",
            0x0B: "BIP-GMAC-128",
            0x0C: "BIP-GMAC-256",
            0x0D: "BIP-CMAC-256"
        })
    ]

    def extract_padding(self, s):
        return "", s
class SNAP(Packet):
    name = "SNAP"
    fields_desc = [X3BytesField("OUI", 0x000000),
                   XShortEnumField("code", 0x000, ETHER_TYPES)]
Example #5
0
class SD(_SDPacketBase):
    """
    SD Packet

    NOTE :   when adding 'entries' or 'options', do not use list.append()
        method but create a new list
    e.g. :  p = SD()
            p.option_array = [SDOption_Config(),SDOption_IP6_EndPoint()]
    """
    SOMEIP_MSGID_SRVID = 0xffff
    SOMEIP_MSGID_SUBID = 0x1
    SOMEIP_MSGID_EVENTID = 0x100
    SOMEIP_PROTO_VER = 0x01
    SOMEIP_IFACE_VER = 0x01
    SOMEIP_MSG_TYPE = SOMEIP.TYPE_NOTIFICATION

    _sdFlag = collections.namedtuple('Flag', 'mask offset')
    FLAGSDEF = {
        "REBOOT": _sdFlag(mask=0x80, offset=7),
        "UNICAST": _sdFlag(mask=0x40, offset=6)
    }

    name = "SD"
    fields_desc = [
        ByteField("flags", 0),
        X3BytesField("res", 0),
        FieldLenField("len_entry_array",
                      None,
                      length_of="entry_array",
                      fmt="!I"),
        PacketListField("entry_array",
                        None,
                        cls=_SDEntry,
                        length_from=lambda pkt: pkt.len_entry_array),
        FieldLenField("len_option_array",
                      None,
                      length_of="option_array",
                      fmt="!I"),
        PacketListField("option_array",
                        None,
                        cls=_SDOption,
                        length_from=lambda pkt: pkt.len_option_array)
    ]

    def get_flag(self, name):
        name = name.upper()
        if (name in self.FLAGSDEF):
            return ((self.flags & self.FLAGSDEF[name].mask) >>
                    self.FLAGSDEF[name].offset)
        else:
            return None

    def set_flag(self, name, value):
        name = name.upper()
        if (name in self.FLAGSDEF):
            self.flags = (self.flags &
                          (ctypes.c_ubyte(~self.FLAGSDEF[name].mask).value)) \
                | ((value & 0x01) << self.FLAGSDEF[name].offset)

    def set_entryArray(self, entry_list):
        if (isinstance(entry_list, list)):
            self.entry_array = entry_list
        else:
            self.entry_array = [entry_list]

    def set_optionArray(self, option_list):
        if (isinstance(option_list, list)):
            self.option_array = option_list
        else:
            self.option_array = [option_list]

    def get_someip(self, stacked=False):
        p = SOMEIP()
        p.msg_id.srv_id = SD.SOMEIP_MSGID_SRVID
        p.msg_id.sub_id = SD.SOMEIP_MSGID_SUBID
        p.msg_id.event_id = SD.SOMEIP_MSGID_EVENTID
        p.proto_ver = SD.SOMEIP_PROTO_VER
        p.iface_ver = SD.SOMEIP_IFACE_VER
        p.msg_type = SD.SOMEIP_MSG_TYPE

        if (stacked):
            return (p / self)
        else:
            return (p)
Example #6
0
class GTPPDUSessionContainer(Packet):
    # TS 38.415-g30 sect 5
    name = "GTP PDU Session Container"
    deprecated_fields = {
        "qmp": ("QMP", "2.4.5"),
        "P": ("PPP", "2.4.5"),
        "R": ("RQI", "2.4.5"),
        "extraPadding": ("padding", "2.4.5"),
    }
    fields_desc = [ByteField("ExtHdrLen", None),
                   BitEnumField("type", 0, 4,
                                {0: "DL PDU SESSION INFORMATION",
                                 1: "UL PDU SESSION INFORMATION"}),
                   BitField("QMP", 0, 1),
                   # UL (type 1)
                   ConditionalField(BitField("dlDelayInd", 0, 1),
                                    lambda pkt: pkt.type == 1),
                   ConditionalField(BitField("ulDelayInd", 0, 1),
                                    lambda pkt: pkt.type == 1),
                   # Common
                   BitField("SNP", 0, 1),
                   # UL (type 1)
                   ConditionalField(BitField("N3N9DelayInd", 0, 1),
                                    lambda pkt: pkt.type == 1),
                   ConditionalField(XBitField("spareUl1", 0, 1),
                                    lambda pkt: pkt.type == 1),
                   # DL (type 0)
                   ConditionalField(XBitField("spareDl1", 0, 2),
                                    lambda pkt: pkt.type == 0),
                   ConditionalField(BitField("PPP", 0, 1),
                                    lambda pkt: pkt.type == 0),
                   ConditionalField(BitField("RQI", 0, 1),
                                    lambda pkt: pkt.type == 0),
                   # Common
                   BitField("QFI", 0, 6),  # QoS Flow Identifier
                   # DL (type 0)
                   ConditionalField(XBitField("PPI", 0, 3),
                                    lambda pkt: pkt.type == 0 and
                                    pkt.PPP == 1),
                   ConditionalField(XBitField("spareDl2", 0, 5),
                                    lambda pkt: pkt.type == 0 and
                                    pkt.PPP == 1),
                   ConditionalField(XBitField("dlSendTime", 0, 64),
                                    lambda pkt: pkt.type == 0 and
                                    pkt.QMP == 1),
                   ConditionalField(X3BytesField("dlQFISeqNum", 0),
                                    lambda pkt: pkt.type == 0 and
                                    pkt.SNP == 1),
                   # UL (type 1)
                   ConditionalField(XBitField("dlSendTimeRpt", 0, 64),
                                    lambda pkt: pkt.type == 1 and
                                    pkt.QMP == 1),
                   ConditionalField(XBitField("dlRecvTime", 0, 64),
                                    lambda pkt: pkt.type == 1 and
                                    pkt.QMP == 1),
                   ConditionalField(XBitField("ulSendTime", 0, 64),
                                    lambda pkt: pkt.type == 1 and
                                    pkt.QMP == 1),
                   ConditionalField(XBitField("dlDelayRslt", 0, 32),
                                    lambda pkt: pkt.type == 1 and
                                    pkt.dlDelayInd == 1),
                   ConditionalField(XBitField("ulDelayRslt", 0, 32),
                                    lambda pkt: pkt.type == 1 and
                                    pkt.ulDelayInd == 1),
                   ConditionalField(XBitField("UlQFISeqNum", 0, 24),
                                    lambda pkt: pkt.type == 1 and
                                    pkt.SNP == 1),
                   ConditionalField(XBitField("N3N9DelayRslt", 0, 32),
                                    lambda pkt: pkt.type == 1 and
                                    pkt.N3N9DelayInd == 1),
                   # Common
                   ByteEnumField("NextExtHdr", 0, ExtensionHeadersTypes),
                   ConditionalField(
                       StrLenField("padding", b"", length_from=lambda p: 0),
                       lambda pkt: pkt.NextExtHdr == 0)]

    def guess_payload_class(self, payload):
        if self.NextExtHdr == 0:
            sub_proto = orb(payload[0])
            if sub_proto >= 0x45 and sub_proto <= 0x4e:
                return IP
            elif (sub_proto & 0xf0) == 0x60:
                return IPv6
            else:
                return PPP
        return GTPHeader.guess_payload_class(self, payload)

    def post_dissect(self, s):
        if self.NextExtHdr == 0:
            # Padding is handled in this layer
            length = len(self.original) - len(s)
            pad_length = (- length) % 4
            self.padding = s[:pad_length]
            return s[pad_length:]
        return s

    def post_build(self, p, pay):
        # Length
        if self.NextExtHdr == 0:
            p += b"\x00" * ((-len(p)) % 4)
        else:
            pay += b"\x00" * ((-len(p + pay)) % 4)
        if self.ExtHdrLen is None:
            p = struct.pack("!B", len(p) // 4) + p[1:]
        return p + pay
Example #7
0
class BTLE(Packet):
    name = "BT4LE"
    fields_desc = [
        XLEIntField("access_addr", 0x8E89BED6),
        X3BytesField("crc", None)
    ]

    @staticmethod
    def compute_crc(pdu, init=0x555555):
        def swapbits(a):
            v = 0
            if a & 0x80 != 0:
                v |= 0x01
            if a & 0x40 != 0:
                v |= 0x02
            if a & 0x20 != 0:
                v |= 0x04
            if a & 0x10 != 0:
                v |= 0x08
            if a & 0x08 != 0:
                v |= 0x10
            if a & 0x04 != 0:
                v |= 0x20
            if a & 0x02 != 0:
                v |= 0x40
            if a & 0x01 != 0:
                v |= 0x80
            return v

        state = swapbits(init & 0xff) + (swapbits((init >> 8) & 0xff) << 8) + (
            swapbits((init >> 16) & 0xff) << 16)  # noqa: E501
        lfsr_mask = 0x5a6000
        for i in (orb(x) for x in pdu):
            for j in range(8):
                next_bit = (state ^ i) & 1
                i >>= 1
                state >>= 1
                if next_bit:
                    state |= 1 << 23
                    state ^= lfsr_mask
        return struct.pack("<L", state)[:-1]

    def post_build(self, p, pay):
        # Switch payload and CRC
        crc = p[-3:]
        p = p[:-3] + pay
        p += crc if self.crc is not None else self.compute_crc(p[4:])
        return p

    def post_dissect(self, s):
        self.raw_packet_cache = None  # Reset packet to allow post_build
        return s

    def pre_dissect(self, s):
        # move crc
        return s[:4] + s[-3:] + s[4:-3]

    def post_dissection(self, pkt):
        if isinstance(pkt, PPI):
            pkt.notdecoded = PPIGenericFldHdr(pkt.notdecoded)

    def hashret(self):
        return struct.pack("!L", self.access_addr)
Example #8
0
class EOAM_VendSpecificMsg(Packet):
    name = "Vendor-Specific OAM"
    fields_desc = [
        X3BytesField("oui", 0x001000),
    ]
Example #9
0
class DlChannelReq(Packet):
    name = "DlChannelReq"
    fields_desc = [ByteField("ChIndex", 0), X3BytesField("Freq", 0)]
Example #10
0
class KWP_RMBA(Packet):
    name = 'ReadMemoryByAddress'
    fields_desc = [
        X3BytesField('memoryAddress', 0),
        ByteField('memorySize', 0)
    ]
Example #11
0
class SD(_SDPacketBase):
    """
    SD Packet

    NOTE :   when adding 'entries' or 'options', do not use list.append()
        method but create a new list
    e.g. :  p = SD()
            p.option_array = [SDOption_Config(),SDOption_IP6_EndPoint()]
    """
    SOMEIP_MSGID_SRVID = 0xffff
    SOMEIP_MSGID_SUBID = 0x1
    SOMEIP_MSGID_EVENTID = 0x100
    SOMEIP_CLIENT_ID = 0x0000
    SOMEIP_MINIMUM_SESSION_ID = 0x0001
    SOMEIP_PROTO_VER = 0x01
    SOMEIP_IFACE_VER = 0x01
    SOMEIP_MSG_TYPE = SOMEIP.TYPE_NOTIFICATION
    SOMEIP_RETCODE = SOMEIP.RET_E_OK

    _sdFlag = collections.namedtuple('Flag', 'mask offset')
    FLAGSDEF = {
        "REBOOT": _sdFlag(mask=0x80, offset=7),
        "UNICAST": _sdFlag(mask=0x40, offset=6)
    }

    name = "SD"
    fields_desc = [
        XByteField("flags", 0),
        X3BytesField("res", 0),
        FieldLenField("len_entry_array",
                      None,
                      length_of="entry_array",
                      fmt="!I"),
        PacketListField("entry_array",
                        None,
                        _sdentry_class,
                        length_from=lambda pkt: pkt.len_entry_array),
        FieldLenField("len_option_array",
                      None,
                      length_of="option_array",
                      fmt="!I"),
        PacketListField("option_array",
                        None,
                        _sdoption_class,
                        length_from=lambda pkt: pkt.len_option_array)
    ]

    def get_flag(self, name):
        name = name.upper()
        if name in self.FLAGSDEF:
            return ((self.flags & self.FLAGSDEF[name].mask) >>
                    self.FLAGSDEF[name].offset)
        else:
            return None

    def set_flag(self, name, value):
        name = name.upper()
        if name in self.FLAGSDEF:
            self.flags = (self.flags &
                          (ctypes.c_ubyte(~self.FLAGSDEF[name].mask).value)) \
                | ((value & 0x01) << self.FLAGSDEF[name].offset)

    def set_entryArray(self, entry_list):
        if isinstance(entry_list, list):
            self.entry_array = entry_list
        else:
            self.entry_array = [entry_list]

    def set_optionArray(self, option_list):
        if isinstance(option_list, list):
            self.option_array = option_list
        else:
            self.option_array = [option_list]
Example #12
0
class VXLAN(Packet):
    name = "VXLAN"

    fields_desc = [
        FlagsField(
            "flags", 0x8, 8,
            ['OAM', 'R', 'NextProtocol', 'Instance', 'V1', 'V2', 'R', 'G']),
        ConditionalField(
            ShortField("reserved0", 0),
            lambda pkt: pkt.flags.NextProtocol,
        ),
        ConditionalField(
            ByteEnumField('NextProtocol', 0, {
                0: 'NotDefined',
                1: 'IPv4',
                2: 'IPv6',
                3: 'Ethernet',
                4: 'NSH'
            }),
            lambda pkt: pkt.flags.NextProtocol,
        ),
        ConditionalField(
            ThreeBytesField("reserved1", 0),
            lambda pkt: (not pkt.flags.G) and (not pkt.flags.NextProtocol),
        ),
        ConditionalField(
            FlagsField("gpflags", 0, 8, _GP_FLAGS),
            lambda pkt: pkt.flags.G,
        ),
        ConditionalField(
            ShortField("gpid", 0),
            lambda pkt: pkt.flags.G,
        ),
        X3BytesField("vni", 0),
        XByteField("reserved2", 0),
    ]

    # Use default linux implementation port
    overload_fields = {
        UDP: {
            'dport': 8472
        },
    }

    def mysummary(self):
        if self.flags.G:
            return self.sprintf("VXLAN (vni=%VXLAN.vni% gpid=%VXLAN.gpid%)")
        else:
            return self.sprintf("VXLAN (vni=%VXLAN.vni%)")

    def guess_payload_class(self, payload):
        if self.underlayer is not None and \
                isinstance(self.underlayer, UDP) and \
                self.underlayer.dport == 250 and \
                self.flags == 8:
            try:
                if six.PY2:
                    first_byte = ord(payload[0])
                else:
                    first_byte = payload[0]
            except IndexError:
                return IP

            version = divmod(first_byte, 0x10)[0]
            if version == 4:
                return IP
            elif version == 6:
                return IPv6
            else:
                return IP

        return Packet.guess_payload_class(self, payload)
Example #13
0
class OFPATSetNwToS(OpenFlow):
    name = "OFPAT_SET_TP_TOS"
    fields_desc = [ShortEnumField("type", 8, ofp_action_types),
                   ShortField("len", 8),
                   ByteField("nw_tos", 0),
                   X3BytesField("pad", 0)]
Example #14
0
class OFPATSetVLANPCP(OpenFlow):
    name = "OFPAT_SET_VLAN_PCP"
    fields_desc = [ShortEnumField("type", 2, ofp_action_types),
                   ShortField("len", 8),
                   ByteField("vlan_pcp", 0),
                   X3BytesField("pad", 0)]
Example #15
0
class EOAM_VendSpecificMsg(Packet):
    name = "Vendor-Specific OAM"
    fields_desc = [
        X3BytesField("oui", CABLELABS_OUI),
    ]
Example #16
0
class RXParamSetupReq(Packet):
    name = "RXParamSetupReq"
    fields_desc = [DLsettings, X3BytesField("Frequency", 0)]
Example #17
0
class NewChannelReq(Packet):
    name = "NewChannelReq"
    fields_desc = [ByteField("ChIndex", 0), X3BytesField("Freq", 0), DrRange]
Example #18
0
class RTPSSubMessage_DATA(EPacket):
    """
    0...2...........7...............15.............23...............31
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | RTPS_DATA     |     flags     |      octetsToNextHeader       |
    +---------------+---------------+---------------+---------------+
    | Flags extraFlags              |      octetsToInlineQos        |
    +---------------+---------------+---------------+---------------+
    | EntityId readerEntityId                                       |
    +---------------+---------------+---------------+---------------+
    | EntityId writerEntityId                                       |
    +---------------+---------------+---------------+---------------+
    |                                                               |
    + SequenceNumber writerSeqNum                                   +
    |                                                               |
    +---------------+---------------+---------------+---------------+
    |                                                               |
    ~ ParameterList inlineQos [only if Q==1]                        ~
    |                                                               |
    +---------------+---------------+---------------+---------------+
    |                                                               |
    ~ SerializedData serializedData [only if D==1 || K==1]          ~
    |                                                               |
    +---------------+---------------+---------------+---------------+
    """

    name = "RTPS DATA (0x15)"
    fields_desc = [
        XByteField("submessageId", 0x15),
        XByteField("submessageFlags", 0x00),
        EField(ShortField("octetsToNextHeader", 0)),
        XNBytesField("extraFlags", 0x0000, 2),
        EField(ShortField("octetsToInlineQoS", 0)),
        X3BytesField("readerEntityIdKey", 0),
        XByteField("readerEntityIdKind", 0),
        X3BytesField("writerEntityIdKey", 0),
        XByteField("writerEntityIdKind", 0),
        # EnumField(
        #     "reader_id",
        #     default=b"\x00\x00\x00\x00",
        #     fmt="4s",
        #     enum=_rtps_reserved_entity_ids,
        # ),
        # EnumField(
        #     "writer_id",
        #     default=b"\x00\x00\x00\x00",
        #     fmt="4s",
        #     enum=_rtps_reserved_entity_ids,
        # ),
        EField(IntField("writerSeqNumHi", 0)),
        EField(IntField("writerSeqNumLow", 0)),
        # -------------------------------------
        ConditionalField(
            InlineQoSPacketField("inlineQoS", "", InlineQoSPacket),
            lambda pkt: pkt.submessageFlags & 0b00000010 == 0b00000010,
        ),
        ConditionalField(
            DataPacketField("key", "", DataPacket),
            lambda pkt: pkt.submessageFlags & 0b00001000 == 0b00001000,
        ),
        ConditionalField(
            DataPacketField("data", "", DataPacket),
            lambda pkt: pkt.submessageFlags & 0b00000100 == 0b00000100,
        ),
    ]
Example #19
0
class RejoinReq(Packet):  # LoRa 1.1 specs
    name = "RejoinReq"
    fields_desc = [ByteField("Type", 0),
                   X3BytesField("NetID", 0),
                   StrFixedLenField("DevEUI", b"\x00" * 8),
                   XShortField("RJcount0", 0)]
Example #20
0
class CRX1NewPacketContent(Packet):
    name = "CRX1 New Packet Content"
    fields_desc = [
        XByteEnumField('protocol_number', 0x12, PROTOCOL_NUMBERS),
        # Login
        ConditionalField(
            BCDStrFixedLenField('terminal_id', '00000000', length=8), lambda
            pkt: len(pkt.original) > 5 and pkt.protocol_number == 0x01),
        # GPS Location
        ConditionalField(
            ByteField('year', 0x00), lambda pkt: len(pkt.original) > 5 and pkt.
            protocol_number in (0x12, 0x16)),
        ConditionalField(
            ByteField('month', 0x01), lambda pkt: len(pkt.original) > 5 and pkt
            .protocol_number in (0x12, 0x16)),
        ConditionalField(
            ByteField('day', 0x01), lambda pkt: len(pkt.original) > 5 and pkt.
            protocol_number in (0x12, 0x16)),
        ConditionalField(
            ByteField('hour', 0x00), lambda pkt: len(pkt.original) > 5 and pkt.
            protocol_number in (0x12, 0x16)),
        ConditionalField(
            ByteField('minute', 0x00), lambda pkt: len(pkt.original) > 5 and
            pkt.protocol_number in (0x12, 0x16)),
        ConditionalField(
            ByteField('second', 0x00), lambda pkt: len(pkt.original) > 5 and
            pkt.protocol_number in (0x12, 0x16)),
        ConditionalField(
            BitField('gps_information_length', 0x00, 4), lambda pkt: len(
                pkt.original) > 5 and pkt.protocol_number in (0x12, 0x16)),
        ConditionalField(
            BitField('positioning_satellite_number', 0x00, 4), lambda pkt: len(
                pkt.original) > 5 and pkt.protocol_number in (0x12, 0x16)),
        ConditionalField(
            ScalingField('latitude', 0x00,
                         scaling=1.0 / 1800000, ndigits=6, fmt="!I"),
            lambda pkt: len(pkt.original) > 5 and \
            pkt.protocol_number in (0x12, 0x16)),
        ConditionalField(
            ScalingField('longitude', 0x00,
                         scaling=1.0 / 1800000, ndigits=6, fmt="!I"),
            lambda pkt: len(pkt.original) > 5 and \
            pkt.protocol_number in (0x12, 0x16)),
        ConditionalField(
            ByteField('speed', 0x00), lambda pkt: len(pkt.original) > 5 and pkt
            .protocol_number in (0x12, 0x16)),
        ConditionalField(
            BitField('course', 0x00, 10), lambda pkt: len(pkt.original) > 5 and
            pkt.protocol_number in (0x12, 0x16)),
        ConditionalField(
            BitEnumField('latitude_hemisphere', 0x00, 1, {
                0: "South",
                1: "North"
            }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number in (
                0x12, 0x16)),
        ConditionalField(
            BitEnumField('longitude_hemisphere', 0x00, 1, {
                0: "East",
                1: "West"
            }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number in (
                0x12, 0x16)),
        ConditionalField(
            BitEnumField('gps_been_positioning', 0x00, 1, {
                0: "No",
                1: "Yes"
            }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number in (
                0x12, 0x16)),
        ConditionalField(
            BitEnumField('gps_status', 0x00, 1, {
                0: "GPS real-time",
                1: "Differential positioning"
            }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number in (
                0x12, 0x16)),
        ConditionalField(
            BitField('course_status_reserved', 0x00, 2), lambda pkt: len(
                pkt.original) > 5 and pkt.protocol_number in (0x12, 0x16)),
        ConditionalField(
            ByteField('lbs_length', 0x00),
            lambda pkt: len(pkt.original) > 5 and \
            pkt.protocol_number in (0x16, )),
        ConditionalField(
            XShortField('mcc', 0x00), lambda pkt: len(pkt.original) > 5 and pkt
            .protocol_number in (0x12, 0x16)),
        ConditionalField(
            XByteField('mnc', 0x00), lambda pkt: len(pkt.original) > 5 and pkt.
            protocol_number in (0x12, 0x16)),
        ConditionalField(
            XShortField('lac', 0x00), lambda pkt: len(pkt.original) > 5 and pkt
            .protocol_number in (0x12, 0x16)),
        ConditionalField(
            X3BytesField('cell_id', 0x00),
            lambda pkt: len(pkt.original) > 5 and \
            pkt.protocol_number in (0x12, 0x16)),
        ConditionalField(
            IntField('mileage', 0x00), lambda pkt: len(pkt.original) > 5 and
            pkt.protocol_number in (0x12, ) and len(pkt.original) > 31),
        # Heartbeat
        ConditionalField(
            BitEnumField('defence', 0x00, 1, {
                0: "Deactivated",
                1: "Activated"
            }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number in (
                0x13, 0x16)),
        ConditionalField(
            BitEnumField('acc', 0x00, 1, {
                0: "Low",
                1: "High"
            }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number in (
                0x13, 0x16)),
        ConditionalField(
            BitEnumField('charge', 0x00, 1, {
                0: "Not Charge",
                1: "Charging"
            }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number in (
                0x13, 0x16)),
        ConditionalField(
            BitEnumField(
                'alarm', 0x00, 3, {
                    0: "Normal",
                    1: "Vibration",
                    2: "Power Cut",
                    3: "Low Battery",
                    4: "SOS"
                }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number
            in (0x13, 0x16)),
        ConditionalField(
            BitEnumField('gps_tracking', 0x00, 1, {
                0: "Not Charge",
                1: "Charging"
            }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number in (
                0x13, 0x16)),
        ConditionalField(
            BitEnumField('oil_and_eletricity', 0x00, 1, {
                0: "Connected",
                1: "Disconnected"
            }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number in (
                0x13, 0x16)),
        ConditionalField(
            ByteEnumField("voltage_level", 0x00, VOLTAGE_LEVELS), lambda pkt:
            len(pkt.original) > 5 and pkt.protocol_number in (0x13, 0x16)),
        ConditionalField(
            ByteEnumField("gsm_signal_strength", 0x00,
                          GSM_SIGNAL_STRENGTH), lambda pkt: len(pkt.original) >
            5 and pkt.protocol_number in (0x13, 0x16)),
        # Online Command
        ConditionalField(
            FieldLenField('command_length',
                          None,
                          fmt='B',
                          length_of="command_content"), lambda pkt:
            len(pkt.original) > 5 and pkt.protocol_number in (0x80, 0x15)),
        ConditionalField(
            XIntField('server_flag_bit', 0x00), lambda pkt: len(pkt.original) >
            5 and pkt.protocol_number in (0x80, 0x15)),
        ConditionalField(
            StrLenField(
                "command_content",
                "",
                length_from=lambda pkt: pkt.command_length - 4), lambda pkt:
            len(pkt.original) > 5 and pkt.protocol_number in (0x80, 0x15)),
        # Commun
        ConditionalField(
            ByteEnumField(
                "alarm_extended", 0x00, {
                    0x00: "Normal",
                    0x01: "SOS",
                    0x02: "Power cut",
                    0x03: "Vibration",
                    0x04: "Enter fence",
                    0x05: "Exit fence",
                    0x06: "Over speed",
                    0x09: "Displacement",
                    0x0a: "Enter GPS dead zone",
                    0x0b: "Exit GPS dead zone",
                    0x0c: "Power on",
                    0x0d: "GPS First fix notice",
                    0x0e: "Low battery",
                    0x0f: "Low battery protection",
                    0x10: "SIM Change",
                    0x11: "Power off",
                    0x12: "Airplane mode",
                    0x13: "Disassemble",
                    0x14: "Door",
                    0xfe: "ACC On",
                    0xff: "ACC Off",
                }), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number
            in (0x13, 0x15, 0x16)),
        ConditionalField(
            ByteEnumField("language", 0x00,
                          LANGUAGE), lambda pkt: len(pkt.original) > 5 and pkt.
            protocol_number in (0x13, 0x15, 0x16)),
        # Information transmission
        ConditionalField(
            ByteEnumField("subprotocol_number", 0x00,
                          SUBPROTOCOL_NUMBERS), lambda pkt: len(pkt.original) >
            5 and pkt.protocol_number in (0x94, )),
        ConditionalField(
            ShortField('external_battery',
                       0x00), lambda pkt: len(pkt.original) > 5 and pkt.
            protocol_number in (0x94, ) and pkt.subprotocol_number == 0x00),
        ConditionalField(
            FlagsField('external_io_detection', 0x00, 8, [
                'door_status',
                'trigger_status',
                'io_status',
            ]), lambda pkt: len(pkt.original) > 5 and pkt.protocol_number in (
                0x94, ) and pkt.subprotocol_number == 0x05),
        # Default
        XShortField('information_serial_number', None),
        XShortField('crc', None),
    ]