Python套接字:在Linux中启用混杂模式
我们知道Python允许通过以下方式在Windows下启用混杂模式
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
但是,RCVALL_ 和SIO_ 仅在Windows中可用。使用C套接字api,在Linux中,可以使用:
ethreq.ifr_flags |= IFF_PROMISC;
ioctl(sock, SIOCSIFFLAGS, ðreq);
或通过
setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP, PACKET_MR_PROMISC)
python socket API中 是否有任何选项 可以允许我们在Linux中设置混杂模式 ?
-
使用
AF_NETLINK
套接字发出打开请求IFF_PROMISC
。Python可以AF_NETLINK
在Linux上构造套接字:>>> from socket import AF_NETLINK, SOCK_DGRAM, socket >>> s = socket(AF_NETLINK, SOCK_DGRAM) >>>
有关如何发出网络链接请求的示例,请参见netlink(7)手册页末尾的示例。您可以使用
ctypes
(或什struct
至)构造序列化的nlmsghdr消息,以通过netlink套接字发送。您可能还需要它来打电话sendmsg
和recvmsg
,因为Python的还是不公开这些API。或者,有一些第三方模块可以公开这两个API。另外,您可以使用的老派路线
ioctl
,可悲的是事实证明这很简单。首先使用ctypes定义ifreq结构:
import ctypes class ifreq(ctypes.Structure): _fields_ = [("ifr_ifrn", ctypes.c_char * 16), ("ifr_flags", ctypes.c_short)]
然后创建一个套接字以用于
ioctl
调用:import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
然后从/ usr / include中复制几个常量值,因为它们没有被Python公开:
IFF_PROMISC = 0x100 SIOCGIFFLAGS = 0x8913 SIOCSIFFLAGS = 0x8914
创建ifreq结构的实例,并填充它以达到所需的效果:
ifr = ifreq() ifr.ifr_ifrn = "eth4"
ifr_flags
使用ioctl
呼叫填充该字段,这样您就不会破坏接口上已经设置的任何标志:import fcntl fcntl.ioctl(s.fileno(), SIOCGIFFLAGS, ifr) # G for Get
添加混杂标志:
ifr.ifr_flags |= IFF_PROMISC
并在接口上设置标志:
fcntl.ioctl(s.fileno(), SIOCSIFFLAGS, ifr) # S for Set
要删除该标志,请将其掩盖并再次设置:
ifr.ifr_flags &= ~IFF_PROMISC fcntl.ioctl(s.fileno(), SIOCSIFFLAGS, ifr)