pcap包解析

在接触激光雷达的时候,不可避免的第一步就是看硬件说明书以及调试厂商发的样例数据。一般情况下,厂商在存储硬件的数据包的时候,都是通过存储pcap包实现的,所以如何读取pcap包,并从中解析出真正有用的数据就变得很重要,接下来我们一步步讲。

1.pcap包结构

一个Pcap文件包括“Pcap报头”,“数据区”两个部分,其中数据区又分成多个数据包,每个包有报头和数据两个部分,总体结构可见下图(注意所有字节都是连续的):
在这里插入图片描述

1.1 pcap报头

“Pcap报头”大小为24个字节,具体结构如下图:
在这里插入图片描述

各个字段含义:

Magic(4B): 标记文件开始,并用来识别文件和字节顺序。值可以为0xa1b2c3d4或者0xd4c3b2a1,如果是0xa1b2c3d4表示是大端模式,按照原来的顺序一个字节一个字节的读,如果是0xd4c3b2a1表示小端模式,下面的字节都要交换顺序。现在的电脑大部分是小端模式。

Major(2B): 当前文件的主要版本号,一般为0x0200

Minor(2B): 当前文件的次要版本号,一般为0x0400

ThisZone(4B): 当地的标准事件,如果用的是GMT则全零,一般全零

SigFigs(4B): 时间戳的精度,一般为全零

SnapLen(4B): 最大的存储长度,设置所抓获的数据包的最大长度,如果所有数据包都要抓获,将值设置为65535

LinkType(4B): 链路类型。解析数据包首先要判断它的LinkType,所以这个值很重要。一般的值为1,即以太网。

常用的LinkType(链路类型):

类型描述
0BSD loopback devices, except for later OpenBSD
1Ethernet, and Linux loopback devices
6802.5 Token Ring
7ARCnet
8SLIP
9PPP
10FDDI
100LLC/SNAP-encapsulated ATM
101“raw IP”, with no link
102BSD/OS SLIP
103BSD/OS PPP
104Cisco HDLC
105802.11
108later OpenBSD loopback devices (with the AF_value in network byte order)
113special Linux “cooked” capture
114LocalTalk

1.2 数据报头

数据报头可以有多个,每个数据报头16字节,后面都跟着真正的数据包。如下图所示:

以下是各个字段含义:

Timestamp(4B): 时间戳高位,精确到seconds,这是Unix时间戳。捕获数据包的时间一般是根据这个值
Timestamp(4B): 时间戳低位,能够精确到microseconds
Caplen(4B): 当前数据区的长度,即抓取到的数据帧长度,由此可以得到下一个数据帧的位置。
Len(4B): 离线数据长度,网路中实际数据帧的长度,一般不大于Caplen,多数情况下和Caplen值一样

这一步中,一定要根据Caplen决定接下来要读的数据长度,至于为什么要这么做,后面解释。

1.3 数据

这里就是抓取到的一个网络包,对于激光雷达一般为以太帧,当然,如果你是分析其他网络包,视具体情况而定。这里以以太帧为例,雷达发送的数据在以太帧的数据部分(ipv4报文)中的数据中,这里有点绕,让我们慢慢解析。

1.3.1Ethernet帧:

解析pcap包,获取到一个数据块时,这个数据块就是以太帧,一般结构如下:

1.目标地址(destination address,DA):6 字节

2.源地址(source address,SA):6 字节

3.类型(type)字段:用于辨别上层协议,2 字节(0x08 0x00 为IPv4)

4.数据(data):64 到1500 字节

1.3.2 ipv4报文

以太帧结构中的type决定数据部分存储什么样的报文,我实际使用时为ipv4,所以数据部分为ipv4报文,所以解析以太帧中的数据部分就是解析ipv4报文,ipv4报文头结构如下:

在这里插入图片描述
更加详细的解释可以参考

  • 这里有一点需要注意,选项部分有多长,得去查资料,我懒得找,就需要自己解析看看,一般雷达发送的数据存在ipv4报的数据部分,也就是除去报头后剩余的字节,会有一个开始标志,这个开始标志在说明书中一定有说明,这样就可以确定选项部分有多长,然后正确获取雷达发送的数据,然后就可以根据说明书进行一步步解析。

2.软件解析pcap

这里用的软件是Wireshark,一个蓝色鱼鳍图标,下载完成后可以直接打开pcap文件,辅助你解析pcap包数据块。下面是打开一个pcap文件后的结果(数据部分为防止泄密,打码了):
在这里插入图片描述

软件中已经解析了pcap文件中的每个数据块,最上方显示了所有数据块的大致信息,中间显示了某个数据块的详细信息,下方显示了某个数据块的原始数据。

  • 以太帧头

  • ipv4报头
    在这里插入图片描述

  • UDP报头

在这里插入图片描述

  • ipv4数据部分(雷达数据(黄色部分))

在这里插入图片描述

3.代码解析(linux)

#include <math.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
int main(int argc, char const *argv[]) {
  /* code */
  FILE *pcap_file;
  if ((pcap_file = fopen("path/to/pcap file", "rb")) == NULL) {
    cout << "cannot open file!\n";
  }
  char buffer[24];
  // read pcap head
  fread(buffer, 24, 1, pcap_file);
  //read 3000 ethernet package
  for (int p = 0; p < 3000; p++) {
    // read package head
    char package_head[16];
    fread(package_head, 16, 1, pcap_file);
    //read package data length
    int package_data_length =
        (int)(unsigned char)package_head[8] +
        ((int)(unsigned char)package_head[9]) * pow(16.0, 2.0) +
        ((int)(unsigned char)package_head[10]) * pow(16.0, 4.0) +
        ((int)(unsigned char)package_head[11]) * pow(16.0, 6.0);
    char package_data[package_data_length];
    fread(package_data, package_data_length, 1, pcap_file);
    //deal package to analysis point
    ReadEthernetPackage(package_data);
  }
  fclose(pcap_file);
  return 0;
}

4.问题

  1. 为什么要读package head中的长度,以此决定后面的数据长度?

    这是个坑,一定要读,因为有时候雷达厂商发给你的pcap包里面可能包含一些奇奇怪怪的东西,我被坑过。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐