Utilice un socket AF_NETLINK
para emitir una solicitud para activar IFF_PROMISC
. Python puede construir AF_NETLINK
tomas en Linux:
>>> from socket import AF_NETLINK, SOCK_DGRAM, socket
>>> s = socket(AF_NETLINK, SOCK_DGRAM)
>>>
Véase el ejemplo al final del enlace de red (7) del manual para un ejemplo de cómo emitir una solicitud de enlace de red. Puede usar ctypes
(o incluso struct
) para construir el mensaje nlmsghdr serializado para enviar a través del zócalo netlink. Es posible que también lo necesite para llamar al sendmsg
y recvmsg
, desde Python still doesn't expose these APIs. Alternativamente, hay algunos third-party modules disponibles que exponen estas dos API.
Alternativamente, puede ir a la ruta de la vieja escuela de usar ioctl
, que tristemente resulta ser bastante más simple.
En primer lugar definir la estructura ifreq usando ctypes:
import ctypes
class ifreq(ctypes.Structure):
_fields_ = [("ifr_ifrn", ctypes.c_char * 16),
("ifr_flags", ctypes.c_short)]
A continuación, hacer una toma de corriente para usar con el ioctl
llamada:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
luego copiar un par de valores constantes de/usr/include desde no están expuestos por Python:
IFF_PROMISC = 0x100
SIOCGIFFLAGS = 0x8913
SIOCSIFFLAGS = 0x8914
Crear un instan ce de la estructura ifreq y rellenarla tengan el efecto deseado:
ifr = ifreq()
ifr.ifr_ifrn = "eth4"
rellenar el campo ifr_flags
con una llamada ioctl
por lo que no Clobber lo banderas ya están establecido en la interfaz:
import fcntl
fcntl.ioctl(s.fileno(), SIOCGIFFLAGS, ifr) # G for Get
Añadir la bandera promiscua:
ifr.ifr_flags |= IFF_PROMISC
y juego de las banderas en la interfaz:
fcntl.ioctl(s.fileno(), SIOCSIFFLAGS, ifr) # S for Set
Para retirar la bandera, enmascararlo apagado y el nuevo:
ifr.ifr_flags &= ~IFF_PROMISC
fcntl.ioctl(s.fileno(), SIOCSIFFLAGS, ifr)
Necesita permisos de raíz en Linux para usar el modo promiscuo. –
Tenía permisos de root, pero gracias por recordar :) – TanB