cap文件格式解析
简介
cap包为通过抓包软件保存下来的数据包文件,不同的抓包软件保存下来的cap包格式也有很大差异,从最开始的4个字节便可以看出,如下列出不同抓包软件的cap包文件前4字节的差异
#define CAP_SNIFFER_WINDOWS_200X "\x58\x43\x50\x00" //sniffer抓包的cap文件 #define PCAP_WIRESHARK_TCPDUMP "\xd4\xc3\xb2\xa1 //wireshark抓包的pcap文件
以下以sniffer抓包的cap文件为示例,但也会介绍下其他cap文件的基本格式。
如下是sniffer cap文件头4个字节:
如下为其他cap文件头4个字节:
cap文件格式
cap文件开始有128字节的文件头部分,接下来是抓获到的数据包部分,包括40字节的数据头和数据内容部分,具体的数据内容的长度需要根据数据头部分确定。cap文件大概结构如下:
在此说明下,除了sniffer抓的文件,其他cap文件的格式区别如下,cap文件开始是24字节的文件头部分,接下来同样是数据包部分,包括16字节的数据头和数据内容部分,具体的数据内容的长度同样需要数据头部分确定。
以上结构中数据内容部分包括从数据链路控制层头开始,然后IP报头,传输层报头,最后到传输层以及后续的应用层数据。
数据头格式
sniffer的128字节或其他类型cap文件的前16字节的文件头部分在此只是取出前4个字节作为区分cap文件类型,其他数据没有用到。所以现在直接开始介绍数据头部分。sniffer的数据头部分为40字节,具体的结构类型如下:
其他类型cap文件的数据头部分格式如下,长度为16字节:
struct tcpdump_record_head { unsigned int time_seconds; //精确到秒的时间戳 unsigned int time_microsecondes; //精确到毫秒的时间戳 unsigned int len; //数包长度:标识所抓获的数据包保存在cap文件中的实际长度,以字节为单位。 unsigned int len_copy; //数据包实际长度:所抓获的数据包真实的长度,如果文件中保存不是完整的数据包,那么这个值可能要比前面的数据包长度的值大 };
数据内容解析
根据以上读取出头部信息中的数据长度,截取相应长度的数据内容进行解析,以下根据协议层数只解析每层协议头部的个别字段,通过此方式对数据内容进行逐层解析。
1、首先解析数据链路层协议
对数据内容跳转12个字节,过滤MAC信息,获取2字节的协议类型字段,此字段标志着数据链路层的下一层是什么协议,对获取出的2字节数据需要进行网络字节序到主机字节序的转换,然后与如下数据进行比较确定下层协议类型:
0x86DD /*ipv6*/ 0x0800 /* ipv4 */ 0x8847 /* MPLS unicast */ 0x8848 /* MPLS multicast */ 0x0806 /* arp */ 0x8035 /* rarp */ 0x8863 /* PPPoE protocol */
2、网络层
通过以上方式获取下层协议的类型后,下边我们以ipv4作为示例,假设数据内容的网络层是IPV4,ipv4网络层的数据内容第1个字节就包含了ip协议的版本号和ip层的头长度,具体内容如下:
上图中的45,4表示为IPV4,5*4(ip头部长度计算方式需要乘以4)表示ip头部长度,因为这次只获取出1字节内容,所以没必要对数据进行字节序转换。
下边是IP的数据包格式:
各字段的含义如下:
3、传输层
通过以上方式知道了网络层头部长度,可以直接跳过网络层头部部分,下边开始解析传输层。传输层分为TCP和UDP,下边以TCP作为示例,如下是TCP报文格式:
根据以上TCP报文格式可知如果想获取TCP头部长度,需要跳过12个字节,获取4位首部长度,为了方便获取,我们会直接获取两个字节(16位)数据,并对获取的数据进行字节序转换,然后获取4位首部长度。如下为实现的代码示例:
short tcpHeaderLenAndFlag = 0; int tcpHeaderLen = ((ntohs(tcpHeaderLenAndFlag)&0xF000)>>12) * 4; //TCP头部的长度同样需要乘以4
4、应用层
通过上诉方式可以获取TCP的首部长度,直接跳过TCP层来到应用层,因为没有对TCP层进行详细解析,目前无法获取应用层协议的具体协议信息。
通过以上方式解析完数据头和数据内容后,按照cap文件的格式,下边又会是数据头和数据内容,直到把cap文件全部解析完。
总结
本次简单介绍了cap文件的格式,以及协议的基本解析,因为会涉及到非常多的协议,在此不对数据包的具体内容进行解析。