How to create ICMP trace in Python

I am trying to implement ICMP based Traceroute in Python.

I found a very useful guide ( https://blogs.oracle.com/ksplice/entry/learning_by_doing_writing_your ) that allowed me to create Traceroute based on UDP (the code below), so I just need a modification. I tried to change the send socket to ICMP, but I can not start anything without exceptions.

Note. The code below works, but it is a UDP trace (sends a UDP packet and receives ICMP), and I need my program to send an ICMP packet and receive an ICMP packet. This is because firewalls are smarter these days than they used to be and do not always send an ICMP response after receiving a UDP packet for a random port. Essentially, the UDP socket needs to be changed for ICMP.

I think that this is not the most common thing that you can try to achieve, and I am having problems finding a network on how to do this. If someone can give some insight, it will be REALLY appreciated :-)

The main thing to remember is that traceroutes work by installing TTL, so if the solution is to use an ICMP library, then it must have a custom TTL :-)

#!/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('google.com')
+3
source share
2 answers

, scapy - / . , ping, ( ), traceroute.

0

, Scapy - KillianDS.

ans,unans=sr(IP(dst="www.google.com",ttl=X)/ICMP())

ans.summary(lambda (s,r): r.sprintf("%IP.src%") )
+2

All Articles