【问题标题】:Extracting packet informations using C++使用 C++ 提取数据包信息
【发布时间】:2013-11-20 14:30:01
【问题描述】:

我一直在搞 Wireshark 一段时间,我想知道是否有人可以帮助我。我用它记录了一次随机浏览,并将其保存到 pcap 文件中。我想创建一个 C/C++ 程序(我知道存在很多,但我想练习),从数据包中提取每个信息,如源和目标 IP、使用的端口、数据等。我学习的最终目标是从流中提取图像或 Youtube 视频或任何内容(我知道,我必须对数据包进行分组并对它们进行排序等),但我猜这是以后的项目。 :)

我正在使用 libpcap(在 Linux 上),到目前为止,我的代码可以逐个数据包读取脱机文件数据包,并且 - 因为我知道在我的情况下它们是 PPP 数据包 - 如果我使用来自的信息加载自定义结构包的第20个字节,可以查看mac地址和ip地址。

我的问题:

1) 在没有 Wireshark 的情况下,我如何知道/确定使用了哪种数据链路类型? (以太网、WiFi、PPP 等)

2) 如何读取数据包的更多数据?如果我只读取一个字节,我的程序什么都不做任何事情,每个变量都为空。

我有一个 ppphdr 结构,其中包含:

u_int16_t htype;
u_int16_t ptype;
u_char hplen;
u_char plen;
u_int16_t oper;
u_char sha[6];
u_char spa[4];
u_char tha[6];
u_char tpa[4];

我对每个数据包都这么称呼:

pppheader = (struct ppphdr*)(packet+20);

因为 ppp 帧从第 20 个字节开始。它会返回发送者和目标 mac 和 IP 地址。

在我继续读取接下来的几个字节后,使用相同的调用只是不同的结构,它返回为空,并且程序在 1 个数据包后停止。我正在尝试使用本指南:http://www.tcpipguide.com/free/t_PPPGeneralFrameFormat.htm

【问题讨论】:

  • 如果您在问题中添加一些代码以及有关您拥有的捕获文件的一些信息,您将有更高的机会获得合理的答案。特别是问题 2 听起来像是您的代码的问题。
  • (从上面继续..),一旦你有了框架,你就可以提取ip头,然后从那里提取tcp/udp头,每个级别都会暴露一些特定的信息位..
  • 我想我会推荐查看tsharktcpdump 和其他此类工具的源代码。基本上,您需要了解您感兴趣的每种类型的数据包的每一层协议头/尾的结构,也就是说,嗯……相当多的信息……

标签: c++ linux sockets networking wireshark


【解决方案1】:

在没有 Wireshark 的情况下,我如何知道/确定使用了哪种数据链路类型? (以太网、WiFi、PPP 等)

Wireshark 本身适用于不同的文件格式。您可能感兴趣的其中两个是“pcap”和“pcap-ng”。

如果你已经记录了“pcap”格式的数据,链接类型存储在pcap文件头中的“Link-layer header type”字段中;见the pcap-savefile man page

如果您使用“pcap-ng”格式记录数据,则链接类型存储在Interface Description Block

您可以阅读有关herethere 这两种格式的更多信息。

如果您使用 libpcap 读取 pcap 或 pcap-ng 文件,pcap_datalink() 例程将返回指定链路层标头类型的 DLT_ 值。有关DLT_ 值和对应于它们的标头的描述,请参见the list of link-layer header typesDLT_EN10MB 用于以太网(“10MB”是历史的 - 它用于所有以太网速度); DLT_PPP 是 PPP 最可能的类型。如果您有带有 Wi-Fi 标头的 Wi-Fi 数据包(如果您不在监控模式下捕获,您可能会获得以太网标头,并且在 Wi-Fi 适配器上获得DLT_EN10MB),您将获得DLT_IEEE802_11;如果您在 802.11 标头之前还有“无线电元数据”标头,您将获得诸如 DLT_IEEE802_11_RADIODLT_IEEE802_11_RADIO_AVSDLT_PRISM_HEADER 之类的内容。

假设您将从 libpcap 获得的数据包的链路层标头类型是什么。 总是 调用pcap_datalink() 来确定链路层标头类型,并使用它来解析数据包;如果您的代码不知道如何解析特定 DLT_ 值的数据包,它应该报告错误并退出。

如何读取数据包的更多数据?如果我只读取一个字节,我的程序什么也不做,每个变量都为空。

假设您记录以太网数据,您需要按照标准规范解析/处理数据。比如先解析Ethernet frame。即使在那个时候,以太网帧也可以是可变长度的。例如,假设 tcpdump/wireshark 不记录 Preamble 字段,您需要读取 15 个八位字节以确定您可以/应该读取多少。

处理完以太网帧后,您需要解析 IP,然后可能是 UDP 和/或 TCP。其他一些数据可以采用其他格式,但在每种情况下,您都必须仔细研究格式规范并相应地解析数据。读取一个字节不会让你到任何地方。所以我建议你先学习基本的网络层——以太网、IP、UDP,然后再回到解析它们的问题。

归根结底,Wireshark 是一个开源程序,可以完成大部分您想做的练习。这意味着您可以随时download 源代码,查看它的作用并从中学习。

希望对您有所帮助。祝你好运!

【讨论】:

  • 查看我对 Vlad 帖子的更新,修复了一些错误(确实 NOT pcap 文件不包含链接层标头类型!) 并添加更多信息。
  • @GuyHarris:是的,我错过了那里的类型字段。感谢您的更新!
  • 一个更简单的也解析数据包的程序是tcpdump;查看其来源可能也很有用。
猜你喜欢
  • 2015-01-26
  • 2015-01-09
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
  • 2012-10-05
相关资源
最近更新 更多