pcap 文件格式

pcap 是 packet capture 的缩写,一般是 tcpdump 或者 wireshark 抓包后存盘的文件。

一般情况下,我们可以使用 wireshark 来直观的查看 pcap 的内容,并且借助 wireshark 强大的过滤器,从浩如烟海的数据包中过滤出我们需要的数据包,进行网络流量分析。

而如果需要自己写代码来读取 pcap 文件,就需要明确 pcap 的文件格式。 概括起来说,pcap 文件格式如下:

  1. 一个 24 byte 的文件头
  2. 一个 16 byte 的数据包头 + 与该数据包头对应数据包
  3. 下一个 16 byte 的数据包头 + 与该数据包头对应数据包
  4. 下一个 16 byte 的数据包头 + 与该数据包头对应数据包
  5. 一直重复直到文件尾 ……

画图直观表示的话如下,图片来自 http://blog.csdn.net/in7defore… pcap file format

数据包的长度是不确定的,由数据包头中的长度字段指定。

数据包中包含着数据帧,数据帧是数据链路层的传输单元

数据帧中可以包含着 TCP 包,(也可以包含其他包,例如 UDP 包),TCP 包是传输层的传输单元

TCP 包可以包含着 HTTP 报文,(也可以包含这其他报文,例如 FTP 报文),HTTP 报文是应用层的传输单元

画图直观表示的话如下,图片来自 http://www.ruanyifeng.com/blog… OSI 分层 网络报文包含关系 根据 http://wiki.wireshark.org/Deve… 所说,这个文件格式从 1998 年以来就没有变过了,所以我们也可以相信他将来一段时间内也不会变化

下面我们开始详细解释每一个部分的具体格式

首先来看整个文件最开始部分的文件头,文件头为定长的 24 byte,并且整个文件只有一个,其格式定义如下,http://wiki.wireshark.org/Deve…

  • This header starts the libpcap file and will be followed by the first packet header:
    typedef struct pcap_hdr_s {
            guint32 magic_number;   /* magic number */
            guint16 version_major;  /* major version number */
            guint16 version_minor;  /* minor version number */
            gint32  thiszone;       /* GMT to local correction */
            guint32 sigfigs;        /* accuracy of timestamps */
            guint32 snaplen;        /* max length of captured packets, in octets */
            guint32 network;        /* data link type */
    } pcap_hdr_t;
    • magic_number: used to detect the file format itself and the byte ordering. The writing application writes 0xa1b2c3d4 with it’s native byte ordering format into this field. The reading application will read either 0xa1b2c3d4 (identical) or 0xd4c3b2a1 (swapped). If the reading application reads the swapped 0xd4c3b2a1 value, it knows that all the following fields will have to be swapped too.
    • version_major, version_minor: the version number of this file format (current version is 2.4)
    • thiszone: the correction time in seconds between GMT (UTC) and the local timezone of the following packet header timestamps. Examples: If the timestamps are in GMT (UTC), thiszone is simply 0. If the timestamps are in Central European time (Amsterdam, Berlin, …) which is GMT + 1:00, thiszone must be -3600. In practice, time stamps are always in GMT, so thiszone is always 0.
    • sigfigs: in theory, the accuracy of time stamps in the capture; in practice, all tools set it to 0
    • snaplen: the “snapshot length” for the capture (typically 65535 or even more, but might be limited by the user), see: incl_len vs. orig_len below
    • network: link-layer header type, specifying the type of headers at the beginning of the packet (e.g. 1 for Ethernet, see tcpdump.org’s link-layer header types page for details); this can be various types such as 802.11, 802.11 with various radio information, PPP, Token Ring, FDDI, etc.

各个字段的中文解释如下,http://songwensheng.iteye.com/…

magic: 4字节 pcap文件标识 目前为“d4 c3 b2 a1” major: 2字节 主版本号 #define PCAP_VERSION_MAJOR 2 minor: 2字节 次版本号 #define PCAP_VERSION_MINOR 4 thiszone:4字节 时区修正 并未使用,目前全为0 sigfigs: 4字节 精确时间戳 并未使用,目前全为0 snaplen: 4字节 抓包最大长度 如果要抓全,设为0x0000ffff(65535), tcpdump -s 0就是设置这个参数,缺省为68字节 linktype:4字节 链路类型 一般都是1:ethernet

其中 linktype 的类型如下,http://www.360doc.com/content/…

LinkType:4B链路类型

    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

其中我们最为常见的类型就是1,以太网链路。

另外,实际上,pcap 中的报文,并不是严格意义上的,网络中的真实数据流,参看这里,http://www.360doc.com/content/…

在网络上实际传输的数据包在数据链路层上每一个Packet开始都会有7个用于同步的字节(10101010, 10101010, 10101010, 10101010, 10101010, 10101010, 10101010,)和一个用于标识该Packet开始的字节(10101011),最后还会有四个CRC校验字节;而PCAP文件中会把前8个字节和最后4个校验自己去掉,因为这些信息对于协议分析是没有用处的。

下面是数据包头的格式,先看定义,http://wiki.wireshark.org/Deve…

Record (Packet) Header

  • Each captured packet starts with (any byte alignment possible):
    typedef struct pcaprec_hdr_s {
            guint32 ts_sec;         /* timestamp seconds */
            guint32 ts_usec;        /* timestamp microseconds */
            guint32 incl_len;       /* number of octets of packet saved in file */
            guint32 orig_len;       /* actual length of packet */
    } pcaprec_hdr_t;
    • ts_sec: the date and time when this packet was captured. This value is in seconds since January 1, 1970 00:00:00 GMT; this is also known as a UN*X time_t. You can use the ANSI C time() function from time.h to get this value, but you might use a more optimized way to get this timestamp value. If this timestamp isn’t based on GMT (UTC), use thiszone from the global header for adjustments.
    • ts_usec: the microseconds when this packet was captured, as an offset to ts_sec. /!\ Beware: this value shouldn’t reach 1 second (1 000 000), in this case ts_sec must be increased instead!
    • incl_len: the number of bytes of packet data actually captured and saved in the file. This value should never become larger than orig_len or the snaplen value of the global header.
    • orig_len: the length of the packet as it appeared on the network when it was captured. If incl_len and orig_len differ, the actually saved packet size was limited by snaplen.

对应的中文解释如下,http://www.360doc.com/content/…

pcap packhead 格式

字段说明:
Timestamp:时间戳高位,精确到seconds      
Timestamp:时间戳低位,精确到microseconds
Caplen:当前数据区的长度,即抓取到的数据帧长度,由此可以得到下一个数据帧的位置。
Len:离线数据长度:网络中实际数据帧的长度,一般不大于caplen,多数情况下和Caplen数值相等。
Packet 数据:即 Packet(通常就是链路层的数据帧去掉前面用于同步和标识帧开始的8字节和最后用于CRC校验的4字节)具体内容,长度就是Caplen,这个长度的后面,就是当前PCAP文件中存放的下一个Packet数据包,也就是说:PCAP文件里面并没有规定捕获的Packet数据包之间有什么间隔字符串,我们需要靠第一个Packet包确定下一组数据在文件中的起始位置,向后以此类推。

关于那个 caplen 字段,有另外一种解释,http://blog.csdn.net/in7defore…

字段说明:
Timestamp:时间戳高位,精确到seconds(值是自从January 1, 1970 00:00:00 GMT以来的秒数来记)
Timestamp:时间戳低位,精确到microseconds (数据包被捕获时候的微秒(microseconds)数,是自ts-sec的偏移量)
Caplen:当前数据区的长度,即抓取到的数据帧长度,由此可以得到下一个数据帧的位置。
Len:离线数据长度网络中实际数据帧的长度,一般不大于caplen,多数情况下和Caplen数值相等。
(例如,实际上有一个包长度是1500 bytes(Len=1500),但是因为在Global Header的snaplen=1300有限制,所以只能抓取这个包的前1300个字节,这个时候,Caplen = 1300 )

先来一个小结,http://www.360doc.com/content/…

综述:pcap文件头:数据链路层14字节包头+20字节ip包头+20字节tcp包头或者udp;

目的MAC(6B)+源MAC(6B)+type(2B,0800,ip)+协议版本及头长度(0x45,1B)+区分服务(1B)

+总长度(2B)+唯一标示(2B)+标志与偏移量(2B)+TTL(1B)+协议(1B,TCP|UDP)+校验和(2B)

+源ip地址(4B)+目的ip地址(4B)+源端口(2B)+目的端口(2B)+序列号(4B)+确认号(4B)+头长度(1B)+ack标志(1b)+窗口大小(2B)+校验和(2B)+紧急数据偏移量(2B)

至于其中的 IP 报文和 TCP 报文格式,后续再补充,未完待续。

———————————————————————

2013-05-20 16:46:56 后续,ip 和 tcp 报文的分析已经完成,但写入的是非公开的文档

One thought on “pcap 文件格式

Leave a Reply

Your email address will not be published. Required fields are marked *