【问题标题】:How to sniff IP packets arriving on a particular port using C++?如何使用 C++ 嗅探到达特定端口的 IP 数据包?
【发布时间】:2021-11-03 02:28:51
【问题描述】:
我目前正在编写一个应用程序,它将读取发送到特定端口 (42557) 的以太网数据包。我正在接口 localhost (lo) 上从 packETH 工具播放 pcap 文件,并能够在 Wireshark 上捕获它。我附上了在 Wireshark 中收到的数据包的屏幕截图。
现在,我想在我的 C++ 应用程序中读取这些数据包。我不知道该怎么办。我创建了一个侦听端口 (42557) 的 IPV6 TCP/IP 服务器,但我没有收到任何原始数据包。我在这里做错了吗?我需要将数据包的目标 IP 编辑到本地主机吗?
任何帮助将不胜感激。
【问题讨论】:
标签:
sockets
networking
ipv6
packet-sniffers
【解决方案1】:
您是否尝试嗅探 UDP 数据包到端口 42994 - 即,即使您没有作为该端口的服务器运行,也被动接收这些数据包 - 或者您是否尝试将 UDP 数据包发送到端口 42994 的服务器,即这些程序应该发送到的程序?
两者非常不同。
如果你想嗅探,你应该使用 libpcap(我假设这是 Linux,因为你将环回设备称为“lo”而不是像其他 UN*Xes 上的“lo0”;libpcap 来了大多数 Linux 发行版)类似于 tcpdump、Wireshark 等。有关 libpcap 的一些教程,请参阅 the DOCUMENTATION section of the tcpdump.org Web site。
您需要使用udp port 42994 的过滤器来捕获从端口 42994 到或的数据包,或者使用udp dst port 42994 的过滤器来捕获数据包到端口 42994。
如果您在环回设备上捕获,数据包将看起来像原始以太网数据包;如果您在以太网设备上捕获,情况也是如此。
您还可以在“任何”设备上捕获,该设备在所有网络接口上捕获。在这种情况下,数据包将具有"Linux cooked" 标头而不是以太网标头。
通过在打开捕获设备后调用pcap_datalink(),确保您获得了您期望的标头,如果您期待以太网标头,请确保它是DLT_EN10MB,如果您期待“Linux”,请确保它是DLT_LINUX_SLL熟”标题。
如果您想成为服务器,请使用标准套接字 API,以及套接字类型为 SOCK_DGRAM(这就是 UDP 服务器的类型)和协议为 IPPROTO_UDP 的套接字。您将不会获得原始数据包;您将获得 Wireshark 向您展示的“数据”部分中的内容。