pcap文件解析--pcap文件头与包文件头(一)
2014-03-18 17:01
239 查看
前段时间接到一个公司关于解析pacp文件的培训(我是被培训的),在完成了一部分的功能后决定把一些关于pcap文件的了解记录到博客中。
如上图所示在一个Pcap文件中存在1个Pcap文件头和多个数据包,其中每个数据包都有自己的头和包内容。
下面我们先看看PCAP文件头每个字段是什么意思:
magic为文件识别头,pcap固定为:0xA1B2C3D4。(4个字节)
magor version为主版本号(2个字节)
minor version为次要版本号(2个字节)
timezone为当地的标准时间(4个字节)
sigflags为时间戳的精度(4个字节)
snaplen为最大的存储长度(4个字节)
linktype为链路类型(4个字节)
常用类型:
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
数据包头则依次为:时间戳(秒)、时间戳(微妙)、抓包长度和实际长度,依次各占4个字节。
pcap_header.h
[cpp] view
plaincopy
#pragma pack( push, 1)
// 为了保证在windows和linux下都能正常编译,放弃使用INT64或者_int_64
typedef short _Int16;
typedef long _Int32;
typedef char Byte;
// Pcap文件头
struct __file_header
{
_Int32 iMagic;
_Int16 iMaVersion;
_Int16 iMiVersion;
_Int32 iTimezone;
_Int32 iSigFlags;
_Int32 iSnapLen;
_Int32 iLinkType;
};
// 数据包头
struct __pkthdr
{
_Int32 iTimeSecond;
_Int32 iTimeSS;
_Int32 iPLength;
_Int32 iLength;
};
#pragma pack( pop)
main.c
[cpp] view
plaincopy
#include<stdio.h>
#include"pcap_header.h"
#include<memory.h>
#include<stdlib.h>
#include<math.h>
int main()
{
struct __pkthdr data;
struct __file_header header;
FILE* pFile = fopen( "iupsc.pcap", "rb");
if( pFile == 0)
{
printf( "打开pcap文件失败");
return 0;
}
fseek( pFile, 0, SEEK_END);
long iFileLen = ftell( pFile);
fseek( pFile, 0, SEEK_SET);
Byte* pBuffer = (Byte*)malloc( iFileLen);
fread( (void*)pBuffer, 1, iFileLen, pFile);
fclose( pFile);
memcpy( (void*)&header, (void*)(pBuffer)
, sizeof(struct __file_header));
int iIndex = sizeof(struct __file_header);
int iNo = 1;
while(iIndex <= iFileLen)
{
memcpy( (void*)&data, (void*)(pBuffer + iIndex)
, sizeof(struct __pkthdr));
char strPath[51];
sprintf( strPath, "export/%d-%d.pcap", iNo++, (int)data.iTimeSecond);
strPath[50] = '\0';
FILE* pwFile = fopen( strPath, "wb");
fwrite((void*)&header, 1, sizeof(struct __file_header), pwFile);
fwrite( (void*)(pBuffer + iIndex), 1,
sizeof(struct __pkthdr) + data.iPLength, pwFile);
fclose( pwFile);
iIndex += sizeof(struct __pkthdr) + data.iPLength;
}
free( pBuffer);
printf( "成功导出%d个文件", iNo - 1);
return 1;
}
初识Pcap文件
在开始读取pcap文件之前,先让我们来看看Pcap文件的大概结构。如上图所示在一个Pcap文件中存在1个Pcap文件头和多个数据包,其中每个数据包都有自己的头和包内容。
下面我们先看看PCAP文件头每个字段是什么意思:
magic为文件识别头,pcap固定为:0xA1B2C3D4。(4个字节)
magor version为主版本号(2个字节)
minor version为次要版本号(2个字节)
timezone为当地的标准时间(4个字节)
sigflags为时间戳的精度(4个字节)
snaplen为最大的存储长度(4个字节)
linktype为链路类型(4个字节)
常用类型:
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
数据包头则依次为:时间戳(秒)、时间戳(微妙)、抓包长度和实际长度,依次各占4个字节。
读取各个数据包到单个pcap文件
c代码:pcap_header.h
[cpp] view
plaincopy
#pragma pack( push, 1)
// 为了保证在windows和linux下都能正常编译,放弃使用INT64或者_int_64
typedef short _Int16;
typedef long _Int32;
typedef char Byte;
// Pcap文件头
struct __file_header
{
_Int32 iMagic;
_Int16 iMaVersion;
_Int16 iMiVersion;
_Int32 iTimezone;
_Int32 iSigFlags;
_Int32 iSnapLen;
_Int32 iLinkType;
};
// 数据包头
struct __pkthdr
{
_Int32 iTimeSecond;
_Int32 iTimeSS;
_Int32 iPLength;
_Int32 iLength;
};
#pragma pack( pop)
main.c
[cpp] view
plaincopy
#include<stdio.h>
#include"pcap_header.h"
#include<memory.h>
#include<stdlib.h>
#include<math.h>
int main()
{
struct __pkthdr data;
struct __file_header header;
FILE* pFile = fopen( "iupsc.pcap", "rb");
if( pFile == 0)
{
printf( "打开pcap文件失败");
return 0;
}
fseek( pFile, 0, SEEK_END);
long iFileLen = ftell( pFile);
fseek( pFile, 0, SEEK_SET);
Byte* pBuffer = (Byte*)malloc( iFileLen);
fread( (void*)pBuffer, 1, iFileLen, pFile);
fclose( pFile);
memcpy( (void*)&header, (void*)(pBuffer)
, sizeof(struct __file_header));
int iIndex = sizeof(struct __file_header);
int iNo = 1;
while(iIndex <= iFileLen)
{
memcpy( (void*)&data, (void*)(pBuffer + iIndex)
, sizeof(struct __pkthdr));
char strPath[51];
sprintf( strPath, "export/%d-%d.pcap", iNo++, (int)data.iTimeSecond);
strPath[50] = '\0';
FILE* pwFile = fopen( strPath, "wb");
fwrite((void*)&header, 1, sizeof(struct __file_header), pwFile);
fwrite( (void*)(pBuffer + iIndex), 1,
sizeof(struct __pkthdr) + data.iPLength, pwFile);
fclose( pwFile);
iIndex += sizeof(struct __pkthdr) + data.iPLength;
}
free( pBuffer);
printf( "成功导出%d个文件", iNo - 1);
return 1;
}
相关文章推荐
- pcap文件解析--pcap文件头与包文件头(一)
- pcap文件解析--pcap文件头与包文件头(一)(初级)
- pcap文件解析--pcap文件头与包文件头(一)
- pcap文件格式及文件解析
- pcap文件解析(二)--初识IP包
- 用scapy解析出pcap文件的http报文
- C语言解析pcap文件得到HTTP信息实例
- pcap文件格式及文件解析
- libpcap--GTPv2协议的cap文件解析
- swf文件格式解析入门(文件头解析)
- mmap的使用及pcap文件解析示例
- C语言解析pcap文件得到HTTP信息实例
- pcap文件解析
- python解析pcap文件中的http数据包
- pcap文件格式及文件解析
- swf文件格式解析入门(文件头解析)
- pcap文件解析(二)--初识IP包(初级)
- C语言解析pcap文件得到HTTP信息实例(原创,附源码)
- pcap文件格式及文件解析
- Wireshark的Pcap文件格式分析及解析源码(转)