简体   繁体   中英

How can I listen for raw ethernet frames in vanilla Python 3?

I'm doing some self-educational low-level network programming in Python. I'm using Ubuntu 18.04 and Python 3 . Using this code, I'm able to send raw ethernet packets:

from socket import socket as Socket, AF_PACKET, SOCK_RAW

def send_bytes(byte_sequence):
    with Socket(AF_PACKET, SOCK_RAW) as socket:
        socket.bind(("enp0s31f6", 0))
        socket.send(bytes(byte_sequence))

I can use this procedure to send pings. I know it's working because I can see the ping going out and receiving a response in Wireshark.

Now I want to listen for packets, like the response to my ping. How can I do this, hopefully without involving any non-standardlib libraries? I'd like the code to be as "close to the metal" as possible, so ideally I'd like to listen for the entire ethernet frame so I can parse it all by hand and figure out if it's the packet I'm looking for.

This works for me

import sys
import socket
ETH_P_ALL=3 # not defined in socket module, sadly...
s=socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
s.bind(("eth0", 0))
r=s.recv(2000)
sys.stdout.write("<%s>\n"%repr(r))

The third argument when creating the socket acts as a filter on the type of incoming frames we want to capture (all of them here).

The ETH_P_ALL constant comes from /usr/include/linux/if_ether.h .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM