TCP/IP详解卷一:链路层

265 阅读12分钟

引言

链路层三个目的:

  • 为IP模块发送和接收IP数据报
  • 为ARP模块发送ARP请求和接收ARP应答
  • 为 RARP 发送 RARP 请求和接收 RARP 应答

此章内容:

  • 以太网链路层协议
  • 两个串行接口链路层协议( SLIP和PPP)
  • 环回( loopback)驱动程序
  • MTU(最大传输单元)

以太网和IEEE 802封装

以太网这个术语一般是指一个标准。为 TCP / IP 采用的主要的局域网技术。采用一种称作 CSMA / CD(Carrier Sense, Multiple Access with Collision Detection;带冲突检测的载波侦听多路接入)的媒体接入方法。它的速率为10 Mb/s,地址为48 bit。 IEEE(电子电气工程师协会) 802委员会公布了一个稍有不同的标准集,802.3针对整个CSMA / CD网络。802.2和802.3定义了一个与以太网不同的帧格式。

  • 以太网IP数据报的封装是在RFC 894[Hornig 1984]中定义
  • IEEE 802 网络的I P数据报封装在RFC 1042[Postel and Reynolds 1988]中定义

主机需求RFC要求每台 Internet主机都与一个10 Mb/s的以太网电缆相连接:

  • 必须能发送和接收采用RFC 894(以太网)封装格式的分组
  • 应该能接收与RFC 894混合的RFC 1042(IEEE 802)封装格式的分组
  • 也许能够发送采用RFC 1042格式封装的分组。如果主机能同时发送两种类型的分组数据,那么发送的分组必须是可以设置的,而且默认条件下必须是 RFC 894分组。

两种帧格式都采用48 bit(6字节)的目的地址和源地址(802.3允许使用16 bit的地址,但一般是48 bit地址)。这就是我们在本书中所称的硬件地址。ARP和RARP协议(第4章和第5章)对32 bit的I P地址和48 bit的硬件地址进行映射。

接下来的2个字节在两种帧格式中互不相同。在 8 0 2标准定义的帧格式中,长度字段是指它后续数据的字节长度,但不包括 C R C检验码。以太网的类型字段定义了后续数据的类型。在8 0 2标准定义的帧格式中,类型字段则由后续的子网接入协议( Sub-network Access Protocol,SNAP)的首部给出。幸运的是,8 0 2定义的有效长度值与以太网的有效类型值无一相同,这样,就可以对两种帧格式进行区分。

在以太网帧格式中,类型字段之后就是数据;而在 8 0 2帧格式中,跟随在后面的是 3字节的802.2 LLC和5字节的802.2 SNAP。目的服务访问点( Destination Service Access Point,D S A P)和源服务访问点(Source Service Access Point, SSAP)的值都设为0xaa。Ctrl字段的值设为3。随后的3个字节o rg code都置为0。再接下来的2个字节类型字段和以太网帧格式一样(其他类型字段值可以参见RFC 1340 [Reynolds and Postel 1992])。

CRC字段用于帧内后续字节差错的循环冗余码检验(检验和)(它也被称为FCS或帧检验序列)。

802.3标准定义的帧和以太网的帧都有最小长度要求。 802.3规定数据部分必须至少为38字节,而对于以太网,则要求最少要有 46字节。为了保证这一点,必须在不足的空间插入填充(pad)字节。在开始观察线路上的分组时将遇到这种最小长度的情况。

尾部封装

RFC 893[Leffler and Karels 1984]描述了另一种用于以太网的封装格式,称作尾部封装(trailer encapsulation)。这是一个早期BSD系统在DEC VA X机上运行时的试验格式,它通过调整IP数据报中字段的次序来提高性能。

现在,尾部封装已遭到反对,因此我们不对它举任何例子。有兴趣的读者请参阅 RFC 893以及文献[ Leffler et al. 1989]的11.8节。

SLIP:串行线路IP

SLIP 的全称是 Serial Line IP。它是一种在串行线路上对 IP 数据报进行封装的简单形式,在 RFC 1055[Romkey 1988]中有详细描述。SLIP 适用于家庭中每台计算机几乎都有的 RS-232串行端口和高速调制解调器接入Internet。

  • IP数据报以一个称作END(0xc0)的特殊字符结束。同时,为了防止数据报到来之前的线路噪声被当成数据报内容,大多数实现在数据报的开始处也传一个 END 字符(开始处end可以避免 噪声当成报文的情况;如果有线路噪声,那么 END 字符将结束这份错误的报文。这样当前的报文得以正确地传输,而前一个错误报文交给上层后,会发现其内容毫无意义而被丢弃)
  • 如果 IP 报文中某个字符为 END ,那么就要连续传输两个字节 0xdb 和 0xdc 来取代它。0xdb 这个特殊字符被称作 SLIP 的 ESC 字符,但是它的值与 ASCII 码的 ESC 字符(0x1b)不同。
  • 如果 IP 报文中某个字符为 SLIP 的 ESC 字符,那么就要连续传输两个字节 0xdb 和 0xdd 来取代它

SLIP 是一种简单的帧封装方法,还有一些值得一提的缺陷:

每一端必须知道对方的 IP 地址。没有办法把本端的 IP 地址通知给另一端 数据帧中没有类型字段(类似于以太网中的类型字段)。如果一条串行线路用于 SLIP,那么它不能同时使用其他协议 没有在数据帧中加上检验和(类似于以太网中的 CRC字段)。如果 SLIP 传输的报文被线路噪声影响而发生错误,只能通过上层协议来发现(另一种方法是,新型的调制解调器可以检测并纠正错误报文)。

压缩的 SLIP

串行线路的速率通常较低( 19200 b/s或更低),而且通信经常是交互式的(如 Telnet和Rlogin,二者都使用 TCP)。为了传送1个 字节的数据需要 20 个字节的 IP 首部和 20 个字节的 TCP 首部,总数超过40个字节。于是提出一种 CSLIP (即压缩 SLIP )的新协议。CSLIP一般能把上面的 40 个字节压缩到3或5个字节。

PPP:点对点协议

PPP,点对点协议修改了 SLIP 协议中的所有缺陷。PPP 包括以下三个部分:

  • 在串行链路上封装 I P数据报的方法。 PPP既支持数据为 8 位和无奇偶检验的异步模式(如大多数计算机上都普遍存在的串行接口),还支持面向比特的同步链接。
  • 建立、配置及测试数据链路的链路控制协议( LCP:Link Control Protocol)。它允许通信双方进行协商,以确定不同的选项。针对不同网络层协议的网络控制协议( NCP:Network Control Protocol)体系。当前 RFC 定义的网络层有 IP、OSI网络层、DECnet 以及 Apple Talk。例如,IP NCP允许双方商定是
  • 否对报文首部进行压缩,类似于 CSLIP(缩写词 NCP 也可用在TCP的前面)

PPP 数据帧的格式看上去很像 ISO 的 HDLC(高层数据链路控制)标准。

每一帧都以标志字符 0x7e 开始和结束。紧接着是一个地址字节,值始终是 0xff,然后是一个值为 0x03 的控制字节。

接下来是协议字段,类似于以太网中类型字段的功能。当它的值为 0x0021时,表示信息字段是一个 IP 数据报;值为0xc021时,表示信息字段是链路控制数据;值为 0x8021时,表示信息字段是网络控制数据。

CRC字段(或FCS,帧检验序列)是一个循环冗余检验码,以检测数据帧中的错误。

由于标志字符的值是 0x7e,因此当该字符出现在信息字段中时, PPP需要对它进行转义。

  • 在同步链路中,该过程是通过一种称作比特填充 (bit stuffing )的硬件技术来完成的[ Tanenbaum 1989]
  • 在异步链路中,特殊字符 0x7d 用作转义字符。当它出现在 PPP 数据帧中时,那么紧接着的字符的第6个比特要取其补码。 具体实现过程如下:
  1. 当遇到字符 0x7e 时,需连续传送两个字符:0x7d 和 0x5e,以实现标志字符的转义。
  2. 当遇到转义字符 0x7d 时,需连续传送两个字符:0x7d 和 0x5e,以实现转义字符的转义。
  3. 默认情况下,如果字符的值小于 0x20(比如,一个 ASCII 控制字符),一般都要进行转。例如,遇到字符0x01时需连续传送 0x7d 和 0x21 两个字符(这时,第6个比特取补码后变为 1,而前面两种情况均把它变为0)。

这样做的原因是防止它们出现在双方主机的串行接口驱动程序或调制解调器中,因为有时它们会把这些控制字符解释成特殊的含义。另一种可能是用链路控制协议来指定是否需要对这3 2个字符中的某一些值进行转义。默认情况下是对所有的 3 2个字符都进行转义。

与 SLIP 类似,由于 PPP 经常用于低速的串行链路,因此减少每一帧的字节数可以降低应用程序的交互时延。利用链路控制协议,大多数的产品通过协商可以省略标志符和地址字段,并且把协议字段由 2个字节减少到1个字节。

总的来说,PPP 比 SLIP 具有下面这些优点:

  1. PPP支持在单根串行线路上运行多种协议,不只是I P协议
  2. 每一帧都有循环冗余检验
  3. 通信双方可以进行I P地址的动态协商(使用IP网络控制协议)
  4. 与 CSLIP 类似,对 TCP 和 IP 报文首部进行压缩;
  5. 链路控制协议可以对多个数据链路选项进行设置。为这些优点付出的代价是在每一帧的首部增加 3个字节,当建立链路时要发送几帧协商数据,以及更为复杂的实现。

环回接口

大多数的产品都支持环回接口( Loopback Interface),以允许运行在同一台主机上的客户程序和服务器程序通过 TCP / IP 进行通信。A类网络号 127 就是为环回接口预留的。根据惯例,大多数系统把 IP 地址 127 . 0 . 0 . 1分配给这个接口,并命名为 localhost。一个传给环回接口的IP数据报不能在任何网络上出现。

一旦传输层检测到目的端地址是环回地址时,大多数的产品还是照样完成传输层和网络层的所有过程,只是当 IP 数据报离开网络层时把它返回给自己。

  1. 传给环回地址(一般是1 2 7 . 0 . 0 . 1)的任何数据均作为I P输入。
  2. 传给广播地址或多播地址的数据报复制一份传给环回接口,然后送到以太网上。这是因为广播传送和多播传送的定义(第 1 2章)包含主机本身。
  3. 任何传给该主机I P地址的数据均送到环回接口。

最大传输单元MTU

以太网和 802.3 对数据帧的长度都有一个限制,其最大值分别是 1500 和 1492 字节。链路层的这个特性称作 MTU,最大传输单元。不同类型的网络大多数都有一个上限。

如果 IP 层有一个数据报要传,而且数据的长度比链路层的 MTU 大,那么 IP 层 就需要进行分片( fragmentation),把数据报分成若干片,这样每一片都小于 MTU。

点到点的链路层(如S L I P和P P P)的 MTU 并非指的是网络媒体的物理特性。相反,它是一个逻辑限制,目的是为交互使用提供足够快的响应时间。

路径 MTU

当在同一个网络上的两台主机互相进行通信时,该网络的 MTU 是非常重要的。但是如果两台主机之间的通信要通过多个网络,那么每个网络的链路层就可能有不同的 MTU 。重要的不是两台主机所在网络的 MTU 的值,重要的是两台通信主机路径中的最小 MTU。它被称作路径MTU。

两台主机之间的路径 MTU 不一定是个常数。它取决于当时所选择的路由。而选路不一定是对称的(从A到B的路由可能与从B到A的路由不同),因此路径 MTU 在两个方向上不一定是一致的。

RFC 1191[Mogul and Deering 1990]描述了路径 MTU 的发现机制,即在任何时候确定路径 MTU 的方法。

小结

如果你的系统支持 netstat(1)命令(参见3 . 9节),那么请用它确定系统上的接口及其 MTU。

[root@23 ~]# netstat -i -n
Kernel Interface table
Iface             MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0             1500 26261946      0     21 0      22095106      0      0      0 BMRU
eth1             1500  8068644      0      0 0        160019      0      0      0 BMRU
lo              65536    14967      0      0 0         14967      0      0      0 LRU