scapy.contrib.automotive.doip

class scapy.contrib.automotive.doip.DoIP(_pkt, /, *, protocol_version=2, inverse_version=253, payload_type=0, payload_length=None, nack=0, vin=b'', logical_address=0, eid=b'', gid=b'', further_action=0, vin_gid_status=0, source_address=0, activation_type=0, logical_address_tester=0, logical_address_doip_entity=0, routing_activation_response=0, reserved_iso=0, reserved_oem=b'', diagnostic_power_mode=0, node_type=0, max_open_sockets=1, cur_open_sockets=0, max_data_size=0, target_address=0, ack_code=0, nack_code=0, previous_msg=b'')[source]

Bases: Packet

Implementation of the DoIP (ISO 13400) protocol. DoIP packets can be sent via UDP and TCP. Depending on the payload type, the correct connection need to be chosen:

Payload Type

Payload Type Name

Connection Kind

0x0000

Generic DoIP header negative acknowledge

UDP / TCP

0x0001

Vehicle Identification request message

UDP

0x0002

Vehicle identification request message with EID

UDP

0x0003

Vehicle identification request message with VIN

UDP

0x0004

Vehicle announcement message/vehicle identification response

UDP

0x0005

Routing activation request

TCP

0x0006

Routing activation response

TCP

0x0007

Alive Check request

TCP

0x0008

Alive Check response

TCP

0x4001

IP entity status request

UDP

0x4002

DoIP entity status response

UDP

0x4003

Diagnostic power mode information request

UDP

0x4004

Diagnostic power mode information response

UDP

0x8001

Diagnostic message

TCP

0x8002

Diagnostic message positive acknowledgement

TCP

0x8003

Diagnostic message negative acknowledgement

TCP

Example with UDP:
>>> socket = L3RawSocket(iface="eth0")
>>> resp = socket.sr1(IP(dst="169.254.117.238")/UDP(dport=13400)/DoIP(payload_type=1))
Example with TCP:
>>> socket = DoIPSocket("169.254.117.238")
>>> pkt = DoIP(payload_type=0x8001, source_address=0xe80, target_address=0x1000) / UDS() / UDS_RDBI(identifiers=[0x1000])
>>> resp = socket.sr1(pkt, timeout=1)
Example with UDS:
>>> socket = UDS_DoIPSocket("169.254.117.238")
>>> pkt = UDS() / UDS_RDBI(identifiers=[0x1000])
>>> resp = socket.sr1(pkt, timeout=1)
aliastypes
answers(other: Packet) int[source]

DEV: true if self is an answer from other

extract_padding(s: bytes) Tuple[bytes, bytes | None][source]
fields_desc
Display RFC-like schema
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|PROTOCOL VERSIO|INVERSE VERSION|          PAYLOAD TYPE         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         PAYLOAD LENGTH                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      NACK     |                      VIN                      |
+-+-+-+-+-+-+-+-+                                               +
|                                                               |
+                                                               +
|                                                               |
+                                                               +
|                                                               |
+                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |        LOGICAL ADDRESS        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              EID                              |
+                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |              GID              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FURTHER ACTION| VIN GID STATUS|         SOURCE ADDRESS        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|ACTIVATION TYPE|     LOGICAL ADDRESS TESTER    |LOGICAL ADDRESS|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               |ROUTING ACTIVAT|          RESERVED ISO         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |          RESERVED OEM         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|DIAGNOSTIC POWE|   NODE TYPE   |MAX OPEN SOCKET|CUR OPEN SOCKET|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         MAX DATA SIZE                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         TARGET ADDRESS        |    ACK CODE   |   NACK CODE   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          PREVIOUS MSG         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                            Fig. DoIP                             
DoIP fields

protocol_version

XByteField

2

inverse_version

XByteField

253

payload_type

XShortEnumField

0

payload_length

IntField

None

nack

ByteEnumField (Cond)

0

vin

StrFixedLenField (Cond)

b''

logical_address

XShortField (Cond)

0

eid

StrFixedLenField (Cond)

b''

gid

StrFixedLenField (Cond)

b''

further_action

MayEnd (Cond)

0

vin_gid_status

XByteEnumField (Cond)

0

source_address

XShortField (Cond)

0

activation_type

XByteEnumField (Cond)

0

logical_address_tester

XShortField (Cond)

0

logical_address_doip_entity

XShortField (Cond)

0

routing_activation_response

XByteEnumField (Cond)

0

reserved_iso

XIntField (Cond)

0

reserved_oem

XStrField (Cond)

b''

diagnostic_power_mode

XByteEnumField (Cond)

0

node_type

ByteEnumField (Cond)

0

max_open_sockets

XByteField (Cond)

1

cur_open_sockets

XByteField (Cond)

0

max_data_size

IntField (Cond)

0

target_address

XShortField (Cond)

0

ack_code

XByteEnumField (Cond)

0

nack_code

ByteEnumField (Cond)

0

previous_msg

XStrField (Cond)

b''

hashret() bytes[source]
payload_guess

Possible sublayers: UDS

payload_types = {0: 'Generic DoIP header NACK', 1: 'Vehicle identification request', 2: 'Vehicle identification request with EID', 3: 'Vehicle identification request with VIN', 4: 'Vehicle announcement message/vehicle identification response message', 5: 'Routing activation request', 6: 'Routing activation response', 7: 'Alive check request', 8: 'Alive check response', 16385: 'DoIP entity status request', 16386: 'DoIP entity status response', 16387: 'Diagnostic power mode information request', 16388: 'Diagnostic power mode information response', 32769: 'Diagnostic message', 32770: 'Diagnostic message ACK', 32771: 'Diagnostic message NACK'}
post_build(pkt: bytes, pay: bytes) bytes[source]

This will set the Field ‘payload_length’ to the correct value.

classmethod tcp_reassemble(data: bytes, metadata: Dict[str, Any], session: Dict[str, Any]) Packet | None[source]
class scapy.contrib.automotive.doip.DoIPSSLStreamSocket(sock: socket, basecls: Type[Packet] | None = None)[source]

Bases: SSLStreamSocket

Custom SSLStreamSocket for DoIP communication.

recv(x: int | None = 65535, **kwargs: Any) Packet | None[source]
class scapy.contrib.automotive.doip.DoIPSocket(ip: str = '127.0.0.1', port: int = 13400, tls_port: int = 3496, activate_routing: bool = True, source_address: int = 3712, target_address: int = 0, activation_type: int = 0, reserved_oem: bytes = b'', force_tls: bool = False, context: SSLContext | None = None)[source]

Bases: DoIPSSLStreamSocket

Socket for DoIP communication. This sockets automatically sends a routing activation request as soon as a TCP or TLS connection is established.

Parameters:
  • ip – IP address of destination

  • port – destination port, usually 13400

  • tls_port – destination port for TLS connection, usually 3496

  • activate_routing – If true, routing activation request is automatically sent

  • source_address – DoIP source address

  • target_address – DoIP target address, this is automatically determined if routing activation request is sent

  • activation_type – This allows to set a different activation type for the routing activation request

  • reserved_oem – Optional parameter to set value for reserved_oem field of routing activation request

  • force_tls – Skip establishing of a TCP connection and directly try to connect via SSL/TLS

  • context – Optional ssl.SSLContext object for initialization of ssl socket connections.

Example

>>> socket = DoIPSocket("169.254.0.131")
>>> pkt = DoIP(payload_type=0x8001, source_address=0xe80, target_address=0x1000) / UDS() / UDS_RDBI(identifiers=[0x1000])
>>> resp = socket.sr1(pkt, timeout=1)
class scapy.contrib.automotive.doip.UDS_DoIPSocket(ip: str = '127.0.0.1', port: int = 13400, tls_port: int = 3496, activate_routing: bool = True, source_address: int = 3712, target_address: int = 0, activation_type: int = 0, reserved_oem: bytes = b'', force_tls: bool = False, context: SSLContext | None = None)[source]

Bases: DoIPSocket

Application-Layer socket for DoIP endpoints. This socket takes care about the encapsulation of UDS packets into DoIP packets.

Example

>>> socket = UDS_DoIPSocket("169.254.117.238")
>>> pkt = UDS() / UDS_RDBI(identifiers=[0x1000])
>>> resp = socket.sr1(pkt, timeout=1)
recv(x: int | None = 65535, **kwargs: Any) Packet | None[source]
send(x: Packet | bytes) int[source]