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_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 SecurityExtension(scapy.Packet): name = "SCION Security Extension" fields_desc = [ scapy.BitEnumField('next_hdr', None, 8, scapy.IP_PROTOS), scapy.ByteField('hdr_len', None), scapy.XByteField('extType', 0x2), scapy.ByteEnumField("secMode", 0x0, { 0x0: "AES-CMAC", 0x1: "HMAC_SHA256", 0x2: "Ed25519", 0x3: "GCM_AES128" }), scapy.XBitField('metadata', 0xffffffff, 4 * 8), scapy.MultipleTypeField([ (scapy.XBitField('authenticator', None, 16 * 8), lambda pkt: pkt.secMode == 0x0), (scapy.XBitField('authenticator', None, 32 * 8), lambda pkt: pkt.secMode == 0x1), (scapy.XBitField('authenticator', None, 64 * 8), lambda pkt: pkt.secMode == 0x2), (scapy.XBitField('authenticator', None, 16 * 8), lambda pkt: pkt.secMode == 0x3), ], scapy.StrField("authenticator", None)), ] def extract_padding(self, p): # TODO fix when removing hard-coded v4 return "", p def post_build(self, pkt, pay): if self.hdr_len == None: self.hdr_len = len(pkt) pkt = pkt[:1] + struct.pack('B', int(self.hdr_len / 8)) + pkt[2:] return pkt + pay
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_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 CIP_PortSegment(scapy_all.Packet): name="CIP_PortSegment" PORT_IDENT={ 0: "Reserved", 1: "Back-Plane", 15: "Extended", } fields_desc = [ scapy_all.BitField("extended_link_address_size", 0, 1), scapy_all.BitEnumField("port_identifier", 0, 4, PORT_IDENT), scapy_all.ByteField("link_address_size", 0), scapy_all.ConditionalField( scapy_all.LEIntField("extended_port_identifier", 0), lambda p: p.port_identifier == 0xf # If the Port Identifier is 15, then a 16-bit field, called the Extended Port Identifier, shall be the next part of the Port Segment ), scapy_all.ConditionalField( scapy_all.FieldListField("Link_Address", [], scapy_all.XByteField("",0), length_from=lambda p: p.link_address_size ), lambda p: p.extended_link_address_size == 0x1 # If the Port Identifier is 15, then a 16-bit field, called the Extended Port Identifier, shall be the next part of the Port Segment ) ] def extract_padding(self, p): print self.__class__.__name__ + ": P=" + str(p) return "", p
class Modbus_ReportSlaveIdResp(scapy_all.Packet): """Layer for report slave ID response""" fields_desc = [ scapy_all.FieldLenField("byte_count", 0, length_of="slave_id"), scapy_all.StrLenField("slave_id", "", length_from=lambda x: x.length), scapy_all.XByteField("run_status", 0x00) ] """
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 Modbus_ExceptionCode(scapy_all.Packet): EXCEPTION_CODES = { 0x01: "ILLEGAL_FUNCTION", 0x02: "ILLEGAL_DATA_ADDRESS", 0x03: "ILLEGAL_DATA_VALUE", 0x04: "SLAVE_DEVICE_FAILURE", 0x05: "ACKNOWLEDGE", 0x06: "SLAVE_DEVICE_BUSY", 0x08: "MEMORY_PARITY_ERROR", 0x0A: "GATEWAY_PATH_UNAVAILABLE", 0x0B: "GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND" } fields_desc = [scapy_all.XByteField("exception_code", None)]
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 MDCData(scapy.Packet): name = "MulticastDataCenterData " fields_desc = [ scapy.ShortField("addr", 0), scapy.XByteField("mode", 0), scapy.XByteField("label", 0), scapy.ByteEnumField( "code", 5, { 1: "REQUEST", 2: "PTCH_REQ", 3: "DATA_FNSD", 4: "PTCH_DATA", 5: "DATA", 6: "FEEDBACK" }, ), scapy.XByteField("appID", 2), scapy.XByteField("dataID", 0), scapy.XByteField("sn", 0), scapy.XByteField("dataSize", 11), ]
class CIP_ResponseStatus(scapy_all.Packet): """The response field of CIP headers""" name = "CIP_ResponseStatus" fields_desc = [ scapy_all.XByteField("reserved", 0), # Reserved byte, always null scapy_all.ByteEnumField("status", 0, {0: "success"}), scapy_all.XByteField("additional_size", 0), scapy_all.StrLenField("additional", "", # additionnal status length_from=lambda p: 2 * p.additional_size), ] ERROR_CODES = { 0x00: "Success", 0x01: "Connection failure", 0x02: "Resource unavailable", 0x03: "Invalid parameter value", 0x04: "Path segment error", 0x05: "Path destination unknown", 0x06: "Partial transfer", 0x07: "Connection lost", 0x08: "Service not supported", 0x09: "Invalid attribute value", 0x0a: "Attribute list error", 0x0b: "Already in requested mode/state", 0x0c: "Object state conflict", 0x0d: "Object already exists", 0x0e: "Attribute not settable", 0x0f: "Privilege violation", 0x10: "Device state conflict", 0x11: "Reply data too large", 0x12: "Fragmentation of a primitive value", 0x13: "Not enough data", 0x14: "Attribute not supported", 0x15: "Too much data", 0x16: "Object does not exist", 0x17: "Service fragmentation sequence not in progress", 0x18: "No stored attribute data", 0x19: "Store operation failure", 0x1a: "Routing failure, request packet too large", 0x1b: "Routing failure, response packet too large", 0x1c: "Missing attribute list entry data", 0x1d: "Invalid attribute value list", 0x1e: "Embedded service error", 0x1f: "Vendor specific error", 0x20: "Invalid parameter", 0x21: "Write-once value or medium already written", 0x22: "Invalid reply received", 0x23: "Buffer overflow", 0x24: "Invalid message format", 0x25: "Key failure in path", 0x26: "Path size invalid", 0x27: "Unexpected attribute in list", 0x28: "Invalid Member ID", 0x29: "Member not settable", 0x2a: "Group 2 only server general failure", 0x2b: "Unknown Modbus error", 0x2c: "Attribute not gettable", } def extract_padding(self, p): return "", p def __repr__(self): if self.reserved != 0: return scapy_all.Packet.__repr__(self) # Known status if self.status in self.ERROR_CODES and self.additional_size == 0: return "<CIP_ResponseStatus status={}>".format(self.ERROR_CODES[self.status]) # Simple status if self.additional_size == 0: return "<CIP_ResponseStatus status=%#x>" % self.status # Forward Open failure if self.status == 1 and self.additional == b"\x00\x01": return "<CIP_ResponseStatus status=Connection failure>" return scapy_all.Packet.__repr__(self)
class AVTP(s.Packet): name = "AVTP" fields_desc = [ s.XByteField("controlData", None), s.XByteField("flags", None), s.XByteField("sequence", None), s.XByteField("timestampUncertain", None), s.IntField("streamID0", None), s.IntField("streamID1", None), s.IntField("ptpTimestamp", None), s.IntField("gateway", None), s.ShortField("pktDataLength", None), s.XByteField("pkt1394format", None), s.XByteField("pkt1394tcode", None), s.XByteField("sourceId", None), s.XByteField("dataBlockSize", None), s.XByteField("packing", None), s.XByteField("DBC", None), s.XByteField("formatId", None), s.XByteField("SYT", None), s.IntField("ptpUpper", None), s.IntField("ptpLower", None), ]