<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
    主站蜘蛛池模板: 久久免费国产精品| 国产亚洲精品仙踪林在线播放| 中国一级毛片免费看视频| 国产aa免费视频| 国产尤物在线视精品在亚洲| 日本久久久免费高清| 亚洲中文字幕无码中文| 好大好深好猛好爽视频免费| 亚洲人成色777777精品| 在线免费观看一级毛片| 欧洲亚洲综合一区二区三区| 亚洲国产精品丝袜在线观看| 久久毛片免费看一区二区三区| 亚洲av永久无码精品秋霞电影影院| 日本黄色动图免费在线观看| 日韩精品一区二区亚洲AV观看| 久久久久久曰本AV免费免费| 亚洲国产电影在线观看| 美女黄网站人色视频免费国产 | 成年性午夜免费视频网站不卡 | 亚洲AV无码专区在线厂| 亚洲高清成人一区二区三区| 最近中文字幕免费大全| 久久精品国产亚洲AV麻豆网站| 在线观看成人免费视频不卡| 亚洲第一成年网站视频| 久久亚洲色一区二区三区| 无码人妻一区二区三区免费n鬼沢| 亚洲国产成人精品无码区在线网站| 午夜寂寞在线一级观看免费| 一本久久A久久免费精品不卡| 亚洲黑人嫩小videos| 欧洲美熟女乱又伦免费视频| 久久久久女教师免费一区| 亚洲视频一区二区在线观看| 国产精品免费看香蕉| 欧洲人免费视频网站在线| 亚洲欧美熟妇综合久久久久 | 亚洲日本一区二区一本一道| 小草在线看片免费人成视久网| 亚洲激情视频图片|