当前位置:文档之家› pcap文件格式

pcap文件格式

PCAP文件格式每个.pcap文件的文件头Pcap Header:24B每个.pcap文件中的数据包头 Packet Header:16B每个.pcap文件中的数据报 Packet Data:14B以太头+TCP/IP数据具体如下:1.pcap文件头部(pcap header)sturct pcap_file_header{DWORD magic;WORD version_major;WORD version_minor;DWORD thiszone;DWORD sigfigs;DWORD snaplen;DWORD linktype;}说明:1、标识位magic:32位的,这个标识位的值是16进制的 0xa1b2c3d4。

32-bit magic number , The magic number has the value hex a1b2c3d4.2、主版本号version_major:16位,默认值为0x2。

返回写入被打开文件所使用的pcap函数的主版本号。

16-bit major version number, The major version number should have the value 2.3、副版本号version_minor:16位,默认值为0x04。

16-bit minor version number, The minor version number should have the value 4.4、区域时间thiszone:32位,实际上该值并未使用,因此可以将该位设置为0。

32-bit time zone offset field that actually not used, so you can (and probably should) just make it 0;5、精确时间戳sigfigs:32位,实际上该值并未使用,因此可以将该值设置为0。

32-bit time stamp accuracy field that not actually used, so you can (and probably should) just make it 0;6、数据包最大长度snaplen:32位,该值设置所抓获的数据包的最大长度,如果所有数据包都要抓获,将该值设置为65535;例如:想获取数据包的前64字节,可将该值设置为64。

32-bit snapshot length" field; The snapshot length field should be the maximum number of bytes perpacket that will be captured. If the entire packet is captured, make it 65535; if you only capture, for example, the first 64 bytes of the packet, make it 64.7、链路层类型linktype:32位,数据包的链路层包头决定了链路层的类型。

32-bit link layer type field. The link-layer type depends on the type of link-layer header that the packets in the capture file have:以下是数据值与链路层类型的对应表0 BSD loopback devices, except for later OpenBSD1 Ethernet, and Linux loopback devices 以太网类型,大多数的数据包为这种类型。

6 802.5 Token Ring7 ARCnet8 SLIP9 PPP10 FDDI100 LLC/SNAP-encapsulated ATM101 raw IP, with no link102 BSD/OS SLIP103 BSD/OS PPP104 Cisco HDLC105 802.11108 later OpenBSD loopback devices (with the AF_value in network byte order)113 special Linux cooked capture114 LocalTalk文件头部后面就是一个一个的数据包头部与数据内容了,格式如下:2. 数据包头结构struct pcap_pkthdr{struct timeval ts; /* time stamp */bpf_u_int32 caplen; /* length of portion present */bpf_u_int32 len; /* length this packet (off wire) */};ts:时间戳cpalen:当前分组的长度len:数据包的长度struct timeval结构体在time.h中的定义为:struct timeval{__time_t tv_sec; /* Seconds. */__suseconds_t tv_usec; /* Microseconds. */};其中,tv_sec为Epoch到创建struct timeval时的秒数,tv_usec为微秒数,即秒后面的零头。

说明:(1) DWORD就是32bit的unsigned long。

(2) 时间戳,包括:秒计时:32位,一个UNIX格式的精确到秒时间值,用来记录数据包抓获的时间,记录方式是记录从格林尼治时间的1970年1月1日 00:00:00 到抓包时经过的秒数;毫秒计时:32位,抓取数据包时的毫秒值。

time stamp, consisting of: UNIX-format time-in-seconds when the packet was captured, i.e. the number of seconds since January 1,1970, 00:00:00 GMT (that GMT, *NOT* local time!);the number of microseconds since that second when the packet was captured;(3) 数据包长度:32位,标识所抓获的数据包保存在pcap文件中的实际长度,以字节为单位。

32-bit value giving the number of bytes of packet data that were captured;(4) 数据包实际长度:所抓获的数据包的真实长度,如果文件中保存不是完整的数据包,那么这个值可能要比前面的数据包长度的值大。

32-bit value giving the actual length of the packet, in bytes (which may be greater than the previous number, if you are not saving the entire packet).3. 数据包内容通常就是链路层的数据帧,长度就是Caplen,这个长度的后面,就是当前PCAP文件中存放的下一个Packet数据包,也就是说:PCAP文件里面并没有规定捕获的Packet数据包之间有什么间隔字符串,下一组数据在文件中的起始位置。

我们需要靠第一个Packet包确定。

最后,Packet数据部分的格式其实就是标准的网路协议格式了可以任何网络教材上找得到。

每个数据包的前14字节是以太头,后面才是ip首部等内容。

读取pcap文件有了pcap文件的格式说明之后,要读取pcap类型的文件就很简单了。

这里只是分离出pcap文件里面一个一个的数据包,而没有对每个数据包进行单独的解析。

打开一个pcap文件,解析后将其写入一个文本文件:fopen = open('f:\\test.pcap','rb')fwrite = open('f:\\result.txt','w')stringPacket = fopen.read()这样整个pcap文件的内容就已经存储在stringPacket里面了,可见该程序在处理大型的pcap文件时候并不适合。

首先找到该pcap文件的头部极其描述,并将其一个一个的写入txt:pcapHeader = {}pcapHeader['magic'] = stringPacket[0:4]pcapHeader['version_major'] = stringPacket[4:6]pcapHeader['version_minor'] = stringPacket[6:8]pcapHeader['thiszone'] = stringPacket[8:12]pcapHeader['sigfigs'] = stringPacket[12:16]pcapHeader['snaplen'] = stringPacket[16:20]pcapHeader['linktype'] = stringPacket[20:24]fwrite.write("the head of this pacpFile is:\n")for key in ['magic','version_major','version_minor','thiszone','sigfigs','snaplen','linktype']:fwrite.write(key + ":" + repr(pcapHeader[key]) + '\n')头部的各个字段,根据其位置,就可以一个一个的找出来了。

这里要说明一点的是,在写入文件的时候,如果用str()函数代替repr()函数,那么写入的全部是乱码。

这两个函数都是将参数转换为字符串类型,但是区别我还不知道,留待以后补充。

找出头部后,剩下的就是一个一个的数据包了。

这个时候,stringPacket已经指向第24个字节处了,令i=24,然后定义三个数据 pcap_pkthdr = {}存储每个数据包的头部, pcapData =''存储每个数据包的内容, pcapNum 记录是第几个数据包,初始化为1,接下来的代码如下:while i < len(stringPacket):pcap_pkthdr['GMTime'] = stringPacket[i:i+4]pcap_pkthdr['microTime'] = stringPacket[i+4:i+8]pcap_pkthdr['caplen'] = stringPacket[i+8:i+12]pcap_pkthdr['len'] = stringPacket[i+12:i+16]pcap_len = struct.unpack('I',pcap_pkthdr['len'])[0]print pcap_pkthdr['len']fwrite.write("the " + repr(pcapNum) + "th packet:\n")for key in ['GMTime','microTime','caplen','len']:fwrite.write(key + ":" + repr(pcap_pkthdr[key]) + '\n')fwrite.write("data: " + repr(stringPacket[i+16:i+16+int(pcap_len)]) + "\n")i = i + 16 + pcap_lenpcapNum = pcapNum + 1这样所有的数据包都被解析出来了。

相关主题