//MAIN// | //GO BACK//

DoIP Network Test

Per my personal policy, I’m disclosing here that this tool was “vibe-coded” using AI.

Download

Download DoIP Network Test

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:

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:

The client can use either:

It can also repeat tests, collect latency information, write CSV results, and stop after UDP discovery if TCP routing activation is not needed.

Requirements

The scripts are intended to work on Windows, Linux, and macOS using the Python standard library.

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:

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:

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:

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.

Scope and limitations

This tool intentionally implements only enough DoIP behavior to validate common network paths.

It does not provide:

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.