@@ -7,7 +7,8 @@ This module provides an interface to Berkeley socket IPC.
77
88Limitations:
99
10- - only AF_INET and AF_UNIX address families are supported
10+ - only AF_INET and AF_UNIX address families are supported in a
11+ portable manner, though AF_PACKET is supported under Linux.
1112- no read/write operations (use send/recv or makefile instead)
1213- additional restrictions apply on Windows
1314
@@ -33,6 +34,13 @@ Module interface:
3334 (including the dd.dd.dd.dd notation) and port is in host byte order
3435- where a hostname is returned, the dd.dd.dd.dd notation is used
3536- a UNIX domain socket address is a string specifying the pathname
37+ - an AF_PACKET socket address is a tuple containing a string
38+ specifying the ethernet interface and an integer specifying
39+ the Ethernet protocol number to be received. For example:
40+ ("eth0",0x1234). Optional 3rd and 4th elements in the tuple
41+ specify packet-type and ha-type -- these are ignored by
42+ networking code, but accepted since they are returned by the
43+ getsockname() method.
3644
3745Socket methods:
3846
@@ -146,6 +154,12 @@ Socket methods:
146154#undef AF_UNIX
147155#endif
148156
157+ #if defined(linux ) && defined(AF_PACKET )
158+ #include <sys/ioctl.h>
159+ #include <net/if.h>
160+ #include <netpacket/packet.h>
161+ #endif
162+
149163#ifndef O_NDELAY
150164#define O_NDELAY O_NONBLOCK /* For QNX only? */
151165#endif
@@ -347,6 +361,9 @@ typedef struct {
347361#ifdef AF_UNIX
348362 struct sockaddr_un un ;
349363#endif
364+ #if defined(linux ) && defined(AF_PACKET )
365+ struct sockaddr_ll ll ;
366+ #endif
350367 } sock_addr ;
351368} PySocketSockObject ;
352369
@@ -550,8 +567,31 @@ makesockaddr(struct sockaddr *addr, int addrlen)
550567 struct sockaddr_un * a = (struct sockaddr_un * ) addr ;
551568 return PyString_FromString (a -> sun_path );
552569 }
553- #endif /* AF_UNIX */
570+ #endif
554571
572+ #if defined(linux ) && defined(AF_PACKET )
573+ case AF_PACKET :
574+ {
575+ struct sockaddr_ll * a = (struct sockaddr_ll * )addr ;
576+ char * ifname = "" ;
577+ struct ifreq ifr ;
578+ int s ;
579+ /* need a socket on which we can do an ioctl to look
580+ * up interface name from index, but only if index is
581+ * non-zero.
582+ */
583+ if (a -> sll_ifindex
584+ && ((s = socket (AF_PACKET , SOCK_RAW , 0 )) >= 0 )) {
585+ ifr .ifr_ifindex = a -> sll_ifindex ;
586+ if (ioctl (s , SIOCGIFNAME , & ifr ) == 0 )
587+ ifname = ifr .ifr_name ;
588+ close (s );
589+ }
590+ return Py_BuildValue ("shbh" , ifname , ntohs (a -> sll_protocol ),
591+ a -> sll_pkttype , a -> sll_hatype );
592+ }
593+ #endif
594+
555595 /* More cases here... */
556596
557597 default :
@@ -622,6 +662,36 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, struct sockaddr **addr_ret
622662 return 1 ;
623663 }
624664
665+ #if defined(linux ) && defined(AF_PACKET )
666+ case AF_PACKET :
667+ {
668+ struct sockaddr_ll * addr ;
669+ struct ifreq ifr ;
670+ char * interfaceName ;
671+ int protoNumber ;
672+ int hatype = 0 ;
673+ int pkttype = 0 ;
674+
675+ if (!PyArg_ParseTuple (args , "si|ii" , & interfaceName ,
676+ & protoNumber , & pkttype , & hatype ))
677+ return 0 ;
678+ strncpy (ifr .ifr_name , interfaceName , sizeof (ifr .ifr_name ));
679+ ifr .ifr_name [(sizeof (ifr .ifr_name ))- 1 ] = '\0' ;
680+ if (ioctl (s -> sock_fd , SIOCGIFINDEX , & ifr ))
681+ return 0 ;
682+ addr = & (s -> sock_addr .ll );
683+ addr -> sll_family = AF_PACKET ;
684+ addr -> sll_protocol = htons ((short )protoNumber );
685+ addr -> sll_ifindex = ifr .ifr_ifindex ;
686+ addr -> sll_pkttype = pkttype ;
687+ addr -> sll_hatype = hatype ;
688+ * addr_ret = (struct sockaddr * ) addr ;
689+ * len_ret = sizeof * addr ;
690+ return 1 ;
691+ }
692+ #endif
693+
694+
625695 /* More cases here... */
626696
627697 default :
@@ -655,6 +725,14 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
655725 return 1 ;
656726 }
657727
728+ #if defined(linux ) && defined(AF_PACKET )
729+ case AF_PACKET :
730+ {
731+ * len_ret = sizeof (struct sockaddr_ll );
732+ return 1 ;
733+ }
734+ #endif
735+
658736 /* More cases here... */
659737
660738 default :
@@ -894,7 +972,8 @@ static char bind_doc[] =
894972"bind(address)\n\
895973\n\
896974Bind the socket to a local address. For IP sockets, the address is a\n\
897- pair (host, port); the host must refer to the local host." ;
975+ pair (host, port); the host must refer to the local host. For raw packet\n\
976+ sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])" ;
898977
899978
900979/* s.close() method.
@@ -2441,6 +2520,17 @@ init_socket(void)
24412520#ifdef AF_ROSE
24422521 insint (d , "AF_ROSE" , AF_ROSE ); /* Amateur Radio X.25 PLP */
24432522#endif
2523+ #if defined(linux ) && defined(AF_PACKET )
2524+ insint (d , "AF_PACKET" , AF_PACKET );
2525+ insint (d , "PF_PACKET" , PF_PACKET );
2526+ insint (d , "PACKET_HOST" , PACKET_HOST );
2527+ insint (d , "PACKET_BROADCAST" , PACKET_BROADCAST );
2528+ insint (d , "PACKET_MULTICAST" , PACKET_MULTICAST );
2529+ insint (d , "PACKET_OTHERHOST" , PACKET_OTHERHOST );
2530+ insint (d , "PACKET_OUTGOING" , PACKET_OUTGOING );
2531+ insint (d , "PACKET_LOOPBACK" , PACKET_LOOPBACK );
2532+ insint (d , "PACKET_FASTROUTE" , PACKET_FASTROUTE );
2533+ #endif
24442534
24452535 /* Socket types */
24462536 insint (d , "SOCK_STREAM" , SOCK_STREAM );
0 commit comments