在局域網(wǎng)進(jìn)行IP包捕獲的一種方法

字號(hào):

首先是幾個(gè)結(jié)構(gòu)的定義(網(wǎng)上搜索或者查閱相關(guān)文檔):
     er=1〉 //定義IP地址結(jié)構(gòu)
     struct IPADDRESS
     {
     unsigned short ip_a,
     ip_b,
     ip_c,
     ip_d;
     };
     //定義IP數(shù)據(jù)包頭的結(jié)構(gòu)
     struct IP_HEADER
     {
     unsigned short ip_version, /*IP的版本號(hào) */
     ip_hdr_len, /*IP包頭的長(zhǎng)度*/
     ip_tos, /*IP包的服務(wù)類型*/
     ip_total_len, /*IP包的總長(zhǎng)度*/
     ip_id, /*IP包的分段標(biāo)識(shí)*/
     ip_flags, /*IP包的分段標(biāo)志*/
     ip_frag_offset, /*IP包的分段偏移*/
     ip_ttl, /*IP包的生存時(shí)間*/
     ip_proto, /*IP包的高層協(xié)議*/
     ip_hdr_chksum; /*IP包的校驗(yàn)和*/
     struct IPADDRESS ip_src_addr, /*IP包的源IP地址*/
     ip_dest_addr; /*IP包的目的IP地址*/
     }ipheader;
     //IP包的鏈表結(jié)構(gòu)
     struct stru_ip_link
     {
     char rcv_ip_buf[MAX_IP_SIZE];
     struct stru_ip_link *next;
     };
     然后是協(xié)議的定義(包含相應(yīng)的頭文件#include #include):
     DWORD dwIoControlCode=SIO_RCVALL, /*接收所有的IP包*/
     dwProtocol=IPPROTO_IP; /*協(xié)議類型為IP*/
     然后是相應(yīng)的捕獲處理:
     1.加載 Winsock;
     2.創(chuàng)建一個(gè)接收原始IP包的socket連接;
     3.綁定到一個(gè)接口;
     4.進(jìn)行WSAIoctl設(shè)置,接收所有的IP數(shù)據(jù)包。
     參考代碼:
     if (WSAIoctl(s, dwIoControlCode, &optval, sizeof(optval),
     NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR)
     ...
     5.接著設(shè)定一個(gè)線程進(jìn)行捕獲:
     (1)創(chuàng)建一個(gè)接收IP包的鏈表頭;
     (2)設(shè)置一個(gè)標(biāo)識(shí),為真,則不斷進(jìn)行IP包的捕獲;
     (3)建立一個(gè)新的結(jié)點(diǎn),將捕獲的數(shù)據(jù)包加入到該結(jié)點(diǎn);
     (4)如果鏈表的長(zhǎng)度達(dá)到指定的長(zhǎng)度,創(chuàng)建一個(gè)線程對(duì)該鏈表的IP包進(jìn)行解析;再設(shè)置一個(gè)在IP數(shù)據(jù)包鏈表不足給定的長(zhǎng)度,而又中止IP捕獲時(shí),對(duì)鏈表的處理;
     (5)為下一個(gè)IP包鏈表創(chuàng)建一個(gè)鏈表頭。
     6.建立一個(gè)進(jìn)行IP包解析并顯示的線程,進(jìn)行解析IP數(shù)據(jù)包,然后顯示IP數(shù)據(jù)包。