C语言 原始套接字 / BPF - 过滤完成一次或多次



>上下文

在 Linux Debian 64 位上研究伯克利数据包过滤器,以过滤打开的套接字接收的数据包。

我使用AF_PACKET所以我甚至管理数据包的第 2 层。

到目前为止,它工作得很好。但是我必须过滤每个套接字上的每个数据包,而且效率不高。因此,我使用 BPF。

问题

由于我让我的应用程序自己设置了过滤器

setsockopt(sd, SOL_PACKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0 )

我想知道:

如果内核将过滤数据包并将其定向到正确的套接字(在内核级别,系统上每个数据包进行一次过滤)

如果内核将像以前一样发送所有数据包,并且 BPF 将在每个套接字中过滤(每个数据包将被分析 + 过滤的次数与系统上有打开的套接字一样多,因为每个应用程序都会看到数据包<>混杂模式。这是没有效率的)。

我不确定。

谢谢

黑人 - 但这个问题显示了对AF_PACKET套接字与混杂模式的根本误解,我想概述一下,在 LINUX 中的AF_PACKET套接字上使用 BPF 过滤器是以有效的方式实现的(对于通常的用例)。

关于这个问题的一般问题:

使用 AF_PACKET 套接字并不意味着 NIC 已切换到混杂模式 - 它只是转发指向主机到用户空间(因此仍然应用基于 L2 地址的过滤器 - 与混杂模式下的 NIC 相反,它愉快地忽略不匹配的目标 MAC)。这应该完全放松您的问题,因为即使有AF_PACKET套接字,也会应用通常的帧/数据包分发过程。

关于效率:

只有AF_PACKET套接字才能看到定向到主机的所有帧。附加到套接字的筛选器按套接字进行评估。内核中没有中心点来处理所有过滤器并将帧分配到其方向。通常AF_PACKET套接字用于在用户空间中实现协议(处理程序)。因此,那些实现AF_PACKET的老聪明人假设大多数指向AF_PACKET套接字的帧将被过滤/删除,因为用户只想处理帧的一个非常特定的子集。

筛选器应用于套接字缓冲区(skb - 保存帧及其关联控制/状态数据的容器),该缓冲区由参与帧处理的所有实体共享。仅当筛选器匹配时,才会创建此缓冲区的克隆并将其移交给用户。在负责在AF_PACKET套接字上下文中处理 skb 的函数之上甚至还有一个注释,上面写着:

 * This function makes lazy skb cloning in hope that most of packets
 * are discarded by BPF.

有关AF_PACKET套接字上的数据包过滤器的更多信息,请参阅网络过滤器的内核文档。

bpf 程序将位于内核中。它将处理发送到 setsockopt 调用中标识的特定套接字的数据。如果特定数据包通过过滤器,它将被传递,否则将被过滤掉。

我的意思是强调,使用不同套接字对 API 的两次并行调用不会影响另一个,并且应该正常工作。

关于内核中的内部实现,我不确定。

德克萨斯州

相关内容

最新更新