<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

    B. 打開相應網卡并設置為混雜模式:

    ?? 在此之前肯定要有一段讓用戶選擇網卡、并獲得用戶選擇的網卡的名字的代碼,既然上面已經可以獲得所有網卡的名字了,這段代碼就暫且略過了。

    ?? 我們主要是要用到 pcap_open_live 函數,不過這個函數 winpcap 的開發小組已經建議用 pcap_open 函數來代替,不過因為我的代碼里面用的就是 pcap_open_live ,所以也不便于修改了,不過 pcap_open_live 使用起來也是沒有任何問題的,下面是 pcap_open_live 的函數聲明:

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

    pcap_t* pcap_open_live? (? char *??? device,?

    ? ?????????????????????????? ?int??? snaplen,?

    ? int??? promisc,?

    ? int??? to_ms,?

    ? char *??? ebuf

    ?) ?

    ???? 功能:

    ?????????? 根據網卡名字打開網卡,并設置為混雜模式,然后返回其句柄

    ???? 參數:

    ?????????? Device? : 就是前前面我們獲得的網卡的名字;

    ?????????? Snaplen :? 我們從每個數據包里取得數據的長度,比如設置為 100 ,則每次我們只是獲得每個數據包 100 個長度的數據,沒有什么特殊需求的話就把它設置為 65535 最大值就可以了;

    ?????????? Promisc :這個參數就是設置是否把網卡設置為“混雜模式”,設置為 1 即可;

    ?????????? to_ms :?? 超時時間,毫秒,一般設置為 1000 即可。

    ???? 返回值:

    ?????????? pcap_t :? 類似于一個網卡“句柄”之類的,不過當然不是,這個參數是后面截獲數據要用到的。

    ******************************************************************************/

    雖然看起來比較復雜,不過用起來還是非常簡單的,其實 1 行就 OK 了:

    ?? ? pcap_t* adhandle;

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

    // 打開網卡,并且設置為混雜模式

    // pCardName 是前面傳來的網卡名字參數

    adhandle = pcap_open_live(pCardName,65535,1,1000,errbuf);

    ?

    C. 截獲數據包并保存為文件: ------------------------------------------------------

    ???? 當然,不把數據包保存為文件也可以,不過如果不保存的話,只能在截獲到數據包的那一瞬間進行分析,轉眼就沒了 ^_^

    所以,為了便于日后分析,所以高手以及我個人經常是把數據包保存下來的慢慢分析的。

    但是注意網絡流量,在流量非常大的時候注意硬盤空間呵呵,常常幾秒中就有好幾兆是很正常的事情。

    下面首先來詳細講解一下,這個步驟中需要用到的 winpcap 函數:

    /**************************************************************

    pcap_dumper_t* pcap_dump_open? (? pcap_t *??? p,?

    ? ??????????????????????????????????? ?const char *??? fname

    ?)

    功能:

    ????? 建立或者打開存儲數據包內容的文件 , 并返回其句柄

    參數:

    ????? ?pcap_t *??? p???? :前面打開的網卡句柄;

    ????? const char * fname :要保存的文件名字 ???

    返回值:

    ?????? pcap_dumper_t* 保存文件的描述句柄,具體細節我們不用關心

    ***************************************************************/

    /***************************************************************

    int pcap_next_ex? ????????(? pcap_t *??? p,?

    ? ??????????????????????????? ?struct pcap_pkthdr **??? pkt_header,?

    ? u_char **??? pkt_data

    ?) ?

    功能:

    ????? 從網卡或者數據包文件中讀取數據內容

    參數:

    ????? pcap_t *??? p:??? 網卡句柄

    ????? struct pcap_pkthdr ** pkt_header: 并非是數據包的指針,只是與數據包捕獲驅動有關的一個 Header

    ????? u_char ** pkt_data :指向數據包內容的指針 ,包括了協議頭 ??

    返回值:

    ????? ??? ?1 : 如果成功讀取數據包

    ????????? 0 pcap_open_live() 設定的超時時間之內沒有讀取到內容

    ????????? -1: 出現錯誤

    ????????? -2: 讀文件時讀到了末尾

    ***************************************************************/

    /***************************************************************

    void pcap_dump? (? u_char *??? user,?

    ? ?????????????????????const struct pcap_pkthdr *??? h,?

    ? const u_char *??? sp

    ?) ??

    功能:

    ????? 將數據包內容依次寫入 pcap_dump_open ()指定的文件中

    參數:

    ????? u_char * user?? :? 網卡句柄

    ????? const struct pcap_pkthdr * h: 并非是數據包的指針,只是與數據包捕獲驅動有關的一個 Header

    ??? ? ?const u_char * sp 數據包內容指針 ???

    返回值:

    ????????? Void

    ****************************************************************/

    ? 下面給出一段完整的捕獲數據包的代碼,是在線程中寫的,為了程序清晰,我去掉了錯誤處理代碼以及線程退出的代碼,完整代碼可下載文后的示例源碼,老規矩,重要的步驟用粗體字標出。

    我們實際在捕獲數據包的時候也最好是把代碼放到另外的線程中。

    /*********************************************************

    *?? 進程 :

    *?????????????????? 這個是程序的核心部分,完成數據包的截獲

    *???? 參數 :

    *?????????????????? pParam: 用戶選擇的用來捕獲數據的網卡的名字

    *********************************************************/

    UINT CaptureThread(LPVOID pParam)

    {

    ?????? const char* pCardName=(char*)pParam;? ????????// 轉換參數,獲得網卡名字 ???????????????????????

    ?

    ?????? pcap_t* adhandle;

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

    ?????? // 打開網卡,并且設置為混雜模式

    ? adhandle=pcap_open_live(pCardName,65535,1,1000,errbuf) ? ??? {

    ?

    ?????? pcap_dumper_t* dumpfile;

    // 建立存儲截獲數據包的文件

    ?????? dumpfile=pcap_dump_open(adhandle, "Packet.dat"); ???

    ?

    ?????? int re;

    ?????? pcap_pkthdr* header;????? // Header

    ?????? u_char* pkt_data;???????? // 數據包內容指針

    // 從網卡或者文件中不停讀取數據包信息

    ?????? while((re=pcap_next_ex(adhandle,&header,(const u_char**)&pkt_data))>=0)

    ? ??? {

    ??? ?????? // 將捕獲的數據包存入文件

    ????????????? pcap_dump((unsignedchar*)dumpfile,header,pkt_data); ?????

    ?????? }

    ?????? return 0;

    } ??

    將個線程加入到程序里面啟動以后。。。等等,如何來啟動這個線程就不用我說了吧,類似這樣的代碼就可以

    ::AfxBeginThread(CaptureThread,chNIC);? ???// chNIC 是網卡的名字 ,char* 類型

    啟動線程一段時間以后 ( 幾秒中就有效果了 ) ,可以看到數據包已經被成功的截獲下來,并存儲到程序目錄下的 Packet.dat 文件中。

    =====================================================

    至此,數據包的截獲方法就講完了,大家看了這篇文章,其實你就一定也明白了,無論是 raw socket 的方法還是 winpcap 的方法,其實都很簡單的,真的沒有什么東西,只是會讓不明白原理的人看起來很神秘而已, isn’t it?

    呵呵,不過也不要高興的太早,這個保存下來的數據包文件,你可以試著用 UltraEdit 打開這個文件看看,是不是大部分都是亂碼?基本上沒有什么可讀性,這是因為:

    此時捕獲到的數據包并不僅僅是單純的數據信息,而是包含有 IP 頭、 TCP 頭等信息頭的最原始的數據信息,這些信息保留了它在網絡傳輸時的原貌。通過對這些在低層傳輸的原始信息的分析可以得到有關網絡的一些信息。由于這些數據經過了網絡層和傳輸層的打包,因此需要根據其附加的幀頭對數據包進行分析。

    呵呵,所以我們要走的路還很長,這只是剛剛入門而已 ^_^

    posted on 2007-02-16 15:53 飛鳥 閱讀(552) 評論(0)  編輯  收藏 所屬分類: VC
    主站蜘蛛池模板: 麻豆最新国产剧情AV原创免费 | 亚洲一级黄色大片| 永久免费av无码网站yy| 全免费a级毛片免费看不卡| 国产一级淫片免费播放电影| 亚洲国产成人私人影院| 三上悠亚电影全集免费| 亚洲精品第一国产综合精品99| 亚洲精品美女久久久久9999| 亚洲理论精品午夜电影| 人人玩人人添人人澡免费| 亚洲中文字幕无码久久2017| 亚洲福利在线视频| 69pao强力打造免费高清| 亚洲视频在线免费观看| 久久青草免费91线频观看站街| 全亚洲最新黄色特级网站| 亚洲中文字幕无码中文字| 成人影片麻豆国产影片免费观看 | 男女超爽刺激视频免费播放 | yellow视频免费在线观看| 热99re久久精品精品免费| 亚洲成a人片在线观看精品| 一个人看的免费视频www在线高清动漫| 亚洲熟妇无码八AV在线播放| 亚洲午夜成人精品电影在线观看| 亚洲色图黄色小说| 老司机午夜在线视频免费观| 日本免费一区尤物| 亚洲成在人线aⅴ免费毛片| 国产麻豆剧传媒精品国产免费| 亚洲中文字幕久久精品蜜桃 | 中文字幕无码精品亚洲资源网久久 | 免费a级毛片无码a∨免费软件| 亚洲一级黄色视频| 免费观看亚洲人成网站| 国产乱子影视频上线免费观看| 亚洲精品乱码久久久久久蜜桃图片| 成人a视频片在线观看免费| 亚洲精品中文字幕麻豆| 嫩草视频在线免费观看|