1.介紹
在linux中提供了pf_packet接口可以操作鍊路層的資料。
2.使用方法
定義一個pf_packet = socket(pf_socket, sock_raw, htons(eth_p_rarp));
就可以利用函數sendto和recefrom來讀取和發送鍊路層的資料包了(當然,發送arp包,上面第三個參數要變為htons(eth_p_arp),或者ip的包為eth_p_ip,可檢視檔案/usr/include/linux/if_ether.h檔案看到所有支援的協定)。
3.在使用sock_raw, sock_dgram和sock_packet的差別
在socket的第一個參數使用pf_packet的時候,上述三種socket的類型都可以使用。但是有差別。
(1)使用sock_raw發送的資料必須包含鍊路層的協定頭,接受得到的資料包,包含鍊路層協定頭。而使用sock_dgram則都不含鍊路層的協定頭。
(2)sock_packet也是可以使用的,但是已經廢棄,以後不保證還能支援,不推薦使用。
(3)在使用sock_raw或sock_dgram和sock_packet時,在sendto和recvfrom中使用的位址類型不同,前兩者使用sockaddr_ll類型的位址,而後者使用sockaddr類型的位址。
(4)如socket的第一個參數使用pf_inet,第二個參數使用sock_raw,則可以得到原始的ip包。
4.下面的例子是一個簡單的rarp協定的server程式和client程式
server程式一開始獲得除lo接口以外接口的mac位址,等待rarp request請求的到來,如果請求的是自己的mac位址,則向用戶端發送rarp reply,回送自己的ip位址。應我使用的地方,一台機器的ip位址每次dhcp以後都會變。是以該程式還是有一些用處。
注意:本程式隻為示範packet socket的工作原理,是以沒有進行任何的錯誤處理,并假設工作的機器上隻有ethernet接口。但是本程式有個缺點,就是兩個程式工作在同一台機器上的時候,server無法接收到client的rarp request。請知道的朋友賜教,謝謝!
//file name : rarp_server.cpp
轉載自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=686647&id=1745799