3

Python で raw ソケットを使用して UDP パケットをホストに送信し、パケットに対する ICMP 応答を取得しようとしています - 基本的に traceroute を再実装しています。

IP および UDP ヘッダーを正しく構築し、パケットを送信することができました。Wiresharkで見ることができます。また、Wireshark で TTL を超えたことを示す ICMP 応答も表示されます。

次のコードがあります。

me = gethostbyname(gethostname())
my_socket = socket(AF_INET, SOCK_RAW)
my_socket.setsockopt(IPPROTO_IP, IP_HDRINCL, 1)
my_socket.bind((me, 0))

hostname = 'www.google.com'
hostip = gethostbyname(hostname)

packet = create_packet(hostname)
send_socket.sendto(packet, (hostip , 0))

次に、パケットが送信された後、次のスニペットを含む着信パケットをリッスンする別の関数を呼び出します。

while True:
    ready = select.select([my_socket], [], [], time_left)
    if ready[0] == []:
        print "timeout"
    time_now = time.time()
    rec_packet, addr = my_socket.recvfrom(5120)

    unpacked_ip = unpack('!BBHHHBBH4s4s', rec_packet[0:20]) #0-20 is IP header
    prot = unpacked_ip[6] #gives the protocol id
    if prot == 1:
        #this is ICMP , let's do things

IP ヘッダーを正常に解凍してプロトコルを確認できますが、常に 6 または 17 (TCP または UDP) です。Wireshark に表示されますが、ICMP ペイロードを含む IP パケットを取得できません。

Wireshark の ICMP パケットを、私のプログラムが認識している Wireshark の他のパケットと比較してみましたが、IP ヘッダーはほとんど同じです。何が悪いのかわかりません。

助けてくれてありがとう

4

1 に答える 1

0

この回答から判断するとIPPROTO_ICMP、ソケットを作成するときにオプションを渡す必要があるようです。

これは次のように行うことができます:

my_socket = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket.IPPROTO_ICMP)
于 2012-11-28T01:00:05.833 に答える