您的位置:首页 > 其它

pcap文件解析--pcap文件头与包文件头(一)

2014-03-18 17:01 239 查看
前段时间接到一个公司关于解析pacp文件的培训(我是被培训的),在完成了一部分的功能后决定把一些关于pcap文件的了解记录到博客中。

初识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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: