class ModbusPDU0FWriteMultipleCoilsRequest(Packet): name = "Write Multiple Coils" fields_desc = [XByteField("funcCode", 0x0F), XShortField("startAddr", 0x0000), XShortField("quantityOutput", 0x0001), BitFieldLenField("byteCount", None, 8, count_of="outputsValue"), FieldListField("outputsValue", [0x00], XByteField("", 0x00), count_from=lambda pkt: pkt.byteCount)]
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 ModbusPDU17ReadWriteMultipleRegistersResponse(Packet): name = "Read Write Multiple Registers Response" fields_desc = [XByteField("funcCode", 0x17), BitFieldLenField("byteCount", None, 8, count_of="registerVal", adjust=lambda pkt, x: x * 2), FieldListField("registerVal", [0x0000], ShortField("", 0x0000), count_from=lambda pkt: pkt.byteCount)]
class LLDPDUPortDescription(LLDPDU): """ ieee 802.1ab-2016 - sec. 8.5.5 / p. 29 """ fields_desc = [ BitEnumField('_type', 0x04, 7, LLDPDU.TYPES), BitFieldLenField('_length', None, 9, length_of='description'), StrLenField('description', '', length_from=lambda pkt: pkt._length) ]
class LLDPDUSystemName(LLDPDU): """ ieee 802.1ab-2016 - sec. 8.5.6 / p. 30 """ fields_desc = [ BitEnumField('_type', 0x05, 7, LLDPDU.TYPES), BitFieldLenField('_length', None, 9, length_of='system_name'), StrLenField('system_name', '', length_from=lambda pkt: pkt._length) ]
class ModbusObjectId(Packet): name = "Object" fields_desc = [ByteEnumField("id", 0x00, _read_device_id_object_id), BitFieldLenField("length", None, 8, length_of="value"), StrLenField("value", "", length_from=lambda pkt: pkt.length)] def guess_payload_class(self, payload): return ModbusObjectId
class ModbusPDU01ReadCoilsResponse(_ModbusPDUNoPayload): name = "Read Coils Response" fields_desc = [ XByteField("funcCode", 0x01), BitFieldLenField("byteCount", None, 8, count_of="coilStatus"), FieldListField("coilStatus", [0x00], ByteField("", 0x00), count_from=lambda pkt: pkt.byteCount) ]
class PIMv2GroupAddrs(_PIMGenericTlvBase): name = "PIMv2 Join/Prune: Multicast Group Address" fields_desc = [ ByteField("addr_family", 1), ByteField("encoding_type", 0), BitField("bidirection", 0, 1), BitField("reserved", 0, 6), BitField("admin_scope_zone", 0, 1), ByteField("mask_len", 32), IPField("gaddr", "0.0.0.0"), BitFieldLenField("num_joins", None, size=16, count_of="join_ips"), BitFieldLenField("num_prunes", None, size=16, count_of="prune_ips"), PacketListField("join_ips", [], PIMv2JoinAddrs, count_from=lambda x: x.num_joins), PacketListField("prune_ips", [], PIMv2PruneAddrs, count_from=lambda x: x.num_prunes), ]
class FCtrl_UpLink(Packet): name = "FCtrl_UpLink" fields_desc = [BitField("ADR", 0, 1), BitField("ADRACKReq", 0, 1), BitField("ACK", 0, 1), BitField("ClassB", 0, 1), BitFieldLenField("FOptsLen", 0, 4)] # pylint: disable=R0201 def extract_padding(self, p): return "", p
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 ModbusPDU02ReadDiscreteInputsResponse(Packet): """ inputStatus: result is represented as bytes, padded with 0 to have a integer number of bytes. The field does not parse this result and present the bytes directly """ name = "Read Discrete Inputs Response" fields_desc = [XByteField("funcCode", 0x02), BitFieldLenField("byteCount", None, 8, count_of="inputStatus"), FieldListField("inputStatus", [0x00], ByteField("", 0x00), count_from=lambda pkt: pkt.byteCount)]
class ModbusPDU11ReportSlaveIdResponse(Packet): name = "Report Slave Id Response" fields_desc = [ XByteField("funcCode", 0x11), BitFieldLenField("byteCount", None, 8, length_of="slaveId"), ConditionalField(StrLenField("slaveId", "", length_from=lambda pkt: pkt.byteCount), lambda pkt: pkt.byteCount > 0), ConditionalField(XByteField("runIdicatorStatus", 0x00), lambda pkt: pkt.byteCount > 0), ]
class LLDPDUPortID(LLDPDU): """ ieee 802.1ab-2016 - sec. 8.5.3 / p. 26 """ LLDP_PORT_ID_TLV_SUBTYPES = { 0x00: 'reserved', 0x01: 'interface alias', 0x02: 'port component', 0x03: 'MAC address', 0x04: 'network address', 0x05: 'interface name', 0x06: 'agent circuit ID', 0x07: 'locally assigned', range(0x08, 0xff): 'reserved' } SUBTYPE_RESERVED = 0x00 SUBTYPE_INTERFACE_ALIAS = 0x01 SUBTYPE_PORT_COMPONENT = 0x02 SUBTYPE_MAC_ADDRESS = 0x03 SUBTYPE_NETWORK_ADDRESS = 0x04 SUBTYPE_INTERFACE_NAME = 0x05 SUBTYPE_AGENT_CIRCUIT_ID = 0x06 SUBTYPE_LOCALLY_ASSIGNED = 0x07 fields_desc = [ BitEnumField('_type', 0x02, 7, LLDPDU.TYPES), BitFieldLenField('_length', None, 9, length_of='id', adjust=lambda pkt, x: _ldp_id_adjustlen(pkt, x)), ByteEnumField('subtype', 0x00, LLDP_PORT_ID_TLV_SUBTYPES), ConditionalField( ByteField('family', 0), lambda pkt: pkt.subtype == 0x04 ), MultipleTypeField([ ( MACField('id', None), lambda pkt: pkt.subtype == 0x03 ), ( IPField('id', None), lambda pkt: pkt.subtype == 0x04 ), ], StrLenField('id', '', length_from=lambda pkt: pkt._length - 1) ) ] def _check(self): """ run layer specific checks """ if conf.contribs['LLDP'].strict_mode() and not self.id: raise LLDPInvalidLengthField('id must be >= 1 characters long')
class FCtrl_Link(Packet): name = "FCtrl_UpLink" fields_desc = [ BitField("ADR", 0, 1), BitField("ADRACKReq", 0, 1), BitField("ACK", 0, 1), BitField("UpClassB_DownFPending", 0, 1), BitFieldLenField("FOptsLen", 0, 4) ] def extract_padding(self, p): return "", p
class ISIS_ExtendedIpPrefix(Packet): name = "ISIS Extended IP Prefix" fields_desc = [IntField("metric", 1), BitField("updown", 0, 1), BitField("subtlvindicator", 0, 1), BitFieldLenField("pfxlen", None, 6, length_of="pfx"), IPPrefixField("pfx", None, wordbytes=1, length_from= lambda x: x.pfxlen), ConditionalField(FieldLenField("subtlvslen", None, length_of=lambda x: x.subtlvs, fmt= "B"), lambda pkt: pkt.subtlvindicator == 1), ConditionalField(PacketListField("subtlvs", [], _isis_guess_subtlv_cls, length_from=lambda x: x.subtlvslen), lambda pkt: pkt.subtlvindicator == 1)] def extract_padding(self, s): return "", s
class ModbusReadFileSubResponse(Packet): name = "Sub-response" fields_desc = [ BitFieldLenField("respLength", None, 8, count_of="recData", adjust=lambda pkt, p: p * 2 + 1), ByteField("refType", 0x06), FieldListField("recData", [0x0000], XShortField("", 0x0000), count_from=lambda pkt: (pkt.respLength - 1) // 2), ] def guess_payload_class(self, payload): return ModbusReadFileSubResponse
class ModbusPDU01ReadCoilsResponse(Packet): name = "Read Coils Response" fields_desc = [ XByteField("funcCode", 0x01), BitFieldLenField("byteCount", None, 8, count_of="coilStatus"), # noqa: E501 FieldListField("coilStatus", [0x00], ByteField("", 0x00), count_from=lambda pkt: pkt.byteCount) ] # noqa: E501 def extract_padding(self, s): return b"", None
class PIMv2CRPAdv(_PIMGenericTlvBase): name = "Bootstrap crp adv" fields_desc = [ BitFieldLenField("prefix_count", None, size=8, count_of="groups"), ByteField("priority", 192), ShortField("holdtime", 150), ByteField("rp_address_family", 1), ByteField("rp_address_type", 0), IPField("rp_address", "0.0.0.0"), PacketListField("groups", [], EncodedGroupAddr, count_from=lambda x: x.groups) ]
class NSH(Packet): """Network Service Header. NSH MD-type 1 if there is no ContextHeaders""" name = "NSH" fields_desc = [ BitField('Ver', 0, 2), BitField('OAM', 0, 1), BitField('Unused1', 0, 1), BitField('TTL', 63, 6), BitFieldLenField('Length', None, 6, count_of='VLCH', adjust=lambda pkt, x: 6 if pkt.MDType == 1 else x + 2), # noqa: E501 BitField('Unused2', 0, 1), BitField('Unused3', 0, 1), BitField('Unused4', 0, 1), BitField('Unused5', 0, 1), BitEnumField( 'MDType', 1, 4, { 0: 'Reserved MDType', 1: 'Fixed Length', 2: 'Variable Length', 0xF: 'Experimental MDType' }), ByteEnumField( 'NextProto', 3, { 1: 'IPv4', 2: 'IPv6', 3: 'Ethernet', 4: 'NSH', 5: 'MPLS', 0xFE: 'Experiment 1', 0xFF: 'Experiment 2' }), X3BytesField('SPI', 0), ByteField('SI', 0xFF), ConditionalField(XIntField('CH1', 0), lambda pkt: pkt.MDType == 1), ConditionalField(XIntField('CH2', 0), lambda pkt: pkt.MDType == 1), ConditionalField(XIntField('CH3', 0), lambda pkt: pkt.MDType == 1), ConditionalField(XIntField('CH4', 0), lambda pkt: pkt.MDType == 1), ConditionalField( PacketListField("VLCH", None, NSHTLV, count_from="Length"), lambda pkt: pkt.MDType == 2) ] def mysummary(self): return self.sprintf("SPI: %SPI% - SI: %SI%")
class LLDPDUChassisID(LLDPDU): """ ieee 802.1ab-2016 - sec. 8.5.2 / p. 26 """ LLDP_CHASSIS_ID_TLV_SUBTYPES = { 0x00: 'reserved', 0x01: 'chassis component', 0x02: 'interface alias', 0x03: 'port component', 0x04: 'MAC address', 0x05: 'network address', 0x06: 'interface name', 0x07: 'locally assigned', range(0x08, 0xff): 'reserved' } LLDP_CHASSIS_ID_TLV_SUBTYPES_FIELDS = { 0x04: MACField, 0x05: IPField, } SUBTYPE_RESERVED = 0x00 SUBTYPE_CHASSIS_COMPONENT = 0x01 SUBTYPE_INTERFACE_ALIAS = 0x02 SUBTYPE_PORT_COMPONENT = 0x03 SUBTYPE_MAC_ADDRESS = 0x04 SUBTYPE_NETWORK_ADDRESS = 0x05 SUBTYPE_INTERFACE_NAME = 0x06 SUBTYPE_LOCALLY_ASSIGNED = 0x07 fields_desc = [ BitEnumField('_type', 0x01, 7, LLDPDU.TYPES), BitFieldLenField('_length', None, 9, length_of='id', adjust=lambda pkt, x: _ldp_id_adjustlen(pkt, x)), ByteEnumField('subtype', 0x00, LLDP_CHASSIS_ID_TLV_SUBTYPES), _LLDPidField('id', '', LLDP_CHASSIS_ID_TLV_SUBTYPES_FIELDS, length_from=lambda pkt: pkt._length - 1) # noqa: E501 ] def _check(self): """ run layer specific checks """ if conf.contribs['LLDP'].strict_mode() and not self.id: raise LLDPInvalidLengthField('id must be >= 1 characters long')
class IEC104_I_Message_SeqIOA(IEC104_I_Message): """ all information objects share a base information object address field sq = 1, see EN 60870-5-101:2003, sec. 7.2.2.1 (p. 33) """ name = 'IEC-104 I APDU (Seq IOA)' fields_desc = [ # APCI XByteField('start', IEC104_I_Message.IEC_104_MAGIC), FieldLenField("apdu_length", None, fmt="!B", length_of='io', adjust=lambda pkt, x: x + 13), IEC104SequenceNumber('tx_seq_num', 0), IEC104SequenceNumber('rx_seq_num', 0), # ASDU ByteEnumField('type_id', 0, IEC104_IO_NAMES), BitEnumField('sq', IEC104_I_Message.SQ_FLAG_SEQUENCE, 1, IEC104_I_Message.SQ_FLAGS), BitFieldLenField('num_io', None, 7, count_of='io'), BitEnumField('test', 0, 1, IEC104_I_Message.TEST_FLAGS), BitEnumField('ack', 0, 1, IEC104_I_Message.ACK_FLAGS), BitEnumField('cot', 0, 6, CAUSE_OF_TRANSMISSIONS), ByteField('origin_address', 0), LEShortField('common_asdu_address', 0), LEThreeBytesField('information_object_address', 0), IEC104ASDUPacketListField('io', conf.raw_layer(), _i_msg_io_dispatcher_sequence, length_from=lambda pkt: pkt.apdu_length - 13) ] def post_dissect(self, s): if self.type_id == IEC104_IO_ID_C_RD_NA_1: # IEC104_IO_ID_C_RD_NA_1 has no payload. we will add the layer # manually to the stack right now. we do this num_io times # as - even if it makes no sense - someone could decide # to add more than one read commands in a sequence... setattr(self, 'io', [IEC104_IO_C_RD_NA_1()] * self.num_io) return s
class ModbusPDU04ReadInputRegistersResponse(Packet): name = "Read Input Registers Response" fields_desc = [ XByteField("funcCode", 0x04), BitFieldLenField("byteCount", None, 8, count_of="registerVal", adjust=lambda pkt, x: x * 2), # noqa: E501 FieldListField( "registerVal", [0x0000], ShortField("", 0x0000), # noqa: E501 count_from=lambda pkt: pkt.byteCount) ]
class ModbusPDU0FWriteMultipleCoilsRequest(Packet): name = "Write Multiple Coils" fields_desc = [ XByteField("funcCode", 0x0F), XShortField("startingAddr", 0x0000), XShortField("quantityOutput", 0x0001), BitFieldLenField("byteCount", None, 8, count_of="outputsValue"), # noqa: E501 FieldListField("outputsValue", [0x00], XByteField("", 0x00), count_from=lambda pkt: pkt.byteCount) ] # noqa: E501 def extract_padding(self, s): return b"", None
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))
class RTP(Packet): name = "RTP" fields_desc = [ BitField('version', 2, 2), BitField('padding', 0, 1), BitField('extension', 0, 1), BitFieldLenField('numsync', None, 4, count_of='sync'), BitField('marker', 0, 1), BitEnumField('payload_type', 0, 7, _rtp_payload_types), ShortField('sequence', 0), IntField('timestamp', 0), IntField('sourcesync', 0), FieldListField('sync', [], IntField("id", 0), count_from=lambda pkt: pkt.numsync) ] # noqa: E501
class BIER(Packet): name = "BIER" fields_desc = [ BitField("id", 5, 4), BitField("version", 0, 4), BitFieldLenField("length", BIERLength.BIER_LEN_256, 4, length_of=lambda x: (x.BitString >> 8)), BitField("entropy", 0, 20), BitField("OAM", 0, 2), BitField("RSV", 0, 2), BitField("DSCP", 0, 6), BitEnumField("Proto", 2, 6, BIERnhcls), ShortField("BFRID", 0), StrLenField("BitString", "", length_from=lambda x: (8 << x.length)) ]
class ModbusWriteFileSubRequest(Packet): name = "Sub request of Write File Record" fields_desc = [ ByteField("refType", 0x06), ShortField("fileNumber", 0x0001), ShortField("recordNumber", 0x0000), BitFieldLenField("recordLength", None, 16, length_of="recordData", adjust=lambda pkt, p: p // 2), FieldListField("recordData", [0x0000], ShortField("", 0x0000), length_from=lambda pkt: pkt.recordLength * 2), ] def guess_payload_class(self, payload): if payload: return ModbusWriteFileSubRequest
class NSH(Packet): """Network Service Header. NSH MD-type 1 if there is no ContextHeaders""" name = "NSH" fields_desc = [ BitField('ver', 0, 2), BitField('oam', 0, 1), BitField('unused1', 0, 1), BitField('ttl', 63, 6), BitFieldLenField('length', None, 6, count_of='vlch', adjust=lambda pkt, x: 6 if pkt.mdtype == 1 else x + 2), BitField('unused2', 0, 4), BitEnumField( 'mdtype', 1, 4, { 0: 'Reserved MDType', 1: 'Fixed Length', 2: 'Variable Length', 0xF: 'Experimental MDType' }), ByteEnumField( 'nextproto', 3, { 1: 'IPv4', 2: 'IPv6', 3: 'Ethernet', 4: 'NSH', 5: 'MPLS', 0xFE: 'Experiment 1', 0xFF: 'Experiment 2' }), X3BytesField('spi', 0), ByteField('si', 0xFF), ConditionalField(XStrFixedLenField("context_header", "", 16), lambda pkt: pkt.mdtype == 1), ConditionalField( PacketListField("vlch", None, NSHTLV, count_from="length"), lambda pkt: pkt.mdtype == 2) ] def mysummary(self): return self.sprintf("SPI: %spi% - SI: %si%")
class NSH(Packet): """Network Service Header. NSH MD-type 1 if there is no ContextHeaders""" name = "NSH" fields_desc = [ BitField('Ver', 0, 2), BitField('OAM', 0, 1), BitField('Critical', 0, 1), BitField('Reserved', 0, 6), BitFieldLenField('Len', None, 6, count_of='ContextHeaders', adjust=lambda pkt, x: 6 if pkt.MDType == 1 else x + 2), ByteEnumField('MDType', 1, { 1: 'Fixed Length', 2: 'Variable Length' }), ByteEnumField('NextProto', 3, { 1: 'IPv4', 2: 'IPv6', 3: 'Ethernet', 4: 'NSH', 5: 'MPLS' }), X3BytesField('NSP', 0), ByteField('NSI', 1), ConditionalField(XIntField('NPC', 0), lambda pkt: pkt.MDType == 1), ConditionalField(XIntField('NSC', 0), lambda pkt: pkt.MDType == 1), ConditionalField(XIntField('SPC', 0), lambda pkt: pkt.MDType == 1), ConditionalField(XIntField('SSC', 0), lambda pkt: pkt.MDType == 1), ConditionalField( PacketListField("ContextHeaders", None, NSHTLV, count_from="Length"), lambda pkt: pkt.MDType == 2) ] def mysummary(self): return self.sprintf("NSP: %NSP% - NSI: %NSI%")
class IEC104_I_Message_SingleIOA(IEC104_I_Message): """ every information object contains an individual information object address field sq = 0, see EN 60870-5-101:2003, sec. 7.2.2.1 (p. 33) """ name = 'IEC-104 I APDU (single IOA)' fields_desc = [ # APCI XByteField('start', IEC104_I_Message.IEC_104_MAGIC), FieldLenField("apdu_length", None, fmt="!B", length_of='io', adjust=lambda pkt, x: x + 10), IEC104SequenceNumber('tx_seq_num', 0), IEC104SequenceNumber('rx_seq_num', 0), # ASDU ByteEnumField('type_id', 0, IEC104_IO_NAMES), BitEnumField('sq', IEC104_I_Message.SQ_FLAG_SINGLE, 1, IEC104_I_Message.SQ_FLAGS), BitFieldLenField('num_io', None, 7, count_of='io'), BitEnumField('test', 0, 1, IEC104_I_Message.TEST_FLAGS), BitEnumField('ack', 0, 1, IEC104_I_Message.ACK_FLAGS), BitEnumField('cot', 0, 6, CAUSE_OF_TRANSMISSIONS), ByteField('origin_address', 0), LEShortField('common_asdu_address', 0), IEC104ASDUPacketListField('io', conf.raw_layer(), _i_msg_io_dispatcher_single, length_from=lambda pkt: pkt.apdu_length - 10) ]