2011-05-20 12 views
9

yılında Promiscuous Modu etkinleştirilmesi Biz *, Python AncakPython Yuva: Linux

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

aracılığıyla Windows altında çoklu modu sağlayan verir o RCVALL_ biliyoruz ve SIO_ * pencerelerde kullanılabilir. kullanma C soket API, Linux, birini kullanabilirsiniz:

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

ya aracılığıyla,

setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP, PACKET_MR_PROMISC) 

bize Linux yılında çoklu modu ayarlamanızı sağlar piton soket API herhangi bir seçenek var mı?

+0

Rasgele mod kullanmak için Linux'ta kök izinlerine ihtiyacınız vardır. –

+0

Kök izinleri vardı ancak hatırlattığınız için teşekkürler :) – TanB

cevap

13

IFF_PROMISC açmak için bir istek yayımlamak için bir AF_NETLINK soketi kullanın. Python Linux üzerinde AF_NETLINK yuvalarına inşa edebilirsiniz:

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

bir netlink isteği nasıl bir örnek için Netlink (7) kılavuz sayfasını sonundaki örneğe bakın. Netlink soketine göndermek için serileştirilmiş nlmsghdr mesajını oluşturmak için ctypes (veya struct) kullanabilirsiniz. Ayrıca, Python still doesn't expose these APIs'dan beri sendmsg ve recvmsg numaralarını aramanız gerekebilir. Alternatif olarak, bu iki API'yi ortaya çıkaran bazı third-party modules mevcuttur.

Alternatif olarak, ioctl'u kullanarak eski okul yoluna gidebilir ve bu da ne yazık ki daha basittir.

import socket 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 

Sonra/usr/dışına birkaç sabit değerleri kopyalamak beri şunlardır: Sonra ioctl çağrı ile kullanmak için bir soket yapmak

import ctypes 

class ifreq(ctypes.Structure): 
    _fields_ = [("ifr_ifrn", ctypes.c_char * 16), 
       ("ifr_flags", ctypes.c_short)] 

:

İlk ctypes kullanarak ifreq yapısını tanımlamak onlar Python tarafından maruz değiliz:

IFF_PROMISC = 0x100 
SIOCGIFFLAGS = 0x8913 
SIOCSIFFLAGS = 0x8914 

bir Instan oluştur

import fcntl 

fcntl.ioctl(s.fileno(), SIOCGIFFLAGS, ifr) # G for Get 
: Zaten arabirimde ayarlanır neyse bayraklar zarar vermiyorum böylece

ifr = ifreq() 
ifr.ifr_ifrn = "eth4" 

bir ioctl çağrıyla ifr_flags alanını doldur: ifreq yapının ce ve onu doldurmak istenen etkiye sahip arabirimde bayrakları

ifr.ifr_flags |= IFF_PROMISC 

Ve ayarlayın::

gelenle bayrağı ekle

fcntl.ioctl(s.fileno(), SIOCSIFFLAGS, ifr) # S for Set 

, bayrağı kaldırmak onu maske ve yeniden ayarlamak için:

ifr.ifr_flags &= ~IFF_PROMISC 
fcntl.ioctl(s.fileno(), SIOCSIFFLAGS, ifr) 
+0

Detaylı yanıt ve kodların yararlı snippet'leri için şerefe. – TanB

3

yoktur benim aklıma başka bir yol. Belki de zarif değil ama iyi çalışıyor gibi görünüyor.

(kök izinlerle) linux, bir kullanabilirsiniz:

# ifconfig eth0 promisc 
# ifconfig eth0 -promisc 

sizin arayüzüne (bu durumda eth0)/devre dışı bırakma promisc modunu etkinleştirmek için.

Yani, (kök izinlerle) piton biri kullanabilirsiniz:

import os 
ret = os.system("ifconfig eth0 promisc") 
if ret == 0: 
    <Do something> 

Yorumlar yapıyor bu yolda açıktır.

+2

Yeni "ip" yardımcı programını kullanan benzer bir yaklaşım, "ip link set eth0 promisc on" komutunu çalıştırmak olacaktır. Bir alt işlemdeki ifconfig'in çağrılması muhtemelen cevaplarıma verdiğim gibi aynı ioctları da yapacaktır. Ve bir alt işlem içinde ip çağırmak ima ettiğim AF_NETLINK şeylerini yapacak ama aslında hecelemedim (çünkü daha zor :) çünkü. –