Python Raw Sockets (Windows): Sniffing Ethernet Frames

TanB picture TanB · Jun 3, 2011 · Viewed 9.1k times · Source

I have seen several examples of creating sockets to sniffing for IP Packets, for example using:

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)

What I am trying to achieve, is sniffing for Ethernet Frames and analysing the data received in Windows. The packets I am interested in are PPPoE Frames not containing IP.

In Linux (using python) I was able to achieve this using :

s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.htons(3))
s.setsockopt(socket.SOL_SOCKET, IN.SO_BINDTODEVICE, struct.pack("%ds"%(len("eth0")+1,),"eth0"))
while condition:
    pkt = s.recvfrom(1500)
    addToQueue(filter(pkt))

Now due to the differences betweeen linux sockets and WinSock2 API, I am having the following compatibility issues :

  • There is no IN package for windows. That means the SO_BINDTODEVICE is not present. How do I sniff everything coming on eth0 interface?
  • What should I use for protocol option in socket() constructor as I dont want to limit it to IPPROTO_IP.

Can anyone point me to the right direction ? I went through similar questions but none of them really solved my problem as they were all concerned with IP Packet sniffing

Note: I know libraries like Scapy could be used for sniffing, but it loses packets if we are trying to do any elaborate filtering (or use the prn function) and does not suit what I am trying to do. Raw sockets fit my need perfectly.

Answer

Justin picture Justin · Jun 3, 2011

I can't verify this without a Windows box but I think all you need is ...

HOST = socket.gethostbyname(socket.gethostname())
s = socket.socket(socket.AF_INET, socket.SOCK_RAW)
s.bind((HOST, 0))
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
while condition:
    pkt = s.recvfrom(1500)
    addToQueue(filter(pkt))

Additionally, I'd recommend that you look in to using something like pypcap (or another libpcap wrapper) instead.