2017-03-03 70 views
1

我正在用C編寫一個工具,用於記錄在我的Linux系統上運行的不同應用程序的數據使用情況。爲此,我創建了一個原始套接字,然後使用「eth0」(它是我的接口的名稱)綁定它。但我的問題是,這個套接字只捕獲傳入數據包(即:目標MAC地址作爲我係統MAC地址的數據包)。我無法找到任何具有源MAC地址的數據包作爲我係統的MAC地址。所以這意味着我自己的機器寫入的數據包不會被原始套接字捕獲。但我想在兩個方向上捕獲數據包以識別上傳和下載的數據大小。任何人都可以幫忙嗎?使用原始套接字捕獲傳入和傳出數據包

int main() 
{ 
    int rs,len; 
    struct sockaddr_ll addr; 
    char buf[65535]; 

    rs = socket(PF_PACKET,SOCK_RAW,htons(ETH_ALL)); 
    setsockopt(rs,SOL_SOCKET,SO_BINDDEVICE,"eth0",4); 
    while(recvfrom(rs,buf,65535,&addr,&len) > 0){ 
     //print packets 
    } 
    return 0; 
} 

回答

1

我在搜索您的問題時發現了這個問題。我沒有試過這個。可能會這樣做。

int v=0; 
    v = PACKET_MASK_ANY & ~(1<<PACKET_OUTGOING) & ~(1 << PACKET_LOOPBACK); 
    setsockopt(raw_sock, SOL_PACKET, PACKET_RECV_TYPE, &v, sizeof(v)); 
+0

感謝您的回覆。但在我的/ usr/include目錄 –

+0

的#define PACKET_MASK_ANY爲0xffffffff/*掩碼包類型位* /#定義 任何PACKET_OUTGOING類型的4/* *呼出/ 的#define PACKET_RECV_TYPE 18 –

+0

沒有沒有宏命名PACKET_MASK_ANY套接字操作宏名爲PACKET_RECV_TYPE。你來自喀拉拉邦嗎? –

1

socket(7)

SO_BINDTODEVICE

綁定此接口將像「eth0的」特定裝置,如在通過接口名指定。 [...] 請注意,這僅適用於某些插座類型, 特別是AF_INET插座。它不支持數據包套接字(在那裏使用普通綁定(2))。

你應該看這種情況的packet(7)手冊頁。

下載libpcap庫源代碼並查看它在做什麼(如果你不能僅僅使用libpcap而不是自己滾動)可能是有益的。它絕對可以獲得傳出數據包以及傳入數據包。

它的出現使這些調用(所以你必須通過的ifdef無數以蜿蜒發現究竟發生了什麼事情有很多支持的選項和配置 - 見pcap-linux.c):

fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL); 
... 
struct sockaddr_ll sll; 
memset(&sll, 0, sizeof(sll)); 
sll.sll_family   = AF_PACKET; 
sll.sll_ifindex   = ifindex; // Interface index from SIOCGIFINDEX 
sll.sll_protocol  = htons(ETH_P_ALL); 
bind(fd, (struct sockaddr *) &sll, sizeof(sll)); 
... 
struct packet_mreq  mr; 
memset(&mr, 0, sizeof(mr)); 
mr.mr_ifindex = handlep->ifindex; 
mr.mr_type = PACKET_MR_PROMISC; 
setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) 

一件事要牢記。當接收到您自己的盒子發送的數據包時,傳出數據包中的校驗和(IP,TCP和UDP)通常是不正確的。這是因爲大多數現代網絡控制器都支持校驗和卸載。這意味着卡將在數據包被DMA存入卡存儲器後計算校驗和。因此,用於傳出數據包的數據在您的程序緩衝區中不正確(由本地內存填充內核)。

相關問題