3

I have a traceroute Python program for a Unix system that prints out the path the packets take to get from the local machine to a destination — that is, the sequence of routers that the packets go through. The problem is I get an output which displays:

traceroute to yahoo.co.in (68.180.206.184), 30 hops max, 60 byte packets

 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  * * *
 7  * * *
 8  * * *
 9  * * *
 .
 .
 .
 30  * * *

I have a DSL connection. The program works great with the Windows command-line (cmd.exe). What is the exact reason for the above output?

The code looks like this:

#!/usr/bin/python
import socket
def main(dest_name):
    dest_addr = socket.gethostbyname(dest_name)
    port = 33434
    max_hops = 30
    icmp = socket.getprotobyname('icmp')
    udp = socket.getprotobyname('udp')
    ttl = 1
    while True:
        recv_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
        send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, udp)
        send_socket.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
        recv_socket.bind(("", port))
        send_socket.sendto("", (dest_name, port))
        curr_addr = None
        curr_name = None
        try:
            _, curr_addr = recv_socket.recvfrom(512)
            curr_addr = curr_addr[0]
            try:
                curr_name = socket.gethostbyaddr(curr_addr)[0]
            except socket.error:
                curr_name = curr_addr
        except socket.error:
            pass
        finally:
            send_socket.close()
            recv_socket.close()
        if curr_addr is not None:
            curr_host = "%s (%s)" % (curr_name, curr_addr)
        else:
            curr_host = "*"
        print "%d\t%s" % (ttl, curr_host)
        ttl += 1
        if curr_addr == dest_addr or ttl > max_hops:
            break
if __name__ == "__main__":
    main('yahoo.co.in')**
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
minnie
  • 51
  • 3
  • You should read over [this](http://stackoverflow.com/editing-help). – Matt Ball Feb 03 '11 at 15:55
  • 1
    This works for me. Did you run it as root? Linux distribution used? – Andrea Spadaccini Feb 03 '11 at 17:08
  • What do you mean by "program works great with windows cmd"? The same Python program? The Windows `tracert` command? If the Python program works on Windows XP but not Linux then it's probably because you need to be root to open a raw socket on Linux. – Jim Garrison Feb 03 '11 at 17:11
  • Hi, The program runs in python IDLE on windows system only when used in combination with win cmd tracert otherwise it doesn't. I even tried running it as root but failed? Shows an error : socket.gaierror: [Errno -5] No address associated with hostname – minnie Feb 05 '11 at 08:52
  • 2
    Works as expected - you see asterisk in tracerout's output if there is no answer to the icmp-ping message send. Is it possible that a firewall blocks your icmp-ping packages if under unix but not from the windows machine? – Tom Regner Feb 05 '11 at 10:27

1 Answers1

2

traceroute/tracert act differently on Linux and Windows.

Linux will send a UDP packet with a decreasing TTL and listen for ICMP responses. Windows sends ICMP echo requests and listens for ICMP responses.

The Python version is failing because the UDP packets are being blocked.

On Unix-like operating systems, the traceroute utility by default uses User Datagram Protocol (UDP) datagrams with destination port numbers from 33434 to 33534. The traceroute utility usually has an option to specify use of ICMP echo request (type 8) instead, as used by the Windows tracert utility.

http://en.wikipedia.org/wiki/Traceroute

Mike Ryan
  • 1,408
  • 12
  • 16