Python套接字:在Linux中启用混杂模式

发布于 2021-01-29 17:03:16

我们知道Python允许通过以下方式在Windows下启用混杂模式

s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

但是,RCVALL_ 和SIO_ 仅在Windows中可用。使用C套接字api,在Linux中,可以使用:

ethreq.ifr_flags |= IFF_PROMISC;
ioctl(sock, SIOCSIFFLAGS, &ethreq);

或通过

setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP, PACKET_MR_PROMISC)

python socket API中 是否有任何选项 可以允许我们在Linux中设置混杂模式

关注者
0
被浏览
173
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    使用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套接字发送。您可能还需要它来打电话sendmsgrecvmsg,因为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)
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看