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

17
我需要一个程序,它可以打印使用pcap格式的捕获文件中数据包的数量。这个数字似乎不在pcap头中可用(可能是因为它在捕获开始之前写入),并且文件中似乎没有“页脚”包含这些信息。
所以,我认为唯一的算法就是循环遍历所有数据包并将它们求和。时间复杂度为O(N),对于大型跟踪文件,耗时相当长。
我在这里发帖是想看看是否有更聪明的方法?
我标记了“C”作为我目前使用的语言,但我认为这是一个与语言无关的问题。

这个数字似乎在pcap头中不可用(可能是因为它是在捕获开始之前写入的),并且文件中似乎没有“页脚”包含此信息。是的,这就是为什么它不在头部中(pcap文件可以写入管道,因此完成后无法寻回并重写头部),而且没有页脚。 - user862787
5个回答

20

pcaputils的作者Robert Edmonds告诉我,Wireshark软件包中已经有一个capinfos程序可以实现我的要求。它会显示关于pcap文件的各种指示,包括其中所包含的数据包数量。

通过阅读源代码,我发现它是通过逐个遍历文件来完成操作的。


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

8
如果您想获取pcap文件中的帧数:

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进行编译


2
或者只需运行capinfos,它与tshark一样是Wireshark发行版的一部分,工作量较少,会更快地产生答案。 - user862787
如果情况是“您已安装Wireshark,它不是太旧的版本,没有capinfos,并且您想快速计算文件中的数据包数量”,那么最好的方法是使用capinfos。 - user862787
这也会产生许多数据包(只有数量) capinfos test.cap | grep "Number of packets" | tr -d " " | cut -d ":" -f 2 - UnX
我不确定我的答案有什么问题。你原来的答案的问题在于它过于复杂了。这就像是绕着街区走去隔壁房子一样。 - user862787
1
使用参数-M覆盖capinfos的默认人类可读格式。 - schuess
显示剩余3条评论

5

只有读取整个文件才能确定其中有多少数据包。事实上,文件头中没有任何数据包计数(因为该格式的设计目的是一次性可写入),而且实际上也没有页脚。


1

我知道的唯一方法是逐帧读取文件,并递增“数据包计数器”。然而,每个小帧都有一个包含存储帧长度的帧头,因此你可以根据该长度在文件中向前搜索。但可能并不会更快。

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


在C语言中,不需要使用“包含存储帧长度的小帧头”,因为pcap_next()函数已经为您完成了这个任务。 - bortzmeyer
我的库可以从http://src.hexapodia.net/pcap.tar.gz下载。我怀疑使用pcap_next()会进行一些帧解析,这可能会使事情变得任意缓慢,这也是我将“读取数据包”与“解析数据包”分开的原因之一。 - Vatine
然而,直接访问跟踪信息而不依赖于pcap_next()函数对我来说似乎是危险的。我更倾向于使用官方的API。谢谢你提供的代码,我已经很久没有读过Lisp了。 - bortzmeyer

0

你可以使用带有 -qz 的 tshark 命令来打印 .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 |         |
==================================

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接