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

问题描述

sock = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
setsockopt(sock,SOL_SOCKET,SO_ATTACH_FILTER,&f,sizeof (f)) 

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

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

所以问题是,如何清除那些数据包?

解决方法

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

  1. 只需在套接字上调用facet_grid直到其为空
  2. 通过在用户模式下以及使用bpf过滤数据包进行双重过滤
  3. 像libpcap一样使用零bpf技术,在这种情况下,您首先应用空的bpf,然后清空套接字,然后应用真实的bpf。

I've written about this problem extensively on my blog尝试将围绕此bug的口头传统整理成具体的建议和最佳实践。