以太网和IEEE 802封装
以太网
一般是指数字设备公司(Digital Equipment Corp.)、英特尔公司(Intel Corp.)和Xerox公司在1982年联合公布的一个标准
采用一种称作CSMA/CD的媒体接入方法,其意思是带冲突检测的载波侦听多路接入(Carrier Sense, Multiple Access with Collision Detection)。它的速率为10 Mb/s,地址为48 bit。
IEEE 802封装
IEEE(电子电气工程师协会)802委员会发布
- 802.3针对整个CSMA/CD网络
- 802.4针对令牌总线网络
- 802.5针对令牌环网络
这三者的共同特性由802.2标准来定义,那就是802网络共有的逻辑链路控制(LLC)
802.2和802.3定义了一个与以太网不同的帧格式
格式区别

- 
字段区别 - 802标准
- 长度字段:指它后续数据的字节长度,但不包括CRC检验码
- 3字节的802.2LLC
- 1个字节的目的服务访问点(Destination Service Access Point, DSAP),值设为0xaa
- 1个字节的源服务访问点(Source Service Access Point, SSAP),值设为0xaa
- 1个字节的ctrl字段,值设为3
 
- 5字节的802.2SNAP
- 3个字节org code值设为0
- 2个字节的类型
 
 
- 以太网
- 类型字段:定义了后续数据的类型
 
 
- 802标准
- 
CRC字段 
 用于帧内后续字节差错的循环冗余码检验(检验和)(它也被称为FCS或帧检验序列)
- 
最小长度 - 802.3规定数据部分必须至少为38字节
- 以太网要求最少要有46字节
 必须在不足的空间插入填充(pad)字节 
以太网帧格式–IEEE802.3
按照顺序

LSB( Last(Least) Significant Bit,最低有效位,或低位前导)
MSB(Most Significant Bit,最高有效位)
- 
前导码(preamble)一般不计入帧头部 - 让接收设备能够跟踪到来的比特流
- 7字节,交替的0和1,即7个1字节的‘10101010’,
- 数据是从低比特开始传送,因此在代码中为方便阅读的前导码数值为0x55555555555555
 
- 
帧开始符(SFD,Start frame delimiter) - 表示帧数据的开始
- 1字节,值为‘10101011’,最后两个1让接收方能够识别中间的 0 和 1 交替模式,进而同步并检查到数据开头
- 数据是从低比特开始传送,所以数值为0xd5
 ‘10101011’ 传送为 ‘11010101’ 
- 
目的地址(DA,Destination Address) - LSB优先
- 6B
- 不是目的主机的MAC地址,而下一跳的MAC地址
- 回程的数据的目的地址不是源主机的私有IP地址,而经过转换的公网地址,转换的对应关系在NAT设备上有转换表,回程数据查表后改变目的IP地址,发给目的主机
 
- 
原地址(SA) - LSB优先
- 6B
- 当前设备的MAC地址
 
- 
长度/类型 - 当有效数据量(Length)小于46字节时需要用0对数据进行填充,保证数据和填充字段总和不低于46字节,注意,填充0并不会改变Length字段值。
 
- 
数据 
- 
帧校验序列(FCS) - 存储 CRC(Cyclic Redundancy Check,循环冗余校验)
 
- 
帧间距 一般不计入帧头部 - 当一个帧发送出去之后,发送方在下次发送帧之前,需要再发送至少12个octet的空闲线路状态码
 
尾部封装
RFC 893[Leffler and Karels 1984]描述了另一种用于以太网的封装格式,称作尾部封装(trailer encapsulation)。这是一个早期BSD系统在DEC VA X机上运行时的试验格式,它通过调整IP数据报中字段的次序来提高性能。在以太网数据帧中,开始的那部分是变长的字段(IP首部和TCP首部)。把它们移到尾部(在CRC之前),这样当把数据复制到内核时,就可以把数据帧中的数据部分映射到一个硬件页面,节省内存到内存的复制过程。TCP数据报的长度是512字节的整数倍,正好可以用内核中的页表来处理。两台主机通过协商使用ARP扩展协议对数据帧进行尾部封装。这些数据帧需定义不同的以太网帧类型值。
现在,尾部封装已遭到反对,因此我们不对它举任何例子。有兴趣的读者请参阅RFC 893以及文献[Leffler et al.1989]的11.8节。
SLIP:串行线路IP
全称是Serial Line IP,它是一种在串行线路上对IP数据报进行封装的简单形式;
在RFC 1055[Romkey 1988]中有详细描述。
SLIP适用于家庭中每台计算机几乎都有的RS-232串行端口和高速调制解调器接入Internet
帧格式
- IP数据报以一个称作END(0xc0)的特殊字符结束。同时,为了防止数据报到来之前的线路噪声被当成数据报内容,大多数实现在数据报的开始处也传一个END字符
如果有线路噪声,那么END字符将结束这份错误的报文。这样当前的报文得以正确地传输,而前一个错误报文交给上层后,会发现其内容毫无意义而被丢弃
- 
如果IP报文中某个字符为END,那么就要连续传输两个字节0xdb和0xdc来取代它。0xdb这个特殊字符被称作SLIP的ESC字符,但是它的值与ASCII码的ESC字符(0x1b)不同 
- 
如果IP报文中某个字符为SLIP的ESC字符,那么就要连续传输两个字节0xdb和0xdd来取代它 

缺陷
- 
每一端必须知道对方的IP地址。没有办法把本端的IP地址通知给另一端。 
- 
数据帧中没有类型字段(类似于以太网中的类型字段)。如果一条串行线路用于SLIP,那么它不能同时使用其他协议。 
- 
SLIP没有在数据帧中加上检验和(类似于以太网中的CRC字段)。如果SLIP传输的报文被线路噪声影响而发生错误,只能通过上层协议或新型的调制解调器检测并纠正错误报 
- 
性能 - 
速率通常较低(19200 b/s或更低) 
- 
通信经常是交互式的(如Telnet和Rlogin,二者都使用TCP),因此在SLIP线路上有许多小的TCP分组进行交换 为了传送1个字节的数据需要20个字节的IP首部和20个字节的TCP首部,总数超过40个字节,比如Rlogin命令 
 
- 
CSLIP:压缩的SLIP
在RFC 1144[Jacobson 1990a]中被详细描述
为了解决SLIP的性能问题;
一般能把上面的40个字节压缩到3或5个字节。它能在CSLIP的每一端维持多达16个TCP连接,并且知道其中每个连接的首部中的某些字段一般不会发生变化。对于那些发生变化的字段,大多数只是一些小的数字和的改变。
PPP:点对点协议
内容
- 
在串行链路上封装IP数据报的方法。PPP既支持数据为8位和无奇偶检验的异步模式(如大多数计算机上都普遍存在的串行接口),还支持面向比特的同步链接。 
- 
建立、配置及测试数据链路的链路控制协议(LCP:Link Control Protocol)。它允许通信双方进行协商,以确定不同的选项。 
- 
针对不同网络层协议的网络控制协议(NCP:Network Control Protocol)体系。 当前RFC定义的网络层有IP、OSI网络层、DECnet以及AppleTalk 
RFC 1548[Simpson 1993]描述了报文封装的方法和链路控制协议。
RFC 1332[McGregor 1992]描述了针对IP的网络控制协议
数据帧格式

- 每一帧都以标志字符0x7e开始和结束
- 紧接着是一个地址字节,值始终是0xff
- 然后是一个值为0x03的控制字节
- 接下来是协议字段,类似于以太网中类型字段的功能。当它的值为0x0021时,表示信息字段是一个IP数据报;值为0xc021时,表示信息字段是链路控制数据;值为0x8021时,表示信息字段是网络控制数据
- CRC字段(或FCS,帧检验序列)是一个循环冗余检验码,以检测数据帧中的错误
字符转义
比如标志字符的值0x7e
- 
在同步链路中,该过程是通过一种称作比特填充(bit stuffing)的硬件技术来完成的[Tanenbaum 1989]。 
- 
在异步链路中,特殊字符0x7d用作转义字符。当它出现在PPP数据帧中时,那么紧接着的字符的第6个比特要取其补码,具体实现过程如下: - 当遇到字符0x7e时,需连续传送两个字符:0x7d和0x5e,以实现标志字符的转义。
- 当遇到转义字符0x7d时,需连续传送两个字符:0x7d和0x5d,以实现转义字符的转义。
- 默认情况下,如果字符的值小于0x20(比如,一个ASCII控制字符),一般都要进行转义。例如,遇到字符0x01时需连续传送0x7d和0x21两个字符(这时,第6个比特取补码后变为1,而前面两种情况均把它变为0)。
 这样做的原因是防止它们出现在双方主机的串行接口驱动程序或调制解调器中,因为有时它们会把这些控制字符解释成特殊的含义。 
 另一种可能是用链路控制协议来指定是否需要对这32个字符中的某一些值进行转义。默认情况下是对所有的32个字符都进行转义
相比SLIP优点
- PPP支持在单根串行线路上运行多种协议,不只是IP协议;
- 每一帧都有循环冗余检验;
- 通信双方可以进行IP地址的动态协商(使用IP网络控制协议);
- 与CSLIP类似,对TCP和IP报文首部进行压缩;
- 链路控制协议可以对多个数据链路选项进行设置。
为这些优点付出的代价是在每一帧的首部增加3个字节,当建立链路时要发送几帧协商数据,以及更为复杂的实现。
环回接口(Loopback Interface)
允许运行在同一台主机上的客户程序和服务器程序通过TCP/IP进行通信;
A类网络号127就是为环回接口预留的;
一个传给环回接口的IP数据报不能在任何网络上出现;
处理流程

关键点:
- 任何传给该主机IP地址的数据均送到环回接口。
- 传给环回地址(一般是127.0.0.1)的任何数据(交给环回驱动程序)均作为IP输入。
- 传给广播地址或多播地址的数据报复制一份传给环回接口,然后送到以太网上。这是因为广播传送和多播传送的定义包含主机本身。
最大传输单元(MTU)
超过时,数据需要分片(fragmentation)

路径MTU
两台通信主机路径中的最小MTU,被称作路径MTU;
- 两台主机之间的路径MTU不一定是个常数,它取决于当时所选择的路由。
- 选路不一定是对称的(从A到B的路由可能与从B到A的路由不同),因此路径MTU在两个方向上不一定是一致的
RFC 1191[Mogul and Deering 1990]描述了路径MTU的发现机制
串行线路吞吐量计算
略
答疑
以太网数据帧最小、大长度
关于最小发送间隙和最小帧长的规定也是为了避免冲突
- 
前提条件 
 CSMA/CD冲突避免的方法:先听后发、边听边发、随机延迟后重发。一旦发生冲突,必须让每台主机都能检测到。
- 
案例分析 
 考虑如下的情况,主机发送的帧很小,而两台冲突主机相距很远。在主机A发送的帧传输到B的前一刻,B开始发送帧。这样,当A的帧到达B时,B检测到冲突,于是发送冲突信号。假如在B的冲突信号传输到A之前,A的帧已经发送完毕,那么A将检测不到冲突而误认为已发送成功。由于信号传播是有时延的,因此检测冲突也需要一定的时间。这也是为什么必须有个最小帧长的限制
- 
解决 
 按照标准,10Mbps以太网采用中继器时,连接的最大长度是2500米,最多经过4个中继器,因此规定对10Mbps以太网一帧的最小发送时间为51.2微秒。这段时间所能传输的数据为512位,因此也称该时间为512位时。这个时间定义为以太网时隙,或冲突时槽。512位=64字节,这就是以太网帧最小64字节的原因512位时是主机捕获信道的时间。如果某主机发送一个帧的64字节仍无冲突,以后也就不会再发生冲突了,称此主机捕获了信道 64-(6+6+2+4)=64-18=46,所以IP数据包长度最小为46
- 
结论 由于信道是所有主机共享的,如果数据帧太长就会出现有的主机长时间不能发送数据,而且有的发送数据可能超出接收端的缓冲区大小,造成缓冲溢出。为避免单一主机占用信道时间过长,规定了以太网帧的最大帧数据长为1500 
100Mbps以太网的时隙仍为512位时,以太网规定一帧的最小发送时间必须为5.12μs
抓包得到的最大帧是1514字节,不是1526
当数据帧到达网卡时,在物理层上网卡要先去掉前导同步码和帧开始定界符,然后对帧进行CRC检验,如果帧校验和错,就丢弃此帧。如果校验和正确,就判断帧的目的硬件地址是否符合自己的接收条件(目的地址是自己的物理硬件地址、广播地址、可接收的多播硬件地址等),如果符合,就将帧交“设备驱动程序”做进一步处理。这时我们的抓包软件才能抓到数据去掉前导同步码、帧开始分界符、FCS之外的数据,其最大值是6+6+2+1500=1514。
目的、源地址
每经过一台路由器,数据帧的源、目IP不会改变,但源、目MAC都会变化
,所有设备都只知道与自己直连设备的MAC地址。
链路层如何知道目标mac地址
假设网络拓扑结构为:A-R1-R2-B
目的MAC为广播MAC(FF:FF:FF:FF:FF:FF)
graph TD
A_find_in_same_segment[主机A发现目标IP是否在统一网段] -->|不在| A2R(需要经过路由器转发)
A2R --> A_get_R{查路由表获得R1的IP地址及出接口?}
A_get_R --> |N| A_arp_request[发起ARP请求,目的IP为R1,目的MAC为广播MAC,源IP和源MAC为主机A网卡的IP和MAC]
A_arp_request --> A_arp_response[R1收到ARP请求,将主机A的IP和MAC加入自己的ARP缓存表,用自身IP和MAC响应主机A的ARP请求]
A_arp_response --> A_save_arp[主机A收到ARP响应,将R1的IP和MAC加入自己的ARP缓存表]
A_save_arp --> A2R_data[用自身IP和MAC为源,主机B的IP和R1的MAC为目的,封装数据帧,并将其转发给R1,此时此时数据帧源IP为主机A,目的IP为主机B,源MAC为主机A,目的MAC为R1]
A[模块A] -->|A1| B(模块B)
B --> C{判断条件C}
C -->|条件C1| D[模块D]
C -->|条件C2| E[模块E]
C -->|条件C3| F[模块F]
用自身IP和MAC为源,主机B的IP和R1的MAC为目的,封装数据帧,并将其转发给R1(此时数据帧源IP为主机A,目的IP为主机B,源MAC为主机A,目的MAC为R1)
sequenceDiagram A->>A: 目标IP是否在同一网段? A-->>A: 不在(需要经过路由器转发), B-->>A: 已收到消息