3

Python で ICMP ベースの Traceroute を実装しようとしています。

非常に役立つガイド ( https://blogs.oracle.com/ksplice/entry/learning_by_doing_writing_your ) を見つけたので、UDP ベースの Traceroute (以下のコード) を作成できるので、変更が必要です。送信ソケットを ICMP に変更しようとしましたが、例外なく何も実行できません。

注 - 以下のコードは機能しますが、これは UDP traceroute (UDP パケットを送信し、ICMP パケットを受信する) であり、ICMP パケットを送信して ICMP パケットを受信するにはプログラムが必要です。これは、最近のファイアウォールが以前よりもスマートになり、ランダムなポートの UDP パケットを受信した後に常に ICMP 応答を送信するとは限らないためです。基本的に、UDP ソケットを ICMP ソケットに変更する必要があります。

これは、試みて達成する最も一般的なことではなく、これを行う方法についてネットで調査するのに苦労していると思います。誰かが洞察を提供できる場合は、本当に感謝します:-)

覚えておくべき主なポイントは、traceroute は TTL を設定することで機能するため、ソリューションが ICMP ライブラリを使用する場合は、設定可能な 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')
4

2 に答える 2

3

Scapy を使用したソリューションを次に示します。KillianDS のおかげです。

ping の送信

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

返信へのアクセス

ans.summary(lambda (s,r): r.sprintf("%IP.src%") )
于 2012-04-26T03:36:57.010 に答える
0

自分でソケットを管理したくない場合、scapyは独自のパケットを作成し、基本的な送受信を行うための優れたツールです。ping を実行する方法の例をここで見つけることができます。ここから (およびいくつかのドキュメントを読むと)、独自の traceroute を非常に簡単に構築できるはずです。

于 2012-04-21T11:08:38.343 に答える