pcap详解

 一、pcap文件格式

一共三部分:

①Global Header:文件头(共24bytes),它定义了本文件的读取规则、最大储存长度限制等内容。

pcap详解_第1张图片

  • Magic:4Byte:标记文件开始,并用来识别文件自己和字节顺序。0xa1b2c3d4用来表示按照原来的顺序读取,0xd4c3b2a1表示下面的字节都要交换顺序读取。考虑到计算机内存的存储结构,一般会采用0xd4c3b2a1,即所有字节都需要交换顺序读取。
    • Major:2Byte: 当前文件主要的版本号,一般为 0x0200【实际上因为需要交换读取顺序,所以计算机看到的应该是 0x0002】
    • Minor:2Byte: 当前文件次要的版本号,一般为 0x0400【计算机看到的应该是 0x0004】
    • ThisZone:4Byte:当地的标准时间,如果用的是GMT则全零,一般都直接写 0000 0000
    • SigFigs:4Byte:时间戳的精度,设置为 全零 即可
    • SnapLen:4Byte:最大的存储长度,如果想把整个包抓下来,设置为 ffff 0000,但一般来说 ff7f 0000就足够了【计算机看到的应该是 0000 ff7f 】
    • LinkType:4Byte:链路类型,常用类型有以下几种,其他的,需要用的时候再查就行了。
      • 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
  • Packet Header(共 16 Byte) Packet Header可以有多个,每个Packet Header后面会跟着一串Packet Data,Packet Header定义了Packet Data的长度、时间戳等信息。

pcap详解_第2张图片

 小端数据存在内存的小端,表示该数据为小端存放。

②Packet Header:可以有多个,每个Packet Header后面会跟着一串Packet Data,Packet Header定义了Packet Data的长度、时间戳等信息。

pcap详解_第3张图片

报文长度,有可能包有2k,但实际只抓到了一半,即1k,len=2k,caplen=1k。

③Packet Data:...

文件结构图例:

pcap详解_第4张图片

二、pcap文件解析API

1.初始化

char errbuf[PCAP_ERRBUF_SIZE];
函数名称:pcap_t *pcap_open_offline(char *fname, char *ebuf) 
函数功能:打开以前保存捕获数据包的文件,用于读取。 
参数说明:fname参数指定打开的文件名,ebuf表示错误信息的输出。
返回值:文件句柄。函数出错返回NULL,并将错误返回给ebuf。

2.业务处理

我们业务是从pcap文件里边去解析每一个报文
每一个报文包含一个packet header + packet data

需要一个循环来读取每一个报文


       typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h,
                                   const u_char *bytes);

       int pcap_loop(pcap_t *p, int cnt,
               pcap_handler callback, u_char *user);

       这是一个循环的函数,用来解析pcap文件中的每个报文
       p : 句柄 ,pcap_open拿到的
       cnt : 遍历多少个报文,如果值为0或者-1 ,遍历所有报文
       callback : 回调函数
                具体回调逻辑可以大概认为如下:

        while(文件还没有到达最后)
        {
              遍历一个packet header + packet data;
              callback(user自定义参数,&packetHeader,&packetData);
        }

        user: 自定义回调参数,就是每次调用我们的回调函数的时候会传进来

        返回值:
             成功返回0,出错失败返回-1


   

3 垃圾回收

    void pcap_close(pcap_t *p);
    p就是pcap_open得到的句柄

报文数量实例:

#include 
#include 

void usage(const char *argv0){
    fprintf(stderr, "usage: %s \n", argv0); // stderr会输出到屏幕
}

void pcap_callback(u_char *user, const struct pcap_pkthdr* h, const u_char *bytes){
    static int count = 0;
    ++count;
    printf("count:%d\n", count);
}

int main(int argc, char** argv){
    if (argc != 2){
        usage(argv[0]);
        return -1;
    }

    char errbuf[PCAP_ERRBUF_SIZE]={0};
    pcap_t *handle = pcap_open_offline(argv[1], errbuf);
    if(!handle){
        fprintf(stderr, "Error in pcap_open_offline: %s\n", errbuf);
        return -1;
    }

    pcap_loop(handle, 0, pcap_callback, NULL);

    pcap_close(handle);
}

你可能感兴趣的:(linux,C++基础,linux,c++)