Drive mtr-packet Safely from a Shell or Script

mtr-packet is the quiet probe engine behind mtr, and you can drive it directly from a script. It is a line-oriented helper you talk to over standard input and standard output, one tagged request per reply. This guide gets you sending a tagged probe, reading its reply correctly, and handling the fact that replies can arrive out of order. The examples use mtr-packet 0.95 from Ubuntu package mtr-tiny 0.95-1.1ubuntu0.1.

Allow about fifteen minutes. You need a shell and the installed mtr-tiny package. The workflow is read-only apart from sending network probes: it does not change routes, services or persistent configuration. Most examples run without sudo; only add privilege if your system specifically denies the requested probe.

1. Confirm the installed contract

mtr-packet is meant to be driven by a controlling program, not typed at directly for real work. Each request carries a unique integer token, a command, and optional name/value argument pairs. Start by checking the binary and package version:

$ command -v mtr-packet
/usr/bin/mtr-packet
$ dpkg-query -W -f='${Package} ${Version}\n' mtr-tiny
mtr-tiny 0.95-1.1ubuntu0.1

It is not a replacement for the interactive mtr display. A controlling program, shell pipeline or small script writes requests to standard input and reads one newline-terminated reply for each completed probe.

Checkpoint: if command -v finds nothing, stop here and install the package through your normal system-management process. Do not copy a different mtr-packet binary into a system directory.

2. Check features before depending on them

Use check-support for capabilities that can vary with the build and operating environment. The special feature name version returns the helper version:

$ printf '%s\n' \
    '1 check-support feature version' \
    '2 check-support feature ip-4' \
    '3 check-support feature ip-6' \
    '4 check-support feature icmp' \
    '5 check-support feature tcp' \
    '6 check-support feature udp' | mtr-packet
1 feature-support support 0.95
2 feature-support support ok
3 feature-support support ok
4 feature-support support ok
5 feature-support support ok
6 feature-support support ok

A response of ok means the feature is available to this version in this environment. A response of no is a capability result, not a probe failure. The Linux-only mark feature is worth checking separately before using mark-based routing:

$ printf '%s\n' '7 check-support feature mark' | mtr-packet
7 feature-support support ok

Keep the token unique within the lifetime of the requests you are tracking. The token is how you match a response to its request; it is not a sequence number and does not need to start at one.

3. Send one harmless IPv4 probe

Send an ICMP probe to loopback. The protocol defaults to icmp, and the destination must be supplied as either ip-4 or ip-6:

$ printf '%s\n' '42 send-probe ip-4 127.0.0.1 timeout 1' | mtr-packet
42 reply ip-4 127.0.0.1 round-trip-time 28

The measured microseconds vary. What matters is the matching token, a reply result, the responding address and round-trip-time. Capture the command's exit status immediately when scripting:

$ printf '%s\n' '42 send-probe ip-4 127.0.0.1 timeout 1' | mtr-packet
42 reply ip-4 127.0.0.1 round-trip-time 31
$ printf 'mtr-packet status: %s\n' "$?"
mtr-packet status: 0

No elevated privilege was needed for this local test on the installed system. Remote ICMP, TCP, UDP or SCTP probes can be affected by local policy, firewalls and the destination's own behaviour, so do not read a timeout as proof the route is broken.

4. Read the possible probe outcomes

A valid request does not always produce reply. Treat the response command as data, not a verdict:

Do not turn every non-reply result into a failed-host alert. A filtered UDP port, an intentionally quiet firewall and an expired TTL each mean something different.

5. Use TTL values to trace hops

Route discovery sends probes to the same destination with increasing ttl values. Use distinct tokens, because the helper can complete requests in a different order from the one you wrote them in:

$ printf '%s\n' \
    '11 send-probe ip-4 8.8.8.8 ttl 1 timeout 1' \
    '12 send-probe ip-4 8.8.8.8 ttl 2 timeout 1' \
    '13 send-probe ip-4 8.8.8.8 ttl 3 timeout 1' | mtr-packet
11 ttl-expired ip-4 192.0.2.1 round-trip-time 1634
13 reply ip-4 8.8.8.8 round-trip-time 17039
12 no-reply

The addresses and results above are illustrative shapes, not promised results. Use a destination you are authorised to test, and expect some networks to hide or rate-limit hop responses. A later token can print first, so never pair replies by line position.

6. Add protocol and packet options carefully

The request can select icmp, sctp, tcp or udp. A destination port is relevant to SCTP, TCP and UDP. UDP can also specify a local-port; local-ip-4 and local-ip-6 select the source address. For example, this UDP request targets a documentation address and will normally produce an environment-dependent result:

$ printf '%s\n' \
    '21 send-probe ip-4 192.0.2.10 protocol udp port 33434 timeout 1' | mtr-packet
21 no-reply

Options such as size, bit-pattern, tos, ttl and the Linux-only mark change the packet or routing request. Validate the feature first, keep values explicit, and test during an approved diagnostic window. A probe is still traffic: it may be logged, filtered or rate-limited by systems between you and the destination.

Warning: do not feed shell input from an untrusted source into a request without validating tokens, command names, argument names and values. The helper's protocol is not an authentication boundary, and a wrapper that accepts arbitrary destinations can be turned into an unwanted network-probing service.

7. Keep the monitor bounded and recoverable

One process can have many probes in flight, but unresolved probes consume capacity until they finish or time out. Set a finite timeout, bound the number of outstanding requests in your caller, and stop sending when you see probes-exhausted. If you started an interactive pipeline you no longer need, press Ctrl-C to terminate your foreground wrapper and child process. No persistent change needs undoing.

If a request returns permission-denied, first reduce it to the loopback ICMP example and re-check support. Only then investigate the host's privileges or security policy. Running the whole monitor with sudo may change which network identity and policy it exercises, so it is not a generic fix. If elevated access is genuinely required, use the smallest, time-limited command and stop it when the test ends.

Done means