如何刷新原始 AF_PACKET 套接字以获得正确的过滤数据包

Rid*_*der 5 sockets linux ethernet raw-sockets bpf

sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &f, sizeof (f)) 
Run Code Online (Sandbox Code Playgroud)

使用这个简单的 BPF/LPF 附加代码,当我尝试在套接字上接收数据包时,会得到一些与过滤器不匹配的错误数据包。在我调用setsockopt() 之前,这些数据包似乎已进入套接字。

似乎应该首先创建 AF_PACKET SOCK_RAW 套接字,然后附加过滤器,然后刷新套接字以摆脱那些错误的数据包。

所以问题是,如何刷新这些数据包?

Nat*_*lin 5

您所描述的“错误”是真实存在的,我在职业生涯中曾在多家公司看到过它。围绕这个错误有一种类似于“口头传统”的东西,它从一个网络工程师传递给另一个网络工程师。以下是常见的修复方法:

  1. 只需调用recv套接字直到它为空
  2. 通过在用户模式下过滤数据包以及使用 bpf 进行双重过滤
  3. 使用零 bpf 技术,就像 libpcap 一样,首先应用一个空 bpf,然后清空套接字,然后应用真正的 bpf。

我在我的博客上广泛撰写了有关此问题的文章,试图将围绕此错误的口头传统编入具体的建议和最佳实践。