<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-17  評論-64  文章-79  trackbacks-1

    ??

    ?? ?? 經常看到論壇有人問起關于數據包的截獲、分析等問題,幸好本人也對此略有所知,也寫過很多的 sniffer ,所以就想寫一系列的文章來詳細深入的探討關于數據包的知識。

    我希望通過這一系列的文章,能使得關于數據包的知識得以普及,所以這系列的每一篇文章我都會有由淺入深的解釋、詳細的分析、以及編碼步驟,另外附上帶有詳細注釋的源碼 ( 為了照顧大多數朋友,我提供的都是 MFC 的源碼 )

    不過由于也是初學者,疏漏之處還望不吝指正。

    本文凝聚著筆者心血,如要轉載,請指明原作者及出處,謝謝! ^_^

    ?

    OK,. Let’s go !? Have fun ! q^_^p

    ?

    第二篇 ?? 手把手教你捕獲數據包

    目錄:

    一. 捕獲數據包的實現原理

    二. 捕獲數據包的編程實現:

    1.? ?raw socket 的實現方法

    2.? ?Winpcap 的實現方法

    a.????? 枚舉本機網卡的信息

    b.????? 打開相應網卡并設置為混雜模式

    c.?????? 截獲數據包并保存為文件

    ?

    作者:

    CSDN? VC/MFC 網絡編程版主 PiggyXP?

    ?

    一.捕獲數據包的實現原理: --------------------------------------------------------------------

    在通常情況下,網絡通信的套接字程序只能響應與自己硬件地址相匹配的或是以廣播形式發出的數據幀,對于其他形式的數據幀比如已到達網絡接口但卻不是發給此地址的數據幀,網絡接口在驗證投遞地址并非自身地址之后將不引起響應,也就是說應用程序無法收取與自己無關的的數據包。

    所以我們要想實現截獲流經網絡設備的所有數據包,就要采取一點特別的手段了:

    將網卡設置為混雜模式

    這樣一來,該主機的網卡就可以捕獲到所有流經其網卡的數據包和幀。

    但是要注意一點,這種截獲僅僅是數據包的一份拷貝,而不能對其進行截斷,要想截斷網絡流量就要采用一些更底層的辦法了,不在本文的討論范圍之內。

    ?

    二. 捕獲數據包的編程實現:

    1.raw socket 的實現方法 --------------------------------------------------------------------

    不同于我們常用的數據流套接字和數據報套接字,在創建了原始套接字后,需要用 WSAIoctl() 函數來設置一下,它的定義是這樣的

    int WSAIoctl(

    ? SOCKET s,

    ? DWORD dwIoControlCode,

    ? LPVOID lpvInBuffer,

    ? DWORD cbInBuffer,

    ? LPVOID lpvOutBuffer,

    ? DWORD cbOutBuffer,

    ? LPDWORD lpcbBytesReturned,

    ? LPWSAOVERLAPPED lpOverlapped,

    ? LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

    );

    雖然咋一看參數比較多,但是其實我們最關心的只是其中的第二項而已,我們需要做的就是把第二項設置為 SIO_RCVALL ,講了這么多其實要做的就是這么一行代碼,很簡單吧? ^_^

    ? 當然我們還可以指定是否親自處理 IP 頭,但是這并不是必須的。

    完整的代碼類似與如下這樣,加粗的代碼是與平常不同的需要注意的地方:

    ( 為了讓代碼一目了然,我把錯誤處理去掉了,下同 )

    ?

    #include “WinSock2.h”

    #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)

    ?

    SOCKET SnifferSocket

    ? WSADATA wsaData;

    ? iFlag=WSAStartup(MAKEWORD(2,2),&wsaData);???????? ? // 開啟 winsock.dll

    ?????????????????????????????????

    SnifferSocket=WSASocket(AF_INET, ????????????// 創建 raw? socket

    SOCK_RAW, IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);

    ?

    ? char FAR name[128];???? ???????????????????????????// 獲取本機 IP 地址

    gethostname(name, sizeof(name));

    ? struct hostent FAR * pHostent;

    ? pHostent = gethostbyname(name);

    ?

    ? SOCKADDR_IN sa;?????????????????????????? // 填充 SOCKADDR_IN 結構的內容

    ? sa.sin_family = AF_INET;

    ? sa.sin_port = htons(6000);????????? ?// 端口號可以隨便改,當然與當然系統不能沖突

    ? memcpy(&(sa.sin_addr),pHostent->h_addr,pHostent->h_length);

    ?

    bind(SnifferSocket,(LPSOCKADDR)&sa,sizeof(sa));????? ????? // 綁定

    ?

    ? // ioctl 來接收所有網絡數據 , 關鍵步驟

    ? DWORD dwBufferLen[10] ;

    ? DWORD dwBufferInLen = 1 ;

    ? DWORD dwBytesReturned = 0 ;

    ? WSAIoctl(SnifferSocket, IO_RCVALL,&dwBufferInLen, izeof(dwBufferInLen),

    ??????? &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );

    ?

    至此,實際就可以開始對網絡數據包進行嗅探了,而對于數據包的接收還是和普通的 socket 一樣,通過 recv() 函數來完成,因為這里涉及到不同的 socket 模型,接收方法差別很大,所以在此就不提供接收的代碼了。

    ?

    2.winpcap 的實現方法: -----------------------------------------------------------------------

    winpcap 驅動包,是我們玩轉數據包不可或缺的好東東, winpcap 的主要功能在于獨立于主機協議(如 TCP-IP) 而發送和接收原始數據報,主要為我們提供了四大功能:

    功能:
    ??? 1>
    捕獲原始數據報,包括在共享網絡上各主機發送 / 接收的以及相互之間交換的數據報;
    ??? 2>
    在數據報發往應用程序之前,按照自定義的規則將某些特殊的數據報過濾掉;
    ??? 3>
    在網絡上發送原始的數據報;
    ??? 4>
    收集網絡通信過程中的統計信息

    如果環境允許的話 ( 比如你做的不是木馬程序 ) ,我還是推薦大家用 winpcap 來截獲數據包,因為它的功能更強大,工作效率更高,唯一的缺點就是在運行用 winpcap 開發的程序以前,都要在主機上先安裝 winpcap driver

    而且一會我們就會發現它比 raw socket 功能強大的多,而且工作得更為底層,最明顯的理由就是 raw socket 捕獲的數據包是沒有以太頭的,此乃后話。

    至于怎么來安裝使用,請參考本系列的系列一《手把手教你玩轉 ARP 包中的》,里面有詳細的加載 winpcap 驅動的方法 ^_^

    廢話不多說了,讓我們轉入正題 , 具體用 winpcap 來截獲數據包需要做如下的一些工作:

    A . 枚舉本機網卡的信息 ( 主要是獲得網卡的名稱 )

    ?? 其中要用到 pcap_findalldevs 函數,它是這樣定義的

    ?? /*************************************************

    int pcap_findalldevs? (? pcap_if_t **??? alldevsp,?

    ? ??????????????????????? ??? ?char *??? errbuf

    ? ? ????????????????? ??? ???)?

    ?? ?? 功能:

    ??????????? ? 枚舉系統所有網絡設備的信息

    ???? 參數: ? alldevsp ? 是一個 pcap_if_t 結構體的指針,如果函數 pcap_findalldevs 函數執行成功,將獲得一個可用網卡的列表,而里面存儲的就是第一個元素的指針。

    ????????? ?? ?Errbuf ??? 存儲錯誤信息的字符串

    ???? 返回值: int ?? 如果返回 0 則執行成功,錯誤返回 -1

    ? ? *************************************************/

    ?? 我們利用這個函數來獲得網卡名字的完整代碼如下:

    ?

    ?????? pcap_if_t* alldevs;

    ?????? pcap_if_t* d;

    ?????? char errbuf[PCAP_ERRBUF_SIZE];

    ?????? pcap_findalldevs(&alldevs,errbuf);?????? // 獲得網絡設備指針

    ?????? for(d=alldevs;d;d=d->next)?????????????? // 枚舉網卡然后添加到 ComboBox

    ?????? {

    d->name;?????????????????????????? ?// d->name 就是我們需要的網卡名字字符串,按照你 // 自己的需要保存到你的相應變量中去

    ?????? }

    pcap_freealldevs(alldevs);?????????????? // 釋放 alldev 資源

    posted on 2007-02-16 15:51 飛鳥 閱讀(633) 評論(0)  編輯  收藏 所屬分類: VC
    主站蜘蛛池模板: 毛片免费观看的视频| 亚欧免费视频一区二区三区| 无码国模国产在线观看免费| 亚洲va成无码人在线观看| 亚洲一区二区在线视频| 亚洲综合色区中文字幕| 特色特黄a毛片高清免费观看| 成人黄页网站免费观看大全| 亚洲精品无码永久在线观看男男| 成人免费777777| 性色av极品无码专区亚洲| 中文字幕久精品免费视频| 亚洲Av综合色区无码专区桃色| 亚洲午夜理论片在线观看| 最近免费中文字幕视频高清在线看 | 亚洲成AV人片在线播放无码| 久久青青草原国产精品免费| 亚洲国产成人精品不卡青青草原| 久久免费观看国产99精品| 亚洲精品高清国产麻豆专区| 中文字幕乱码系列免费| 亚洲久本草在线中文字幕| 久久精品国产免费观看| 亚洲高清视频在线| 免费观看国产精品| 亚洲jjzzjjzz在线观看| 国产精品美女自在线观看免费| 一级特级aaaa毛片免费观看| 日本一区二区三区日本免费| 国产免费牲交视频免费播放| 五月天网站亚洲小说| 无限动漫网在线观看免费| 美女视频黄频a免费| 在线免费观看国产视频| 久久久WWW成人免费精品| 99人中文字幕亚洲区| 日韩免费观看的一级毛片| 两个人看的www免费视频中文| 亚洲国产精品专区| 一二三四视频在线观看中文版免费| 亚洲aⅴ无码专区在线观看春色 |