gpt4 book ai didi

c++ - 异步 lib​​pcap : losing packets?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:44:09 25 4
gpt4 key购买 nike

我有一个程序向主机发送一组 TCP SYN 数据包(使用原始套接字)并使用 libpcap(带过滤器)来获取响应。我正在尝试在异步 I/O 框架中实现它,但似乎 libpcap 缺少一些响应(即当它花费少于 100 时的系列的第一个数据包TCP SYN 和响应之间的微秒)。 pcap 句柄设置如下:

pcap_t* pcap = pcap_open_live(NULL, -1, false, -1, errorBuffer);
pcap_setnonblock(pcap, true, errorBuffer);

然后我添加一个过滤器(包含在 filterExpression 字符串中):

struct bpf_program filter;
pcap_compile(pcap, &filter, filterExpression.c_str(), false, 0);
pcap_setfilter(pcap, &filter);
pcap_freecode(&filter);

在一个循环中,在发送每个数据包之后,我使用 select 来了解我是否可以从 libpcap 中读取:

int pcapFd = pcap_get_selectable_fd(pcap);
fd_set fdRead;
FD_ZERO(&fdRead);
FD_SET(pcapFd, &fdRead);
select(pcapFd + 1, &fdRead, NULL, NULL, &selectTimeout);

然后阅读:

if (FD_ISSET(pcapFd, &fdRead)) {
struct pcap_pkthdr* pktHeader;
const u_char* pktData;
if (pcap_next_ex(pcap, &pktHeader, &pktData) > 0) {
// Process received response.
}
else {
// Nothing to receive (or error).
}
}

正如我之前所说,一些数据包被遗漏了(属于“没有接收到”的情况)。我知道这些数据包在那里,因为我可以以同步方式捕获它们(使用 tcpdump 或运行 pcap_loop 的线程)。我在这里遗漏了一些细节吗?或者这是 libpcap 的问题?

最佳答案

如果 pcap_t 的 FD 被报告为可被 select()(或 poll() 或任何调用/机制所读取) re using),不能保证这意味着只能读取一个数据包而不会阻塞。

如果您使用pcap_next_ex(),您将只读取一个数据包;如果有多个数据包可供读取,那么,如果你执行另一个 select(),它应该立即返回,报告 FD 再次可读,在这种情况下你可能会调用 pcap_next_ex() 再次,依此类推。这意味着每个数据包至少有一个系统调用(select()),并且可能有更多调用,具体取决于您正在执行的操作系统版本以及您拥有的 libpcap 版本。

相反,如果您调用 pcap_dispatch(),将数据包计数参数设置为 -1,该调用将返回可通过单个读取操作和处理获得的所有数据包所有这些,因此,在大多数平台上,如果有多个可用数据包(如果您正在使用 SYN 洪水测试您的程序,您可能会得到高网络流量),您可能会通过一个或两个系统调用获得多个数据包, 很可能是这种情况)。

此外,在支持内存映射数据包捕获的 Linux 系统上(我认为所有 2.6 和更高版本的内核都支持,即使不是所有 2.4 内核也支持),以及较新版本的 libpcap,pcap_next_ex() 必须制作数据包的拷贝,以避免内核将数据包从处理数据包的代码下更改出来,并避免无限期地“锁定”环形缓冲区中的插槽,因此有一个涉及额外的拷贝。

关于c++ - 异步 lib​​pcap : losing packets?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11637063/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com