我对网络数据包的低级接口感兴趣。据我了解,tcpdump 和 libpcap 等工具使用 BPF 数据包过滤设备 /dev/bpf* 来读取链路层网络数据包(在 Mac OS X 和 FreeBSD 上)。
但是 /dev/bpf* 的数据从哪里来呢?如果我们从下往上开始,数据首先由硬件网卡读取(来自wifi的无线电波)。然后网卡驱动程序读取这些数据包并将它们提供给内核。例如,在我的计算机中,网卡是 Airport Brcm_4331,其驱动程序在 IOReg 中列为“com.apple.driver.AirPort.Brcm4331”。但是当你从套接字层或使用ifconfig查看时,网络接口被称为“en0”。这也是您使用 bpf 抓包 API 时提供的接口名称。
那么我的 Airport Brcm_4331 卡的实际驱动程序与通用“en0”接口之间的差距是什么?
我的猜测是网卡驱动程序本身提供了一个通用接口来读取原始数据包。因此它从硬件(物理层、wifi)读取数据包,然后提供一些标准函数,以与设备无关的方式为数据链路层(以太网)读取数据包。这就是所谓的“en0”接口。然后bpf从“en0”接口读取数据并将其数据写入/dev/bpf文件以提供类似Unix文件的接口。
那是对的吗?如果是,那么是否可以编写直接与驱动程序交互的代码,而不使用 bpf API?我在这个层面上真的很困惑,因为很难找到关于这些东西的文档。通常只讨论高级 Unix API(原始套接字、libpcap 和 bpf),而不解释它们如何与实际驱动程序交互。