最近在用Wireshark抓包工具的時候,老感受這東西用起來很簡單,功能強大,因此想了解他的實現原理,我就本身好奇寫了一個實現基本功能的demo吧。git
其實叫抓包工具,其實就是抓取流經本身網卡的全部ip包,咱們可以按照ip包的協議解析不就好了。github
實現的核心在這裏:socket
1 //建立SOCKET 2 sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP); 3 if (sock == INVALID_SOCKET) 4 { 5 cout << WSAGetLastError(); 6 return 0; 7 } 8 //獲取本機地址 9 char name[128]; 10 if (-1 == gethostname(name, sizeof(name))) 11 { 12 closesocket(sock); 13 cout << WSAGetLastError(); 14 return 0; 15 } 16 struct hostent * pHostent; 17 pHostent = gethostbyname(name); 18 //綁定本地地址到SOCKET句柄 19 sockaddr_in addr; 20 addr.sin_family = AF_INET; 21 addr.sin_addr = *(in_addr*)pHostent->h_addr_list[0]; //IP 22 addr.sin_port = 8888; //端口,IP層端口可隨意填 23 if (SOCKET_ERROR == bind(sock, (sockaddr *)&addr, sizeof(addr))) 24 { 25 closesocket(sock); 26 cout << WSAGetLastError(); 27 return 0; 28 } 29 30 //設置該SOCKET爲接收全部流經綁定的IP的網卡的全部數據,包括接收和發送的數據包 31 u_long sioarg = 1; 32 DWORD wt = 0; 33 if (SOCKET_ERROR == WSAIoctl(sock, SIO_RCVALL, &sioarg, sizeof(sioarg), NULL, 0, &wt, NULL, NULL)) 34 { 35 closesocket(sock); 36 cout << WSAGetLastError(); 37 return 0; 38 } 39 //咱們只須要接收數據,所以設置爲阻塞IO,使用最簡單的IO模型 40 u_long bioarg = 0; 41 if (SOCKET_ERROR == ioctlsocket(sock, FIONBIO, &bioarg)) 42 { 43 closesocket(sock); 44 cout << WSAGetLastError(); 45 return 0; 46 } 47 //開始接收數據 48 //由於前面已經設置爲阻塞IO,recv在接收到數據前不會返回。 49 g_event = CreateEvent(NULL,TRUE,FALSE,NULL);
其餘的就很少說了,有開發經驗的應該都會,這個是半天弄出來的,因此不少代碼沒有整理,還請見諒。我主要是實現功能,好本身用。工具
下面是截圖: url
代碼地址:spa
http://download.csdn.net/detail/hegangle/9777070.net
垃圾csdn,竟然不讓我上傳免費的版本了,上面免費的地址被csdn刪掉了:code
csdn:http://download.csdn.net/download/hegangle/10012672blog
git:https://github.com/alexhegang/ipattr/blob/master/IPATTRC.zipip