WinCap数据包显示
BackGround: 計算機網絡實驗到了用WinpCap進行編程的課時
本實驗是通過WinpCap編程來做一個簡單的數據包獲取顯示的軟件
---------------------------------------------------------------
一.WinpCap
libpcap是一個UNIX下的C函數庫,它提供的API,能獲取和過濾從任意一塊網卡在數據鏈路層上的幀。不同的UNIX系統有不同的架構去處理數據鏈路層上的數據幀,所以程序員如果想要寫一個能運行在UNIX上的、直接讀取或者操作數據鏈路層上的幀的應用程序,他就不得不專門為這個特點版本的UNIX寫一個訪問幀的函數。libpcap的目的就是提供一個抽象層,這樣程序員就能編寫可運行在所有版本的UNIX上的包獲取和分析工具了。
WinPcap是一個專為Windows系統設計的、基于libpcap開發的庫.
winpcap有兩種 一種是需要安裝的驅動程序,一種是直接解壓使用的開發包,這里我們要使用的是開發包,但是開發包是基于驅動程序上面使用的,所有首先應該安裝Winpcap驅動程序,之后再使用編程軟件去使用開發包進行開發
學校使用校園網軟件的同學電腦上,基本已經安裝好winpcap驅動軟件了。
1、下載winpcap驅動軟件。
如果是安裝了wireshark或者其他數據包攔截軟件的話,它就自動幫我們裝了winpcap驅動。(wireshark是基于winpcap開發的)
http://www.winpcap.org/install/default.htm 這個是winpcap官網下載頁面,我下載的是4.1.3版本的。
下載到本地后,直接雙擊安裝就可以了。
2、下載winpcap開發包
http://www.winpcap.org/devel.htm 這個是winpcap官網的開發包下載,主要它的版本要和驅動版本一致。
下載到本地后,解壓縮就可以了。里面有winpcap的庫、頭文件,以及例子和使用文檔
二.配置VS2015支持進行基于WinPcap開發
1.設置環境目錄
右鍵點擊項目-屬性-VC++目錄
2.設置 ?包含目錄 ?和 ?庫目錄
①首先設置 包含目錄,設置為解壓的WinpCap開發包的include目錄
---------------------------------
-----------------------------------
-----------------------------------
②同樣操作設置 庫目錄,庫目錄為 Lib目錄
------------------------------
以上兩個設置好之后就會是這樣的
----------------------------------------------------------
3.設置編譯預處理
在預處理器里面添加“預處理定義” WPCAP 和HAVE_REMOTE
--------------------------------------------
4.設置鏈接器
在輸入 中添加附加依賴項ws2_32.lib ? wpcap.lib Packet.lib 三個依賴包
自此VS2015配置WinpCap開發環境完畢,vs2013配置方法相同
------------------------------------------
#include "pcap.h" #include <stdio.h> #include<Windows.h> typedef struct ip_address {u_char byte1; u_char byte2;u_char byte3;u_char byte4; } ip_address;//ipv4地址typedef struct ip_header {u_char versionAndHeader; //版本 + 首部長度u_char serviceType; //服務類型 u_short totalLength; //總長 u_short identification; //標識u_short flagsAndOffset; //標志位+段偏移 u_char timeToLive; //存活時間u_char protocal; //協議名u_short headerChecksum; //校驗和ip_address sourceAddress; //源地址ip_address destinationAddress;//目的地址u_int option;//附加 } ip_header;//TCP數據包頭部typedef struct udp_header {u_short sourcePort; //源端口 u_short destinationPort; //目的端口 u_short len; //udp數據包長度u_short Checksum; //校驗和 } udp_header;//UDP數據包頭部void packHandleFunc(u_char *param, const struct pcap_pkthdr *header, const u_char *data) {struct tm *localTime; //本地時間結構char timeString[16]; //轉換正常的顯示時間time_t local_second;//時間戳ip_header *ipHeader; //ip數據包頭部udp_header *udpHeader;//udp數據包頭部u_int ip_len; //ip頭部長度u_short sourceport, destinationport; //源和目的端口local_second = header->ts.tv_sec;//數據包到達時間戳localTime = localtime(&local_second); //時間戳轉本地時間格式strftime(timeString, sizeof(timeString), "%H:%M:%S", localTime);//本地時間格式轉正常21:11:30時間格式printf("時間:%s, 包長度:%d ", timeString, header->len);ipHeader = (ip_header *)(data + 14);//跳過以太網頭部14字節長度獲得ip數據包頭部位置ip_len = (ipHeader->versionAndHeader & 0xf) * 4; //只取頭部長度udpHeader = (udp_header *)((u_char *)ipHeader + ip_len);//跳到udp頭部地址sourceport = ntohs(udpHeader->sourcePort); // ntohs 網絡字節轉主機字節端口destinationport = ntohs(udpHeader->destinationPort);printf("%d.%d.%d.%d:%d -> %d.%d.%d.%d:%d\n",ipHeader->sourceAddress.byte1,ipHeader->sourceAddress.byte2,ipHeader->sourceAddress.byte3,ipHeader->sourceAddress.byte4,sourceport,ipHeader->destinationAddress.byte1,ipHeader->destinationAddress.byte2,ipHeader->destinationAddress.byte3,ipHeader->destinationAddress.byte4,destinationport); } int main(int argc, char* argv[]) {pcap_if_t *Devs;pcap_if_t *d;int selectNum;int i = 0;pcap_t *handle;char errBuff[PCAP_ERRBUF_SIZE];if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &Devs, errBuff) == -1){fprintf(stderr, "獲取適配器列表失敗:%s\n", errBuff);system("pause");exit(1);}for (d = Devs; d; d = d->next){if (d->description)printf("%d. %s\n",++i, d->description);}if (i == 0){printf("\n沒有發現適配器,請確認是否已經安裝WinCap\n");system("pause");return -1;}printf("請輸入要捕獲數據包的適配器編號 (1-%d):", i);scanf("%d", &selectNum);if (selectNum < 1 || selectNum > i){printf("\n輸入有誤噢\n");pcap_freealldevs(Devs);system("pause");return -1;}for (d = Devs, i = 0; i< selectNum - 1; d = d->next, i++);if ((handle = pcap_open(d->name, 65535, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errBuff)) == NULL){fprintf(stderr, "\n不能夠打開所選擇適配器 %s 不支持WinCap\n", d->name);pcap_freealldevs(Devs);return -1;}printf("接下來開始監聽數據包%s...\n", d->description);pcap_freealldevs(Devs);pcap_loop(handle, 0, packHandleFunc, NULL);system("pause");return 0; }實驗截圖:
總結
以上是生活随笔為你收集整理的WinCap数据包显示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: format的几种用法
- 下一篇: 小游戏系列——猜数字游戏