[issue46089] Problems with AF_PACKET sockets

2021-12-15 Thread G. Allard


G. Allard  added the comment:

Next 3 steps must be (in decreasing priorities):
- fix the code
- write a mini-howto. It will be used for test purposes
- write documentation (a Howto/tutorial)

For the 3rd step, I would accept to join a team.

--

___
Python tracker 
<https://bugs.python.org/issue46089>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46089] Problems with AF_PACKET sockets

2021-12-15 Thread G. Allard


New submission from G. Allard :

For educational purposes, I'm developing my own IP stack in Python. It's going 
well but I'm stuck at a low level.
I need to implement the following (simple) task:
- open an AF_PACKET socket (socket.socket)
- bind it to a specific interface (socket.bind)
Python code would look like this:
- sock = socket.socket( socket.AF_PACKET, socket.SOCK_RAW, socket.htons( 
ETH_P_ALL))
- sock.setblocking( False)
- sock.bind(( 'eth0', socket.htons( ETH_P_ALL)))
It does not work. bind always return "TypeError: AF_PACKET address must be a 
tuple of two to five elements"
I spent many days on that problem. No success.

Desperate, I tried to verify it wasn't a kernel problem. I wrote the C version 
of the above snippet. 
- sock = socket( AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, htons( 3));
- struct sockaddr_ll addr = {0};
  addr.sll_family = AF_PACKET;
  addr.sll_ifindex = 2;  /* index of 'eth0' */
  addr.sll_protocol = htons( ETH_P_ALL);
- bind( sock, (struct sockaddr*) , sizeof( addr));
I'm not an expert in C programming but it worked on first try.

First problem is that AF_PACKET sockets are broken in Python.

Second problem is inadequate documentation.
Following issue ID 25041, some documentation has been added but there is still 
lot of room for improvements.
For example:
- recvfrom return 2 values. The first is the binary packet and the second one 
is a 5 member structure. The first member of the structure is the interface 
name. The 5th member if the MAC address (assuming the interface is an Ethernet 
NIC). The 3rd one is a protocol number (the data-link protocol) whose data is 
in front of the returnet packet (for WiFi packets, we will see Radiotap 
protocol at that level).
That's a whole new world for documentors.

- socket.bind() parameter is documented to be an address. For AF_PACKET, the 
address is documented in "Socket Families" section. Definition is vague. The 
'proto' description would be easier to understand with "An integer (in 
network-byte-order) representing the low level protocol (enumerated in 
linux/if_ether.h) or ETH_P_ALL for all protocols. This parameter is only used 
for filtering inbound packets."
IMO 'pkttype', 'hatype', 'addr' are there to document the information returned 
by recvfrom(). It's written they are "optional" but I think it's not correct.

- Working examples of AF_PACKET must be provided, possibly in a HOWTO.

When it's easier to program in C, it should tell you there is a problem on 
Python side.

--
assignee: docs@python
components: Documentation
messages: 408638
nosy: docs@python, gallard
priority: normal
severity: normal
status: open
title: Problems with AF_PACKET sockets
type: enhancement
versions: Python 3.8

___
Python tracker 
<https://bugs.python.org/issue46089>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com