2011-05-20 69 views
9

啓用混雜模式我們知道,Python允許在Windows下通過Python的套接字:在Linux中

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) 

是否有蟒蛇套接字API的任何選項,允許我們設置混雜模式的Linux

+0

您需要Linux上的root權限才能使用混雜模式。 – 2011-05-20 04:27:26

+0

我有根權限,但感謝提醒:) – TanB 2011-05-22 21:44:42

回答

13

使用一個AF_NETLINK套接字發出請求打開IFF_PROMISC。 Python可以在Linux構造AF_NETLINK插口:

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

參見例如在網絡鏈路(7)手冊頁面的末尾有關如何發出網絡鏈路請求的示例。您可以使用​​(或甚至struct)構建序列化的nlmsghdr消息通過netlink套接字發送。您可能還需要撥打電話sendmsgrecvmsg,因爲Python still doesn't expose these APIs。或者,有一些third-party modules可用,它們暴露這兩個API。

另外,你可以去舊的路線使用ioctl,這可悲的是事實證明是相當簡單。

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 /因爲包括

首先使用ctypes的定義爲ifreq結構它們沒有被Python公開:

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

創建一個instan爲ifreq結構的CE和填充它有預期的效果:

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

填充有ioctl調用ifr_flags場,這樣你就不會破壞任何標誌已經設置界面:

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) 
+0

歡呼的詳細答案,並提供有用的代碼片段。 – TanB 2011-05-22 21:43:46

3

還有另一種方法我想到的。也許不夠優雅,但似乎工作正常。

在linux中(使用根權限),可以使用:

# ifconfig eth0 promisc 
# ifconfig eth0 -promisc 

要啓用接口(在此情況下的eth0)上啓用/禁用PROMISC模式。

因此,在蟒蛇(帶root權限),人們可以使用:

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

評論,歡迎做它的這種方式。

+2

使用較新的「ip」實用程序的類似方法是運行「ip link set eth0 promisc on」。在子進程中調用ifconfig可能會按照我的回答做相同的ioctls。在子進程中調用ip會執行我提到的AF_NETLINK,但實際上並沒有說出來(因爲它更難:)。 – 2011-05-23 03:14:49