I'm developing a custom packet sniffer in Python3.
It does not have to be platform independant. I'm using Linux.
The method I use is to recvfrom() from a socket (AF_PACKET, SOCK_RAW).
It works fine but I have problem with info returned by recvfrom().
recvfrom() returns a tuple with 5 components.
Example: ('eno1', 2054, 0, 1, b'\x00!\x9b\x16\xfa\xd1')
How do I interpret the last 4 components?
Where is it documented?
I prefer not to use libpcap or scapy.
OK! here's a code fragment:
    s = socket.socket( socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003))    ...    packet,pktAdr = s.recvfrom(65565)
    print( 'pktAdr:'+str(pktAdr))  
Thanks!
It's not documented on  docs.python.org so I did some research.
I'm now in a position to answer to myself.  
The tuple returned by recvfrom is similar to a sockaddr_ll structure returned by the Linux kernel.
The tuple contains 5 components:
 - [0]: interface name (eg 'eth0')
 - [1]: protocol at the physical level (defined in linux/if_ether.h)
 - [2]: packet type (defined in linux/if_packet.h)
 - [3]: ARPHRD (defined in linux/if_arp.h)
 - [4]: physical address
The example provided in  the question can be decoded into:
 - 'eno1'
 - ARP protocol (0x806)
 - Incoming packet
 - Ethernet frame
 - MAC address
In case of a WiFi interface in monitor mode, the [3] element would be 803 (meaning 'IEEE802.11 + RadioTap header').  
Hope this will help somebody
How to interpret result of recvfrom (raw socket)