获取 pcap 捕获文件中的数据包数量?

Posted

技术标签:

【中文标题】获取 pcap 捕获文件中的数据包数量?【英文标题】:Getting the number of packets in a pcap capture file? 【发布时间】:2010-10-15 10:12:44 【问题描述】:

我需要一个程序来打印捕获文件中的数据包数量,该文件使用pcap format。这个数字在 pcap 标头中似乎不可用(可能是因为它是在捕获开始之前写入的),并且文件中似乎没有带有此信息的“页脚”。

所以,我相信唯一的算法是遍历所有数据包并将它们相加。它在 O(N) 中,并且对于大迹线来说,相当长。

我在这里发帖看看是否有人有更聪明的想法?

我用“C”标记是因为它是我目前使用的语言,但我相信这是一个与语言无关的问题。

【问题讨论】:

"pcap 标头中似乎没有这个数字(可能是因为它是在捕获开始之前写入的),并且文件中似乎没有包含此信息的“页脚”。是的,这就是它不在页眉中的原因(pcap 文件可以写入管道,因此完成后你不能回溯并重写页眉),不,没有页脚。 【参考方案1】:

pcaputils 的作者罗伯特·埃德蒙兹(Robert Edmonds)向我提到,在 Wireshark 包中已经有一个程序在做我想做的事情,capinfos。它显示有关 pcap 文件的各种指示,包括它包含的数据包数量。

阅读代码源,它似乎可以通过按顺序遍历整个文件来工作。

【讨论】:

这正是它的工作原理。在一般情况下(Wireshark 可以读取多种不同的捕获文件格式,包括 pcap 和 pcap-ng),这是它可以工作的唯一方式,因为大多数文件格式在开始时没有数据包计数。 要显示确切的数据包数量而不是人类可读的版本,请尝试以下命令:capinfos -Mc file.pcap | grep "数字" | tr -d " " |剪切 -d ":" -f 2【参考方案2】:

确定文件中有多少数据包的唯一方法是读取整个文件。实际上,文件头中没有数据包计数(因为该格式被设计为一次可写),实际上没有页脚。

【讨论】:

【参考方案3】:

如果您想要 pcap 中的 number 帧:

tshark -r test.cap | wc -l

使用 capinfos:

capinfos test.cap | grep "Number of packets"| tr -d " " | cut -d ":" -f 2

使用 tcpdump:

tcpdump -r test.cap 2>/dev/null| wc -l

所以基本上,使用 libpcap,这里是一个例子:

#include <stdio.h>
#include <pcap.h>
#include <stdlib.h>

int main(int argc, char **argv) 
 
  unsigned int packet_counter=0;
  struct pcap_pkthdr header; 
  const u_char *packet;

  if (argc < 2)  
    fprintf(stderr, "Usage: %s <pcap>\n", argv[0]); 
    exit(1); 
   

   pcap_t *handle; 
   char errbuf[PCAP_ERRBUF_SIZE];  
   handle = pcap_open_offline(argv[1], errbuf); 

   if (handle == NULL)  
     fprintf(stderr,"Couldn't open pcap file %s: %s\n", argv[1], errbuf); 
     return(2); 
    

   while (packet = pcap_next(handle,&header))  

      packet_counter++;

     
    pcap_close(handle);


  printf("%d\n", packet_counter);
  return 0;

注意:您需要安装 libpcap 头文件(在 Linux 上搜索 libpcap dev/devel 包)

然后用 gcc -o myprogram myprogram.c -lpcap 编译

【讨论】:

或者只运行 capinfos,它和 tshark 一样,是 Wireshark 发行版的一部分,它的工作量要少得多,而且会更快地产生答案。 如果情况是“你安装了 Wireshark,它不是一个太旧的版本,它没有 capinfos,并且你想快速计算一个文件中的数据包”,最好的方法是事情是使用capinfos。 我不确定我的回答有什么问题,但问题是 这也会产生一些数据包(只是数字) capinfos test.cap|grep "Number of packet"| tr -d""|剪切 -d ":" -f 2 参数 -M 到 capinfos 以覆盖人类可读的默认值【参考方案4】:

我知道的唯一方法是读取文件,逐帧捕获并增加“数据包计数器”。但是,有一个包含存储帧长度的小帧头,因此您可以向前搜索以该长度在文件中。请注意,它可能不会更快。

但是,如果您有兴趣做的不仅仅是简单地计算捕获的帧数,那么阅读数据并构建捕获的帧链并同时计数它们以供将来使用可能是有意义的。我的 Common Lisp 的 PCAP 库就是这样做的。它根据需要读取“下一帧”,将原始帧存储在双链表中,以便将来更轻松地进行“下一帧/前一帧”导航,根据需要从磁盘读取更多帧。但是,框架内容的解析由库用户自行决定,而不是通过简单地将框架八位字节读入数据结构来强制执行。

【讨论】:

在C语言中,不需要使用“包含存储帧长度的小帧头”,pcap_next()会帮你搞定。 我的图书馆可以从src.hexapodia.net/pcap.tar.gz下载。我怀疑使用 pcap_next() 会进行一些帧解析,这可能会使事情变得更慢,这是我将“读取数据包”与“解析数据包”分开的原因之一。 Nervertheless,直接访问跟踪,而不是依赖 pcap_next() 对我来说似乎很危险。我更喜欢使用官方 API。感谢代码,好久没看Lisp了。【参考方案5】:

您可以使用 tshark 和 -qz 打印 .pcap 文件的统计信息

例如,以 5 秒为间隔分析文件:

❯ tshark -r file1.pcap -qz io,stat,5,"COUNT(frame) frame"

=============================
| IO Statistics             |
|                           |
| Duration: 17. 29551 secs  |
| Interval:  5 secs         |
|                           |
| Col 1: COUNT(frame) frame |
|---------------------------|
|          |1      |        |
| Interval | COUNT |        |
|------------------|        |
|  0 <>  5 |    10 |        |
|  5 <> 10 |    10 |        |
| 10 <> 15 |    10 |        |
| 15 <> Dur|     6 |        |
=============================

同一个文件,现在使用一个 30 秒的间隔

❯ tshark -r file1.pcap -qz io,stat,30,"COUNT(frame) frame"

==================================
| IO Statistics                  |
|                                |
| Duration: 17.0 secs            |
| Interval: 17.0 secs            |
|                                |
| Col 1: COUNT(frame) frame      |
|--------------------------------|
|              |1      |         |
| Interval     | COUNT |         |
|----------------------|         |
|  0.0 <> 17.0 |    36 |         |
==================================

【讨论】:

以上是关于获取 pcap 捕获文件中的数据包数量?的主要内容,如果未能解决你的问题,请参考以下文章

Pcap 数据包捕获格式详解

Pcap 数据包捕获格式详解

Tshark - 将数据包信息从pcap导出到cvs

使用 pcap.net 在同一网络中捕获不同 PC 的网络数据包

使用 libpcap,有没有办法从离线 pcap 文件中确定捕获的数据包的文件偏移量?

Winpcap笔记3之打开适配器并捕获数据包