class GMLAN_DPBA(Packet): name = 'DefinePIDByAddress' fields_desc = [ XShortField('parameterIdentifier', 0), MultipleTypeField([ (XShortField('memoryAddress', 0), lambda pkt: GMLAN.determine_len(2)), (X3BytesField('memoryAddress', 0), lambda pkt: GMLAN.determine_len(3)), (XIntField('memoryAddress', 0), lambda pkt: GMLAN.determine_len(4)) ], XIntField('memoryAddress', 0)), XByteField('memorySize', 0), ] @staticmethod def get_log(pkt): return pkt.sprintf("%GMLAN.service%"), \ (pkt.parameterIdentifier, pkt.memoryAddress, pkt.memorySize)
class PPP_PAP_Request(PPP_PAP): fields_desc = [ ByteEnumField("code", 1, _PPP_paptypes), XByteField("id", 0), FieldLenField("len", None, fmt="!H", length_of="username", adjust=lambda p, x: x + 6 + len(p.password)), FieldLenField("username_len", None, fmt="B", length_of="username"), StrLenField("username", None, length_from=lambda p: p.username_len), FieldLenField("passwd_len", None, fmt="B", length_of="password"), StrLenField("password", None, length_from=lambda p: p.passwd_len) ] def mysummary(self): return self.sprintf("PAP-Request username=%PPP_PAP_Request.username%" + " password=%PPP_PAP_Request.password%")
class PPP_LCP_Configure(PPP_LCP): fields_desc = [ ByteEnumField("code", 1, _PPP_lcptypes), XByteField("id", 0), FieldLenField("len", None, fmt="H", length_of="options", adjust=lambda _, val: val + 4), PacketListField("options", [], PPP_LCP_Option, length_from=lambda pkt: pkt.len - 4), ] def answers(self, other): return (isinstance(other, PPP_LCP_Configure) and self.code in [2, 3, 4] and other.code == 1 and other.id == self.id)
class LEAP(EAP): """ Cisco LEAP (Lightweight EAP) https://freeradius.org/rfc/leap.txt """ name = "Cisco LEAP" fields_desc = [ ByteEnumField("code", 1, eap_codes), ByteField("id", 0), ShortField("len", None), ByteEnumField("type", 17, eap_types), ByteField('version', 1), XByteField('unused', 0), FieldLenField("count", None, "challenge_response", "B", adjust=lambda p, x: len(p.challenge_response)), # noqa: E501 XStrLenField("challenge_response", "", length_from=lambda p: 0 or p.count), # noqa: E501 StrLenField("username", "", length_from=lambda p: p.len - (8 + (0 or p.count))) # noqa: E501 ]
class OFPTPacketIn(_ofp_header): name = "OFPT_PACKET_IN" fields_desc = [ ByteEnumField("version", 0x01, ofp_version), ByteEnumField("type", 10, ofp_type), ShortField("len", None), IntField("xid", 0), IntEnumField("buffer_id", "NO_BUFFER", ofp_buffer), ShortField("total_len", 0), ShortEnumField("in_port", 0, ofp_port_no), ByteEnumField("reason", 0, { 0: "OFPR_NO_MATCH", 1: "OFPR_ACTION" }), XByteField("pad", 0), PacketField("data", None, Ether) ] overload_fields = {TCP: {"dport": 6653}}
class CDPMsgVoIPVLANQuery(CDPMsgGeneric): name = "VoIP VLAN Query" type = 0x000f fields_desc = [ XShortEnumField("type", 0x000f, _cdp_tlv_types), FieldLenField("len", None, "unknown2", fmt="!H", adjust=lambda pkt, x: x + 7), XByteField("unknown1", 0), ShortField("vlan", 1), # TLV length (len) - 2 (type) - 2 (len) - 1 (unknown1) - 2 (vlan) # noqa: E501 StrLenField("unknown2", "", length_from=lambda p: p.len - 7, max_length=65528) ]
class ModbusPDU10WriteMultipleRegistersRequest(Packet): name = "Write Multiple Registers" fields_desc = [ XByteField("funcCode", 0x10), XShortField("startAddr", 0x0000), BitFieldLenField("quantityRegisters", None, 16, count_of="outputsValue"), BitFieldLenField("byteCount", None, 8, count_of="outputsValue", adjust=lambda pkt, x: x * 2), FieldListField("outputsValue", [0x0000], XShortField("", 0x0000), count_from=lambda pkt: pkt.byteCount) ]
class Join_Accept(Packet): name = "Join_Accept" dcflist = False fields_desc = [LEX3BytesField("JoinAppNonce", 0), LEX3BytesField("NetID", 0), XLEIntField("DevAddr", 0), DLsettings, XByteField("RxDelay", 0), ConditionalField(StrFixedLenField("CFList", b"\x00" * 16, 16), # noqa: E501 lambda pkt:(Join_Accept.dcflist is True))] # pylint: disable=R0201 def extract_padding(self, p): return "", p def __init__(self, packet=""): # CFList calculated with rest of packet len if len(packet) > 18: Join_Accept.dcflist = True super(Join_Accept, self).__init__(packet)
class ModbusADUResponse(Packet): name = "ModbusADU" fields_desc = [ # needs to be unique XShortField("transId", 0x0000), # needs to be zero (Modbus) XShortField("protoId", 0x0000), # is calculated with payload ShortField("len", None), # 0xFF or 0x00 should be used for Modbus over TCP/IP XByteField("unitId", 0xff), ] def guess_payload_class(self, payload): function_code = orb(payload[0]) if function_code == 0x2B: sub_code = orb(payload[1]) try: return _mei_types_response[sub_code] except KeyError: pass try: return _modbus_response_classes[function_code] except KeyError: pass try: return _modbus_error_classes[function_code] except KeyError: pass if function_code in _reserved_funccode_response: return ModbusPDUReservedFunctionCodeResponse elif function_code in _reserved_funccode_error: return ModbusPDUReservedFunctionCodeError if function_code < 0x80: return ModbusPDUUserDefinedFunctionCodeResponse return ModbusPDUUserDefinedFunctionCodeError def post_build(self, p, pay): if self.len is None: tmp_len = len(pay) + 1 # +len(p) p = p[:4] + struct.pack("!H", tmp_len) + p[6:] return p + pay
class OFPTFlowRemoved(_ofp_header): name = "OFPT_FLOW_REMOVED" fields_desc = [ByteEnumField("version", 0x01, ofp_version), ByteEnumField("type", 11, ofp_type), ShortField("len", None), IntField("xid", 0), PacketField("match", OFPMatch(), OFPMatch), LongField("cookie", 0), ShortField("priority", 0), ByteEnumField("reason", 0, {0: "OFPRR_IDLE_TIMEOUT", 1: "OFPRR_HARD_TIMEOUT", 2: "OFPRR_DELETE"}), XByteField("pad1", 0), IntField("duration_sec", 0), IntField("duration_nsec", 0), ShortField("idle_timeout", 0), XShortField("pad2", 0), LongField("packet_count", 0), LongField("byte_count", 0)]
class VXLAN(Packet): name = "VXLAN" fields_desc = [ FlagsField( "flags", 0x8, 8, ['OAM', 'R', 'NextProtocol', 'Instance', 'V1', 'V2', 'R', 'G']), ByteEnumField('NextProtocol', 0, { 0: 'NotDefined', 1: 'IPv4', 2: 'IPv6', 3: 'Ethernet', 4: 'NSH' }), ConditionalField( ThreeBytesField("reserved1", 0x000000), lambda pkt: not pkt.flags & 0x80, ), ConditionalField( FlagsField("gpflags", 0x0, 8, _GP_FLAGS), lambda pkt: pkt.flags & 0x80, ), ConditionalField( ShortField("gpid", 0), lambda pkt: pkt.flags & 0x80, ), X3BytesField("vni", 0), XByteField("reserved2", 0x00), ] # Use default linux implementation port overload_fields = { UDP: { 'dport': 8472 }, } def mysummary(self): if self.flags & 0x80: return self.sprintf("VXLAN (vni=%VXLAN.vni% gpid=%VXLAN.gpid%)") else: return self.sprintf("VXLAN (vni=%VXLAN.vni%)")
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%)" )
class ModbusPDU17ReadWriteMultipleRegistersRequest(Packet): name = "Read Write Multiple Registers" fields_desc = [ XByteField("funcCode", 0x17), XShortField("readStartingAddr", 0x0000), XShortField("readQuantityRegisters", 0x0001), XShortField("writeStartingAddr", 0x0000), BitFieldLenField("writeQuantityRegisters", None, 16, count_of="writeRegistersValue"), BitFieldLenField("byteCount", None, 8, count_of="writeRegistersValue", adjust=lambda pkt, x: x * 2), FieldListField("writeRegistersValue", [0x0000], XShortField("", 0x0000), count_from=lambda pkt: pkt.byteCount) ]
class Profisafe(PNIORealTimeRawData): """PROFISafe profil to be encapsulated inside the PNRT.data list. It's a configurable packet whose config includes a fix length, and a CRC length. The config parameter must then be a dict {"length": X, "CRC": Y}. """ name = "PROFISafe" fields_desc = [ StrFixedLenField("load", "", length_from=lambda p: p[Profisafe].data_length()), XByteField("Control_Status", 0), XVarBytesField("CRC", 0, length_from=lambda p: p[Profisafe].crc_length()) ] def data_length(self): """Return the length of the data""" ret = self.length() - self.crc_length() - 1 return ret def crc_length(self): """Return the length of the crc""" return self._config["CRC"]
class IE_EndUserAddress(IE_Base): # Supply protocol specific information of the external packet name = "End User Address" fields_desc = [ByteEnumField("ietype", 128, IEType), # data network accessed by the GGPRS subscribers. # - Request # 1 Type (1byte) # 2-3 Length (2bytes) - value 2 # 4 Spare + PDP Type Organization # 5 PDP Type Number # - Response # 6-n PDP Address ShortField("length", 2), BitField("SPARE", 15, 4), BitField("PDPTypeOrganization", 1, 4), XByteField("PDPTypeNumber", None), ConditionalField(IPField("PDPAddress", RandIP()), lambda pkt: pkt.length == 6 or pkt.length == 22), # noqa: E501 ConditionalField(IP6Field("IPv6_PDPAddress", '::1'), lambda pkt: pkt.length == 18 or pkt.length == 22)] # noqa: E501
class IEC104_U_Message(IEC104_APDU): """ message used for connection tx control (start/stop) and monitoring (test) """ name = 'IEC-104 U APDU' fields_desc = [ XByteField('start', 0x68), ByteField("apdu_length", 4), BitField('testfr_con', 0, 1), BitField('testfr_act', 0, 1), BitField('stopdt_con', 0, 1), BitField('stopdt_act', 0, 1), BitField('startdt_con', 0, 1), BitField('startdt_act', 0, 1), BitField('octet_1_1_2', 3, 2), ByteField('octet_2', 0), ByteField('octet_3', 0), ByteField('octet_4', 0) ]
class PortIngressRuleResultOLTBroadcastQueue(Packet): """ Variable Descriptor: Port Ingress Rule Result OLT Broadcast Queue """ name = "Variable Descriptor: Port Ingress Rule Result OLT Broadcast Queue" fields_desc = [ XByteField("branch", 0xD7), XShortField("leaf", 0x0501), ByteField("length", 15), XByteField("result", 3), XByteField("oltqueuerule", 0x13), XShortField("objecttype", 0x0001), XByteField("instance", 0), XByteField("pon", 0), XLongField("broadcast", 0xffffffffffff0000), XByteField("pad", 0), ]
class OBD_NR(Packet): name = "NegativeResponse" responses = { 0x10: 'generalReject', 0x11: 'serviceNotSupported', 0x12: 'subFunctionNotSupported-InvalidFormat', 0x21: 'busy-RepeatRequest', 0x22: 'conditionsNotCorrectOrRequestSequenceError', 0x78: 'requestCorrectlyReceived-ResponsePending' } fields_desc = [ XByteField('request_service_id', 0), XByteEnumField('response_code', 0, responses) ] def answers(self, other): return self.request_service_id == other.service and \ (self.response_code != 0x78 or conf.contribs['OBD']['treat-response-pending-as-answer'])
class GMLAN_RDBPKTI(Packet): name = 'ReadDataByPacketIdentifier' subfunctions = { 0x00: "stopSending", 0x01: "sendOneResponse", 0x02: "scheduleAtSlowRate", 0x03: "scheduleAtMediumRate", 0x04: "scheduleAtFastRate" } fields_desc = [ XByteEnumField('subfunction', 0, subfunctions), ConditionalField( FieldListField('request_DPIDs', [], XByteField("", 0)), lambda pkt: pkt.subfunction > 0x0) ] @staticmethod def get_log(pkt): return pkt.sprintf("%GMLAN.service%"), \ pkt.sprintf("%GMLAN_RDBPKTI.subfunction%")
class DCPDeviceRoleBlock(Packet): fields_desc = [ ByteEnumField("option", 2, DCP_OPTIONS), MultiEnumField("sub_option", 4, DCP_SUBOPTIONS, fmt='B', depends_on=lambda p: p.option), LenField("dcp_block_length", 4), ShortEnumField("block_info", 0, BLOCK_INFOS), ByteEnumField("device_role_details", 1, DCP_DEVICE_ROLES), XByteField("reserved", 0x00), PadField(StrLenField("padding", b"\x00", length_from=lambda p: p.dcp_block_length % 2), 1, padwith=b"\x00") ] def extract_padding(self, s): return '', s
class PPP_PAP_Response(PPP_PAP): fields_desc = [ ByteEnumField("code", 2, _PPP_paptypes), XByteField("id", 0), FieldLenField("len", None, fmt="!H", length_of="message", adjust=lambda _, val: val + 5), FieldLenField("msg_len", None, fmt="B", length_of="message"), StrLenField("message", "", length_from=lambda pkt: pkt.msg_len), ] def answers(self, other): return isinstance(other, PPP_PAP_Request) and other.id == self.id def mysummary(self): res = "PAP-Ack" if self.code == 2 else "PAP-Nak" if self.msg_len > 0: res += self.sprintf(" msg=%PPP_PAP_Response.message%") return res
class SCTPChunkSACK(_SCTPChunkGuessPayload, Packet): fields_desc = [ ByteEnumField("type", 3, sctpchunktypes), XByteField("flags", None), ShortField("len", None), XIntField("cumul_tsn_ack", None), IntField("a_rwnd", None), FieldLenField("n_gap_ack", None, count_of="gap_ack_list"), FieldLenField("n_dup_tsn", None, count_of="dup_tsn_list"), FieldListField("gap_ack_list", [], GapAckField("gap_ack", None), count_from=lambda pkt: pkt.n_gap_ack), # noqa: E501 FieldListField("dup_tsn_list", [], XIntField("dup_tsn", None), count_from=lambda pkt: pkt.n_dup_tsn), # noqa: E501 ] def post_build(self, p, pay): if self.len is None: p = p[:2] + struct.pack(">H", len(p)) + p[4:] return p + pay
class PPP_CHAP(Packet): name = "PPP Challenge Handshake Authentication Protocol" fields_desc = [ ByteEnumField("code", 1, _PPP_chaptypes), XByteField("id", 0), FieldLenField("len", None, fmt="!H", length_of="data", adjust=lambda _, val: val + 4), StrLenField("data", "", length_from=lambda pkt: pkt.len - 4), ] def answers(self, other): return isinstance(other, PPP_CHAP_ChallengeResponse) \ and other.code == 2 and self.code in (3, 4) \ and self.id == other.id @classmethod def dispatch_hook(cls, _pkt=None, *_, **kargs): code = None if _pkt: code = orb(_pkt[0]) elif "code" in kargs: code = kargs["code"] if isinstance(code, six.string_types): code = cls.fields_desc[0].s2i[code] if code in (1, 2): return PPP_CHAP_ChallengeResponse return cls def extract_padding(self, pay): return "", pay def mysummary(self): if self.code == 3: return self.sprintf("CHAP Success message=%PPP_CHAP.data%") elif self.code == 4: return self.sprintf("CHAP Failure message=%PPP_CHAP.data%")
class PortIngressRuleResultOLTQueue(Packet): """ Variable Descriptor: Port Ingress Rule Result OLT Queue """ name = "Variable Descriptor: Port Ingress Rule Result OLT Queue" fields_desc = [ XByteField("branch", 0xD7), XShortField("leaf", 0x0501), ByteField("length", 15), XByteField("result", 3), XByteField("oltqueuerule", 0x13), XShortField("objecttype", 0x0001), XByteField("instance", 0), XByteField("pon", 0), StrField("unicastvssn", "TBIT"), XIntField("unicastlink", 0xe2222900), XByteField("pad", 0), ]
class PPP_CHAP_ChallengeResponse(PPP_CHAP): fields_desc = [ByteEnumField("code", 1, _PPP_chaptypes), XByteField("id", 0), FieldLenField("len", None, fmt="!H", length_of="value", adjust=lambda p, x: x + len(p.optional_name) + 5), FieldLenField("value_size", None, fmt="B", length_of="value"), XStrLenField("value", b"\0"*8, length_from=lambda p: p.value_size), StrLenField("optional_name", "", length_from=lambda p: p.len - p.value_size - 5)] def answers(self, other): return isinstance(other, PPP_CHAP_ChallengeResponse) and other.code == 1\ and self.code == 2 and self.id == other.id def mysummary(self): if self.code == 1: return self.sprintf("CHAP challenge=0x%PPP_CHAP_ChallengeResponse.value% " + "optional_name=%PPP_CHAP_ChallengeResponse.optional_name%") elif self.code == 2: return self.sprintf("CHAP response=0x%PPP_CHAP_ChallengeResponse.value% " + "optional_name=%PPP_CHAP_ChallengeResponse.optional_name%") else: return PPP_CHAP.mysummary(self)
class ISOTPHeaderEA(ISOTPHeader): name = 'ISOTPHeaderExtendedAddress' fields_desc = [ FlagsField('flags', 0, 3, ['error', 'remote_transmission_request', 'extended']), XBitField('identifier', 0, 29), ByteField('length', None), ThreeBytesField('reserved', 0), XByteField('extended_address', 0) ] def post_build(self, p, pay): # type: (bytes, bytes) -> bytes """ This will set the ByteField 'length' to the correct value. 'chb(len(pay) + 1)' is required, because the field 'extended_address' is counted as payload on the CAN layer """ if self.length is None: p = p[:4] + chb(len(pay) + 1) + p[5:] return p + pay
class AOE(Packet): name = "ATA over Ethernet" fields_desc = [ BitField("version", 1, 4), FlagsField("flags", 0, 4, ["Response", "Error", "r1", "r2"]), ByteEnumField( "error", 0, { 1: "Unrecognized command code", 2: "Bad argument parameter", 3: "Device unavailable", 4: "Config string present", 5: "Unsupported exception", 6: "Target is reserved" }), XShortField("major", 0xFFFF), XByteField("minor", 0xFF), ByteEnumField( "cmd", 1, { 0: "Issue ATA Command", 1: "Query Config Information", 2: "Mac Mask List", 3: "Reserve / Release" }), XIntField("tag", 0), ConditionalField( PacketField("i_ata_cmd", IssueATACommand(), IssueATACommand), lambda x: x.cmd == 0), ConditionalField( PacketField("q_conf_info", QueryConfigInformation(), QueryConfigInformation), lambda x: x.cmd == 1), ConditionalField(PacketField("mac_m_list", MacMaskList(), MacMaskList), lambda x: x.cmd == 2), ConditionalField( PacketField("res_rel", ReserveRelease(), ReserveRelease), lambda x: x.cmd == 3) ] def extract_padding(self, s): return "", s
class RSVP(Packet): name = "RSVP" fields_desc = [ BitField("Version", 1, 4), BitField("Flags", 1, 4), ByteEnumField("Class", 0x01, rsvpmsgtypes), XShortField("chksum", None), ByteField("TTL", 1), XByteField("dataofs", 0), ShortField("Length", None) ] def post_build(self, p, pay): p += pay if self.Length is None: tmp_len = len(p) tmp_p = p[:6] + chb((tmp_len >> 8) & 0xff) + chb(tmp_len & 0xff) p = tmp_p + p[8:] if self.chksum is None: ck = checksum(p) p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:] return p
class Dot11EltMicrosoftWPA(Dot11Elt): name = "802.11 Microsoft WPA" 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) ]
class BTLE_ADV(Packet): # BT Core 5.2 - 2.3 ADVERTISING PHYSICAL CHANNEL PDU name = "BTLE advertising header" fields_desc = [ BitEnumField("RxAdd", 0, 1, { 0: "public", 1: "random" }), BitEnumField("TxAdd", 0, 1, { 0: "public", 1: "random" }), # 4.5.8.3.1 - LE Channel Selection Algorithm #2 BitEnumField("ChSel", 0, 1, {1: "#2"}), BitField("RFU", 0, 1), # Unused BitEnumField( "PDU_type", 0, 4, { 0: "ADV_IND", 1: "ADV_DIRECT_IND", 2: "ADV_NONCONN_IND", 3: "SCAN_REQ", 4: "SCAN_RSP", 5: "CONNECT_REQ", 6: "ADV_SCAN_IND" }), XByteField("Length", None), ] def post_build(self, p, pay): p += pay if self.Length is None: if len(pay) > 2: l_pay = len(pay) else: l_pay = 0 p = p[:1] + chb(l_pay & 0xff) + p[2:] if not isinstance(self.underlayer, BTLE): self.add_underlayer(BTLE) return p
def i2repr(self, pkt, x): return XByteField.i2repr(self, pkt, x)