DoIP Network Test
Per my personal policy, I’m disclosing here that this tool was “vibe-coded” using AI.
Download
DoIP (Diagnostic Over IP) is a communications standard used in automotive diagnostic and I rencently found myself neededing to troubleshoot it’s use on a network. I needed a way to run tests without having to invlove the actual diagnostic app.
It consists of two parts:
doip_server.py— acts as a synthetic DoIP vehicle/entity.doip_client.py— acts as a simple DoIP tester/client.
The test is useful for checking Ethernet cabling, VLANs, switch trunks, link-local networks, broadcast discovery, firewall behavior, and basic TCP reachability without needing a real vehicle or a full diagnostic application at both ends.
Important: This is a network-path test tool, not a full DoIP or diagnostic ECU implementation. It does not implement UDS diagnostics and should not be treated as an ISO 13400 conformance test.
What it tests
The client and server exercise several basic DoIP functions:
- UDP port
13400 - TCP port
13400 - Vehicle Identification Request (
0x0001) - Vehicle Identification Response / Announcement (
0x0004) - Routing Activation Request (
0x0005) - Routing Activation Response (
0x0006) - Optional Alive Check handling (
0x0007/0x0008) - EID-specific and VIN-specific identification requests on the responder (
0x0002/0x0003)
The client can use either:
- a known unicast IPv4 address, or
- broadcast discovery.
It can also repeat tests, collect latency information, write CSV results, and stop after UDP discovery if TCP routing activation is not needed.
Requirements
- Python 3.10 or newer
- No third-party Python packages
- IPv4 network connectivity between the two test systems
- UDP/TCP
13400allowed by the local host firewalls
The scripts are intended to work on Windows, Linux, and macOS using the Python standard library.
Typical use case: isolated or link-local VLAN testing
This is especially useful when validating an isolated Layer-2 path where no DHCP server exists.
For example:
Test computer A Ethernet/VLAN Test computer B
169.254.20.10 <--------------------------------------> 169.254.50.20
DoIP client DoIP responder
With no DHCP server available, the operating systems may self-assign IPv4 link-local addresses in the 169.254.0.0/16 range.
On Windows, check the Ethernet address with:
ipconfig
On Linux:
ip addr
When a computer has multiple interfaces, such as Ethernet plus Wi-Fi, use --bind so the script uses the intended test interface.
Quick start
1. Start the DoIP responder
On the computer at the vehicle/entity end of the test path:
python doip_server.py --bind 169.254.50.20
To also transmit a DoIP vehicle announcement once per second:
python doip_server.py --bind 169.254.50.20 --announce 1
Typical startup output:
[12:00:00.000] DoIP test responder starting
[12:00:00.000] VIN=TESTDOIP123456789 logical=0x1000 EID=00:11:22:33:44:55 GID=aa:bb:cc:dd:ee:ff
[12:00:00.001] TCP DoIP listener started on 169.254.50.20:13400
[12:00:00.001] UDP DoIP listener started on 0.0.0.0:13400
The UDP listener intentionally listens on all local IPv4 interfaces so it can receive broadcast discovery packets. --bind controls the TCP listener and the source address used for periodic announcements.
2. Run broadcast discovery from the client
On the other computer:
python doip_client.py --discover --bind 169.254.20.10
A successful test should look similar to:
[12:01:00.000] Broadcasting DoIP discovery from 169.254.20.10:ephemeral to 255.255.255.255:13400
[12:01:00.003] FOUND 169.254.50.20 VIN=TESTDOIP123456789 logical=0x1000 EID=00:11:22:33:44:55
[12:01:01.004] 169.254.50.20: opening TCP/13400
[12:01:01.005] 169.254.50.20: TCP CONNECT OK 1.0 ms
[12:01:01.006] 169.254.50.20: TX Routing Activation Request
[12:01:01.007] 169.254.50.20: Routing Activation Response tester=0x0E00 entity=0x1000 code=0x10
[12:01:01.007] 169.254.50.20: *** DOIP TEST SUCCESS ***
That verifies, at a minimum:
UDP discovery request
↓
UDP identification response
↓
TCP/13400 connection
↓
DoIP routing activation
Client usage
Show all options:
python doip_client.py --help
Discover a responder by broadcast
python doip_client.py --discover --bind 169.254.20.10
The default broadcast destination is 255.255.255.255.
For an IPv4 link-local segment, you can explicitly use 169.254.255.255:
python doip_client.py \
--discover \
--bind 169.254.20.10 \
--broadcast 169.254.255.255
Use UDP source port 13400
By default, the operating system selects an ephemeral UDP source port. To use source port 13400 instead:
python doip_client.py \
--discover \
--bind 169.254.20.10 \
--source-port 13400
Only one process can normally own the same address/port combination. Close any diagnostic software or other process already using UDP/13400 before using this option.
Test a known target
If the responder’s address is known:
python doip_client.py \
--target 169.254.50.20 \
--bind 169.254.20.10
UDP-only test
To perform vehicle identification without opening TCP/13400:
python doip_client.py \
--target 169.254.50.20 \
--bind 169.254.20.10 \
--udp-only
This is useful when you only want to validate DoIP discovery and do not want to initiate routing activation.
Stress test
Run the test 500 times with a 250 ms delay between attempts:
python doip_client.py \
--target 169.254.50.20 \
--bind 169.254.20.10 \
--repeat 500 \
--interval 0.25 \
--summary
The summary reports discovery success, TCP success, routing-activation success, and latency statistics.
Write CSV results
python doip_client.py \
--target 169.254.50.20 \
--bind 169.254.20.10 \
--repeat 100 \
--summary \
--csv results.csv
The CSV contains:
- attempt number
- target IP
- synthetic VIN returned by the responder
- UDP success/failure
- UDP latency
- TCP success/failure
- TCP connection latency
- routing activation success/failure
- error text
Responder usage
Show all options:
python doip_server.py --help
Basic responder
python doip_server.py --bind 169.254.50.20
Send periodic announcements
python doip_server.py \
--bind 169.254.50.20 \
--announce 1
Limit responses to one client
On a shared test network, the responder can ignore all clients except one IPv4 address:
python doip_server.py \
--bind 169.254.50.20 \
--allowed-tester 169.254.20.10
Change the synthetic identity
The responder uses a generic synthetic identity by default:
VIN: TESTDOIP123456789
Logical address: 0x1000
EID: 00:11:22:33:44:55
GID: AA:BB:CC:DD:EE:FF
These can be overridden:
python doip_server.py \
--bind 169.254.50.20 \
--vin ABCDEFGHIJKLMNOPQ \
--logical-address 0x1234 \
--eid 10:20:30:40:50:60 \
--gid A1:A2:A3:A4:A5:A6
The VIN value must be exactly 17 ASCII characters.
Common troubleshooting
No responder is discovered
Check:
- both systems are on the intended Ethernet/VLAN path
- the two systems have IPv4 addresses on the same local segment
- local firewalls allow UDP/13400
- the responder is running
- the client is bound to the intended Ethernet address
- VLAN access-port and trunk membership is correct
- broadcast traffic is allowed across the Layer-2 path
For link-local testing, verify that both systems have 169.254.x.x addresses.
UDP works but TCP fails
If identification succeeds but TCP routing activation fails, check:
- TCP/13400 firewall rules
- VLAN or ACL behavior affecting TCP
- whether the target address is reachable from the selected client interface
- whether another application already owns TCP/13400 on the responder
Could not bind UDP/13400
Another process is probably already using the port. Either close that process or omit:
--source-port 13400
The default source port is ephemeral and is sufficient for most network-path tests.
Multi-NIC systems
If the system has Ethernet, Wi-Fi, VPN adapters, virtual adapters, or multiple link-local addresses, explicitly bind the test to the intended interface address:
--bind 169.254.20.10
Exit codes
The client returns a non-zero exit code when a test does not succeed, making it useful in scripts and automated port checks.
0- at least one requested test succeeded1- no requested UDP/routing-activation test succeeded2- no result records were produced130- interrupted with Ctrl+C
Scope and limitations
This tool intentionally implements only enough DoIP behavior to validate common network paths.
It does not provide:
- UDS diagnostic services
- ECU programming
- authentication or security access
- a complete DoIP state machine
- every ISO 13400 payload type
- standards-conformance certification
A successful result means that the tested UDP discovery and TCP routing-activation path is working between the two endpoints. It does not prove that a complete diagnostic application will work in every environment.
Responsible use
Use this tool only on networks, systems, and vehicles you are authorized to test. It is intended for lab, workshop, infrastructure, and troubleshooting use.