主題:pcap檔案格式及寫pcap檔案
Pcap檔案格式,這個網絡上資料比較多,參考即可。
一、pcap檔案格式(該部分引用網絡資料)
原文網址:http://www.cnblogs.com/kernel0815/p/3803304.html
第一部分:PCAP封包件格式
(一)、基本格式:
檔案頭 資料標頭資料報資料標頭資料報......
(二)、檔案頭:
檔案頭結構體,libpcap源碼中定義如下
struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone;
bpf_u_int32 sigfigs;
bpf_u_int32 snaplen;
bpf_u_int32 linktype;
};
說明:
1、辨別位:32位的,這個辨別位的值是16進制的 0xa1b2c3d4。
2、主版本号:16位, 預設值為0x2。
3、副版本号:16位,預設值為0x04。
4、區域時間:32位,實際上該值并未使用,是以可以将該位設定為0。
5、精确時間戳:32位,實際上該值并未使用,是以可以将該值設定為0。
6、資料包最大長度:32位,該值設定所抓獲的資料包的最大長度,如果所有資料包都要抓獲,将該值設定為65535;例如:想擷取資料包的前64位元組,可将該值設定為64。
7、鍊路層類型:32位, 資料包的鍊路層標頭決定了鍊路層的類型。
以下是資料值與鍊路層類型的對應表
0 BSD loopback devices, except for later OpenBSD
1 Ethernet, and Linux loopback devices 以太網類型,大多數的資料包為這種類型。
6 802.5 Token Ring
7 ARCnet
8 SLIP
9 PPP
10 FDDI
100 LLC/SNAP-encapsulated ATM
101 raw IP, with no link
102 BSD/OS SLIP
103 BSD/OS PPP
104 Cisco HDLC
105 802.11
108 later OpenBSD loopback devices (with the AF_value in network byte order)
113 special Linux cooked capture
114 LocalTalk
(三)、 packet資料標頭:
struct pcap_sf_pkthdr {
struct pcap_timeval ts;
bpf_u_int32 caplen;
bpf_u_int32 len;
};
struct pcap_timeval {
bpf_int32 tv_sec;
bpf_int32 tv_usec;
};
說明:
1、時間戳,包括:
秒計時:32位,一個UNIX格式的精确到秒時間值,用來記錄資料包抓獲的時間,記錄方式是記錄從格林尼治時間的1970年1月1日 00:00:00 到抓包時經過的秒數;
微秒計時:32位, 抓取資料包時的微秒值。
2、資料包長度:32位 ,辨別所抓獲的資料包儲存在pcap檔案中的實際長度,以位元組為機關。
3、資料包實際長度: 所抓獲的資料包的真實長度,如果檔案中儲存不是完整的資料包,那麼這個值可能要比前面的資料包長度的值大。
(四)、packet資料:
即Packet(通常就是鍊路層的資料幀)具體内容,長度就是Caplen,這個長度的後面,就是目前PCAP檔案中存放的下一個Packet資料包,也就是說:PCAP檔案裡面并沒有規定捕獲的Packet資料包之間有什麼間隔字元串,下一組資料在檔案中的起始位置。我們需要靠第一個Packet包确定。最後,Packet資料部分的格式其實就是标準的網路協定格式了可以任何網絡教材上找得到。
二、寫pcap檔案
官網上關于libpcap的介紹挺全面,可以參考,以下為寫pcap檔案的代碼,這裡隻列出需要調用的函數,函數參數原型參考官方文檔。
說明:表示省略的代碼。頭檔案為#include <pcap.h>,編譯時連結-lpcap
如果沒有安裝libpcap動态庫的話,centos下,鏡像源和網絡正常的情況下,安裝指令為:
yum install libpcap
yum install libpcap-devel
int test{
pcap_dumper_t *pdumper;
pcap_t *handler;
handler = pcap_open_dead(1, 65535);
pdumper = pcap_dump_open(handler, pcap_path);
if(handler){
free(handler);
handler = NULL;
}
struct pcap_pkthdr hdr;
hdr.ts.tv_sec = 0;
hdr.ts.tv_usec = 0;
DataUnit *p = ptr_head;
int len = 0;
int loop_count = 0;
char sessid[SESSLEN+1] = {0};
memcpy(sessid, p->sessid, strlen(p->sessid));
sessid[strlen(p->sessid)] = '\0';
int count_len = 0;
char *buf = NULL;
char end_flag[SESSLEN + 1];
loop_count = 0;
while(loop_count < SESSLEN){
end_flag[loop_count] = 'F';
loop_count++;
}
end_flag[SESSLEN] = '\0';
loop_count = 500;
// while((strcmp(sessid ,p->sessid) == 0) && (count_len++ < FILEPACKETS)){
while((count_len++ < FILEPACKETS)&&(loop_count--)){
if(strcmp(p->sessid, end_flag) == 0)
break;
len = (p+1)->offset - p->offset;
printf("packet len = %d\n", len);
buf = (char*)malloc(len+1);
if(NULL == buf)
goto err_exit_free;
memcpy(buf, ptr_read + p->offset, len);
hdr.caplen = len;
hdr.len = len;
pcap_dump((u_char*)pdumper, &hdr, buf);
free(buf);
buf = NULL;
p++;
}
pcap_dump_flush(pdumper);
pcap_dump_close(pdumper);
}