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