class SWAT_P1_PLC(scapy_all.Packet): name = "SWAT_P1_PLC" fields_desc = [ scapy_all.LEShortField('counter', 0), scapy_all.LEIntField('number', 0), scapy_all.LEShortField('spare', 0), ]
class CIP_ReqForwardOpen(scapy_all.Packet): """Forward Open request""" name = "CIP_ReqForwardOpen" fields_desc = [ scapy_all.XByteField("priority_ticktime", 0), scapy_all.ByteField("timeout_ticks", 249), scapy_all.LEIntField("OT_network_connection_id", 0x80000031), scapy_all.LEIntField("TO_network_connection_id", 0x80fe0030), scapy_all.LEShortField("connection_serial_number", 0x1337), scapy_all.LEShortField("vendor_id", 0x004d), scapy_all.LEIntField("originator_serial_number", 0xdeadbeef), scapy_all.ByteField("connection_timeout_multiplier", 0), scapy_all.XByteField("reserved1", 0), scapy_all.XByteField("reserved2", 0), scapy_all.XByteField("reserved3", 0), scapy_all.LEIntField("OT_rpi", 0x007a1200), # 8000 ms scapy_all.LEShortField("OT_connection_param", 0x43f4), # exclusive, PtP, low prio, size 500 scapy_all.LEIntField("TO_rpi", 0x007a1200), scapy_all.LEShortField("TO_connection_param", 0x43f4), scapy_all.XByteField( "transport_type", 0xa3), # direction server, application object, class 3 scapy_all.ByteField("path_wordsize", None), CIP_PathField("path", None, length_from=lambda p: 2 * p.path_wordsize), ]
class CIP_ReqForwardOpen(scapy_all.Packet): """Forward Open request""" name = "CIP_ReqForwardOpen" fields_desc = [ scapy_all.BitField("priority", 0, 4), scapy_all.BitField("tick_time", 0, 4), scapy_all.ByteField("timeout_ticks", 249), scapy_all.LEIntField("OT_network_connection_id", 0x80000031), scapy_all.LEIntField("TO_network_connection_id", 0x80fe0030), scapy_all.LEShortField("connection_serial_number", 0x1337), scapy_all.LEShortField("vendor_id", 0x004d), scapy_all.LEIntField("originator_serial_number", 0xdeadbeef), scapy_all.ByteField("connection_timeout_multiplier", 0), scapy_all.X3BytesField("reserved", 0), scapy_all.LEIntField("OT_rpi", 0x007a1200), # 8000 ms For ToCNC and ToCell #scapy_all.LEIntField("OT_rpi", 0x00000000), # for j scapy_all.LEShortField("OT_connection_param", 0x4802), #for ToCNC and ToCell #scapy_all.LEShortField("OT_connection_param", 0x0400), #for j #scapy_all.PacketField('OT_connection_param', CIP_ConnectionParam(), CIP_ConnectionParam), scapy_all.LEIntField("TO_rpi", 0x007a1200), #ToCNC and ToCell #scapy_all.LEIntField("TO_rpi", 0x00000000), #for j scapy_all.LEShortField("TO_connection_param", 0x281a), #for ToCNC and ToCell #scapy_all.LEShortField("TO_connection_param", 0x0400), #for j #scapy_all.PacketField('TO_connection_param', CIP_ConnectionParam(), CIP_ConnectionParam), scapy_all.XByteField("transport_type", 0x81), # direction server, application object, class 3 scapy_all.ByteField("path_wordsize", None), CIP_PathField("path", None, length_from=lambda p: 2 * p.path_wordsize), ]
class ENIP_ListIdentity_TargetItem(scapy_all.Packet): name = "ENIP_ListIdentity_TargetItem" fields_desc = [ scapy_all.LEShortField("item_type_code", 0), scapy_all.LEShortField("length", 0), scapy_all.LEShortField("encapsulation_version", 1), scapy_all.PacketField("ListIdentityItems", ENIP_ListIdentity_SocketItem(), ENIP_ListIdentity_SocketItem), #, count_from=1), scapy_all.LEShortField("vendor_ID", 0), scapy_all.LEShortEnumField("device_type", 0x21, DEVICE_PROFILES), scapy_all.LEShortField("product_code", 0), scapy_all.PacketField("ENIP_DeviceRevision", ENIP_DeviceRevision(), ENIP_DeviceRevision), scapy_all.XShortField("status", 0x0000), utils.XLEIntField("serial", 0x00000000), scapy_all.ByteField("product_name_length", 0), scapy_all.StrLenField("product_name", "", length_from=lambda p: p.product_name_length), scapy_all.XByteField("state", 0), ] def extract_padding(self, p): # print self.__class__.__name__ + ": P=" + str(p) return "", p
class CIP_ReqReadOtherTag(scapy_all.Packet): """Optional information to be sent with a Read_Tag_Service FIXME: this packet has been built from experiments, not from official doc """ fields_desc = [ scapy_all.LEShortField("start", 0), scapy_all.LEShortField("zero", 0), scapy_all.LEShortField("length", None), ]
class SWAT_P1_WRIO_AI(scapy_all.Packet): name = "SWAT_P1_WRIO_AI" fields_desc = [ scapy_all.LEShortField('counter', 0), scapy_all.LEIntField('padding', 0), scapy_all.LEShortField('level', 0), scapy_all.LEShortField('flow', 0), scapy_all.FieldListField( "spare", [], scapy_all.LEShortField("", 0), length_from=lambda p: p.underlayer.length - 10), ]
class CIP_ReqForwardClose(scapy_all.Packet): """Forward Close request""" name = "CIP_ReqForwardClose" fields_desc = [ scapy_all.XByteField("priority_ticktime", 0), scapy_all.ByteField("timeout_ticks", 249), scapy_all.LEShortField("connection_serial_number", 0x1337), scapy_all.LEShortField("vendor_id", 0x004d), scapy_all.LEIntField("originator_serial_number", 0xdeadbeef), scapy_all.ByteField("path_wordsize", None), scapy_all.XByteField("reserved", 0), CIP_PathField("path", None, length_from=lambda p: 2 * p.path_wordsize), ]
class ENIP_ListServices_TargetItem(scapy_all.Packet): name = "ENIP_ListServicesTarget_Item" fields_desc = [ scapy_all.LEShortField("item_type_code", 0), scapy_all.LEShortField("length", 0), scapy_all.LEShortField("encapsulation_version", 1), scapy_all.LEShortField("capability_flags", 0), scapy_all.StrFixedLenField("name_of_service", "", 16), ] def extract_padding(self, p): return "", p
class CIP_RespForwardOpen(scapy_all.Packet): """Forward Open response""" name = "CIP_RespForwardOpen" fields_desc = [ scapy_all.LEIntField("OT_network_connection_id", None), scapy_all.LEIntField("TO_network_connection_id", None), scapy_all.LEShortField("connection_serial_number", None), scapy_all.LEShortField("vendor_id", None), scapy_all.LEIntField("originator_serial_number", None), scapy_all.LEIntField("OT_api", None), scapy_all.LEIntField("TO_api", None), scapy_all.ByteField("application_reply_size", None), scapy_all.XByteField("reserved", 0), ]
class SWAT_P1_RIO_DI(scapy_all.Packet): name = 'SWAT_P1_RIO_DI' fields_desc = [ scapy_all.LEShortField('counter', 0), scapy_all.LEIntField('padding', 0), scapy_all.BitEnumField('pump2_fault', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('pump2_run', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('pump2_auto', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('pump1_fault', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('pump1_run', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('pump1_auto', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('rio_wireless', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('plc_wireless', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitField('spare', 0, 6), scapy_all.BitEnumField('valve_close', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('valve_open', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.LEShortField('spare2', 0), ]
class Header(scapy.Packet): name = "Header" fields_desc = [ scapy.IntField("MagicWord", 0xDEC0DED), # 32 bit scapy.ByteField("MessageDataType", 0x00), # 8 bit scapy.LEShortField("MessageDataSize", 0x00) # 16 bit ]
class ENIP_TCP(scapy_all.Packet): """Ethernet/IP packet over TCP""" name = "ENIP_TCP" fields_desc = [ #add missing bits here scapy_all.LEShortEnumField( "command_id", None, { 0x0004: "ListServices", 0x0063: "ListIdentity", 0x0064: "ListInterfaces", 0x0065: "RegisterSession", 0x0066: "UnregisterSession", 0x006f: "SendRRData", # Send Request/Reply data 0x0070: "SendUnitData", }), scapy_all.LEShortField("length", None), scapy_all.LEIntField("session", 0), scapy_all.LEIntEnumField("status", 0, {0: "success"}), scapy_all.LELongField("sender_context", 0), scapy_all.LEIntField("options", 0), ] def extract_padding(self, p): return p[:self.length], p[self.length:] def post_build(self, p, pay): if self.length is None and pay: l = len(pay) p = p[:2] + struct.pack("<H", l) + p[4:] return p + pay
class CIP_ReqGetAttributeList(scapy_all.Packet): """The list of requested attributes in a CIP Get_Attribute_List request""" fields_desc = [ utils.LEShortLenField("count", None, count_of="attrs"), scapy_all.FieldListField("attrs", [], scapy_all.LEShortField("", 0), count_from=lambda pkt: pkt.count), ]
class ENIP_SendUnitData_Item(scapy_all.Packet): name = "ENIP_SendUnitData_Item" fields_desc = [ scapy_all.LEShortEnumField( "type_id", 0, { 0x0000: "null_address", # NULL Address 0x00a1: "conn_address", # Address for connection based requests 0x00b1: "conn_packet", # Connected Transport packet 0x00b2: "unconn_message", # Unconnected Messages (eg. used within CIP command SendRRData) 0x0100: "listservices_response", # ListServices response }), scapy_all.LEShortField("length", None), ] def extract_padding(self, p): return p[:self.length], p[self.length:] def post_build(self, p, pay): if self.length is None and pay: l = len(pay) p = p[:2] + struct.pack("<H", l) + p[4:] return p + pay
class SWAT_P2_RIO_DO(scapy_all.Packet): name = "SWAT_P2_RIO_DO" fields_desc = [ scapy_all.LEShortField('counter', 0), scapy_all.ByteField('number', 0), scapy_all.StrFixedLenField('reserved', 0, length=5), scapy_all.BitEnumField('P208_Start', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P207_Start', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P206_Start', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P205_Start', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P204_Start', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P203_Start', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P202_Start', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P201_Start', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('spare', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('spare', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('spare', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('spare', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('spare', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('LED_RED', 0, 1, {0: 'disable', 1: 'enable'}), #LED_RED scapy_all.BitEnumField('MV201_Close', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('MV201_Open', 0, 1, {0: 'disable', 1: 'enable'}), ]
class SWAT_P1_RIO_DO(scapy_all.Packet): name = "SWAT_P1_RIO_DO" fields_desc = [ scapy_all.LEShortField('counter', 0), scapy_all.ByteField('number', 0), scapy_all.StrFixedLenField('reserved', 0, length=5), scapy_all.BitField('spare', 0, 4), scapy_all.BitEnumField('valve_close', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('valve_open', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('pump2_start', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('pump1_start', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.FieldListField( "spare2", [], scapy_all.ByteField('', 0), length_from=lambda p: p.underlayer.length - 9), ]
class ENIP_SendUnitData(scapy_all.Packet): """Data in ENIP header specific to the specified command""" name = "ENIP_SendUnitData" fields_desc = [ scapy_all.LEIntField("interface_handle", 0), scapy_all.LEShortField("timeout", 0), utils.LEShortLenField("count", None, count_of="items"), scapy_all.PacketListField("items", [], ENIP_SendUnitData_Item, count_from=lambda p: p.count), ]
class CIP_LogicalSegment(scapy_all.Packet): name="CIP_LogicalSegment" LOGICAL_TYPE = { 0: "Class ID", 1: "Instance ID", 2: "Member ID", 3: "Connection Point", 4: "Attribute ID", 5: "Special", 6: "Service ID", 7: "Reserved" # The Special and Service ID Logical Types do not use the logical addressing definition for the Logical Format. } LOGICAL_FORMAT = { 0: "8 - bit logical address", 1: "16-bit logical address", 2: "32-bit logical address", 3: "Reserved for future use" } fields_desc = [ scapy_all.BitEnumField("logical_type", 0, 3, LOGICAL_TYPE), scapy_all.BitEnumField("logical_format", 0, 2, LOGICAL_FORMAT), # When the logical segment is included within a Padded Path, the 16 - bit and 32 - bit # logical formats shall have a pad inserted between the segment type byte and the Logical Value # (the 8 - bit format is identical to the Packed Path).The pad byte shall be set to zero. scapy_all.ConditionalField(scapy_all.ByteField("padding", 0), lambda p: p.logical_format > 0x0), # scapy_all.ByteField("value", 0), scapy_all.ConditionalField( scapy_all.ByteField("value8bit", 0), lambda p: p.logical_format >= 0x0 ), scapy_all.ConditionalField( scapy_all.LEShortField("value16bit", 0), lambda p: p.logical_format >= 0x1 ), scapy_all.ConditionalField( scapy_all.LELongField("value32bit", 0), lambda p: p.logical_format >= 0x2 ), ] def extract_padding(self, p): # print self.__class__.__name__ + ": P=" + str(p) return "", p
class CPF_Item(scapy_all.Packet): name = "CPF_Item" fields_desc = [ scapy_all.LEShortEnumField('type_id', 0, ITEM_ID_NUMBERS), scapy_all.LEShortField("length", None), ] def extract_padding(self, p): return p[:self.length], p[self.length:] def post_build(self, p, pay): if self.length is None and pay: l = len(pay) p = p[:2] + struct.pack("<H", l) + p[4:] return p + pay
class TE_FCN_SENSORS(scapy_all.Packet): name = "TE_FCN_SENSORS" fields_desc = [ scapy_all.LEShortField('group', 0), LEIEEEFloatField('field0', 0), LEIEEEFloatField('field1', 0), LEIEEEFloatField('field2', 0), LEIEEEFloatField('field3', 0), LEIEEEFloatField('field4', 0), LEIEEEFloatField('field5', 0), LEIEEEFloatField('field6', 0), LEIEEEFloatField('reactor_pressure', 0), LEIEEEFloatField('field8', 0), LEIEEEFloatField('reactor_temperature', 0), LEIEEEFloatField('field10', 0), LEIEEEFloatField('field11', 0), LEIEEEFloatField('field12', 0), LEIEEEFloatField('field13', 0), LEIEEEFloatField('field14', 0), LEIEEEFloatField('field15', 0), LEIEEEFloatField('field16', 0), LEIEEEFloatField('field17', 0), LEIEEEFloatField('field18', 0), LEIEEEFloatField('field19', 0), LEIEEEFloatField('field20', 0), LEIEEEFloatField('field21', 0), LEIEEEFloatField('field22', 0), LEIEEEFloatField('field23', 0), LEIEEEFloatField('field24', 0), LEIEEEFloatField('field25', 0), LEIEEEFloatField('field26', 0), LEIEEEFloatField('field27', 0), LEIEEEFloatField('field28', 0), LEIEEEFloatField('field29', 0), LEIEEEFloatField('field30', 0), LEIEEEFloatField('field31', 0), LEIEEEFloatField('field32', 0), LEIEEEFloatField('field33', 0), LEIEEEFloatField('field34', 0), LEIEEEFloatField('field35', 0), LEIEEEFloatField('field36', 0), LEIEEEFloatField('field37', 0), LEIEEEFloatField('field38', 0), LEIEEEFloatField('field39', 0), LEIEEEFloatField('field40', 0), LEIEEEFloatField('field41', 0), ]
class ENIP_UDP_Item(scapy_all.Packet): name = "ENIP_UDP_Item" fields_desc = [ scapy_all.LEShortEnumField("type_id", 0, { 0x00b1: "Connected_Data_Item", 0x8002: "Sequenced_Address", }), scapy_all.LEShortField("length", None), ] def extract_padding(self, p): return p[:self.length], p[self.length:] def post_build(self, p, pay): if self.length is None and pay: l = len(pay) p = p[:2] + struct.pack("<H", l) + p[4:] return p + pay
class SWAT_P2_RIO_DI(scapy_all.Packet): name = "SWAT_P2_RIO_DI" fields_desc =[ scapy_all.LEShortField('counter', 0), scapy_all.LEIntField('padding', 0), scapy_all.BitEnumField('P202_Fault', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P202_Run', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P202_Auto', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P201_Fault', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P201_Run', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P201_Auto', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('RIO2_Wifi', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('PLC2_Wifi', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P205_Run', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P205_Auto', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P204_Fault', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P204_Run', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P204_Auto', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P203_Fault', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P203_Run', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P203_Auto', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P208_Auto', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P207_Fault', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P207_Run', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P207_Auto', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P206_Fault', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P206_Run', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P206_Auto', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P205_Fault', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('spare', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('LS203_Low', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('LS202_Low', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('LS201_Low', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('MV201_Close', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('MV201_Open', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P208_Fault', 0, 1, {0: 'disable', 1: 'enable'}), scapy_all.BitEnumField('P208_Run', 0, 1, {0: 'disable', 1: 'enable'}), ]
class ENIP_PACKET(scapy_all.Packet): """Ethernet/IP packet over TCP""" name = "ENIP_PACKET" fields_desc = [ scapy_all.LEShortEnumField("command_id", None, ENCAPSULATION_COMMANDS), scapy_all.LEShortField("length", None), utils.XLEIntField("session", 0), scapy_all.LEIntEnumField("status", 0, {0: "success"}), scapy_all.LELongField("sender_context", 0), scapy_all.LEIntField("options", 0), ] def extract_padding(self, p): return p[:self.length], p[self.length:] def post_build(self, p, pay): if self.length is None and pay: l = len(pay) p = p[:2] + struct.pack("<H", l) + p[4:] return p + pay
class CIP_ReqForwardOpen(scapy_all.Packet): """Forward Open request""" name = "CIP_ReqForwardOpen" SEGMENT_TYPE = { 0x00: "Port Segment", 0x01: "Logical Segment", 0x02: "Network Segment", 0x03: "Symbolic Segment", 0x04: "Data Segment", 0x05: "Data Type (constructed)", 0x06: "Data Type (elementary)", 0x07: "Reserved for future use", } fields_desc = [ # Updated a few field descriptions to adjust how they are displayed # Altered fields begin with utils. rather than scapy_all. - MED scapy_all.BitField("priority", 0, 4), scapy_all.BitField("tick_time", 0, 4), scapy_all.ByteField("timeout_ticks", 249), utils.XLEIntField("OT_network_connection_id", 0x80000031), utils.XLEIntField("TO_network_connection_id", 0x80fe0030), scapy_all.LEShortField("connection_serial_number", 0x1337), utils.XLEShortField("vendor_id", 0x004d), utils.XLEIntField("originator_serial_number", 0xdeadbeef), scapy_all.ByteField("connection_timeout_multiplier", 0), scapy_all.X3BytesField("reserved", 0), utils.XLEIntField("OT_rpi", 0x007a1200), # 8000 ms scapy_all.PacketField('OT_connection_param', CIP_ConnectionParam(), CIP_ConnectionParam), utils.XLEIntField("TO_rpi", 0x007a1200), scapy_all.PacketField('TO_connection_param', CIP_ConnectionParam(), CIP_ConnectionParam), scapy_all.XByteField("transport_type", 0xa3), # direction server, application object, class 3 # Changed name - MED scapy_all.ByteField("Connection_Path_Size", None), #The number of 16 bit words in the Connection_Path field. # scapy_all.PacketListField("path_segment_items", [], CIP_Path1, length_from=lambda p: 2 * p.Connection_Path_Size), # Modified Implementation - MED scapy_all.PacketListField("path_segment_items", [], CIP_PathPadded, length_from=lambda p: 6), # CIP_PathField("path", None, length_from=lambda p: 2 * p.path_wordsize), ]
class CIP_MultipleServicePacket(scapy_all.Packet): """Multiple_Service_Packet request or response""" name = "CIP_MultipleServicePacket" fields_desc = [ utils.LEShortLenField("count", None, count_of="packets"), scapy_all.FieldListField("offsets", [], scapy_all.LEShortField("", 0), count_from=lambda pkt: pkt.count), # Assume the offsets are increasing, and no padding. FIXME: remove this assumption _CIPMSPPacketList("packets", [], CIP) ] def do_build(self): """Build the packet by concatenating packets and building the offsets list""" # Build the sub packets subpkts = [str(pkt) for pkt in self.packets] # Build the offset lists current_offset = 2 + 2 * len(subpkts) offsets = [] for p in subpkts: offsets.append(struct.pack("<H", current_offset)) current_offset += len(p) return struct.pack("<H", len(subpkts)) + "".join(offsets) + "".join(subpkts)
class CPF_AddressDataItem(scapy_all.Packet): name = "CPF_AddressDataItem" fields_desc = [ scapy_all.LEShortEnumField( 'type_id', 0, { 0x0000: "Null Address", 0x00a1: "Connection-based Address", 0x00b1: "Connected Transport Packet", 0x00b2: "Unconnected Message", 0x0100: "ListServices response", 0x8002: 'Sequenced Address Item', }), scapy_all.LEShortField("length", None), ] def extract_padding(self, p): return p[:self.length], p[self.length:] def post_build(self, p, pay): if self.length is None and pay: l = len(pay) p = p[:2] + struct.pack("<H", l) + p[4:] return p + pay
class SWAT_P4_RIO_DO(scapy_all.Packet): name = "SWAT_P4_RIO_DO" fields_desc = [ scapy_all.LEShortField('counter', 0), scapy_all.ByteField('number', 0), scapy_all.StrFixedLenField('reserved', 0, length=5), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('UV_Start', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P404_Start', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P403_Start', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P402_Start', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P401_Start', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), ]
class SWAT_P4_RIO_AI(scapy_all.Packet): name = "SWAT_P4_RIO_AI" fields_desc = [ scapy_all.LEShortField('counter', 0), scapy_all.LEIntField('padding', 0), scapy_all.LEShortField('LIT401_Level', 0), scapy_all.LEShortField('AIT401_Hardness', 0), scapy_all.LEShortField('FIT401_Flow', 0), scapy_all.LEShortField('AIT402_ORP', 0), scapy_all.LEShortField('spare', 0), scapy_all.LEShortField('spare', 0), scapy_all.LEShortField('spare', 0), scapy_all.LEShortField('spare', 0), scapy_all.LEShortField('spare', 0), scapy_all.LEShortField('spare', 0), scapy_all.LEShortField('spare', 0), scapy_all.LEShortField('spare', 0), ]
class SWAT_P4_RIO_DI(scapy_all.Packet): name = 'SWAT_P4_RIO_DI' fields_desc = [ scapy_all.LEShortField('counter', 0), scapy_all.LEIntField('padding', 0), scapy_all.BitEnumField('P402_Fault', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P402_Run', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P402_Auto', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P401_Fault', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P401_Run', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P401_Auto', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('RIO4_Wifi', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('PLC4_Wifi', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('UV401_Run', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('UV401_Auto', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P404_Fault', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P404_Run', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P404_Auto', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P403_Fault', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P403_Run', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('P403_Auto', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('LS401_Low', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('UV401_Fault', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), scapy_all.BitEnumField('spare', 0, 1, { 0: 'disable', 1: 'enable' }), ]
class ENIP_RegisterSession(scapy_all.Packet): name = "ENIP_RegisterSession" fields_desc = [ scapy_all.LEShortField("protocol_version", 1), scapy_all.LEShortField("options", 0), ]