Используйте сокет AF_NETLINK
для выдачи запроса на включение IFF_PROMISC
. Python может создавать AF_NETLINK
сокеты в Linux:
>>> from socket import AF_NETLINK, SOCK_DGRAM, socket
>>> s = socket(AF_NETLINK, SOCK_DGRAM)
>>>
См. Пример в конце справочной страницы netlink (7) для примера того, как выполнить запрос netlink. Вы можете использовать ctypes
(или даже struct
) для создания сериализованного сообщения nlmsghdr для отправки через сокет netlink. Вам также может понадобиться вызывать sendmsg
и recvmsg
, поскольку Python по-прежнему не предоставляет эти API . Кроме того, есть несколько сторонних модулей , которые предоставляют эти два API.
В качестве альтернативы, вы можете пойти по старому школьному пути, используя ioctl
, который, к сожалению, оказывается гораздо проще.
Сначала определите структуру ifreq, используя ctypes:
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)