1. 程式人生 > >網路程式設計系列之五 libpcap庫(共24個函式的例項)

網路程式設計系列之五 libpcap庫(共24個函式的例項)

之前在windows下用過winpcap,但是libpcap終究與它還是有區別的。 已經決定從事Linux的方向了,下面就完整的學習下libpcap函式庫。

目的:熟悉庫中的所有函式, 對於其中所有的函式都用例項來驗證

理論知識可以看看下面的連結:

1)    http://www.cnblogs.com/sunev/archive/2012/06/23/2559389.html

2)    http://www.cnblogs.com/coder2012/archive/2013/04/13/3012390.html

由這兩篇文章我們可以知道,如果將網路分為四層的話,那我們的網絡卡驅動程式和網路分介面(network Tap,這個在第三篇文章中能夠清楚的瞭解)是在網路介面層, linux的核心空間是由網路層和傳輸層組成,它包含了過濾規則和核心緩衝;使用者空間則是應用層。

3) http://blog.chinaunix.net/uid-21768364-id-3244502.html

現在基本的理論知識已經掌握了,下面就是程式的編寫:

程式中涉及的函式較多,下面的連結對每個函式進行說明和解析。

上文所寫的每個函式在下面的程式中都有用到。涉及到的資料結構和遺漏的函式會在系列下一篇說明。

#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <arpa/inet.h>
#define CAP_LEN 1024

pcap_handler handle(u_char * user, const struct pcap_pkthdr * h, const u_char * p) ;


int main()
{
    char *pcap_error;  //用來返回錯誤資訊
    char  *device;   //用來存放裝置名
    char ebuf[PCAP_ERRBUF_SIZE];   //錯放錯誤資訊
    char *fname = "/home/pgm/libpcap/save.pcap";

    int pcap_net;

    int cap_len = CAP_LEN;   //捕獲資料長度
    int dev_flag = 1;  //是否處於混雜模式
    int dev_time = 1000;  //設定超時時間

    pcap_t *pd;    //存放資料包捕獲描述字

    struct bpf_program fcode;// 存放捕獲規則
    bpf_u_int32 netmaskp;//存放掩碼   需要先轉換為 in_addr格式的,然後再進行inet_ntoa()轉換
    bpf_u_int32 netp;  //存放網路號  需要先轉換為 in_addr格式的,然後再進行inet_ntoa()轉換
    char *netmask;    //存放轉換後的掩碼
    char *net;  //存放轉換後的網路號
    struct in_addr addr;   //作為轉換的過度

    int  pcap_link;  //用於返回資料鏈路層型別

    pcap_dumper_t *pd_t;  //開啟用於儲存捕獲資料包的檔案, 函式返回值
    pcap_t *pd_tp;  //開啟以前儲存資料包的檔案
    FILE *pcapfile;  //返回被開啟的檔名
    int pcapno;        //返回被開啟的檔案描述字

    struct pcap_stat stat;

    device = pcap_lookupdev(ebuf);
    if(NULL == device)
        printf("pcap_lookupdev error\n");
    printf("device is %s\n", device);

    pcap_net = pcap_lookupnet(device, &netp,&netmaskp,ebuf);
    if(-1 == (pcap_net))
        printf("pcap_net error\n");

    addr.s_addr = netp; //先賦值給addr
    net = inet_ntoa(addr);//將addr進行轉換,成點分十進位制
    printf("net is:%s\n",inet_ntoa(addr));

    addr.s_addr = netmaskp; //先賦值給addr
    netmask = inet_ntoa(addr);//將addr進行轉換,成點分十進位制
    printf("netmask is:%s\n",inet_ntoa(addr));


    //獲得捕獲描述字
    pd = pcap_open_live(device, cap_len,dev_flag,dev_time,ebuf);
    if(NULL == pd)
        printf("pcap_open_live error\n");

//返回鏈路層型別,每一種都有一個代號
    pcap_link = pcap_datalink(pd);
    printf("now the datalink is:%d\n",pcap_link);

    //返回實際抓取的字元
    int real_cap_len = pcap_snapshot(pd);
    printf("最長抓多少位元組:%d\n",real_cap_len);

    //開啟用於捕獲資料包的檔案
    if( NULL == (pd_t = pcap_dump_open(pd, fname) ) )
        printf("pcap_dump_open error\n");

    //為了驗證這個函式,可以故意在fname中設定一個非法路徑
    /*    1  第一個錯誤函式
    pcap_error = pcap_geterr(pd);
    printf("error information:%s\n",pcap_error);
    */

/*     2 第二個錯誤函式
    pcap_perror(pd, "capture error");
*/
/*3 第三個錯誤函式
    char *pcap_strerror(int error);  這個函式等同於strerror,我就不介紹了。
*/
    netmask = 0;
    //設定過濾規則
    if(pcap_compile(pd, &fcode, NULL,1, netmaskp) < 0)
        printf("pcap_compile error\n");

    //設定過濾器
    if(pcap_setfilter(pd, &fcode) < 0)
        printf("pcap_setfilter error\n");
    //資料包捕獲
    if(pcap_loop(pd, 10 ,handle, (u_char*)pd_t ) < 0)     //這裡可以使用pcap_dispatch,後者在讀取超時的時候也返回,這時的超時時間就是pcap_live_open設定的
        printf("pcap_loop error\n");

//將捕獲的資料包統計資訊計入stat結構體
    if( pcap_stats(pd, &stat) )
        printf("pcap_stat error\n");
    printf("recv:%d, drop:%d,not support:%d\n",stat.ps_recv,stat.ps_drop,stat.ps_ifdrop);

//重新整理緩衝區
    pcap_dump_flush(pd_t);

//開啟儲存的捕獲資料包的檔案,用於對dump檔案進行分析
    if( NULL == (pd_tp = pcap_open_offline(fname, ebuf) ) )
        printf("pcap_dumper_t error\n");
    pcapfile = pcap_file(pd_tp);   //獲得檔案控制代碼 FILE *
    pcapno = pcap_fileno(pd_tp);  //獲得檔案描述字

    //返回當前系統位元組序與被開啟檔案位元組序號是否不同
    printf("zijiexu:%d\n",pcap_is_swapped(pd_tp));

    //獲取被開啟檔案所使用的函式版本號
    printf("major version:%d\n",pcap_major_version(pd_tp));
    printf("minor version:%d\n",pcap_minor_version(pd_tp));

//關閉資源
    pcap_close(pd);
    pcap_dump_close(pd_t);

    return 0;
}


//捕獲的資料包內容由這個函式處理,這個回撥函式的格式必須是下面的形式
pcap_handler handle(u_char * user, const struct pcap_pkthdr * packet_header, const u_char * packet_content)
{
    pcap_dump(user, packet_header,packet_content);    //輸出資料到檔案,輸出過後的檔案就是pcap格式的,可以用wireshark開啟
    printf("I get one packet! \n");
}


相關推薦

網路程式設計系列 libpcap(24函式例項)

之前在windows下用過winpcap,但是libpcap終究與它還是有區別的。 已經決定從事Linux的方向了,下面就完整的學習下libpcap函式庫。 目的:熟悉庫中的所有函式, 對於其中所有的函式都用例項來驗證 理論知識可以看看下面的連結: 1)    http:

C#網路程式設計系列文章()Socket實現非同步UDP伺服器

原創性宣告 本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 轉載請註明出處 文章系列目錄 本文介紹 在.Net中,System.Net.Sockets 名稱

網路程式設計系列十一 radius客戶端(802.1x客戶端)

學習802.1x客戶端的開發必須要了解下下面的內容: 1)802.1x客戶端開發一般是因為準入專案,這個准入系統的大環境 2) 802.1x協議的工作過程  和 EAP協議所屬的層次,以及層次之間的關係 3) 802.1x協議的具體詳細的結構可以看這個連結 然後的開

Java併發程式設計系列:happens-before原則

前言 happens-before是JMM的核心,之所以設計happens-before,主要出於以下兩個方面的因素考慮的:1)程式設計師的角度,JMM記憶體模型需要易於理解、易於程式設計;2)編譯器和處理器的角度,編譯器和處理器希望記憶體模型對其束縛越少越好

網路程式設計系列十二 codeblocks匯入makefile工程

最近需要用codeblocks開發一個客戶端程式,需要用到一個開源專案, 在codeblocks上加入Makefile工程。 1)“File -> New -> Project”,選擇“Empty Project”並建立。 2)選中 Project,右鍵,選擇“

數據面試系列:mysql的存儲引擎

當前 查看 efault 表鎖 blog 如果 show 事務 測試 mysql的默認存儲引擎是innoDB,是唯一一個支持事務和支持外鍵的存儲引擎, 可以通過:show variables like ‘default_storage_engine‘;查看當前數據庫到默認引

Java網路程式設計入門(TCP程式設計——複用Socket連線

如何複用Socket連線? 在前面的示例中,客戶端中建立了一次連線,只發送一次資料就關閉了,這就相當於撥打電話時,電話打通了只對話一次就關閉了,其實更加常用的應該是撥通一次電話以後多次對話,這就是複用客戶端連線。 那 麼如何實現建立一次連線,進行多次資料交換呢?其實很簡單

Java併發程式設計系列 Executor框架

                     Java使用執行緒完成非同步任務是很普遍的事,而執行緒的建立與銷燬需要一定的開銷,如果每個任務都需要建立一個執行緒將會消耗大量的計算資源,JDK 5之後把工作單元和執行機制區分開了,工作單元包括Runnable和Callable,而執行機制則由Executor框架提供

敏捷開發 鬆結對程式設計 系列 L型程式碼結構(程式設計篇之一)

        public ActionResult LinkTeam2Product(int focusedDepartmentID = 0)        {            ViewBag.ItemTreeViewModel = new ItemTreeViewModel("團隊-產品對映",

.Neter玩轉Linux系列:crontab使用詳解和Linux的程序管理以及網路狀態監控

基礎篇 實戰篇 一、crontab使用詳解  概述:任務排程:是指系統在某個時間執行的特定的命令或程式。 任務排程分類:       (1)系統工作:有些重要的工作必須周而 復始地執行。       (2)個別使用者工作:個別使用者可能希望執 行某些程式。

C#網路程式設計系列文章(一)Socket實現非同步TCP伺服器

原創性宣告 文章系列目錄 程式碼下載地址 開篇 本人因為對於網路程式設計的喜愛,經常性的使用c#編寫各類伺服器(e.g TCP伺服器,UDP伺服器),但是基本上都是搞著玩,網上也有很多講c#網路程式設計的文章,當然我也參考了很多作者寫的文章。看了這篇

Python貓薦書系列:Python高效能程式設計

  稍微關心程式語言的使用趨勢的人都知道,最近幾年,國內最火的兩種語言非 Python 與 Go 莫屬,於是,隔三差五就會有人問:這兩種語言誰更厲害/好找工作/高工資…… 對於程式語言的爭論,就是猿界的生理週期,每個月都要鬧上一回。到了年末,各類榜單也是特別抓人眼球,鬧得更凶。 其實,它們各有

C#網路程式設計系列文章(八)UdpClient實現同步UDP伺服器

原創性宣告 本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 轉載請註明出處 文章系列目錄 本文介紹 UdpClient 類在同步阻塞模式中為傳送和接收無連線的 U

程式設計師網路安全系列):數字證書以及12306的證書問題

系列目錄: 前文回顧 假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去 如何保證隔壁老王不能看到情書內容?(保密性) 如何保證隔壁老王不修改情書的內容?(完整性) 如何保證隔壁老王不冒充明明?(身份認證) 如何保證明明不能否認情書是自己寫的?(來源的不可否認) 中間人攻擊 上面

C#網路程式設計系列文章(二)Socket實現同步TCP伺服器

原創性宣告 本文作者:小竹zz  本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 轉載請註明出處 文章系列目錄 本文介紹 在上一篇部落格中我說了,我將會介紹c#中使用Socke

C#網路程式設計系列文章(三)TcpListener實現非同步TCP伺服器

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; namespace NetFrame.Net.TC

boost在工作(35)網路服務端

在前面的例子裡,只是處理每個連線發來的訊息,然後再把訊息轉回自己的那裡,跟別的連線沒有什麼關聯,這種情況只會適應一種像HTTP的那樣,只關心自己的東西。但在網路伺服器裡,最多的是跟別人有關聯的服務。比如說聊天室,就是不斷地把所有進入這個聊天室的人的訊息向所有人廣播出去,也就是

神經網路系列 -- 線性二分類的方法與原理

系列部落格,原文在筆者所維護的github上:https://aka.ms/beginnerAI, 點選star加星不要吝嗇,星越多筆者越努力。 第6章 多入單出的單層神經網路 6.0 線性二分類 6.0.1 提出問題 我們經常看到中國象棋棋盤中,用楚河漢界分割開了兩個陣營的棋子。回憶歷史,公元前206年前後

提升HTML5的性能體驗系列 webview啟動速度優化及事件順序解析

執行時間 很快 runt 代碼 模式 本地 技術 apk loaded webview加載時有5個事件。觸發順序為loading、titleUpdate、rendering、rendered、loaded。webview開始載入頁面時觸發loading,載入過程中如果&am

R語言數據分析系列

r語 來看 tab barplot code 繪制 ber map lib R語言數據分析系列之五 —— by comaple.zhang 本節來討論一下R語言的基本圖形展示,先來看一張效果圖吧。 這是一張用R語言生成的,虛擬的wordcloud雲圖,詳細