您的位置:首页 > 编程语言 > C语言/C++

C++ 读取 pcap文件

2016-07-07 22:52 337 查看
1.了解下pcap文件的结构



2.定义pcap文件头部结构体pcapFileHeader_t,

定义pcap数据包头部结构体pcapPkthdr_t

3.代码实现

base_type.h

#ifndef  BASE_TYPE_H
#define  BASE_TYPE_H

typedef  unsigned char uchar8_t;
typedef  char  char8_t;
typedef  unsigned short uint16_t;
typedef  short int16_t;
typedef  unsigned int uint32_t;
typedef  int int32_t;
typedef  unsigned long  ulong64_t;
typedef  long long64_t;

const uint32_t MAX_MTU = 1500;          //设置最大MTU为1500

const int ETHER_DATA_MIN_SIZE = 28; //IP头长度 + UDP 长度

const int HTTP_PORT_NUMBER = 80;    //默认HTTP端口号

#endif


pcap.h

#ifndef  PCAP_H
#define  PCAP_H

#include "base_type.h"
#include <queue>
#include <fstream>
#include <iostream>

using namespace std;

#define  PCAP_FILE_MAGIC_1   0Xd4
#define  PCAP_FILE_MAGIC_2   0Xc3
#define  PCAP_FILE_MAGIC_3   0Xb2
#define  PCAP_FILE_MAGIC_4   0Xa1

/*pcap file header*/
typedef struct pcapFileHeader
{
uchar8_t   magic[4];
uint16_t   version_major;
uint16_t   version_minor;
int32_t    thiszone;      /*时区修正*/
uint32_t   sigfigs;       /*精确时间戳*/
uint32_t   snaplen;       /*抓包最大长度*/
uint32_t   linktype;      /*链路类型*/
} pcapFileHeader_t;

/*pcap packet header*/
typedef struct pcapPkthdr
{
uint32_t   seconds;     /*秒数*/
uint32_t   u_seconds;   /*毫秒数*/
uint32_t   caplen;      /*数据包长度*/
uint32_t   len;         /*文件数据包长度*/
} pcapPkthdr_t;

class Pcap
{
public:
Pcap(const char* fileName);
~Pcap();
void  parsePcapFile(queue<string>&  rawQueue);

private:
ifstream  fileHandler;
const char*    fileName;
};

#endif


pcap类只有一个parsePcapFile接口,fileName记录pcap文件的名称

pcap.cpp

#include "pcap.h"

Pcap::Pcap(const char* fileName)
{
this->fileName = fileName;
}

void  Pcap::parsePcapFile(queue<string>&  rawQueue)
{
pcapFileHeader_t  pcapFileHeader = {0};
pcapPkthdr_t  packetHeader = {0};

fileHandler.open(fileName);
if (!fileHandler)
{
cout << "The file does not exits or file name is error" << endl;

return;
}

//读取pcap文件头部长度
fileHandler.read((char8_t*)&pcapFileHeader, sizeof(pcapFileHeader));
if (pcapFileHeader.magic[0] != PCAP_FILE_MAGIC_1 || pcapFileHeader.magic[1] != PCAP_FILE_MAGIC_2 ||
pcapFileHeader.magic[2] != PCAP_FILE_MAGIC_3 || pcapFileHeader.magic[3] != PCAP_FILE_MAGIC_4)
{
cout << "The file is not a pcap file" << endl;

return;
}

while (fileHandler.read((char8_t*)&packetHeader, sizeof(packetHeader)))
{
uint32_t len = packetHeader.caplen;
// if (packetHeader.caplen != packetHeader.len)
{
//cout << "It is a invalid packet" << endl;
//fileHandler.seekg(packetHeader.caplen, ios::cur);
//continue;
}

char8_t *buf = new char8_t[len];
if (NULL == buf)
{
return;
}
fileHandler.read(buf, len);
string temp(buf, len);
rawQueue.push(temp);
delete buf;
}

}

Pcap::~Pcap()
{
fileHandler.close();
}


其实linux平台下的libpcap库也能处理pcap的离线文件,比如tcpflow的C++版本的-r参数就是处理pcap离线文件的

待时间充裕玩玩看看,分析出来个思路来.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息