pcap的pcap_dump()保存的文件格式

时间:2024-04-28 00:05:47

pcap的pcap_dump()保存的文件格式 (2009-09-01 20:36:49)

标签:

杂谈

分类: 专业

首先是tcpdump文件格式

当你在Windows或者Linux环境下用tcpdump命令抓取数据包时,你将得到如下格式的tcpdump文件:

文件头| 数据包头 | 链路层数据 | 数据包头 | 链路层数据 | 数据包头 | 链路层数据 |......

1. 文件头:每一个文件都以一个24字节的文件头开头。前四个字节是tcpdump文件标志“A1 B2 C3 D4”或为“D4 C3 B2 A1”。

2. 数据包头 | 链路层数据:文件头之后,就是“数据包头 | 链路层数据”为一组的这样一组组数据。

3. 数据包头长度16个字节,它不是网路上真正传输的数据,它包含的信息主要是截获这个包的时间等信息。数据包头的第8-11和12-15字节(按编程习惯,第一个字节为0字节)表示后面链路层数据包的长度。8-11字节是其理论长度,12-15字节为其实际长度,如果存在截断情况,两者可能不同。如果在tcpdump命令中使用了 -s 0 参数,则8-11字节和12-15字节应该相等。

从数据包头结束,到长度指明的字节数为止,是实际在网络中传输的链路层数据包。然后,就是下一个数据包头。

4. 链路层数据

链路层数据包格式和传输的方式有关:局域网共享上网,则是RFC894以太网协议,少数情况下是RFC 1042和802.3协议;如果是Modem拨号上网,则是RFC 1055的SLIP协议;如果是ADSL,则是RFC 1548的PPP协议。RFC894/RFC 1042/RFC 1548这三种协议的格式都是:

包头 | IP数据包 |(包尾)

对于RFC894,包头长度为14字节; ------>局域网方式上网;

对于RFC1042,包头长度为22字节;

对于RFC1548,包头长度为5字节;------>ADSL方式上网;

跨过这些包头字节,就是IP数据包了。

5.IP数据包: IP数据包格式为: IP包头 | IP包数据

1)IP包头的长度:IP包头的长度由IP包的第0个字节决定,如果应用的是IPv4协议,则IP包头的第0个字节总是“45”(高四位‘4’表示IPv4协议;低四位为‘5’,则IP包头的长度为 5×4=20字节,头的长度是以四字节为单位的)。

2)IP包数据:跨过IP包头的20个字节,就是IP包数据部分了。

IP包数据部分的长度,由IP包头的第2-3个字节表示(第一个字节为第0字节)。

IP包数据部分,也就是UDP部分;

6.UDP包格式: UDP包头| UDP包数据

1)UDP包头:固定的8个字节。第4-5字节是UDP包的长度(含8字节包头);

2)UDP包数据: 此部分为网络传送的具体信息,加密、解密等都是处理该部分数据。在处理该部分数据之前,需要先层层剥离出UDP包原始数据。处理过之后,写入新的文件中时,注意新数据的长度,根据需要重写 数据包头表示长度的字节、IP包头中表示长度的字节以及UDP包头中表示长度的字节,同时要注意写入时的字节序(大端or小端);

pcap的pcap_dump()保存的文件格式

pcap_dump()所保存.cap文件格式,应该也是按照tcpdump格式存储的:

一上来是4字节的文件标示:D4 C3 B2 A1,或者说是一个整数0xA1B2C3D4按照主机序(高位在后低位在前)保存起来了。

接下来的4字节看起来像是版本号,但完全搞不清楚这个版本号是怎么排的,我的电脑商安装的是4.1Beta4版,这4个字节是:02 00 04 00。另外,Wireshark识别这一字段时认为前两字节是主版本号,我尝试将这4字节改为01 00 04 00,再打开文件时报错说main version 1 unsupported……。

接下来是8字节的00,没什么好说的。

再下去是4字节记录Winpcap抓包时所抓取的数据长度,也就是pcap_open()函数的第二个参数snaplen的值。例如snaplen=65535时,这4字节成为FF FF 00 00.

然后4字节记录网络类型,如十进制1表示以太网,6表示令牌环网,15表示帧中继硬件格式等等。一般在以太网环境下,这4个字节为01 00 00 00.

以上几个字段属于文件头部分,接着就是一个一个的数据包了。每个数据包前面还有相应的16字节标记信息,前8字节为时间戳;然后4字节是捕获到的数据长度,例如一个数据包实际长度为60字节,但由于pcap_open()函数的第二个参数snaplen的值设置为50,所以捕获到的长度为50,如果snaplen设置为65535,那么捕获到的长度应为实际数据包长60;再然后是该数据包的实际长度,用4字节表示;最后是数据包全文,从链路层数据开始记录。一个数据包完了之后是下一个数据包,直到所有数据包记录结束为止。实际上就是把抓包函数的两个参数struct pcap_pkthdr *header和const u_char *pkt_data写到了文件里。