libpcap是socket实现的吗API?

Is libpcap implemented by socket API?

libpcap用于抓包。据我了解,它可以从 all 端口捕获网络包。并且可以抓取link层的包数据(比如以太网帧)。

这让我有点困惑,因为在类 Unix 系统中仅使用套接字 API 似乎不可能拦截所有网络流量(来自所有端口)。而且,socket API 似乎无法获取 link 层的信息(例如以太网帧的头部)。

libpcap是由socket实现的API是真的吗?如果不是,用哪个OS级API来实现?

它是通过在网络栈中插入一个驱动程序来实现的。

在 Linux 上,使用 PF_PACKET 套接字访问 libpcap 所需的原始数据包。

http://man7.org/linux/man-pages/man7/packet.7.html

libpcap 不是套接字的一部分 API。在Linux上使用了PF_PACKET,这是BSD机制的演进。在其他操作系统上还有其他机制(DLPI,Windows 需要 DLL)。
任何接口机制上的捕获都是Linux特定的机制,捕获机制发生在网络接口层之上。 内核中的捕获机制要么显式调用内核数据包过滤器,要么通过调整管道 (SVR4) 插入。

Is it true that libpcap is implemented by socket API?

如果您使用的是 Linux 或 IRIX,则为真。如果您使用的是另一种风格的 UN*X,则事实并非如此。

If not, which OS-level API is used to implement it?

在 *BSD、OS X、AIX 和 Solaris 11 及更高版本上:BPF。

在早期版本的 Solaris 和 HP-UX 上:STREAMS+DLPI。

it seems impossible to intercept all network traffic (from all ports) by just using the socket API in Unix-like system

在 Linux 上,如果您打开 PF_PACKET 套接字,并且 将其绑定到特定接口,则来自所有接口的数据包都会被传送到插座。

socket API seems unable to get the information in link layer

您必须使用正确的类型套接字,即Linux上的PF_PACKET套接字或具有协议的PF_RAW套接字RAWPROTO_SNOOP 在 IRIX 上。其他UN*Xes没有socket类型抓包,采用其他机制

通常,应用程序使用内核级 TCP 堆栈。通过在用户 space 中使用您自己的 TCP/IP 堆栈处理实现,而不是使用默认的内核级实现,您可以绕过内核。

阅读更多 "zero copy networking" vs "kernel bypass"?

根据 Whosebug post pcap 也在做内核绕过