velotraveler / potraceroute

Portable TCP/UDP/ICMP traceroute tool, written in Python
GNU General Public License v3.0
15 stars 3 forks source link

potraceroute - a portable Python TCP/UDP/ICMP traceroute tool

This project grew out of my experience as a system/network administrator in a heavily firewalled environment. TCP traceroute was the best way to check if a connection was being blocked by a firewall, but the Windows, Solaris, and AIX hosts on our network only supported UDP or ICMP traceroute. Installing binaries on the hosts I was asked to troubleshoot was not an option, so I wrote a traceroute utility in Python that could be easily copied onto the target computer, via copy/paste if necessary.

FEATURES

COMMAND-LINE OPTIONS

  -f FIRST_HOP, --first-hop=FIRST_HOP
                        Starting hop (ttl) value [default: 1]
  -m MAX_HOPS, --max-hops=MAX_HOPS
                        Max hops before giving up [default: 30]
  -n, --no-dns          do not lookup hostnames of IP addresses
  -p PORT, --port=PORT  port number or service name for UDP or TCP
  -s SOURCE_IP, --source-ip=SOURCE_IP
                        interface IP to send probe traffic from
  -S SOURCE_PORT, --source-port=SOURCE_PORT
                        source port for TCP/UDP probes
  -w WAIT_TIME, --wait-time=WAIT_TIME
                        Timeout in seconds for each hop [default: 2]
  --banner-wait=BANNER_WAIT
                        How long to wait for possible TCP banner output
                        [default: 0.5]
  -U, --udp             Use UDP protocol [default: TCP]
  -I, --icmp            Use ICMP protocol [default: TCP]
  -P PAYLOAD, --payload=PAYLOAD
                        hex string to use as data in UDP or ICMP probe packet
  -D, --debug           dump packets and other debugging info
  -v, --verbose         verbose output

COMMAND-LINE EXAMPLES

PROGRAMMATIC EXAMPLES

from potraceroute import Traceroute, parse_options
import sys
dest = "google.com" if len(sys.argv) != 2 else sys.argv[1]
(options, args) = parse_options(["--port", "443", dest])
t = Traceroute(options, dest)
hop = t.probe(1)
if hop.reached:
    print("we are only one hop away from {dest}".format(dest=dest))
else:
    print("First hop is {ip}".format(ip=hop.ipfields.ip_source_address))

hop = t.probe(32)
print("{r} {dest}.".format(r="reached" if hop.reached else "could not reach", dest=dest))

For more examples, see the file tests/test_potraceroute.py

LIMITATIONS / POSSIBLE FUTURE WORK

SHOUTOUTS AND HAT TIPS

Along with the NetBSD traceroute source code (which includes Van Jacobson's 1988 comment "Don't use this as a coding example"), these two Python scripts provided useful demonstrations of traceroute: