2009-08-24 68 views
3

我有socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))創建了一個socket,我已經用它設置成混雜模式:包插座只接收當地交通

struct ifreq ifr; 
strncpy((char*)ifr.ifr_name, interface, IF_NAMESIZE); 
if(ioctl(sock, SIOCGIFINDEX, &ifr)<0) fail(2); 

struct packet_mreq mr; 
memset(&mr, 0, sizeof(mr)); 
mr.mr_ifindex = ifr.ifr_ifindex; 
mr.mr_type = PACKET_MR_PROMISC; 
if(setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0) fail(2); 

的問題是,當我從插座做read() ,它只會返回來自或來自我的計算機的數據。

我怎樣才能讀取並處理網絡上的所有數據包?

Wireshark顯示所有的數據包都很好,所以我知道它不是我的電腦或網卡。 ifconfig報告它在運行時爲PROMISC

回答

4

與Rob Jones的建議一起,嘗試使用像Wireshark這樣的工具來確保您正在接收您期望的界面上的數據包。至少這會確認(或否認)你的代碼有問題。

還需要確保接口本身設置爲混雜模式。 如果沒有,那麼你可以使用ioctl()來設置它:

ifr.ifr_flags |= IFF_PROMISC; 
if(ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) 
{ 
    // handle error here 
} 

當你的應用程序正在運行,確保使用ifconfig報告PROMISC標誌用於接口。

請注意,這需要作爲特權用戶執行。


試驗了所提供的代碼。適用於我。當然(由於第102行的測試),這隻會打印TCP流量的詳細信息。

+0

Wireshark顯示數據包正常,tcpdump也一樣。 – computergeek6 2009-08-25 00:48:38

+0

確實如此,但套接字仍然不會收到其他流量。 – computergeek6 2009-08-25 01:39:34

+0

我設法修復它在我的最後,這是最有用的答案。謝謝! – computergeek6 2009-08-25 04:13:47

1

嘗試使用SOCK_PACKET作爲socket()的第二個參數,而不是SOCK_RAW。

如果你在一臺交換機上,你可能只會看到目的地或源自你的計算機的數據包。嘗試一箇中心。

+0

如果我這樣做,bind()失敗。此外,它已被棄用。 – computergeek6 2009-08-25 03:06:22

+1

夠公平的。你是否以特權用戶身份運行? – 2009-08-25 03:13:13

0

這很可能不是軟件問題。

您可能會使用錯誤的硬件。您的計算機可能連接到交換機。 交換機足夠聰明,可以「學習」哪些計算機位於哪個端口,並將流量路由到所需的位置。因此,交換機正在爲您過濾數據包。

要解決此問題,您需要獲取Hub。雖然集線器和交換機顯示非常相似,但它們的工作方式不同Hub是愚蠢的,會將所有流量路由到所有端口,使您能夠以混雜模式查看其他流量。

請注意,即使您更換計算機連接的設備,它可能會連接到更多的交換機上行,這也會限制流量。因此,您將無法從比您自己的集線器或測試實驗室設置更遠的地方嗅探流量。