1
votes

I'm trying to read Ethernet (IEEE 802.2 / 3) frames using primarily socket. The application shuld just sniff ethernet frames and depending on the content, act on it. However, there are almost no information on how to do this on Windows, the default (unix way) being socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0800)). This is nonexistent in winsock apparently. So how do I sniff eth frames?

I suspect I need to bind to a MAC using socket.bind() instead of IP.

My current piece of code:

def _receive(interface): #Receive Eth packets.
    #Interface = '192.168.0.10'

    sock2 = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
    sock2.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1))
    sock2.bind((interface, 0)) 

    while True:
        data, sender = sock2.recvfrom(1500)
        handle_data(sender, data) 

Gets me nowhere. I see packets on Local connection in Wireshark, but it's not picked up in python..

On linux, I can do sock_raw = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_802_2)) , then bind and setsockopt(sock_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq))

I would like to not have to depend on too many external libraries becuase this is supposed to be distributed and thus pretty lightweight. pip install-able packages are OK though, they can be bundled with the installer..

1

1 Answers

0
votes

Python's socket doesn't come with sniffing capabilites. Simple as that.

The idea of having a network stack in your operating system is that programs "register" for specific types of packets to be delivered to them – typically, this is something like listening on a IP port, ie. one to two levels above raw ethernet packets.

To get all raw ethernet packets, your operating system's network stack needs some kind of driver/interface to support you with that. That's why wireshark needs WinPcap.

My guess is you're going to be pretty happy with pypcap, which probably is PyPi/pip installable.