UNPv1第二十六章:数据链路访问

1. 概述

目前大多数操作系统都为应用程序提供了访问数据链路层的手段,它使得应用程序拥有如下功能:

  1. 监视数据链路层上的所收到的分组,这使得我们可以在普通计算机系统上通过tcpdump来检测网络,而无需使用特殊的硬件设备
  2. 作为普通应用进程而不是内核的一部分运行某些程序

Unix上三种最常用的数据链路访问方法

  1. BSD的BSD分组过滤器BPF
  2. SVR4的数据链路提供者接口DLPI
  3. Linux的SOCK_PACKET接口

2. BPF: BSD分组过滤器

虽然在数据链路嵌入一个分组捕获机制并不困难,BPF的强大威力却在于它的过滤功能。
为了减少开销,BPF使用以下三种技术:
(1)BPF过滤由内核完成,以减少从BPF拷贝到应用进程的数据量。
(2)每个分组只有部分数据由BPF传递给应用进程,被称为捕获长度。大多数应用进程只需要分组头部,而不需要分组数据,这同样减少了内核到用户空间的数据拷贝量。
(3)BPF缓冲递送给应用进程的数据,该缓冲只有在已满或者读超时发生时才拷贝给应用进程。超时值可由应用进程指定。
UNPv1第二十六章:数据链路访问_第1张图片

3. DLPI:数据链路提供者接口

应用进程介入数据链路层只需打开设备(例如le0)并使用DLPI的DL_ATTACH_REQQ请求将它与DLPI附接就可以了。不过为了提高效率,一般还需压入两个流模块:pfmod(在内核中进行分组过滤)和bufmod(缓冲递送给应用进程的数据)
从原理上说,这与上一节所讲的BPF相类似:pfmod在内核中使用伪机器实现分组过滤,bufmod则通过支持捕获长度和读超时来减少系统调用次数和拷贝的数据量。
UNPv1第二十六章:数据链路访问_第2张图片

4. Linux:SOCK_PACKET

从数据链路获取所有帧
fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
获得IPv4帧
fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP));

与BPF和DLPI相比较,Linux有如下不同:
(1)Linux不提供基于核心的缓冲和分组过滤机制。它提供普通的套接口接收缓冲区,但多个帧不能缓冲在一起,一次性的由应用进程读取。这么一来从内核向应用进程拷贝大量数据的开销势必增长
(2)Linux不提供针对设备的过滤。

你可能感兴趣的:(UNPv1第二十六章:数据链路访问)