2014-06-25 4 views
13

um die Netzwerk-Konzepte ein bisschen besser zu verstehen und meine Python-Fähigkeiten zu verbessern Ich versuche, einen Paket-Sniffer mit Python zu implementieren. Ich habe gerade begonnen, Python zu lernen, so dass der Code natürlich optimiert werden konnte;)Python arp schnüffeln rohe Socket keine Antwort Pakete

Ich habe einen Paket-Sniffer implementiert, der den Ethernet-Frame und den ARP-Header entpackt. Ich möchte es mit rohen Sockets machen, weil ich jedes Byte in diesen Headern verstehen will, also bitte keine scapy Hilfe :)

Das Problem ist, dass ich keine ARP Antwort Paket bekommen werde. Es ist Opcode immer 1 und I

Hier ist meine Quellcode:

import socket 
import struct 
import binascii 

rawSocket = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.htons(0x0806)) 

while True: 

    packet = rawSocket.recvfrom(2048) 

    ethernet_header = packet[0][0:14] 
    ethernet_detailed = struct.unpack("!6s6s2s", ethernet_header) 

    arp_header = packet[0][14:42] 
    arp_detailed = struct.unpack("2s2s1s1s2s6s4s6s4s", arp_header) 

    print "****************_ETHERNET_FRAME_****************" 
    print "Dest MAC:  ", binascii.hexlify(ethernet_detailed[0]) 
    print "Source MAC:  ", binascii.hexlify(ethernet_detailed[1]) 
    print "Type:   ", binascii.hexlify(ethernet_detailed[2]) 
    print "************************************************" 
    print "******************_ARP_HEADER_******************" 
    print "Hardware type: ", binascii.hexlify(arp_detailed[0]) 
    print "Protocol type: ", binascii.hexlify(arp_detailed[1]) 
    print "Hardware size: ", binascii.hexlify(arp_detailed[2]) 
    print "Protocol size: ", binascii.hexlify(arp_detailed[3]) 
    print "Opcode:   ", binascii.hexlify(arp_detailed[4]) 
    print "Source MAC:  ", binascii.hexlify(arp_detailed[5]) 
    print "Source IP:  ", socket.inet_ntoa(arp_detailed[6]) 
    print "Dest MAC:  ", binascii.hexlify(arp_detailed[7]) 
    print "Dest IP:   ", socket.inet_ntoa(arp_detailed[8]) 
    print "*************************************************\n" 

könnte mir bitte jemand erklären, warum ich diese keine Antwortpakete nur immer bin?

OUTPUT:

****************_ETHERNET_FRAME_**************** 
Dest MAC:   ffffffffffff 
Source MAC:  0012bfc87243 
Type:    0806 
************************************************ 
******************_ARP_HEADER_****************** 
Hardware type: 0001 
Protocol type: 0800 
Hardware size: 06 
Protocol size: 04 
Opcode:   0001 
Source MAC:  0012bfc87243 
Source IP:  192.168.2.1 
Dest MAC:   000000000000 
Dest IP:   192.168.2.226 
************************************************* 

Dank so weit! :)

+0

Ich glaube nicht, es ist die ARP-Opcode per se. Ihr 'recvfrom()' scheint nur * eingehende * Pakete zu erfassen, keine ausgehenden. In diesem Fall geht der Opcode 2 (ARP-Antwort) aus und wird nicht erfasst. – Santa

+0

Wenn Sie Ihr Skript ausführen und Ihr Computer stattdessen einen ARP-Ping sendet, sehen Sie nur den Opcode 2 (ARP-Antwort) und nichts vom ursprünglichen ausgehenden Ping. – Santa

Antwort

14

Ich denke, Sie müssen Socket-Protokollnummer 0x0003 angeben, um alles zu schnüffeln und dann nicht-ARP-Pakete nach der Tatsache herauszufiltern. Dieser arbeitete für mich:

import socket 
import struct 
import binascii 

rawSocket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003)) 

while True: 

    packet = rawSocket.recvfrom(2048) 

    ethernet_header = packet[0][0:14] 
    ethernet_detailed = struct.unpack("!6s6s2s", ethernet_header) 

    arp_header = packet[0][14:42] 
    arp_detailed = struct.unpack("2s2s1s1s2s6s4s6s4s", arp_header) 

    # skip non-ARP packets 
    ethertype = ethernet_detailed[2] 
    if ethertype != '\x08\x06': 
     continue 

    print "****************_ETHERNET_FRAME_****************" 
    print "Dest MAC:  ", binascii.hexlify(ethernet_detailed[0]) 
    print "Source MAC:  ", binascii.hexlify(ethernet_detailed[1]) 
    print "Type:   ", binascii.hexlify(ethertype) 
    print "************************************************" 
    print "******************_ARP_HEADER_******************" 
    print "Hardware type: ", binascii.hexlify(arp_detailed[0]) 
    print "Protocol type: ", binascii.hexlify(arp_detailed[1]) 
    print "Hardware size: ", binascii.hexlify(arp_detailed[2]) 
    print "Protocol size: ", binascii.hexlify(arp_detailed[3]) 
    print "Opcode:   ", binascii.hexlify(arp_detailed[4]) 
    print "Source MAC:  ", binascii.hexlify(arp_detailed[5]) 
    print "Source IP:  ", socket.inet_ntoa(arp_detailed[6]) 
    print "Dest MAC:  ", binascii.hexlify(arp_detailed[7]) 
    print "Dest IP:   ", socket.inet_ntoa(arp_detailed[8]) 
    print "*************************************************\n" 

Beispielausgabe mit arpping Übertragung aus dem gleichen Host und seine Antwort:

****************_ETHERNET_FRAME_**************** 
Dest MAC:   ffffffffffff 
Source MAC:  000c29eb37bf 
Type:    0806 
************************************************ 
******************_ARP_HEADER_****************** 
Hardware type: 0001 
Protocol type: 0800 
Hardware size: 06 
Protocol size: 04 
Opcode:   0001 
Source MAC:  000c29eb37bf 
Source IP:  192.168.16.133 
Dest MAC:   ffffffffffff 
Dest IP:   192.168.16.2 
************************************************* 

****************_ETHERNET_FRAME_**************** 
Dest MAC:   000c29eb37bf 
Source MAC:  005056f37861 
Type:    0806 
************************************************ 
******************_ARP_HEADER_****************** 
Hardware type: 0001 
Protocol type: 0800 
Hardware size: 06 
Protocol size: 04 
Opcode:   0002 
Source MAC:  005056f37861 
Source IP:  192.168.16.2 
Dest MAC:   000c29eb37bf 
Dest IP:   192.168.16.133 
************************************************* 
+0

Ok, danke! Das funktioniert definitiv! Jetzt muss ich dieses Verhalten analysieren! Vielen Dank! – user3325230

+0

Danke dafür! Woher wussten Sie, dass Protokoll "0x0003" alles schnüffeln würde? Ich lese das Dokument "Assigned Internet Protocol Numbers" und es besagt, dass Nummer "3" GGP - Gateway-to-Gateway ist. – Matt

+1

Die Semantik des dritten Parameters ('Proto') hängt tatsächlich von der AF_ * -Familie im ersten Parameter ab. Für 'AF_PACKET' bedeutet das Protokoll '0x3' in Linux-Headern "alle Ethernet-Frames" oder "ETH_P_ALL". – Santa