在Linux下如何利用C語言來實現一個Sniffer
if (n42) {
perror(recvfrom():);
printf(Incomplete packet (errno is %d)n,
errno);
close(sock);
exit(0);
}
ethhead = buffer;
printf(Source MAC address:
%02x:%02x:%02x:%02x:%02x:%02xn,
ethhead[0],ethhead[1],ethhead[2],
ethhead[3],ethhead[4],ethhead[5]);
printf(Destination MAC address:
%02x:%02x:%02x:%02x:%02x:%02xn,
ethhead[6],ethhead[7],ethhead[8],
ethhead[9],ethhead[10],ethhead[11]);
iphead = buffer+14; /* Skip Ethernet header */
if (*iphead==0x45) { /* Double check for IPv4
* and no options present */
printf(Source host %d.%d.%d.%dn,
iphead[12],iphead[13],
iphead[14],iphead[15]);
printf(Dest host %d.%d.%d.%dn,
iphead[16],iphead[17],
iphead[18],iphead[19]);
printf(Source,Dest ports %d,%dn,
(iphead[20]8)+iphead[21],
(iphead[22]8)+iphead[23]);
printf(Layer-4 protocol %dn,iphead[9]);
}
}
}
PF_PACKET協議簇可以讓一個應用程序把數據包變成似乎從網絡層接收的樣子,但是沒有辦法抓到那些不是發向自己主機的包。正如我們前面看到的,網卡丟棄所有不含有主機MAC地址的數據包,這是因為網卡處于非混雜模式,即每個網卡只處理源地址是它自己的幀!
只有三個例外:如果一個幀的目的MAC地址是一個受限的廣播地址(255.255.255.255)那么它將被所有的網卡接收:如果一個幀的目的地址是組播地址,那么它將被那些打開組播接收功能的網卡所接收;網卡如被設置成混雜模式,那么它將接收所有流經它的數據包最后一種情況當然是我們最感興趣的了,把網卡設置成混雜模式,我們只需要發出一個特殊的ioctl()調用在那個網卡上打開一個socket,因為這是一個具有危險性的操作,所以這個調用只有具有root權限的用戶才可完成,假設那個“sock”包含一個已經打開的socket。
linux操作系統文章專題:linux操作系統詳解(linux不再難懂)
評論