一尘不染

从混杂的网络设备中读取

linux

我想编写一个用于无线流量的实时分析工具。

有谁知道如何从C中的混杂(或嗅探)设备读取数据?

我知道您需要具有root用户访问权限才能执行此操作。我想知道是否有人知道执行此操作所需的功能。普通的插座在这里似乎没有意义。


阅读 269

收藏
2020-06-07

共1个答案

一尘不染

在Linux上,您使用PF_PACKET套接字从原始设备读取数据,例如以混杂模式运行的以太网接口:

s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

这会将收到的每个数据包的副本发送到您的套接字。但是,您很可能并不需要所有数据包。内核可以使用BPF(伯克利分组过滤器)执行第一级过滤。BPF本质上是一个基于堆栈的虚拟机:它处理一小部分指令,例如:

ldh = load halfword (from packet)  
jeq = jump if equal  
ret = return with exit code

BPF的退出代码告诉内核是否将数据包复制到套接字。可以使用setsockopt(s,SOL_SOCKET,SO_ATTACH_FILTER,)直接编写相对较小的BPF程序。(警告:内核采用的是sock_fprog结构,而不是bpf_program结构,请勿混用,否则您的程序将无法在某些平台上运行)。

对于相当复杂的任何事情,您真的想使用libpcap。BPF的功能受到限制,尤其是每个数据包可以执行的指令数受到限制。libpcap将负责将一个复杂的过滤器分为两部分,内核执行第一级过滤,而功能更强大的用户空间代码将丢弃实际上不希望看到的数据包。

libpcap还从应用程序代码中抽象出内核接口。Linux和BSD使用类似的API,但是Solaris需要DLPI,而Windows使用其他东西。

2020-06-07