Python MTR

Page content

Setup Project

Poetry

poetry init
poetry add twisted
poetry add twisted-mtr

Build Python Script

cat << 'EOF' > main.py
#!/usr/bin/env python3

'''
    An example usage for twisted-mtr which initiates multiple async traceroutes
    to multiple IPv4 and IPv6 target IP addresses at the same time. You will
    need to set your source IP addresses correctly and have a working dual
    IPv4/IPv6 networking stack to run this example.

'''

import sys
import signal
import logging
import ipaddress
from twisted.internet import reactor
from twisted_mtr import logger, errors, mtr, utils


log = logger.get_logger('trace', level=logging.DEBUG)


if __name__ == '__main__':

    log.info(f'Starting up...')

    # Find mtr-packet in your path
    mtr_binary_name = 'mtr-packet'
    mtr_binary_path = utils.find_binary(mtr_binary_name)

    # Replace with your local IPv4 address
    # Note that if you set this to an IP address not available on your system
    # your traceroutes will simply all time out
    local_ipv4 = ipaddress.IPv4Address('10.1.2.3')

    # Replace with your local IPv6 address
    # Note that if you set this to an IP address not available on your system
    # your traceroutes will simply all time out
    local_ipv6 = ipaddress.IPv6Address('2404:1:2:3:4:5:6:7')

    # Create the TraceRoute Twisted process object
    app_mtr = mtr.TraceRoute(
        mtr_binary_path=mtr_binary_path,
        local_ipv4=local_ipv4,
        local_ipv6=local_ipv6
    )

    # Bind to the Twisted tractor with the mtr-packet binary
    reactor.spawnProcess(app_mtr, mtr_binary_name, [mtr_binary_path], {})

    # Sets to track the traceroutes that have been dispatched and completed
    requested = set()
    completed = set()

    # Success callback
    def _test_traceroute_callback(timestamp, target_ip, protocol, port, hops):
        log.info(f'Completed traceroute started at {timestamp} to: '
                 f'{target_ip} ({protocol}:{port})')
        completed.add(str(target_ip))
        for (hop_num, hop_ip, microseconds) in hops:
            log.info(f' - {hop_num} {hop_ip} {microseconds}')
        if requested == completed:
            log.info('All traces complete, stopping reactor')
            reactor.stop()

    # Error callback
    def _test_trace_error(counter, joined_request, error, extra):
        log.error(f'Error running traceroute: {error}')
        reactor.stop()

    # Queue up our traceroutes
    target_ip = utils.parse_ip('8.1.1.1')  # No route after a few hops to test
    requested.add(str(target_ip))
    app_mtr.trace(_test_traceroute_callback, _test_trace_error, target_ip)

    target_ip = utils.parse_ip('8.8.8.8')
    requested.add(str(target_ip))
    app_mtr.trace(_test_traceroute_callback, _test_trace_error, target_ip, protocol='udp', port=53)

    target_ip = utils.parse_ip('1.1.1.1')
    requested.add(str(target_ip))
    app_mtr.trace(_test_traceroute_callback, _test_trace_error, target_ip, protocol='tcp', port=53, ttl=3)

    target_ip = utils.parse_ip('2404:6800:4015:802::200e')
    requested.add(str(target_ip))
    app_mtr.trace(_test_traceroute_callback, _test_trace_error, target_ip)

    target_ip = utils.parse_ip('2606:4700::6810:7b60')
    requested.add(str(target_ip))
    app_mtr.trace(_test_traceroute_callback, _test_trace_error, target_ip)

    # Polite hook for control+c to abort the traceroutes before they complete
    def signal_handler(sig, frame):
        sys.stdout.write('\n')  # put the ^C on its own line
        log.info(f'Caught keyboard interrupt, shutting down...')
        reactor.stop()

    signal.signal(signal.SIGINT, signal_handler)

    # Start the Twisted reactor event loop
    log.info(f'Starting event loop...')
    reactor.run()

    # If we reach here the reactor has been stopped, all done
    log.info(f'Goodbye')
EOF

don’t forget to set your local_ipv4 and local_ipv6 address correctly

Run Script

poetry run python main.py

sample output

root@yourhost /data/sample# poetry run python main.py
2024-04-05 08:57:59,528 trace [INFO] Starting up...
2024-04-05 08:57:59,556 trace [INFO] Starting event loop...
2024-04-05 08:58:06,567 mtr [ERROR] Probe to 8.8.8.8 with TTL 1 had no reply from mtr, retry attempt 1...
2024-04-05 08:58:06,567 mtr [ERROR] Probe to 2606:4700::6810:7b60 with TTL 1 had no reply from mtr, retry attempt 1...
2024-04-05 08:58:09,692 trace [INFO] Completed traceroute started at 1712300279.5556347 to: 1.1.1.1 (tcp:53)
2024-04-05 08:58:09,692 trace [INFO]  - 1 None None
2024-04-05 08:58:09,692 trace [INFO]  - 2 None None
2024-04-05 08:58:09,692 trace [INFO]  - 3 None None
2024-04-05 08:58:09,693 trace [INFO]  - 4 88.198.248.193 42501
2024-04-05 08:58:09,693 trace [INFO]  - 5 None None
2024-04-05 08:58:09,693 trace [INFO]  - 6 213.239.239.141 1059
2024-04-05 08:58:09,693 trace [INFO]  - 7 213.239.245.250 3873
2024-04-05 08:58:09,693 trace [INFO]  - 8 213.239.224.174 4183
2024-04-05 08:58:09,693 trace [INFO]  - 9 213.133.112.34 29514
2024-04-05 08:58:09,693 trace [INFO]  - 10 172.70.240.5 26938
2024-04-05 08:58:09,693 trace [INFO]  - 11 1.1.1.1 6303
2024-04-05 08:58:11,587 mtr [ERROR] Probe to 8.1.1.1 with TTL 4 had no reply from mtr, retry attempt 1...
2024-04-05 08:58:16,587 mtr [ERROR] Probe to 2606:4700::6810:7b60 with TTL 1 had no reply from mtr, retry attempt 2...
2024-04-05 08:58:19,641 trace [INFO] Completed traceroute started at 1712300279.5561163 to: 2606:4700::6810:7b60 (icmp:-1)
2024-04-05 08:58:19,642 trace [INFO]  - 1 fe80:: 2582
2024-04-05 08:58:19,642 trace [INFO]  - 2 2a01:4f8:0:e0c0::8313 3189
2024-04-05 08:58:19,642 trace [INFO]  - 3 2a01:4f8:0:e0c0::8301 8233
2024-04-05 08:58:19,642 trace [INFO]  - 4 2a01:4f8:0:e0c0::a34d 1128
2024-04-05 08:58:19,642 trace [INFO]  - 5 2a01:4f8:0:e0c0::a2da 484
2024-04-05 08:58:19,642 trace [INFO]  - 6 2a01:4f8:0:3::2a1 648
2024-04-05 08:58:19,642 trace [INFO]  - 7 2a01:4f8:0:3::1d 3912
2024-04-05 08:58:19,642 trace [INFO]  - 8 2a01:4f8:0:3::52 4198
2024-04-05 08:58:19,642 trace [INFO]  - 9 2a01:4f8:0:e0f0::6a 6917
2024-04-05 08:58:19,643 trace [INFO]  - 10 2400:cb00:471:3:: 4818
2024-04-05 08:58:19,643 trace [INFO]  - 11 2606:4700::6810:7b60 4483
2024-04-05 08:58:21,607 mtr [ERROR] Probe to 8.8.8.8 with TTL 5 had no reply from mtr, retry attempt 1...
2024-04-05 08:58:21,637 mtr [ERROR] Probe to 2404:6800:4015:802::200e with TTL 15 had no reply from mtr, retry attempt 1...
2024-04-05 08:58:31,672 trace [INFO] Completed traceroute started at 1712300279.5559797 to: 2404:6800:4015:802::200e (icmp:-1)
2024-04-05 08:58:31,672 trace [INFO]  - 1 fe80:: 8313
2024-04-05 08:58:31,672 trace [INFO]  - 2 2a01:4f8:0:e0c0::8313 638
2024-04-05 08:58:31,672 trace [INFO]  - 3 2a01:4f8:0:e0c0::8301 13392
2024-04-05 08:58:31,672 trace [INFO]  - 4 2a01:4f8:0:e0c0::a34d 1443
2024-04-05 08:58:31,673 trace [INFO]  - 5 2a01:4f8:0:e0c0::a2d6 647
2024-04-05 08:58:31,673 trace [INFO]  - 6 2a01:4f8:0:e0c0::a1e1 1108
2024-04-05 08:58:31,673 trace [INFO]  - 7 2a01:4f8:0:3::fa 3698
2024-04-05 08:58:31,673 trace [INFO]  - 8 2001:4860:1:1::19c8 3724
2024-04-05 08:58:31,673 trace [INFO]  - 9 2a00:1450:809c::1 4879
2024-04-05 08:58:31,673 trace [INFO]  - 10 2001:4860:0:1::30e 4083
2024-04-05 08:58:31,673 trace [INFO]  - 11 2001:4860:0:1::88d8 4466
2024-04-05 08:58:31,673 trace [INFO]  - 12 None None
2024-04-05 08:58:31,673 trace [INFO]  - 13 None None
2024-04-05 08:58:31,674 trace [INFO]  - 14 None None
2024-04-05 08:58:31,674 trace [INFO]  - 15 None None
2024-04-05 08:58:31,674 trace [INFO]  - 16 2001:4860::c:4002:1224 104717
2024-04-05 08:58:31,674 trace [INFO]  - 17 2001:4860::c:4002:97e0 162344
2024-04-05 08:58:31,674 trace [INFO]  - 18 2001:4860::c:4002:a966 284131
2024-04-05 08:58:31,674 trace [INFO]  - 19 2001:4860::9:4003:589a 281460
2024-04-05 08:58:31,675 trace [INFO]  - 20 2001:4860::9:4002:3e2 293657
2024-04-05 08:58:31,675 trace [INFO]  - 21 2001:4860:0:1::7ebd 294044
2024-04-05 08:58:31,675 trace [INFO]  - 22 2001:4860:0:1::462d 296593
2024-04-05 08:58:31,675 trace [INFO]  - 23 2404:6800:4015:802::200e 293815
2024-04-05 08:58:35,687 trace [INFO] Completed traceroute started at 1712300279.554946 to: 8.1.1.1 (icmp:-1)
2024-04-05 08:58:35,687 trace [INFO]  - 1 172.31.1.1 6706
2024-04-05 08:58:35,687 trace [INFO]  - 2 128.140.17.51 613
2024-04-05 08:58:35,687 trace [INFO]  - 3 None None
2024-04-05 08:58:35,687 trace [INFO]  - 4 88.198.248.193 1007
2024-04-05 08:58:35,687 trace [INFO]  - 5 213.133.127.6 1038957
2024-04-05 08:58:35,687 trace [INFO]  - 6 213.239.239.121 851
2024-04-05 08:58:35,688 trace [INFO]  - 7 213.239.245.74 911
2024-04-05 08:58:35,688 trace [INFO]  - 8 None None
2024-04-05 08:58:35,688 trace [INFO]  - 9 None None
2024-04-05 08:58:35,688 trace [INFO]  - 10 None None
2024-04-05 08:58:35,688 trace [INFO]  - 11 None None
2024-04-05 08:58:44,687 trace [INFO] Completed traceroute started at 1712300279.555522 to: 8.8.8.8 (udp:53)
2024-04-05 08:58:44,687 trace [INFO]  - 1 172.31.1.1 3657
2024-04-05 08:58:44,687 trace [INFO]  - 2 128.140.17.51 536
2024-04-05 08:58:44,687 trace [INFO]  - 3 None None
2024-04-05 08:58:44,687 trace [INFO]  - 4 88.198.248.193 3360
2024-04-05 08:58:44,687 trace [INFO]  - 5 None None
2024-04-05 08:58:44,687 trace [INFO]  - 6 213.239.239.121 1076
2024-04-05 08:58:44,688 trace [INFO]  - 7 213.239.252.25 4074
2024-04-05 08:58:44,688 trace [INFO]  - 8 None None
2024-04-05 08:58:44,688 trace [INFO]  - 9 None None
2024-04-05 08:58:44,688 trace [INFO]  - 10 None None
2024-04-05 08:58:44,688 trace [INFO] All traces complete, stopping reactor
2024-04-05 08:58:44,691 trace [INFO] Goodbye

Any Comments ?

sha256: 721b7b46e5ae218e142655f6b85e6f990f67e6c5823ed21b9864d963bdc77779