gpt4 book ai didi

Python 套接字 : Enabling Promiscuous Mode in Linux

转载 作者:太空狗 更新时间:2023-10-29 18:19:38 27 4
gpt4 key购买 nike

我们知道Python Allows enabling promiscuous mode under Windows through

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

但是,RCVALL_* 和 SIO_* 仅在 Windows 中可用。使用 C socket api,在 Linux 中,可以使用:

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

或通过,

setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP, PACKET_MR_PROMISC)

python 套接字 API 中是否有任何选项允许我们在 Linux 中设置混杂模式

最佳答案

使用AF_NETLINK 套接字发出打开IFF_PROMISC 的请求。 Python 可以在 Linux 上构建 AF_NETLINK 套接字:

>>> from socket import AF_NETLINK, SOCK_DGRAM, socket 
>>> s = socket(AF_NETLINK, SOCK_DGRAM)
>>>

有关如何发出网络链接请求的示例,请参阅 netlink(7) 手册页末尾的示例。您可以使用 ctypes(甚至 struct)构建序列化的 nlmsghdr 消息以通过 netlink 套接字发送。您可能还需要它来调用 sendmsgrecvmsg,因为 Python still doesn't expose these APIs .或者,有一些 third-party modules可用于公开这两个 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"

使用 ioctl 调用填充 ifr_flags 字段,这样您就不会破坏接口(interface)上已经设置的任何标志:

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)

关于Python 套接字 : Enabling Promiscuous Mode in Linux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6067405/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com