Search code examples
pythonarpsniffer

Python arp sniffing raw socket no reply packets


to understand the network concepts a bit better and to improve my python skills I am trying to implement a packet sniffer with python. I have just started to learn python, so the code could be optimized of course ;)

I have implemented an packet sniffer which unpacks the ethernet frame and the arp header. I want to make it with raw sockets because I want to understand every byte within those headers, so please no scapy help :)

The problem is, that I won´t get any arp reply packet. It´s always opcode 1 and I

Here is my source code:

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"

could someone please explain me why I am getting no response packets just these?

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
*************************************************

Thanks so far! :)


Solution

  • I think you need to specify socket protocol number 0x0003 to sniff everything, and then filter out non-ARP packets after the fact. This worked for me:

    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"
    

    Sample output using arpping broadcast from the same host and its reply:

    ****************_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
    *************************************************