C++ 读取 pcap文件.

http://blog.csdn.net/haolipengzhanshen/article/details/51854853

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
  • 1

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

1

  • 2

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();
}
  • 1

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

待时间充裕玩玩看看,分析出来个思路来.

原文地址:https://www.cnblogs.com/zhangzl/p/5997191.html