日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux下libpcap抓包分析

發布時間:2023/12/18 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux下libpcap抓包分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、首先下載libpcap包http://www.tcpdump.org/#latest-release

  然后安裝,安裝完成后進入安裝根目錄的tests文件夾,編譯運行findalldevstest.c(編譯時加上-lpcap),查看是否發現所有網絡設備。

二、下載wireshark觀察抓包軟件的各種功能

三、熟悉libpcap工作原理:

四、了解libpcap抓包基本流程:

五、編程實現

未完待續。。。?

?

PS:整理了一下libpcap常用的數據類型定義

  • libpcap的類型定義:

0)、typedef int bpf_int32

1)、typedef u_int bpf_u_int32

??? 32bit 的無類型整形;

2)、typedef pcap pcap_t

??? Descriptor of an open capture instance(一個打開的捕獲實例的描述符?)這個結構對用戶是不透明的。

3)、typedef pcap_dumper pcap_dumper_t

libpcap保存文件的描述符。

4)、typedef pcap_if pcap_if_t

網卡鏈表的一個元素;

5)、typedef pcap_addr pcap_addr_t

網卡地址的表示;

6)、typedef void (*pcap_handler)(u_char *args, const struct pcap_pkthdr *header, ? ?const u_char *packet);

??? 其中agrs是從pcap_dispatch()函數傳遞過來的第四個形參 ,一般我們自己的包捕捉程序不需要提供它,總是為NULL ;header指向
pcap_pkthdr結構,該結構位于真正的物理幀前面,用于消除不同鏈路層支持的差異 ;packet指向所捕獲報文的物理幀。

?

  • libpcap結構體

Libpcap庫函數所必須的數據結構定義主要包含在pcap.h和pcap-int.h兩個頭文件中

1)、pcap結構在pcap-int.h頭文件中被定義:
?編程時需要涉及到的成員有:int fd; 打開設備的描述符;u_char *buffer; 是指向所捕獲到數據的緩沖區指針
struct pcap
{
?? int fd; /* 文件描述字,實際就是 socket */

??? int selectable_fd; /* 在 socket 上,可以使用 select() 和 poll() 等 I/O 復用類型函數 */

??? int snapshot; /* 用戶期望的捕獲數據包最大長度 */

??? int linktype; /* 設備類型 */

??? int tzoff;???????? /* 時區位置,實際上沒有被使用 */

??? int offset;?????? /* 邊界對齊偏移量 */

??? int break_loop; /* 強制從讀數據包循環中跳出的標志 */

??? struct pcap_sf sf; /* 數據包保存到文件的相關配置數據結構 */

??? struct pcap_md md; /* 具體描述如下 */

???

??? int bufsize; /* 讀緩沖區的長度 */

??? u_char buffer; /* 讀緩沖區指針 */

??? u_char *bp;

??? int cc;

??? u_char *pkt;

??? /* 相關抽象操作的函數指針,最終指向特定操作系統的處理函數 */

??? int?? (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);

??? int?? (*setfilter_op)(pcap_t *, struct bpf_program *);

??? int?? (*set_datalink_op)(pcap_t *, int);

??? int?? (*getnonblock_op)(pcap_t *, char *);

??? int?? (*setnonblock_op)(pcap_t *, int, char *);

??? int?? (*stats_op)(pcap_t *, struct pcap_stat *);

??? void (*close_op)(pcap_t *);

??? /*如果 BPF 過濾代碼不能在內核中執行,則將其保存并在用戶空間執行 */

??? struct bpf_program fcode;

??? /* 函數調用出錯信息緩沖區 */

??? char errbuf[PCAP_ERRBUF_SIZE + 1];

???

??? /* 當前設備支持的、可更改的數據鏈路類型的個數 */

??? int dlt_count;

??? /* 可更改的數據鏈路類型號鏈表,在 linux 下沒有使用 */

??? int *dlt_list;

??? /* 數據包自定義頭部,對數據包捕獲時間、捕獲長度、真實長度進行描述 [pcap.h] */

??? struct pcap_pkthdr pcap_header;??

};

?

/* 包含了捕獲句柄的接口、狀態、過濾信息? [pcap-int.h] */

struct pcap_md {

/* 捕獲狀態結構? [pcap.h] */

struct pcap_stat stat;?

??? int use_bpf; /* 如果為1,則代表使用內核過濾*/

??? u_long??? TotPkts;

??? u_long??? TotAccepted; /* 被接收數據包數目 */

??? u_long??? TotDrops;?????? /* 被丟棄數據包數目 */

??? long TotMissed;????? /* 在過濾進行時被接口丟棄的數據包數目 */

??? long OrigMissed; /*在過濾進行前被接口丟棄的數據包數目*/

#ifdef linux

??? int?? sock_packet; /* 如果為 1,則代表使用 2.0 內核的 SOCK_PACKET 模式 */

??? int?? timeout;? /* pcap_open_live() 函數超時返回時間*/

??? int?? clear_promisc; /* 關閉時設置接口為非混雜模式 */

??? int?? cooked;????????? /* 使用 SOCK_DGRAM 類型 */

??? int?? lo_ifindex;????? /* 回路設備索引號 */

??? char *device;? /* 接口設備名稱 */

???

/* 以混雜模式打開 SOCK_PACKET 類型 socket 的 pcap_t 鏈表*/

struct pcap *next;??????

#endif

};

?

(2)bpf_program結構
?
該結構在pcap_compile()函數中被使用,在bpf.h頭文件中定義。

/* [pcap-bpf.h] */

struct bpf_program {

u_int bf_len; /* BPF 代碼中謂詞判斷指令的數目 */

struct bpf_insn *bf_insns; /* 第一個謂詞判斷指令 */

};

???

/* 謂詞判斷指令結構 */

struct bpf_insn {

u_short??? code;

u_char ?? jt;

u_char ?? jf;

bpf_int32 k;

};

?(3)

/usr/include/net/bpf.h

/*
* Structure prepended to each packet.
*/

內核過濾器每輸出一個包,將在輸出的數據前加了20字節的數據,這就是 struct bpf_hdr
struct bpf_hdr
{
??? struct timeval bh_tstamp;?? /* time stamp???????????????? */
??? bpf_u_int32??? bh_caplen;?? /* length of captured portion數據長度*/
??? bpf_u_int32??? bh_datalen;? /* original length of packet?實際包長度 */
??? u_short??????? bh_hdrlen;?? /* length of bpf header (this struct
?????????????????????????????????? plus alignment padding)??? */
};

(4)pcap_stat結構
?調用函數 pcap_stats() 可以返回一個該結構
struct pcap_stat {
??????? u_int ps_recv; /* number of packets received */
??????? u_int ps_drop; /* number of packets dropped */
??????? u_int ps_ifdrop; /* drops by interface XXX not yet supported */
};

?

5)、

struct pcap_addr:網卡地址描述
{
pcap_addr *next;如果非空,指向鏈表中一個元素的指針;空表示鏈表中的最后一個元素
sockaddr ?*addr; ?指向包含一個地址的sockaddr的結構的指針
sockaddr *netmask;如果非空,指向包含相對于addr指向的地址的一個網絡掩碼的結構
sockaddr *broadaddr;如果非空,指向包含相對于addr指向的地址的一個網絡掩碼的結構
sockaddr *dstaddr; 如果非空,指向一個相對于addr指向的源地址的目的地址,如果網絡不支持點對點通訊,則為空
};

6)、dump文件格式

首先是Dump文件頭

struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */

};

然后是每一個包的包頭和數據

pcap_pkthdr結構
?
/usr/include/pcap.h

/*
* Each packet in the dump file is prepended with this generic header.
* This gets around the problem of different headers for different
* packet interfaces.
*/
/* 自定義頭部在把數據包保存到文件中也被使用 */

struct pcap_pkthdr

{

?????????? struct timeval ts; /* 捕獲時間戳 */

?????????? bpf_u_int32 caplen; /* 捕獲到數據包的長度 */

?????????? bpf_u_int32 len; /* 數據包的真正長度 */

}

?

/* 單個數據包結構,包含數據包元信息和數據信息 */

struct singleton [pcap.c]

{

struct pcap_pkthdr hdr; /* libpcap 自定義數據包頭部 */

const u_char * pkt; /* 指向捕獲到的網絡數據 */

};

?

?

7)、pcap_if (libpcap 自定義的接口信息鏈表 [pcap.h])

?

struct pcap_if

{

struct pcap_if *next;

char *name; /* 接口設備名 */

char *description; /* 接口描述 */

??????????

/*接口的 IP 地址, 地址掩碼, 廣播地址,目的地址 */

struct pcap_addr addresses;

bpf_u_int32 flags;????? /* 接口的參數 */

};

轉載于:https://www.cnblogs.com/Seiyagoo/archive/2012/04/28/2475618.html

總結

以上是生活随笔為你收集整理的linux下libpcap抓包分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。