Esempio n. 1
0
class OFPMatch(Packet):
    name = "OFP_MATCH"
    fields_desc = [
        FlagsField("wildcards1", None, 12, ["DL_VLAN_PCP", "NW_TOS"]),
        BitField("nw_dst_mask", None, 6),
        BitField("nw_src_mask", None, 6),
        FlagsField("wildcards2", None, 8, [
            "IN_PORT", "DL_VLAN", "DL_SRC", "DL_DST", "DL_TYPE", "NW_PROTO",
            "TP_SRC", "TP_DST"
        ]),
        ShortEnumField("in_port", None, ofp_port_no),
        MACField("dl_src", None),
        MACField("dl_dst", None),
        ShortField("dl_vlan", None),
        ByteField("dl_vlan_pcp", None),
        XByteField("pad1", None),
        ShortField("dl_type", None),
        ByteField("nw_tos", None),
        ByteField("nw_proto", None),
        XShortField("pad2", None),
        IPField("nw_src", "0"),
        IPField("nw_dst", "0"),
        ShortField("tp_src", None),
        ShortField("tp_dst", None)
    ]

    def extract_padding(self, s):
        return b"", s

    # with post_build we create the wildcards field bit by bit
    def post_build(self, p, pay):
        # first 10 bits of an ofp_match are always set to 0
        lst_bits = "0" * 10

        # when one field has not been declared, it is assumed to be wildcarded
        if self.wildcards1 is None:
            if self.nw_tos is None:
                lst_bits += "1"
            else:
                lst_bits += "0"
            if self.dl_vlan_pcp is None:
                lst_bits += "1"
            else:
                lst_bits += "0"
        else:
            w1 = binrepr(self.wildcards1)
            lst_bits += "0" * (2 - len(w1))
            lst_bits += w1

        # ip masks use 6 bits each
        if self.nw_dst_mask is None:
            if self.nw_dst is "0":
                lst_bits += "111111"
            # 0x100000 would be ok too (32-bit IP mask)
            else:
                lst_bits += "0" * 6
        else:
            m1 = binrepr(self.nw_dst_mask)
            lst_bits += "0" * (6 - len(m1))
            lst_bits += m1
        if self.nw_src_mask is None:
            if self.nw_src is "0":
                lst_bits += "111111"
            else:
                lst_bits += "0" * 6
        else:
            m2 = binrepr(self.nw_src_mask)
            lst_bits += "0" * (6 - len(m2))
            lst_bits += m2

        # wildcards2 works the same way as wildcards1
        if self.wildcards2 is None:
            if self.tp_dst is None:
                lst_bits += "1"
            else:
                lst_bits += "0"
            if self.tp_src is None:
                lst_bits += "1"
            else:
                lst_bits += "0"
            if self.nw_proto is None:
                lst_bits += "1"
            else:
                lst_bits += "0"
            if self.dl_type is None:
                lst_bits += "1"
            else:
                lst_bits += "0"
            if self.dl_dst is None:
                lst_bits += "1"
            else:
                lst_bits += "0"
            if self.dl_src is None:
                lst_bits += "1"
            else:
                lst_bits += "0"
            if self.dl_vlan is None:
                lst_bits += "1"
            else:
                lst_bits += "0"
            if self.in_port is None:
                lst_bits += "1"
            else:
                lst_bits += "0"
        else:
            w2 = binrepr(self.wildcards2)
            lst_bits += "0" * (8 - len(w2))
            lst_bits += w2

        # In order to write OFPMatch compliant with the specifications,
        # if prereq_autocomplete has been set to True
        # we assume ethertype=IP or nwproto=TCP when appropriate subfields are provided.  # noqa: E501
        if conf.contribs['OPENFLOW']['prereq_autocomplete']:
            if self.dl_type is None:
                if self.nw_src is not "0" or self.nw_dst is not "0" or self.nw_proto is not None or self.nw_tos is not None:  # noqa: E501
                    p = p[:22] + struct.pack("!H", 0x0800) + p[24:]
                    lst_bits = lst_bits[:-5] + "0" + lst_bits[-4:]
            if self.nw_proto is None:
                if self.tp_src is not None or self.tp_dst is not None:
                    p = p[:22] + struct.pack("!H", 0x0800) + p[24:]
                    lst_bits = lst_bits[:-5] + "0" + lst_bits[-4:]
                    p = p[:25] + struct.pack("!B", 0x06) + p[26:]
                    lst_bits = lst_bits[:-6] + "0" + lst_bits[-5:]

        ins = b"".join(
            chb(int("".join(x), 2))
            for x in zip(*[iter(lst_bits)] * 8))  # noqa: E501
        p = ins + p[4:]
        return p + pay
Esempio n. 2
0
class DNS(Packet):
    name = "DNS"
    fields_desc = [
        ConditionalField(ShortField("length", None),
                         lambda p: isinstance(p.underlayer, TCP)),
        ShortField("id", 0),
        BitField("qr", 0, 1),
        BitEnumField("opcode", 0, 4, {0: "QUERY", 1: "IQUERY", 2: "STATUS"}),
        BitField("aa", 0, 1),
        BitField("tc", 0, 1),
        BitField("rd", 1, 1),
        BitField("ra", 0, 1),
        BitField("z", 0, 1),
        # AD and CD bits are defined in RFC 2535
        BitField("ad", 0, 1),  # Authentic Data
        BitField("cd", 0, 1),  # Checking Disabled
        BitEnumField("rcode", 0, 4, {0: "ok", 1: "format-error",
                                     2: "server-failure", 3: "name-error",
                                     4: "not-implemented", 5: "refused"}),
        DNSRRCountField("qdcount", None, "qd"),
        DNSRRCountField("ancount", None, "an"),
        DNSRRCountField("nscount", None, "ns"),
        DNSRRCountField("arcount", None, "ar"),
        DNSQRField("qd", "qdcount"),
        DNSRRField("an", "ancount"),
        DNSRRField("ns", "nscount"),
        DNSRRField("ar", "arcount", 0),
    ]

    def answers(self, other):
        return (isinstance(other, DNS) and
                self.id == other.id and
                self.qr == 1 and
                other.qr == 0)

    def mysummary(self):
        name = ""
        if self.qr:
            type = "Ans"
            if self.ancount > 0 and isinstance(self.an, DNSRR):
                name = ' "%s"' % self.an.rdata
        else:
            type = "Qry"
            if self.qdcount > 0 and isinstance(self.qd, DNSQR):
                name = ' "%s"' % self.qd.qname
        return 'DNS %s%s ' % (type, name)

    def post_build(self, pkt, pay):
        if isinstance(self.underlayer, TCP) and self.length is None:
            pkt = struct.pack("!H", len(pkt) - 2) + pkt[2:]
        return pkt + pay

    def compress(self):
        """Return the compressed DNS packet (using `dns_compress()`"""
        return dns_compress(self)

    def pre_dissect(self, s):
        """
        Check that a valid DNS over TCP message can be decoded
        """
        if isinstance(self.underlayer, TCP):

            # Compute the length of the DNS packet
            if len(s) >= 2:
                dns_len = struct.unpack("!H", s[:2])[0]
            else:
                message = "Malformed DNS message: too small!"
                log_runtime.info(message)
                raise Scapy_Exception(message)

            # Check if the length is valid
            if dns_len < 14 or len(s) < dns_len:
                message = "Malformed DNS message: invalid length!"
                log_runtime.info(message)
                raise Scapy_Exception(message)

        return s
Esempio n. 3
0
 def __init__(self, name, default, calculate_length=None):
     BitField.__init__(self, name, default, 0)
     self.length_f = calculate_length
Esempio n. 4
0
 def getfield(self, pkt, s):
     self.size = self.length_f(pkt)
     return BitField.getfield(self, pkt, s)
Esempio n. 5
0
class LLDPDUManagementAddress(LLDPDU):
    """
        ieee 802.1ab-2016 - sec. 8.5.9 / p. 32

        currently only 0x00..0x1e are used by standards, no way to
        use anything > 0xff as management address subtype is only
        one octet wide

        see https://www.iana.org/assignments/
        address-family-numbers/address-family-numbers.xhtml
    """
    IANA_ADDRESS_FAMILY_NUMBERS = {
        0x00: 'other',
        0x01: 'IPv4',
        0x02: 'IPv6',
        0x03: 'NSAP',
        0x04: 'HDLC',
        0x05: 'BBN',
        0x06: '802',
        0x07: 'E.163',
        0x08: 'E.164',
        0x09: 'F.69',
        0x0a: 'X.121',
        0x0b: 'IPX',
        0x0c: 'Appletalk',
        0x0d: 'Decnet IV',
        0x0e: 'Banyan Vines',
        0x0f: 'E.164 with NSAP',
        0x10: 'DNS',
        0x11: 'Distinguished Name',
        0x12: 'AS Number',
        0x13: 'XTP over IPv4',
        0x14: 'XTP over IPv6',
        0x15: 'XTP native mode XTP',
        0x16: 'Fiber Channel World-Wide Port Name',
        0x17: 'Fiber Channel World-Wide Node Name',
        0x18: 'GWID',
        0x19: 'AFI for L2VPN',
        0x1a: 'MPLS-TP Section Endpoint ID',
        0x1b: 'MPLS-TP LSP Endpoint ID',
        0x1c: 'MPLS-TP Pseudowire Endpoint ID',
        0x1d: 'MT IP Multi-Topology IPv4',
        0x1e: 'MT IP Multi-Topology IPv6'
    }

    SUBTYPE_MANAGEMENT_ADDRESS_OTHER = 0x00
    SUBTYPE_MANAGEMENT_ADDRESS_IPV4 = 0x01
    SUBTYPE_MANAGEMENT_ADDRESS_IPV6 = 0x02
    SUBTYPE_MANAGEMENT_ADDRESS_NSAP = 0x03
    SUBTYPE_MANAGEMENT_ADDRESS_HDLC = 0x04
    SUBTYPE_MANAGEMENT_ADDRESS_BBN = 0x05
    SUBTYPE_MANAGEMENT_ADDRESS_802 = 0x06
    SUBTYPE_MANAGEMENT_ADDRESS_E_163 = 0x07
    SUBTYPE_MANAGEMENT_ADDRESS_E_164 = 0x08
    SUBTYPE_MANAGEMENT_ADDRESS_F_69 = 0x09
    SUBTYPE_MANAGEMENT_ADDRESS_X_121 = 0x0A
    SUBTYPE_MANAGEMENT_ADDRESS_IPX = 0x0B
    SUBTYPE_MANAGEMENT_ADDRESS_APPLETALK = 0x0C
    SUBTYPE_MANAGEMENT_ADDRESS_DECNET_IV = 0x0D
    SUBTYPE_MANAGEMENT_ADDRESS_BANYAN_VINES = 0x0E
    SUBTYPE_MANAGEMENT_ADDRESS_E_164_WITH_NSAP = 0x0F
    SUBTYPE_MANAGEMENT_ADDRESS_DNS = 0x10
    SUBTYPE_MANAGEMENT_ADDRESS_DISTINGUISHED_NAME = 0x11
    SUBTYPE_MANAGEMENT_ADDRESS_AS_NUMBER = 0x12
    SUBTYPE_MANAGEMENT_ADDRESS_XTP_OVER_IPV4 = 0x13
    SUBTYPE_MANAGEMENT_ADDRESS_XTP_OVER_IPV6 = 0x14
    SUBTYPE_MANAGEMENT_ADDRESS_XTP_NATIVE_MODE_XTP = 0x15
    SUBTYPE_MANAGEMENT_ADDRESS_FIBER_CHANNEL_WORLD_WIDE_PORT_NAME = 0x16
    SUBTYPE_MANAGEMENT_ADDRESS_FIBER_CHANNEL_WORLD_WIDE_NODE_NAME = 0x17
    SUBTYPE_MANAGEMENT_ADDRESS_GWID = 0x18
    SUBTYPE_MANAGEMENT_ADDRESS_AFI_FOR_L2VPN = 0x19
    SUBTYPE_MANAGEMENT_ADDRESS_MPLS_TP_SECTION_ENDPOINT_ID = 0x1A
    SUBTYPE_MANAGEMENT_ADDRESS_MPLS_TP_LSP_ENDPOINT_ID = 0x1B
    SUBTYPE_MANAGEMENT_ADDRESS_MPLS_TP_PSEUDOWIRE_ENDPOINT_ID = 0x1C
    SUBTYPE_MANAGEMENT_ADDRESS_MT_IP_MULTI_TOPOLOGY_IPV4 = 0x1D
    SUBTYPE_MANAGEMENT_ADDRESS_MT_IP_MULTI_TOPOLOGY_IPV6 = 0x1E

    INTERFACE_NUMBERING_SUBTYPES = {
        0x01: 'unknown',
        0x02: 'ifIndex',
        0x03: 'system port number'
    }

    SUBTYPE_INTERFACE_NUMBER_UNKNOWN = 0x01
    SUBTYPE_INTERFACE_NUMBER_IF_INDEX = 0x02
    SUBTYPE_INTERFACE_NUMBER_SYSTEM_PORT_NUMBER = 0x03
    '''
        Note - calculation of _length field:
        _length = 1@_management_address_string_length +
                  1@management_address_subtype +
                  management_address.len +
                  1@interface_numbering_subtype +
                  4@interface_number +
                  1@_oid_string_length +
                  object_id.len
    '''

    fields_desc = [
        BitEnumField('_type', 0x08, 7, LLDPDU.TYPES),
        BitFieldLenField('_length',
                         None,
                         9,
                         length_of='management_address',
                         adjust=lambda pkt, x: 8 + len(pkt.management_address)
                         + len(pkt.object_id)),
        BitFieldLenField(
            '_management_address_string_length',
            None,
            8,
            length_of='management_address',
            adjust=lambda pkt, x: len(pkt.management_address) + 1),
        ByteEnumField('management_address_subtype', 0x00,
                      IANA_ADDRESS_FAMILY_NUMBERS),
        XStrLenField(
            'management_address',
            '',
            length_from=lambda pkt: pkt._management_address_string_length - 1),
        ByteEnumField('interface_numbering_subtype',
                      SUBTYPE_INTERFACE_NUMBER_UNKNOWN,
                      INTERFACE_NUMBERING_SUBTYPES),
        BitField('interface_number', 0, 32),
        BitFieldLenField('_oid_string_length', None, 8, length_of='object_id'),
        XStrLenField('object_id',
                     '',
                     length_from=lambda pkt: pkt._oid_string_length),
    ]

    def _check(self):
        """
        run layer specific checks
        """
        if conf.contribs['LLDP'].strict_mode():
            management_address_len = len(self.management_address)
            if management_address_len == 0 or management_address_len > 31:
                raise LLDPInvalidLengthField(
                    'management address must be  1..31 characters long - '
                    'got string of size {}'.format(management_address_len))
Esempio n. 6
0
class ZigbeeNWKCommandPayload(Packet):
    name = "Zigbee Network Layer Command Payload"
    fields_desc = [
        ByteEnumField("cmd_identifier", 1, {
            1: "route request",
            2: "route reply",
            3: "network status",
            4: "leave",
            5: "route record",
            6: "rejoin request",
            7: "rejoin response",
            8: "link status",
            9: "network report",
            10: "network update",
            11: "end device timeout request",
            12: "end device timeout response"
            # 0x0d - 0xff reserved
        }),

        # - Route Request Command - #
        # Command options (1 octet)
        ConditionalField(BitField("res1", 0, 1),
                         lambda pkt: pkt.cmd_identifier in [1, 2]),
        ConditionalField(BitField("multicast", 0, 1),
                         lambda pkt: pkt.cmd_identifier in [1, 2]),
        ConditionalField(BitField("dest_addr_bit", 0, 1), lambda pkt: pkt.cmd_identifier == 1),  # noqa: E501
        ConditionalField(
            BitEnumField("many_to_one", 0, 2, {
                0: "not_m2one", 1: "m2one_support_rrt", 2: "m2one_no_support_rrt", 3: "reserved"}  # noqa: E501
            ), lambda pkt: pkt.cmd_identifier == 1),
        ConditionalField(BitField("res2", 0, 3), lambda pkt: pkt.cmd_identifier == 1),  # noqa: E501

        # - Route Reply Command - #
        # Command options (1 octet)
        ConditionalField(BitField("responder_addr_bit", 0, 1), lambda pkt: pkt.cmd_identifier == 2),  # noqa: E501
        ConditionalField(BitField("originator_addr_bit", 0, 1), lambda pkt: pkt.cmd_identifier == 2),  # noqa: E501
        ConditionalField(BitField("res3", 0, 4), lambda pkt: pkt.cmd_identifier == 2),  # noqa: E501
        # Route request identifier (1 octet)
        ConditionalField(ByteField("route_request_identifier", 0),
                         lambda pkt: pkt.cmd_identifier in [1, 2]),  # noqa: E501
        # Originator address (2 octets)
        ConditionalField(XLEShortField("originator_address", 0x0000), lambda pkt: pkt.cmd_identifier == 2),  # noqa: E501
        # Responder address (2 octets)
        ConditionalField(XLEShortField("responder_address", 0x0000), lambda pkt: pkt.cmd_identifier == 2),  # noqa: E501

        # - Network Status Command - #
        # Status code (1 octet)
        ConditionalField(ByteEnumField("status_code", 0, {
            0x00: "No route available",
            0x01: "Tree link failure",
            0x02: "Non-tree link failure",
            0x03: "Low battery level",
            0x04: "No routing capacity",
            0x05: "No indirect capacity",
            0x06: "Indirect transaction expiry",
            0x07: "Target device unavailable",
            0x08: "Target address unallocated",
            0x09: "Parent link failure",
            0x0a: "Validate route",
            0x0b: "Source route failure",
            0x0c: "Many-to-one route failure",
            0x0d: "Address conflict",
            0x0e: "Verify addresses",
            0x0f: "PAN identifier update",
            0x10: "Network address update",
            0x11: "Bad frame counter",
            0x12: "Bad key sequence number",
            # 0x13 - 0xff Reserved
        }), lambda pkt: pkt.cmd_identifier == 3),
        # Destination address (2 octets)
        ConditionalField(XLEShortField("destination_address", 0x0000),
                         lambda pkt: pkt.cmd_identifier in [1, 3]),
        # Path cost (1 octet)
        ConditionalField(ByteField("path_cost", 0),
                         lambda pkt: pkt.cmd_identifier in [1, 2]),  # noqa: E501
        # Destination IEEE Address (0/8 octets), only present when dest_addr_bit has a value of 1  # noqa: E501
        ConditionalField(dot15d4AddressField("ext_dst", 0, adjust=lambda pkt, x: 8),  # noqa: E501
                         lambda pkt: (pkt.cmd_identifier == 1 and pkt.dest_addr_bit == 1)),  # noqa: E501
        # Originator IEEE address (0/8 octets)
        ConditionalField(dot15d4AddressField("originator_addr", 0, adjust=lambda pkt, x: 8),  # noqa: E501
                         lambda pkt: (pkt.cmd_identifier == 2 and pkt.originator_addr_bit == 1)),  # noqa: E501
        # Responder IEEE address (0/8 octets)
        ConditionalField(dot15d4AddressField("responder_addr", 0, adjust=lambda pkt, x: 8),  # noqa: E501
                         lambda pkt: (pkt.cmd_identifier == 2 and pkt.responder_addr_bit == 1)),  # noqa: E501

        # - Leave Command - #
        # Command options (1 octet)
        # Bit 7: Remove children
        ConditionalField(BitField("remove_children", 0, 1), lambda pkt: pkt.cmd_identifier == 4),  # noqa: E501
        # Bit 6: Request
        ConditionalField(BitField("request", 0, 1), lambda pkt: pkt.cmd_identifier == 4),  # noqa: E501
        # Bit 5: Rejoin
        ConditionalField(BitField("rejoin", 0, 1), lambda pkt: pkt.cmd_identifier == 4),  # noqa: E501
        # Bit 0 - 4: Reserved
        ConditionalField(BitField("res4", 0, 5), lambda pkt: pkt.cmd_identifier == 4),  # noqa: E501

        # - Route Record Command - #
        # Relay count (1 octet)
        ConditionalField(ByteField("rr_relay_count", 0), lambda pkt: pkt.cmd_identifier == 5),  # noqa: E501
        # Relay list (variable in length)
        ConditionalField(
            FieldListField("rr_relay_list", [], XLEShortField("", 0x0000), count_from=lambda pkt:pkt.rr_relay_count),  # noqa: E501
            lambda pkt:pkt.cmd_identifier == 5),

        # - Rejoin Request Command - #
        # Capability Information (1 octet)
        ConditionalField(BitField("allocate_address", 0, 1), lambda pkt:pkt.cmd_identifier == 6),  # Allocate Address  # noqa: E501
        ConditionalField(BitField("security_capability", 0, 1), lambda pkt:pkt.cmd_identifier == 6),  # Security Capability  # noqa: E501
        ConditionalField(BitField("reserved2", 0, 1), lambda pkt:pkt.cmd_identifier == 6),  # bit 5 is reserved  # noqa: E501
        ConditionalField(BitField("reserved1", 0, 1), lambda pkt:pkt.cmd_identifier == 6),  # bit 4 is reserved  # noqa: E501
        ConditionalField(BitField("receiver_on_when_idle", 0, 1), lambda pkt:pkt.cmd_identifier == 6),  # Receiver On When Idle  # noqa: E501
        ConditionalField(BitField("power_source", 0, 1), lambda pkt:pkt.cmd_identifier == 6),  # Power Source  # noqa: E501
        ConditionalField(BitField("device_type", 0, 1), lambda pkt:pkt.cmd_identifier == 6),  # Device Type  # noqa: E501
        ConditionalField(BitField("alternate_pan_coordinator", 0, 1), lambda pkt:pkt.cmd_identifier == 6),  # Alternate PAN Coordinator  # noqa: E501

        # - Rejoin Response Command - #
        # Network address (2 octets)
        ConditionalField(XLEShortField("network_address", 0xFFFF), lambda pkt:pkt.cmd_identifier == 7),  # noqa: E501
        # Rejoin status (1 octet)
        ConditionalField(ByteField("rejoin_status", 0), lambda pkt:pkt.cmd_identifier == 7),  # noqa: E501

        # - Link Status Command - #
        # Command options (1 octet)
        ConditionalField(BitField("res5", 0, 1), lambda pkt:pkt.cmd_identifier == 8),  # Reserved  # noqa: E501
        ConditionalField(BitField("last_frame", 0, 1), lambda pkt:pkt.cmd_identifier == 8),  # Last frame  # noqa: E501
        ConditionalField(BitField("first_frame", 0, 1), lambda pkt:pkt.cmd_identifier == 8),  # First frame  # noqa: E501
        ConditionalField(BitField("entry_count", 0, 5), lambda pkt:pkt.cmd_identifier == 8),  # Entry count  # noqa: E501
        # Link status list (variable size)
        ConditionalField(
            PacketListField("link_status_list", [], LinkStatusEntry, count_from=lambda pkt:pkt.entry_count),  # noqa: E501
            lambda pkt:pkt.cmd_identifier == 8),

        # - Network Report Command - #
        # Command options (1 octet)
        ConditionalField(
            BitEnumField("report_command_identifier", 0, 3, {0: "PAN identifier conflict"}),  # 0x01 - 0x07 Reserved  # noqa: E501
            lambda pkt: pkt.cmd_identifier == 9),
        ConditionalField(BitField("report_information_count", 0, 5), lambda pkt: pkt.cmd_identifier == 9),  # noqa: E501
        # Report information (variable length)
        # Only present if we have a PAN Identifier Conflict Report
        ConditionalField(
            FieldListField("PAN_ID_conflict_report", [], XLEShortField("", 0x0000),  # noqa: E501
                           count_from=lambda pkt:pkt.report_information_count),
            lambda pkt:(pkt.cmd_identifier == 9 and pkt.report_command_identifier == 0)  # noqa: E501
        ),

        # - Network Update Command - #
        # Command options (1 octet)
        ConditionalField(
            BitEnumField("update_command_identifier", 0, 3, {0: "PAN Identifier Update"}),  # 0x01 - 0x07 Reserved  # noqa: E501
            lambda pkt: pkt.cmd_identifier == 10),
        ConditionalField(BitField("update_information_count", 0, 5), lambda pkt: pkt.cmd_identifier == 10),  # noqa: E501
        # EPID: Extended PAN ID (8 octets)
        ConditionalField(
            dot15d4AddressField("epid", 0, adjust=lambda pkt, x: 8),
            lambda pkt: pkt.cmd_identifier in [9, 10]
        ),
        # Update Id (1 octet)
        ConditionalField(ByteField("update_id", 0), lambda pkt: pkt.cmd_identifier == 10),  # noqa: E501
        # Update Information (Variable)
        # Only present if we have a PAN Identifier Update
        # New PAN ID (2 octets)
        ConditionalField(XLEShortField("new_PAN_ID", 0x0000),
                         lambda pkt: (pkt.cmd_identifier == 10 and pkt.update_command_identifier == 0)),  # noqa: E501

        # - End Device Timeout Request Command - #
        # Requested Timeout (1 octet)
        ConditionalField(
            ByteEnumField("req_timeout", 3, {
                0: "10 seconds",
                1: "2 minutes",
                2: "4 minutes",
                3: "8 minutes",
                4: "16 minutes",
                5: "32 minutes",
                6: "64 minutes",
                7: "128 minutes",
                8: "256 minutes",
                9: "512 minutes",
                10: "1024 minutes",
                11: "2048 minutes",
                12: "4096 minutes",
                13: "8192 minutes",
                14: "16384 minutes"
            }),
            lambda pkt: pkt.cmd_identifier == 11),
        # End Device Configuration (1 octet)
        ConditionalField(
            ByteField("ed_conf", 0),
            lambda pkt: pkt.cmd_identifier == 11),

        # - End Device Timeout Response Command - #
        # Status (1 octet)
        ConditionalField(
            ByteEnumField("status", 0, {
                0: "Success",
                1: "Incorrect Value"
            }),
            lambda pkt: pkt.cmd_identifier == 12),
        # Parent Information (1 octet)
        ConditionalField(
            BitField("res6", 0, 6),
            lambda pkt: pkt.cmd_identifier == 12),
        ConditionalField(
            BitField("ed_timeout_req_keepalive", 0, 1),
            lambda pkt: pkt.cmd_identifier == 12),
        ConditionalField(
            BitField("mac_data_poll_keepalive", 0, 1),
            lambda pkt: pkt.cmd_identifier == 12)

        # StrField("data", ""),
    ]
Esempio n. 7
0
class VlanTaggingOperation(Packet):
    name = "VlanTaggingOperation"
    fields_desc = [
        BitField("filter_outer_priority", 0, 4),
        BitField("filter_outer_vid", 0, 13),
        BitField("filter_outer_tpid_de", 0, 3),
        BitField("pad1", 0, 12),
        BitField("filter_inner_priority", 0, 4),
        BitField("filter_inner_vid", 0, 13),
        BitField("filter_inner_tpid_de", 0, 3),
        BitField("pad2", 0, 8),
        BitField("filter_ether_type", 0, 4),
        BitField("treatment_tags_to_remove", 0, 2),
        BitField("pad3", 0, 10),
        BitField("treatment_outer_priority", 0, 4),
        BitField("treatment_outer_vid", 0, 13),
        BitField("treatment_outer_tpid_de", 0, 3),
        BitField("pad4", 0, 12),
        BitField("treatment_inner_priority", 0, 4),
        BitField("treatment_inner_vid", 0, 13),
        BitField("treatment_inner_tpid_de", 0, 3),
    ]

    def to_json(self):
        return json.dumps(self.fields, separators=(',', ':'))

    @staticmethod
    def json_from_value(value):
        bits = BitArray(hex=hexlify(value))
        temp = VlanTaggingOperation(
            filter_outer_priority=bits[0:4].uint,  # 4  <-size
            filter_outer_vid=bits[4:17].uint,  # 13
            filter_outer_tpid_de=bits[17:20].uint,  # 3
            # pad 12
            filter_inner_priority=bits[32:36].uint,  # 4
            filter_inner_vid=bits[36:49].uint,  # 13
            filter_inner_tpid_de=bits[49:52].uint,  # 3
            # pad 8
            filter_ether_type=bits[60:64].uint,  # 4
            treatment_tags_to_remove=bits[64:66].uint,  # 2
            # pad 10
            treatment_outer_priority=bits[76:80].uint,  # 4
            treatment_outer_vid=bits[80:93].uint,  # 13
            treatment_outer_tpid_de=bits[93:96].uint,  # 3
            # pad 12
            treatment_inner_priority=bits[108:112].uint,  # 4
            treatment_inner_vid=bits[112:125].uint,  # 13
            treatment_inner_tpid_de=bits[125:128].uint,  # 3
        )
        return json.dumps(temp.fields, separators=(',', ':'))
Esempio n. 8
0
class SAPDiag(PacketNoPadded):
    """SAP Diag packet

    This packet holds the Diag Header and serve as a container for
    :class:`SAPDiagItem` items. It handles compression/decompression, adding the
    appropriate Compression Header when necessary.
    """
    name = "SAP Diag"
    fields_desc = [
        ByteField("mode", 0),

        # Communication flags
        BitField("com_flag_TERM_GRA", 0, 1),
        BitField("com_flag_TERM_NNM", 0, 1),
        BitField("com_flag_TERM_CAS", 0, 1),
        BitField("com_flag_TERM_INI", 0, 1),
        BitField("com_flag_TERM_EOP", 0, 1),
        BitField("com_flag_TERM_NOP", 0, 1),
        BitField("com_flag_TERM_EOC", 0, 1),
        BitField("com_flag_TERM_EOS", 0, 1),
        ByteField("mode_stat", 0),
        ByteField("err_no", 0),
        ByteField("msg_type", 0),
        ByteField("msg_info", 0),
        ByteField("msg_rc", 0),
        ByteEnumKeysField("compress", 0, diag_compress_values),

        # Compression Header
        ConditionalField(LEIntField("uncompress_length", None),
                         lambda pkt: pkt.compress == 1),
        ConditionalField(
            ByteEnumField("algorithm", 0x12, {
                0x12: "LZH",
                0x10: "LZC"
            }), lambda pkt: pkt.compress == 1),
        ConditionalField(StrFixedLenField("magic_bytes", "\x1f\x9d", 2),
                         lambda pkt: pkt.compress == 1),
        ConditionalField(ByteField("special", 2),
                         lambda pkt: pkt.compress == 1),

        # SNC Frame
        ConditionalField(PacketField("snc_frame", None, SAPSNCFrame),
                         lambda pkt: pkt.compress in [2, 3]),

        # Message info
        ConditionalField(StrEncodedPaddedField("info", None),
                         lambda pkt: pkt.err_no != 0),

        # Payload
        PacketListField("message", None, SAPDiagItem)
    ]

    def do_compress(self, s):
        """Compress a string using SAP compression C++ extension.

        :param s: string to compress
        :type s: C{string}

        :return: string compression header plus the compressed string
        :rtype: C{string}

        :raise pysapcompress.Error: when a compression error is raised
        """
        if len(s) > 0:
            # Compress the payload and return the output
            (_, _, outbuffer) = pysapcompress.compress(s,
                                                       pysapcompress.ALG_LZH)
            return outbuffer

    def do_decompress(self, s, length):
        """Decompress a string using SAP compression C++ extension.

        :param s: compression header plus compressed string
        :type s: C{string}

        :param length: reported compressed length
        :type length: ``int``

        :return: decompressed string
        :rtype: C{string}

        :raise pysapcompress.Error: when a decompression error is raised
        """
        if len(s) > 0:
            # Decompress the payload and return the output
            (_, _, outbuffer) = pysapcompress.decompress(s, length)
            return outbuffer

    def pre_dissect(self, s):
        """Prepares the packet for dissection. If the compression flag is set,
        decompress the payload.
        """
        # If the compression flag is set, decompress everything after the headers
        if s[7] == "\x01":
            # First need to get the reported decompressed length
            (reported_length, ) = unpack("<I", s[8:12])

            # Then return the headers (Diag and Compression) and the payload (message field)
            try:
                return s[:16] + self.do_decompress(s[8:], reported_length)
            except DecompressError:
                return s
        # Uncompressed packet, just return them
        return s

    def post_build(self, p, pay):
        """Compress the payload. If the compression flag is set, compress both
        the message field and the payload.
        """
        if pay is None:
            pay = ''
        if self.compress == 1:
            payload = "".join([str(item) for item in self.message]) + pay
            if len(payload) > 0:
                try:
                    return p[:8] + self.do_compress(payload)
                except CompressError:
                    return p + pay
        return p + pay

    def get_item(self, item_type=None, item_id=None, item_sid=None):
        """Get an item from the packet's message. Returns None if the message
        is not found, or a list if the item is found multiple times.

        :param item_type: item type byte or string value
        :type item_type: ``int`` or C{string} or ``list``

        :param item_id: item ID byte or string value
        :type item_id: ``int`` or C{string} or ``list``

        :param item_sid: item SID byte or string value
        :type item_sid: ``int`` or C{string} or ``list``

        :return: list of items found on the packet or None
        :rtype: ``list`` of :class:`SAPDiagItem`
        """
        # Expand list lookups
        items = []
        if item_type is not None and type(item_type) == list:
            for itype in item_type:
                items.extend(self.get_item(itype, item_id, item_sid))
            return items
        if item_id is not None and type(item_id) == list:
            for iid in item_id:
                items.extend(self.get_item(item_type, iid, item_sid))
            return items
        if item_sid is not None and type(item_sid) == list:
            for isid in item_sid:
                items.extend(self.get_item(item_type, item_id, isid))
            return items

        # Perform name lookups
        if item_type is not None and isinstance(item_type, str):
            item_type = list(diag_item_types.keys())[list(
                diag_item_types.values()).index(item_type)]
        if item_id is not None and isinstance(item_id, str):
            item_id = list(diag_appl_ids.keys())[list(
                diag_appl_ids.values()).index(item_id)]
        if item_sid is not None and isinstance(item_sid, str):
            item_sid = list(diag_appl_sids[item_id].keys())[list(
                diag_appl_sids[item_id].values()).index(item_sid)]

        # Filter and return items
        if item_sid is None and item_id is None:
            items = [
                item for item in self.message
                if hasattr(item, "item_type") and item.item_type == item_type
            ]
        elif item_sid is None:
            items = [
                item for item in self.message if hasattr(item, "item_type")
                and item.item_type == item_type and item.item_id == item_id
            ]
        else:
            items = [
                item for item in self.message
                if hasattr(item, "item_type") and item.item_type == item_type
                and item.item_id == item_id and item.item_sid == item_sid
            ]

        return items
Esempio n. 9
0
class DNS(Packet):
    name = "DNS"
    fields_desc = [
        ConditionalField(ShortField("length", None),
                         lambda p: isinstance(p.underlayer, TCP)),
        ShortField("id", 0),
        BitField("qr", 0, 1),
        BitEnumField("opcode", 0, 4, {
            0: "QUERY",
            1: "IQUERY",
            2: "STATUS"
        }),
        BitField("aa", 0, 1),
        BitField("tc", 0, 1),
        BitField("rd", 1, 1),
        BitField("ra", 0, 1),
        BitField("z", 0, 1),
        # AD and CD bits are defined in RFC 2535
        BitField("ad", 0, 1),  # Authentic Data
        BitField("cd", 0, 1),  # Checking Disabled
        BitEnumField(
            "rcode", 0, 4, {
                0: "ok",
                1: "format-error",
                2: "server-failure",
                3: "name-error",
                4: "not-implemented",
                5: "refused"
            }),
        DNSRRCountField("qdcount", None, "qd"),
        DNSRRCountField("ancount", None, "an"),
        DNSRRCountField("nscount", None, "ns"),
        DNSRRCountField("arcount", None, "ar"),
        DNSQRField("qd", "qdcount"),
        DNSRRField("an", "ancount"),
        DNSRRField("ns", "nscount"),
        DNSRRField("ar", "arcount", 0),
    ]

    def answers(self, other):
        return (isinstance(other, DNS) and self.id == other.id and self.qr == 1
                and other.qr == 0)

    def mysummary(self):
        type = ["Qry", "Ans"][self.qr]
        name = ""
        if self.qr:
            type = "Ans"
            if self.ancount > 0 and isinstance(self.an, DNSRR):
                name = ' "%s"' % self.an.rdata
        else:
            type = "Qry"
            if self.qdcount > 0 and isinstance(self.qd, DNSQR):
                name = ' "%s"' % self.qd.qname
        return 'DNS %s%s ' % (type, name)

    def post_build(self, pkt, pay):
        if isinstance(self.underlayer, TCP) and self.length is None:
            pkt = struct.pack("!H", len(pkt) - 2) + pkt[2:]
        return pkt + pay

    def compress(self):
        """Return the compressed DNS packet (using `dns_compress()`"""
        return dns_compress(self)
class IEC104_IE_CP56TIME2A(IEC104_IE_CommonQualityFlags):
    """
    CP56Time2a - dual time, 7 octets
                 (milliseconds, valid flag, minutes, hours,
                  summer-time-indicator, day of month, weekday, years)

    well, someone should have talked to them about the idea of the
    unix timestamp...

    EN 60870-5-101:2003, sec. 7.2.6.18 (p. 50)

    time representation format according IEC 60870-5-4:1993, sec. 6.8, p. 23
    """
    WEEK_DAY_FLAG_UNUSED = 0
    WEEK_DAY_FLAG_MONDAY = 1
    WEEK_DAY_FLAG_TUESDAY = 2
    WEEK_DAY_FLAG_WEDNESDAY = 3
    WEEK_DAY_FLAG_THURSDAY = 4
    WEEK_DAY_FLAG_FRIDAY = 5
    WEEK_DAY_FLAG_SATURDAY = 6
    WEEK_DAY_FLAG_SUNDAY = 7
    WEEK_DAY_FLAGS = {
        WEEK_DAY_FLAG_UNUSED: 'unused',
        WEEK_DAY_FLAG_MONDAY: 'Monday',
        WEEK_DAY_FLAG_TUESDAY: 'Tuesday',
        WEEK_DAY_FLAG_WEDNESDAY: 'Wednesday',
        WEEK_DAY_FLAG_THURSDAY: 'Thursday',
        WEEK_DAY_FLAG_FRIDAY: 'Friday',
        WEEK_DAY_FLAG_SATURDAY: 'Saturday',
        WEEK_DAY_FLAG_SUNDAY: 'Sunday'
    }

    GEN_FLAG_REALTIME = 0
    GEN_FLAG_SUBSTITUTED_TIME = 1
    GEN_FLAGS = {
        GEN_FLAG_REALTIME: 'real time',
        GEN_FLAG_SUBSTITUTED_TIME: 'substituted time'
    }

    SU_FLAG_NORMAL_TIME = 0
    SU_FLAG_SUMMER_TIME = 1
    SU_FLAGS = {
        SU_FLAG_NORMAL_TIME: 'normal time',
        SU_FLAG_SUMMER_TIME: 'summer time'
    }

    informantion_element_fields = [
        LEShortField('sec_milli', 0),
        BitEnumField('iv', 0, 1, IEC104_IE_CommonQualityFlags.IV_FLAGS),
        BitEnumField('gen', 0, 1, GEN_FLAGS),
        # only valid in monitor direction ToDo: special treatment needed?
        BitField('minutes', 0, 6),
        BitEnumField('su', 0, 1, SU_FLAGS),
        BitField('reserved_2', 0, 2),
        BitField('hours', 0, 5),
        BitEnumField('weekday', 0, 3, WEEK_DAY_FLAGS),
        BitField('day-of-month', 0, 5),
        BitField('reserved_3', 0, 4),
        BitField('month', 0, 4),
        BitField('reserved_4', 0, 1),
        BitField('year', 0, 7),
    ]
Esempio n. 11
0
class Dot11(Packet):
    name = "802.11"
    fields_desc = [
        BitField("subtype", 0, 4),
        BitEnumField("type", 0, 2, ["Management", "Control", "Data",
                                    "Reserved"]),
        BitField("proto", 0, 2),
        FlagsField("FCfield", 0, 8, ["to-DS", "from-DS", "MF", "retry",
                                     "pw-mgt", "MD", "protected", "order"]),
        ShortField("ID", 0),
        MACField("addr1", ETHER_ANY),
        ConditionalField(
            MACField("addr2", ETHER_ANY),
            lambda pkt: (pkt.type != 1 or
                         pkt.subtype in [0x8, 0x9, 0xa, 0xb, 0xe, 0xf]),
        ),
        ConditionalField(
            MACField("addr3", ETHER_ANY),
            lambda pkt: pkt.type in [0, 2],
        ),
        ConditionalField(LEShortField("SC", 0), lambda pkt: pkt.type != 1),
        ConditionalField(
            MACField("addr4", ETHER_ANY),
            lambda pkt: (pkt.type == 2 and
                         pkt.FCfield & 3 == 3),  # from-DS+to-DS
        )
    ]

    def mysummary(self):
        # Supports both Dot11 and Dot11FCS
        return self.sprintf("802.11 %%%s.type%% %%%s.subtype%% %%%s.addr2%% > %%%s.addr1%%" % ((self.__class__.__name__,) * 4))  # noqa: E501

    def guess_payload_class(self, payload):
        if self.type == 0x02 and (0x08 <= self.subtype <= 0xF and self.subtype != 0xD):  # noqa: E501
            return Dot11QoS
        elif self.FCfield.protected:
            # When a frame is handled by encryption, the Protected Frame bit
            # (previously called WEP bit) is set to 1, and the Frame Body
            # begins with the appropriate cryptographic header.
            return Dot11Encrypted
        else:
            return Packet.guess_payload_class(self, payload)

    def answers(self, other):
        if isinstance(other, Dot11):
            if self.type == 0:  # management
                if self.addr1.lower() != other.addr2.lower():  # check resp DA w/ req SA  # noqa: E501
                    return 0
                if (other.subtype, self.subtype) in [(0, 1), (2, 3), (4, 5)]:
                    return 1
                if self.subtype == other.subtype == 11:  # auth
                    return self.payload.answers(other.payload)
            elif self.type == 1:  # control
                return 0
            elif self.type == 2:  # data
                return self.payload.answers(other.payload)
            elif self.type == 3:  # reserved
                return 0
        return 0

    def unwep(self, key=None, warn=1):
        if self.FCfield & 0x40 == 0:
            if warn:
                warning("No WEP to remove")
            return
        if isinstance(self.payload.payload, NoPayload):
            if key or conf.wepkey:
                self.payload.decrypt(key)
            if isinstance(self.payload.payload, NoPayload):
                if warn:
                    warning("Dot11 can't be decrypted. Check conf.wepkey.")
                return
        self.FCfield &= ~0x40
        self.payload = self.payload.payload
Esempio n. 12
0
class RadioTap(Packet):
    name = "RadioTap"
    deprecated_fields = {
        "Channel": ("ChannelFrequency", "2.4.3"),
        "ChannelFlags2": ("ChannelPlusFlags", "2.4.3"),
        "ChannelNumber": ("ChannelPlusNumber", "2.4.3"),
    }
    fields_desc = [
        ByteField('version', 0),
        ByteField('pad', 0),
        LEShortField('len', None),
        FlagsField('present', None, -32, _rt_present),  # noqa: E501
        # Extended presence mask
        ConditionalField(PacketListField("Ext", [], next_cls_cb=_next_radiotap_extpm), lambda pkt: pkt.present and pkt.present.Ext),  # noqa: E501
        # RadioTap fields - each starts with a _RadiotapReversePadField
        # to handle padding

        # TSFT
        ConditionalField(
            _RadiotapReversePadField(
                LELongField("mac_timestamp", 0)
            ),
            lambda pkt: pkt.present and pkt.present.TSFT),
        # Flags
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("Flags", None, -8, _rt_flags)
            ),
            lambda pkt: pkt.present and pkt.present.Flags),
        # Rate
        ConditionalField(
            _RadiotapReversePadField(ByteField("Rate", 0)),
            lambda pkt: pkt.present and pkt.present.Rate),
        # Channel
        ConditionalField(
            _RadiotapReversePadField(LEShortField("ChannelFrequency", 0)),
            lambda pkt: pkt.present and pkt.present.Channel),
        ConditionalField(
            FlagsField("ChannelFlags", None, -16, _rt_channelflags),
            lambda pkt: pkt.present and pkt.present.Channel),
        # dBm_AntSignal
        ConditionalField(
            _RadiotapReversePadField(
                ScalingField("dBm_AntSignal", 0, offset=-256,
                             unit="dBm", fmt="B")),
            lambda pkt: pkt.present and pkt.present.dBm_AntSignal),
        # dBm_AntNoise
        ConditionalField(
            _RadiotapReversePadField(
                ScalingField("dBm_AntNoise", 0, offset=-256,
                             unit="dBm", fmt="B")),
            lambda pkt: pkt.present and pkt.present.dBm_AntNoise),
        # Lock_Quality
        ConditionalField(
            _RadiotapReversePadField(LEShortField("Lock_Quality", 0)),
            lambda pkt: pkt.present and pkt.present.Lock_Quality),
        # Antenna
        ConditionalField(
            _RadiotapReversePadField(ByteField("Antenna", 0)),
            lambda pkt: pkt.present and pkt.present.Antenna),
        # RX Flags
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("RXFlags", None, -16, _rt_rxflags)),
            lambda pkt: pkt.present and pkt.present.RXFlags),
        # TX Flags
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("TXFlags", None, -16, _rt_txflags)),
            lambda pkt: pkt.present and pkt.present.TXFlags),
        # ChannelPlus
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("ChannelPlusFlags", None, -32, _rt_channelflags2)),
            lambda pkt: pkt.present and pkt.present.ChannelPlus),
        ConditionalField(
            LEShortField("ChannelPlusFrequency", 0),
            lambda pkt: pkt.present and pkt.present.ChannelPlus),
        ConditionalField(
            ByteField("ChannelPlusNumber", 0),
            lambda pkt: pkt.present and pkt.present.ChannelPlus),
        # MCS
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("knownMCS", None, -8, _rt_knownmcs)),
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            BitField("Ness_LSB", 0, 1),
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            BitField("STBC_streams", 0, 2),
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            BitEnumField("FEC_type", 0, 1, {0: "BCC", 1: "LDPC"}),
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            BitEnumField("HT_format", 0, 1, {0: "mixed", 1: "greenfield"}),
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            BitEnumField("guard_interval", 0, 1, {0: "Long_GI", 1: "Short_GI"}),  # noqa: E501
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            BitEnumField("MCS_bandwidth", 0, 2, _rt_bandwidth),
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            ByteField("MCS_index", 0),
            lambda pkt: pkt.present and pkt.present.MCS),
        # A_MPDU
        ConditionalField(
            _RadiotapReversePadField(
                LEIntField("A_MPDU_ref", 0)),
            lambda pkt: pkt.present and pkt.present.A_MPDU),
        ConditionalField(
            FlagsField("A_MPDU_flags", None, -32, _rt_a_mpdu_flags),
            lambda pkt: pkt.present and pkt.present.A_MPDU),
        # VHT
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("KnownVHT", None, -16, _rt_knownvht)),
            lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(
            FlagsField("PresentVHT", None, -8, _rt_presentvht),
            lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(
            ByteEnumField("VHT_bandwidth", 0, _rt_vhtbandwidth),
            lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(
            StrFixedLenField("mcs_nss", 0, length=5),
            lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(
            ByteField("GroupID", 0),
            lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(
            ShortField("PartialAID", 0),
            lambda pkt: pkt.present and pkt.present.VHT),
        # timestamp
        ConditionalField(
            _RadiotapReversePadField(
                LELongField("timestamp", 0)),
            lambda pkt: pkt.present and pkt.present.timestamp),
        ConditionalField(
            LEShortField("ts_accuracy", 0),
            lambda pkt: pkt.present and pkt.present.timestamp),
        ConditionalField(
            ByteField("ts_position", 0),
            lambda pkt: pkt.present and pkt.present.timestamp),
        ConditionalField(
            ByteField("ts_flags", 0),
            lambda pkt: pkt.present and pkt.present.timestamp),
        # HE - XXX not complete
        ConditionalField(
            _RadiotapReversePadField(
                ShortField("he_data1", 0)),
            lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(
            ShortField("he_data2", 0),
            lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(
            ShortField("he_data3", 0),
            lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(
            ShortField("he_data4", 0),
            lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(
            ShortField("he_data5", 0),
            lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(
            ShortField("he_data6", 0),
            lambda pkt: pkt.present and pkt.present.HE),
        # HE_MU
        ConditionalField(
            _RadiotapReversePadField(
                LEShortField("hemu_flags1", 0)),
            lambda pkt: pkt.present and pkt.present.HE_MU),
        ConditionalField(
            LEShortField("hemu_flags2", 0),
            lambda pkt: pkt.present and pkt.present.HE_MU),
        ConditionalField(
            FieldListField("RU_channel1", [], ByteField,
                           count_from=lambda x: 4),
            lambda pkt: pkt.present and pkt.present.HE_MU),
        ConditionalField(
            FieldListField("RU_channel2", [], ByteField,
                           count_from=lambda x: 4),
            lambda pkt: pkt.present and pkt.present.HE_MU),
        # HE_MU_other_user
        ConditionalField(
            _RadiotapReversePadField(
                LEShortField("hemuou_per_user_1", 0x7fff)),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        ConditionalField(
            LEShortField("hemuou_per_user_2", 0x003f),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        ConditionalField(
            ByteField("hemuou_per_user_position", 0),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        ConditionalField(
            FlagsField("hemuou_per_user_known", 0, -16,
                       _rt_hemuother_per_user_known),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        # L_SIG
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("lsig_data1", 0, -16, ["rate", "length"])),
            lambda pkt: pkt.present and pkt.present.L_SIG),
        ConditionalField(
            BitField("lsig_length", 0, 12),
            lambda pkt: pkt.present and pkt.present.L_SIG),
        ConditionalField(
            BitField("lsig_rate", 0, 4),
            lambda pkt: pkt.present and pkt.present.L_SIG),
        # Remaining
        StrLenField('notdecoded', "", length_from=lambda pkt: 0)
    ]

    def guess_payload_class(self, payload):
        if self.present and self.present.Flags and self.Flags.FCS:
            return Dot11FCS
        return Dot11

    def post_dissect(self, s):
        length = max(self.len - len(self.original) + len(s), 0)
        self.notdecoded = s[:length]
        return s[length:]

    def post_build(self, p, pay):
        if self.len is None:
            p = p[:2] + struct.pack("!H", len(p))[::-1] + p[4:]
        return p + pay
Esempio n. 13
0
class Dot15d4Beacon(Packet):
    name = "802.15.4 Beacon"
    fields_desc = [
        # Superframe spec field:
        BitField("sf_sforder", 15, 4),  # not used by ZigBee
        BitField("sf_beaconorder", 15, 4),  # not used by ZigBee
        BitEnumField("sf_assocpermit", 0, 1, [False, True]),
        BitEnumField("sf_pancoord", 0, 1, [False, True]),
        BitField("sf_reserved", 0, 1),  # not used by ZigBee
        BitEnumField("sf_battlifeextend", 0, 1, [False, True]),  # not used by ZigBee  # noqa: E501
        BitField("sf_finalcapslot", 15, 4),  # not used by ZigBee

        # GTS Fields
        #  GTS Specification (1 byte)
        BitEnumField("gts_spec_permit", 1, 1, [False, True]),  # GTS spec bit 7, true=1 iff PAN cord is accepting GTS requests  # noqa: E501
        BitField("gts_spec_reserved", 0, 4),  # GTS spec bits 3-6
        BitField("gts_spec_desccount", 0, 3),  # GTS spec bits 0-2
        #  GTS Directions (0 or 1 byte)
        ConditionalField(BitField("gts_dir_reserved", 0, 1), lambda pkt:pkt.getfieldval("gts_spec_desccount") != 0),  # noqa: E501
        ConditionalField(BitField("gts_dir_mask", 0, 7), lambda pkt:pkt.getfieldval("gts_spec_desccount") != 0),  # noqa: E501
        #  GTS List (variable size)
        # TODO add a Packet/FieldListField tied to 3bytes per count in gts_spec_desccount  # noqa: E501

        # Pending Address Fields:
        #  Pending Address Specification (1 byte)
        BitField("pa_reserved_1", 0, 1),
        BitField("pa_num_long", 0, 3),  # number of long addresses pending
        BitField("pa_reserved_2", 0, 1),
        BitField("pa_num_short", 0, 3),  # number of short addresses pending
        #  Address List (var length)
        FieldListField("pa_short_addresses", [],
                       XLEShortField("", 0x0000),
                       count_from=lambda pkt: pkt.pa_num_short),
        FieldListField("pa_long_addresses", [], LEEUI64Field("", 0),
                       count_from=lambda pkt: pkt.pa_num_long),
        # TODO beacon payload
    ]

    def mysummary(self):
        return self.sprintf(
            "802.15.4 Beacon "
            "( %Dot15d4Beacon.src_panid%:%Dot15d4Beacon.src_addr% "
            "assocPermit %Dot15d4Beacon.sf_assocpermit% "
            "panCoord %Dot15d4Beacon.sf_pancoord%)")
Esempio n. 14
0
 def addfield(self, pkt, s, val):
     self.size = self.length_f(pkt)
     return BitField.addfield(self, pkt, s, val)
Esempio n. 15
0
class NBNSNodeStatusResponseEnd(Packet):
    name = "NBNS Node Status Response"
    fields_desc = [
        SourceMACField("MAC_ADDRESS"),
        BitField("STATISTICS", 0, 57 * 8)
    ]
Esempio n. 16
0
class Dot15d4(Packet):
    FRAME_TYPE = {
        0b000: "Beacon",
        0b001: "Data",
        0b010: "Ack",
        0b011: "Command",
        0b101: "Multipurpose",
        0b110: "Fragment",
        0b111: "Extended"
    }

    FRAME_VERSION = {
        0b00: "2003",
        0b01: "2006",
        0b10: "2015"
    }

    name = "802.15.4"
    fields_desc = [
        # Frame control
        BitField("fcf_reserved_1", 0, 1),
        BitEnumField("fcf_panidcompress", 0, 1, [False, True]),
        BitEnumField("fcf_ackreq", 0, 1, [False, True]),
        BitEnumField("fcf_pending", 0, 1, [False, True]),
        BitEnumField("fcf_security", 0, 1, [False, True]),
        Emph(BitEnumField("fcf_frametype", 0, 3, FRAME_TYPE)),
        AddressingModeField("fcf_srcaddrmode", 0, "src_addr"),
        BitEnumField("fcf_framever", 0, 2, FRAME_VERSION),
        AddressingModeField("fcf_destaddrmode", 2, "dest_addr"),
        BitField("fcf_reserved_2", 0, 2),
        # Sequence number
        Emph(ByteField("seqnum", 1)),
        # Addressing fields
        ConditionalField(
            XLEShortField("dest_panid", 0xFFFF),
            lambda pkt: panids_present(pkt)[0]),
        MultipleTypeField(
            [(ShortAddressField("dest_addr", 0xFFFF),
              lambda pkt: pkt.fcf_destaddrmode == 0b10),
             (LEEUI64Field("dest_addr", 0xFFFFFFFFFFFFFFFF),
              lambda pkt: pkt.fcf_destaddrmode == 0b11)],
            NoneField("dest_addr", 0xFFFF)),
        ConditionalField(
            XLEShortField("src_panid", 0x0000),
            lambda pkt: panids_present(pkt)[1]),
        MultipleTypeField(
            [(ShortAddressField("src_addr", None),
              lambda pkt: pkt.fcf_srcaddrmode == 0b10),
             (LEEUI64Field("src_addr", None),
              lambda pkt: pkt.fcf_srcaddrmode == 0b11)],
            NoneField("src_addr", None)),
        # Security field
        ConditionalField(
            PacketField("aux_sec_header", Dot15d4AuxSecurityHeader(),
                        Dot15d4AuxSecurityHeader),
            lambda pkt: pkt.fcf_security),
    ]

    def mysummary(self):
        return self.sprintf(
            "802.15.4 %Dot15d4.fcf_frametype% "
            "(ackreq=%Dot15d4.fcf_ackreq% "
            "%Dot15d4.fcf_destaddrmode% -> %Dot15d4.fcf_srcaddrmode% "
            "Seq#%Dot15d4.seqnum%)")

    def answers(self, other):
        if isinstance(other, Dot15d4):
            if self.fcf_frametype == 2:  # ack
                # check for seqnum matching
                if self.seqnum != other.seqnum:
                    return 0
                # check that an ack was indeed requested
                elif other.fcf_ackreq == 1:
                    return 1
        return 0

    def post_build(self, p, pay):
        # This just forces destaddrmode to None for Ack frames.
        if self.fcf_frametype == 2 and self.fcf_destaddrmode != 0:
            self.fcf_destaddrmode = 0
            return p[:1] + \
                chb((self.fcf_srcaddrmode << 6) + (self.fcf_framever << 4)) \
                + p[2:] + pay
        else:
            return p + pay
Esempio n. 17
0
class DutyCyclePL(Packet):
    name = "DutyCyclePL"
    fields_desc = [BitField("MaxDCycle", 0, 4)]
Esempio n. 18
0
class LLDPDUSystemCapabilities(LLDPDU):
    """
        ieee 802.1ab-2016 - sec. 8.5.8 / p. 31
    """
    fields_desc = [
        BitEnumField('_type', 0x07, 7, LLDPDU.TYPES),
        BitFieldLenField('_length', 4, 9),
        BitField('reserved_5_available', 0, 1),
        BitField('reserved_4_available', 0, 1),
        BitField('reserved_3_available', 0, 1),
        BitField('reserved_2_available', 0, 1),
        BitField('reserved_1_available', 0, 1),
        BitField('two_port_mac_relay_available', 0, 1),
        BitField('s_vlan_component_available', 0, 1),
        BitField('c_vlan_component_available', 0, 1),
        BitField('station_only_available', 0, 1),
        BitField('docsis_cable_device_available', 0, 1),
        BitField('telephone_available', 0, 1),
        BitField('router_available', 0, 1),
        BitField('wlan_access_point_available', 0, 1),
        BitField('mac_bridge_available', 0, 1),
        BitField('repeater_available', 0, 1),
        BitField('other_available', 0, 1),
        BitField('reserved_5_enabled', 0, 1),
        BitField('reserved_4_enabled', 0, 1),
        BitField('reserved_3_enabled', 0, 1),
        BitField('reserved_2_enabled', 0, 1),
        BitField('reserved_1_enabled', 0, 1),
        BitField('two_port_mac_relay_enabled', 0, 1),
        BitField('s_vlan_component_enabled', 0, 1),
        BitField('c_vlan_component_enabled', 0, 1),
        BitField('station_only_enabled', 0, 1),
        BitField('docsis_cable_device_enabled', 0, 1),
        BitField('telephone_enabled', 0, 1),
        BitField('router_enabled', 0, 1),
        BitField('wlan_access_point_enabled', 0, 1),
        BitField('mac_bridge_enabled', 0, 1),
        BitField('repeater_enabled', 0, 1),
        BitField('other_enabled', 0, 1),
    ]

    def _check(self):
        """
        run layer specific checks
        """
        if conf.contribs['LLDP'].strict_mode() and self._length != 4:
            raise LLDPInvalidLengthField('length must be 4 - got '
                                         '{}'.format(self._length))
Esempio n. 19
0
class DevLoraWANversion(Packet):
    name = "DevLoraWANversion"
    fields_desc = [BitField("RFU", 0b0000, 4), BitField("Minor", 0b0001, 4)]
Esempio n. 20
0
class ZCLPriceGetCurrentPrice(Packet):
    name = "Price Cluster: Get Current Price Command (Server: Received)"
    fields_desc = [
        BitField("reserved", 0, 7),
        BitField("Requestor_Rx_On_When_Idle", 0, 1),
    ]
Esempio n. 21
0
class ADRparam(Packet):
    name = "ADRparam"
    fields_desc = [
        BitField("Limit_exp", 0b0000, 4),
        BitField("Delay_exp", 0b0000, 4)
    ]
Esempio n. 22
0
class LoWPANUncompressedIPv6(Packet):
    name = "6LoWPAN Uncompressed IPv6"
    fields_desc = [BitField("_type", 0x0, 8)]

    def default_payload_class(self, pay):
        return IPv6
Esempio n. 23
0
class RejoinParamSetupReq(Packet):
    name = "RejoinParamSetupReq"
    fields_desc = [BitField("MaxTimeN", 0, 4), BitField("MaxCountN", 0, 4)]
Esempio n. 24
0
 def addfield(self, pkt, s, val):
     self.size = self.length_f(pkt)
     return BitField.addfield(self, pkt, s, val)
Esempio n. 25
0
class RejoinParamSetupAns(Packet):
    name = "RejoinParamSetupAns"
    fields_desc = [BitField("RFU", 0, 7), BitField("TimeOK", 0, 1)]
Esempio n. 26
0
class LoWPAN_IPHC(Packet):
    """6LoWPAN IPv6 header compressed packets

    It follows the implementation of draft-ietf-6lowpan-hc-15.
    """
    # the LOWPAN_IPHC encoding utilizes 13 bits, 5 dispatch type
    name = "LoWPAN IP Header Compression Packet"
    _address_modes = ["Unspecified", "1", "16-bits inline", "Compressed"]
    _state_mode = ["Stateless", "Stateful"]
    fields_desc = [
        # dispatch
        BitField("_reserved", 0x03, 3),
        BitField("tf", 0x0, 2),
        BitEnumField("nh", 0x0, 1, ["Inline", "Compressed"]),
        BitField("hlim", 0x0, 2),
        BitEnumField("cid", 0x0, 1, [False, True]),
        BitEnumField("sac", 0x0, 1, _state_mode),
        BitEnumField("sam", 0x0, 2, _address_modes),
        BitEnumField("m", 0x0, 1, [False, True]),
        BitEnumField("dac", 0x0, 1, _state_mode),
        BitEnumField("dam", 0x0, 2, _address_modes),
        ConditionalField(
            ByteField("_contextIdentifierExtension", 0x0),
            lambda pkt: pkt.cid == 0x1
        ),
        # TODO: THIS IS WRONG!!!!!
        BitVarSizeField("tc_ecn", 0, calculate_length=lambda pkt: _tf_last_attempt(pkt)[0]),  # noqa: E501
        BitVarSizeField("tc_dscp", 0, calculate_length=lambda pkt: _tf_last_attempt(pkt)[1]),  # noqa: E501
        BitVarSizeField("_padd", 0, calculate_length=lambda pkt: _tf_last_attempt(pkt)[2]),  # noqa: E501
        BitVarSizeField("flowlabel", 0, calculate_length=lambda pkt: _tf_last_attempt(pkt)[3]),  # noqa: E501

        # NH
        ConditionalField(
            ByteField("_nhField", 0x0),
            lambda pkt: not pkt.nh
        ),
        # HLIM: Hop Limit: if it's 0
        ConditionalField(
            ByteField("_hopLimit", 0x0),
            lambda pkt: pkt.hlim == 0x0
        ),
        IP6FieldLenField("sourceAddr", "::", 0, length_of=source_addr_mode2),
        IP6FieldLenField("destinyAddr", "::", 0, length_of=destiny_addr_mode),  # problem when it's 0  # noqa: E501

        # LoWPAN_UDP Header Compression ########################################  # noqa: E501
        # TODO: IMPROVE!!!!!
        ConditionalField(
            FlagsField("header_compression", 0, 8, ["A", "B", "C", "D", "E", "C", "PS", "PD"]),  # noqa: E501
            lambda pkt: pkt.nh
        ),
        ConditionalField(
            BitFieldLenField("udpSourcePort", 0x0, 16, length_of=lambda pkt: nhc_port(pkt)[0]),  # noqa: E501
            # ShortField("udpSourcePort", 0x0),
            lambda pkt: pkt.nh and pkt.header_compression & 0x2 == 0x0
        ),
        ConditionalField(
            BitFieldLenField("udpDestinyPort", 0x0, 16, length_of=lambda pkt: nhc_port(pkt)[1]),  # noqa: E501
            lambda pkt: pkt.nh and pkt.header_compression & 0x1 == 0x0
        ),
        ConditionalField(
            XShortField("udpChecksum", 0x0),
            lambda pkt: pkt.nh and pkt.header_compression & 0x4 == 0x0
        ),

    ]

    def post_dissect(self, data):
        """dissect the IPv6 package compressed into this IPHC packet.

        The packet payload needs to be decompressed and depending on the
        arguments, several conversions should be done.
        """

        # uncompress payload
        packet = IPv6()
        packet.version = IPHC_DEFAULT_VERSION
        packet.tc, packet.fl = self._getTrafficClassAndFlowLabel()
        if not self.nh:
            packet.nh = self._nhField
        # HLIM: Hop Limit
        if self.hlim == 0:
            packet.hlim = self._hopLimit
        elif self.hlim == 0x1:
            packet.hlim = 1
        elif self.hlim == 0x2:
            packet.hlim = 64
        else:
            packet.hlim = 255
        # TODO: Payload length can be inferred from lower layers from either the  # noqa: E501
        # 6LoWPAN Fragmentation header or the IEEE802.15.4 header

        packet.src = self.decompressSourceAddr(packet)
        packet.dst = self.decompressDestinyAddr(packet)

        if self.nh == 1:
            # The Next Header field is compressed and the next header is
            # encoded using LOWPAN_NHC

            packet.nh = 0x11  # UDP
            udp = UDP()
            if self.header_compression and \
               self.header_compression & 0x4 == 0x0:
                udp.chksum = self.udpChecksum

            s, d = nhc_port(self)
            if s == 16:
                udp.sport = self.udpSourcePort
            elif s == 8:
                udp.sport = 0xF000 + s
            elif s == 4:
                udp.sport = 0xF0B0 + s
            if d == 16:
                udp.dport = self.udpDestinyPort
            elif d == 8:
                udp.dport = 0xF000 + d
            elif d == 4:
                udp.dport = 0xF0B0 + d

            packet.payload = udp / data
            data = raw(packet)
        # else self.nh == 0 not necessary
        elif self._nhField & 0xE0 == 0xE0:  # IPv6 Extension Header Decompression  # noqa: E501
            warning('Unimplemented: IPv6 Extension Header decompression')  # noqa: E501
            packet.payload = conf.raw_layer(data)
            data = raw(packet)
        else:
            packet.payload = conf.raw_layer(data)
            data = raw(packet)

        return Packet.post_dissect(self, data)

    def decompressDestinyAddr(self, packet):
        try:
            tmp_ip = inet_pton(socket.AF_INET6, self.destinyAddr)
        except socket.error:
            tmp_ip = b"\x00" * 16

        if self.m == 0 and self.dac == 0:
            if self.dam == 0:
                pass
            elif self.dam == 1:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[-8:]
            elif self.dam == 2:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00" + tmp_ip[-2:]  # noqa: E501
            elif self.dam == 3:
                # TODO May need some extra changes, we are copying
                # (self.m == 0 and self.dac == 1)
                tmp_ip = _extract_dot15d4address(self, source=False)

        elif self.m == 0 and self.dac == 1:
            if self.dam == 0:
                raise Exception('Reserved')
            elif self.dam == 0x3:
                tmp_ip = _extract_dot15d4address(self, source=False)
            elif self.dam not in [0x1, 0x2]:
                warning("Unknown destiny address compression mode !")
        elif self.m == 1 and self.dac == 0:
            if self.dam == 0:
                raise Exception("unimplemented")
            elif self.dam == 1:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 9 + tmp_ip[-5:]
            elif self.dam == 2:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 11 + tmp_ip[-3:]
            else:  # self.dam == 3:
                tmp_ip = b"\xff\x02" + b"\x00" * 13 + tmp_ip[-1:]
        elif self.m == 1 and self.dac == 1:
            if self.dam == 0x0:
                raise Exception("Unimplemented: I didn't understand the 6lowpan specification")  # noqa: E501
            else:  # all the others values
                raise Exception("Reserved value by specification.")

        self.destinyAddr = inet_ntop(socket.AF_INET6, tmp_ip)
        return self.destinyAddr

    def compressSourceAddr(self, ipv6):
        tmp_ip = inet_pton(socket.AF_INET6, ipv6.src)

        if self.sac == 0:
            if self.sam == 0x0:
                tmp_ip = tmp_ip
            elif self.sam == 0x1:
                tmp_ip = tmp_ip[8:16]
            elif self.sam == 0x2:
                tmp_ip = tmp_ip[14:16]
            else:  # self.sam == 0x3:
                pass
        else:  # self.sac == 1
            if self.sam == 0x0:
                tmp_ip = b"\x00" * 16
            elif self.sam == 0x1:
                tmp_ip = tmp_ip[8:16]
            elif self.sam == 0x2:
                tmp_ip = tmp_ip[14:16]

        self.sourceAddr = inet_ntop(socket.AF_INET6, b"\x00" * (16 - len(tmp_ip)) + tmp_ip)  # noqa: E501
        return self.sourceAddr

    def compressDestinyAddr(self, ipv6):
        tmp_ip = inet_pton(socket.AF_INET6, ipv6.dst)

        if self.m == 0 and self.dac == 0:
            if self.dam == 0x0:
                tmp_ip = tmp_ip
            elif self.dam == 0x1:
                tmp_ip = b"\x00" * 8 + tmp_ip[8:16]
            elif self.dam == 0x2:
                tmp_ip = b"\x00" * 14 + tmp_ip[14:16]
        elif self.m == 0 and self.dac == 1:
            if self.dam == 0x1:
                tmp_ip = b"\x00" * 8 + tmp_ip[8:16]
            elif self.dam == 0x2:
                tmp_ip = b"\x00" * 14 + tmp_ip[14:16]
        elif self.m == 1 and self.dac == 0:
            if self.dam == 0x1:
                tmp_ip = b"\x00" * 10 + tmp_ip[1:2] + tmp_ip[11:16]
            elif self.dam == 0x2:
                tmp_ip = b"\x00" * 12 + tmp_ip[1:2] + tmp_ip[13:16]
            elif self.dam == 0x3:
                tmp_ip = b"\x00" * 15 + tmp_ip[15:16]
        elif self.m == 1 and self.dac == 1:
            raise Exception('Unimplemented')

        self.destinyAddr = inet_ntop(socket.AF_INET6, tmp_ip)

    def decompressSourceAddr(self, packet):
        try:
            tmp_ip = inet_pton(socket.AF_INET6, self.sourceAddr)
        except socket.error:
            tmp_ip = b"\x00" * 16

        if self.sac == 0:
            if self.sam == 0x0:
                pass
            elif self.sam == 0x1:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[16 - source_addr_mode2(self):16]  # noqa: E501
            elif self.sam == 0x2:
                tmp = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00"
                tmp_ip = tmp + tmp_ip[16 - source_addr_mode2(self):16]
            elif self.sam == 0x3:  # EXTRACT ADDRESS FROM Dot15d4
                tmp_ip = _extract_dot15d4address(self, source=True)
            else:
                warning("Unknown source address compression mode !")
        else:  # self.sac == 1:
            if self.sam == 0x0:
                pass
            elif self.sam == 0x2:
                # TODO: take context IID
                tmp = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00"
                tmp_ip = tmp + tmp_ip[16 - source_addr_mode2(self):16]
            elif self.sam == 0x3:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + b"\x00" * 8  # TODO: CONTEXT ID  # noqa: E501
            else:
                raise Exception('Unimplemented')
        self.sourceAddr = inet_ntop(socket.AF_INET6, tmp_ip)
        return self.sourceAddr

    def guess_payload_class(self, payload):
        if self.underlayer and isinstance(self.underlayer, (LoWPANFragmentationFirst, LoWPANFragmentationSubsequent)):  # noqa: E501
            return Raw
        return IPv6

    def do_build(self):
        if not isinstance(self.payload, IPv6):
            return Packet.do_build(self)
        ipv6 = self.payload

        self._reserved = 0x03

        # NEW COMPRESSION TECHNIQUE!
        # a ) Compression Techniques

        # 1. Set Traffic Class
        if self.tf == 0x0:
            self.tc_ecn = ipv6.tc >> 6
            self.tc_dscp = ipv6.tc & 0x3F
            self.flowlabel = ipv6.fl
        elif self.tf == 0x1:
            self.tc_ecn = ipv6.tc >> 6
            self.flowlabel = ipv6.fl
        elif self.tf == 0x2:
            self.tc_ecn = ipv6.tc >> 6
            self.tc_dscp = ipv6.tc & 0x3F
        else:  # self.tf == 0x3:
            pass  # no field is set

        # 2. Next Header
        if self.nh == 0x0:
            self.nh = 0  # ipv6.nh
        elif self.nh == 0x1:
            self.nh = 0  # disable compression
            # The Next Header field is compressed and the next header is encoded using LOWPAN_NHC, which is discussed in Section 4.1.  # noqa: E501
            warning('Next header compression is not implemented yet ! Will be ignored')  # noqa: E501

        # 3. HLim
        if self.hlim == 0x0:
            self._hopLimit = ipv6.hlim
        else:  # if hlim is 1, 2 or 3, there are nothing to do!
            pass

        # 4. Context (which context to use...)
        if self.cid == 0x0:
            pass
        else:
            # TODO: Context Unimplemented yet in my class
            self._contextIdentifierExtension = 0

        # 5. Compress Source Addr
        self.compressSourceAddr(ipv6)
        self.compressDestinyAddr(ipv6)

        return Packet.do_build(self)

    def do_build_payload(self):
        if self.header_compression and\
           self.header_compression & 240 == 240:  # TODO: UDP header IMPROVE
            return raw(self.payload)[40 + 16:]
        else:
            return raw(self.payload)[40:]

    def _getTrafficClassAndFlowLabel(self):
        """Page 6, draft feb 2011 """
        if self.tf == 0x0:
            return (self.tc_ecn << 6) + self.tc_dscp, self.flowlabel
        elif self.tf == 0x1:
            return (self.tc_ecn << 6), self.flowlabel
        elif self.tf == 0x2:
            return (self.tc_ecn << 6) + self.tc_dscp, 0
        else:
            return 0, 0
Esempio n. 27
0
class PPP_LCP_ACCM_Option(PPP_LCP_Option):
    fields_desc = [
        ByteEnumField("type", 2, _PPP_lcp_optiontypes),
        FieldLenField("len", 6, fmt="B"),
        BitField("accm", 0x00000000, 32)
    ]
Esempio n. 28
0
class MKASAKUseParamSet(MKAParamSet):
    """
    SAK Use Parameter Set (802.1X-2010, section 11.11).
    """

    #________________________________________________________________________
    #
    # IEEE 802.1X-2010 standard
    # Section 11.11
    #________________________________________________________________________
    #

    name = "SAK Use Parameter Set"
    fields_desc = [
        ByteEnumField("param_set_type", 3, _parameter_set_types),
        BitField("latest_key_an", 0, 2),
        BitField("latest_key_tx", 0, 1),
        BitField("latest_key_rx", 0, 1),
        BitField("old_key_an", 0, 2),
        BitField("old_key_tx", 0, 1),
        BitField("old_key_rx", 0, 1),
        BitField("plain_tx", 0, 1),
        BitField("plain_rx", 0, 1),
        BitField("X", 0, 1),
        BitField("delay_protect", 0, 1),
        BitField("param_set_body_len", 0, 12),
        XStrFixedLenField("latest_key_key_server_member_id", "", length=12),
        XStrFixedLenField("latest_key_key_number", "", length=4),
        XStrFixedLenField("latest_key_lowest_acceptable_pn", "", length=4),
        XStrFixedLenField("old_key_key_server_member_id", "", length=12),
        XStrFixedLenField("old_key_key_number", "", length=4),
        XStrFixedLenField("old_key_lowest_acceptable_pn", "", length=4)
    ]
Esempio n. 29
0
class IE_Bearer_QoS(gtp.IE_Base):
    name = "IE Bearer Quality of Service"
    fields_desc = [
        ByteEnumField("ietype", 80, IEType),
        ShortField("length", None),
        BitField("CR_flag", 0, 4),
        BitField("instance", 0, 4),
        BitField("SPARE", 0, 1),
        BitField("PCI", 0, 1),
        BitField("PriorityLevel", 0, 4),
        BitField("SPARE", 0, 1),
        BitField("PVI", 0, 1),
        ByteField("QCI", 0),
        BitField("MaxBitRateForUplink", 0, 40),
        BitField("MaxBitRateForDownlink", 0, 40),
        BitField("GuaranteedBitRateForUplink", 0, 40),
        BitField("GuaranteedBitRateForDownlink", 0, 40)
    ]
Esempio n. 30
0
 def __init__(self, name, default, calculate_length=None):
     BitField.__init__(self, name, default, 0)
     self.length_f = calculate_length
Esempio n. 31
0
class IE_Indication(gtp.IE_Base):
    name = "IE Indication"
    fields_desc = [
        ByteEnumField("ietype", 77, IEType),
        ShortField("length", None),
        BitField("CR_flag", 0, 4),
        BitField("instance", 0, 4),
        BitField("DAF", 0, 1),
        BitField("DTF", 0, 1),
        BitField("HI", 0, 1),
        BitField("DFI", 0, 1),
        BitField("OI", 0, 1),
        BitField("ISRSI", 0, 1),
        BitField("ISRAI", 0, 1),
        BitField("SGWCI", 0, 1),
        BitField("SQCI", 0, 1),
        BitField("UIMSI", 0, 1),
        BitField("CFSI", 0, 1),
        BitField("CRSI", 0, 1),
        BitField("PS", 0, 1),
        BitField("PT", 0, 1),
        BitField("SI", 0, 1),
        BitField("MSV", 0, 1),
        ConditionalField(BitField("RetLoc", 0, 1), lambda pkt: pkt.length > 2),
        ConditionalField(BitField("PBIC", 0, 1), lambda pkt: pkt.length > 2),
        ConditionalField(BitField("SRNI", 0, 1), lambda pkt: pkt.length > 2),
        ConditionalField(BitField("S6AF", 0, 1), lambda pkt: pkt.length > 2),
        ConditionalField(BitField("S4AF", 0, 1), lambda pkt: pkt.length > 2),
        ConditionalField(BitField("MBMDT", 0, 1), lambda pkt: pkt.length > 2),
        ConditionalField(BitField("ISRAU", 0, 1), lambda pkt: pkt.length > 2),
        ConditionalField(BitField("CCRSI", 0, 1), lambda pkt: pkt.length > 2),
        ConditionalField(BitField("CPRAI", 0, 1), lambda pkt: pkt.length > 3),
        ConditionalField(BitField("ARRL", 0, 1), lambda pkt: pkt.length > 3),
        ConditionalField(BitField("PPOFF", 0, 1), lambda pkt: pkt.length > 3),
        ConditionalField(BitField("PPON", 0, 1), lambda pkt: pkt.length > 3),
        ConditionalField(BitField("PPSI", 0, 1), lambda pkt: pkt.length > 3),
        ConditionalField(BitField("CSFBI", 0, 1), lambda pkt: pkt.length > 3),
        ConditionalField(BitField("CLII", 0, 1), lambda pkt: pkt.length > 3),
        ConditionalField(BitField("CPSR", 0, 1), lambda pkt: pkt.length > 3),
    ]
Esempio n. 32
0
 def getfield(self, pkt, s):
     self.size = self.length_f(pkt)
     return BitField.getfield(self, pkt, s)
Esempio n. 33
0
class BFD(Packet):
    """ BFD protocol layer for scapy """

    udp_dport = 3784  #: BFD destination port per RFC 5881
    udp_dport_echo = 3785  # : BFD destination port for ECHO per RFC 5881
    udp_sport_min = 49152  #: BFD source port min value per RFC 5881
    udp_sport_max = 65535  #: BFD source port max value per RFC 5881
    bfd_pkt_len = 24  # : length of BFD pkt without authentication section
    sha1_auth_len = 28  # : length of authentication section if SHA1 used

    name = "BFD"

    fields_desc = [
        BitField("version", 1, 3),
        BitEnumField("diag", 0, 5, BFDDiagCode.desc_dict),
        BitEnumField("state", 0, 2, BFDState.desc_dict),
        FlagsField("flags", 0, 6, ['M', 'D', 'A', 'C', 'F', 'P']),
        XByteField("detect_mult", 0),
        BitField("length", bfd_pkt_len, 8),
        BitField("my_discriminator", 0, 32),
        BitField("your_discriminator", 0, 32),
        BitField("desired_min_tx_interval", 0, 32),
        BitField("required_min_rx_interval", 0, 32),
        BitField("required_min_echo_rx_interval", 0, 32),
        ConditionalField(
            BitEnumField("auth_type", 0, 8, BFDAuthType.desc_dict),
            bfd_is_auth_used),
        ConditionalField(BitField("auth_len", 0, 8), bfd_is_auth_used),
        ConditionalField(BitField("auth_key_id", 0, 8), bfd_is_auth_used),
        ConditionalField(BitField("auth_reserved", 0, 8),
                         bfd_is_md5_or_sha1_used),
        ConditionalField(BitField("auth_seq_num", 0, 32),
                         bfd_is_md5_or_sha1_used),
        ConditionalField(StrField("auth_key_hash", "0" * 16), bfd_is_md5_used),
        ConditionalField(StrField("auth_key_hash", "0" * 20),
                         bfd_is_sha1_used),
    ]

    def mysummary(self):
        return self.sprintf("BFD(my_disc=%BFD.my_discriminator%,"
                            "your_disc=%BFD.your_discriminator%)")