{"id":17974706,"url":"https://github.com/meeb/twisted-mtr","last_synced_at":"2025-03-25T14:32:14.856Z","repository":{"id":39704643,"uuid":"401623416","full_name":"meeb/twisted-mtr","owner":"meeb","description":"Python \u0026 Twisted library that performs asynchronous high performance traceroutes using mtr-packet.","archived":false,"fork":false,"pushed_at":"2024-07-29T18:34:28.000Z","size":102,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-20T12:51:35.801Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meeb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-31T08:09:34.000Z","updated_at":"2024-07-29T18:34:31.000Z","dependencies_parsed_at":"2024-10-29T18:04:49.841Z","dependency_job_id":null,"html_url":"https://github.com/meeb/twisted-mtr","commit_stats":{"total_commits":36,"total_committers":2,"mean_commits":18.0,"dds":0.02777777777777779,"last_synced_commit":"0c61be06c6b14af6b1f3b9513f19020ae68e5d5e"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Ftwisted-mtr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Ftwisted-mtr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Ftwisted-mtr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Ftwisted-mtr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meeb","download_url":"https://codeload.github.com/meeb/twisted-mtr/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245480549,"owners_count":20622334,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-29T17:15:10.674Z","updated_at":"2025-03-25T14:32:14.595Z","avatar_url":"https://github.com/meeb.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# twisted-mtr\n\nA Python Twisted library that performs asynchronous high performance\ntraceroutes using mtr-packet.\n\n`twisted-mtr` is designed to enable Twisted (as in the\n[Python Twisted networking framework](https://twistedmatrix.com/) to perform\nfully asynchronous IPv4 and IPv6 traceroutes.\n\n\n## Installation\n\n`twisted-mtr` requires the Twisted library as a dependancy as well as the the\n`mtr-packet` binary to be available in your systems PATH. You can install\n`twisted-mtr` via pip:\n\n```bash\n$ pip install twisted-mtr\n```\n\nAny modern version of Python3 will be compatible.\n\nFor `mtr-packet` this is typically available from your systems package manager.\nFor example on Debian / Ubuntu based systems install the `mtr-tiny` package:\n\n```bash\n# Will need to be run as root\n$ apt install mtr-tiny\n```\n\nFor Fedora / Redhat based systems this package is called `mtr`:\n\n```bash\n# Will need to be run as root\n$ yum install mtr\n```\n\nFor Alpine based systems this package is called `mtr`:\n\n```bash\n# Will need to be run as root\n$ apk add mtr\n```\n\nConsult whatever package manager your system uses if it's not one of the above\nexamples. There may not be a suitable option for Windows systems and Windows\nsupport has not been tested.\n\nOnce you have Python, Twisted, the `twisted-mtr` library and the `mtr-packet`\nbinary installed you are good to go.\n\n\n## Usage\n\n`twisted-mtr` requires a source IP, either IPv4 or IPv6, as the source of your\ntraceroutes. This is not detected for you and needs to be manually set. It's\noutside the scope of this library to detect your local IP. Specifying the IP\naddress also selects which physical or virtual network interface you want to\nsend the traceroutes from.\n\nA helper utility exists to help find the path to your `mtr-packet` binary.\n\nA basic example would be:\n\n```python\nimport ipaddress\nfrom twisted.internet import reactor \nfrom twisted_mtr import utils, mtr\n\n# Find mtr-packet\nmtr_binary_name = 'mtr-packet'\nmtr_binary_path = utils.find_binary(mtr_binary_name)\n\n# Replace with a local IPv4 address\nlocal_ipv4 = ipaddress.IPv4Address('10.11.22.33')\n\n# Address we're tracing to\ntarget_ipv4 = ipaddress.IPv4Address('1.1.1.1')\n\n# Create the Twisted Protocol instance\napp_mtr = mtr.TraceRoute(mtr_binary_path=mtr_binary_path,\n                         local_ipv4=local_ipv4)\n\n# Spawn the mtr-packet process attached to the protocol\nreactor.spawnProcess(app_mtr, mtr_binary_name, [mtr_binary_path], {})\n\n# Callback fired when the traceroute is complete\ndef traceroute_complete(target_ip, hops):\n    print(f'Traceroute complete to {target_ip} in {len(hops)} hops')\n    for (hop_num, hop_ip, microseconds) in hops:\n        print(f' - {hop_num} {hop_ip} {microseconds}')\n    # Trace complete, stop the reactor\n    reactor.stop()\n\n# Callback fired if there's an error\ndef trace_error(counter, joined_request, error, extra):\n    print(f'Error running traceroute: {error}')\n    # Error during traceroute, stop the reactor\n    reactor.stop()\n\n# Start our trace with our callbacks set\napp_mtr.trace(traceroute_complete, trace_error, target_ip)\n\n# Start the Twisted reactor to begin the traceroute\nreactor.run()\n```\n\nSee [example-trace.py](example-trace.py) for an example implementation with\nmultiple IPv4 and IPv6 traceroutes running concurrently.\n\n\n# API synopsis\n\n`twisted-mtr` has really only one class you would interact with at\n`twisted_mtr.mtr.TraceRoute` that takes the following parameters:\n\n```python\nmy_traceroute_object = TraceRoute(\n    # Full path to your mtr-packet binary\n    mtr_binary_path='/usr/bin/mtr-packet',\n    # An IPv4Address object for your local (source) IPv4 address\n    local_ipv4=ipaddress.IPv4Adddress('127.2.3.4'),\n    # An IPv6Address object for your local (source) IPv6 address\n    local_ipv6=ipaddress.IPv6Adddress('::1')\n)\n```\n\nYou may leave `local_ipv4` or `local_ipv6` out if your system only has IPv4\nor IPv6 available, however at least one of them must be set or an exception\nwill be raised.\n\nYou can, for obvious reasons, only send IPv4 traceroutes if `local_ipv4` is\nset and you can only send IPv6 traceroutes if `local_ipv6` is set.\n\nIf you set your `local_ipv*` address incorrectly your traceroutes may trigger\nthe error callback with a network error or simply time out.\n\nOnce your `TraceRoute` object has been created you start a traceroute with\nthe following method:\n\n```python\nmy_traceroute_object.trace(\n    # Must be a function that exists or a lambda\n    success_callback_function,\n    # Must be a function that exists or a lambda\n    failure_callback_function,\n    # An IPv4Address or IPv6Address object of the address to traceroute to\n    ipaddress.IPv4Address('1.1.1.1'),\n    # The protocol to use, defaults to 'icmp', can be 'icmp' or 'tcp'\n    protocol='tcp',\n    # The port number to use if the protocol is 'tcp', otherwise ignored\n    port=443,\n    # TTL to start the trace at, defaults to 1, set to 2 or more to skip hops\n    ttl=1\n)\n```\n\nWhen the traceroute completes or errors the callbacks will be called with the\nfollowing parameters:\n\n```python\ndef success_callback_function(timestamp, target_ip, protocol, port, hops):\n    # target_ip is an IPvNAddress object of the address the traceroute was to\n    # protocol is either 'icmp' or 'tcp'\n    # port is the TCP port if the trace type is 'tcp', otherwise -1\n    print(f'Completed trace started at {timestamp} to: {target_ip} '\n          f'({protocol}:{port})')\n    # hops is a list of the traceroute hops, each hop has 5 parameters, e.g.\n    #hops = [\n    #    (1, '10.0.0.1', 20),\n    #    (2, '22.22.22.22', 111),\n    #    (3, '33.33.33.33', 222),\n    #    (4,  None, None),\n    #    (5, '55.55.55.55', 444),\n    #]\n    # The IP and milliseconds of the hop may be None if the hop did not\n    # respond to the traceroute request or it timed out. Parameter 4 is the\n    # protocol of the trace. Prameter 5 is the port number if the protocol is\n    # 'tcp'. Example TCP trace hop:\n    #  (1, '10.0.0.1', 20, 'tcp', 443)\n    for hop in hops:\n        hop_number, hop_ip, latency_in_milliseconds = hop\n        print(f' - {hop}: {hop_ip} {latency_in_milliseconds} ms')\n\ndef failure_callback_function(hop_number, request, error, extra):\n    # Errors are things like mtr-packet return a serious error for your\n    # traceroute request or network errors, not Python errors.\n    #\n    # hop_number is the traceroute hop where the error occured\n    # request the mtr-packet request that generated the error\n    # error is the error message as a string\n    # extra is any addtional data that was bundled with the request\n    print(f'An error occured at hop {hop_number} sending MTR request '\n          f'\"{request}\" with error: {error}')\n```\n\n\n# Tests\n\nThere is a test suite that you can run by cloning this repository, installing\nthe required dependancies and execuiting:\n\n```bash\n$ make test\n```\n\n\n# Debugging\n\n`twisted-mtr` will emit debug logs if you use Python's logging module. Enable\nthem with `level=logging.DEBUG` in your application when you initialise your\nlogger.\n\n\n# Contributing\n\nAll properly formatted and sensible pull requests, issues and comments are\nwelcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeeb%2Ftwisted-mtr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeeb%2Ftwisted-mtr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeeb%2Ftwisted-mtr/lists"}