物理层上就是数据链路层,也属于计算机网络的低层。像诸如以太网协议就是数据链路层的协议,本章进行详细介绍。
1 数据链路层
链路(link) - 是从一个结点到相邻结点的一段物理线路(有线或无线),而中间没有任何其他的交换结点。在进行数据通信时,两台计算机之间的通信路径往往要经过许多段这样的链路。可见链路只是一条路径的组成部分。
数据链路(data link) - 当需要一条线路上传送数据时,除了必须有一条物理线路外,还必须有一些必要的通信协议来控制这些数据的传输。把实现这些协议的硬件和软件加到链路上,就构成了数据链路。
现在最常用的方法就是使用网路适配器(即网卡,即包含硬件,也包括软件)来实现这些协议。一般的适配器都包括数据链路层和物理层这两层的功能。
1.1 数据链路和帧
帧–数据链路层的协议数据单元。
数据链路层把网络层下发的数据构成帧,然后发送到链路上。同时把从链路上接收到的帧中的数据取出并上发给网络层。
数据链路层使用的信道主要有以下两种类型:
- 点对点信道 – 这种信道使用一对一的点对点通信方式。
- 广播信道 – 这种信道使用专门的共享信道协议来协调这些主机的数据发送。广播信道上链接的主机很多,因此必须使用专用的共享信道协议来协调这些主机的数据发送。
针对每种信道,其帧的格式各不相同,稍后会详细介绍。
1.2 三个基本问题
数据链路层协议有许多种,但有三个基本问题则是相同的。这三个问题分别是:
1.2.1 封装成帧
封装成帧(framing)就是将网络层下发的数据前后分别添加首部和尾部,这样就构成了一个帧。
所有在互联网上传送的数据都是以分组(即IP数据报)为传送单位,这个来自网络层的IP数据报传送到数据链路层就称为帧的数据部分。然后在帧的数据部分的前面和后面分别添加上首部和尾部,就构成一个完整的帧。这样的帧就是数据链路层的数据传送单位。
1.2.1.1 帧长度
帧的长度 = 帧的数据部分长度 + 帧首部长度 + 帧尾部长度,而帧的数据部分的长度的最大上限为MTU(最大传送单元 Maxinum Transfer Unit)。
1.2.1.2 帧定界
帧首部和尾部除了包含许多的控制信息,另外的作用就是帧定界(即确定帧的界限),帧定界可以使用特殊的帧定界符。
ASCII码是7位编码,一共可组成128个不同的ASCII码,其中可打印的有95个,而不可打印的控制字符33个。当帧的数据部分为可打印的ASCII码构成时,帧定界符是SOH
(十六进制01,二进制00000001)和EOT
(十六进制04,二进制00000100)。其中SOH
表示帧开始,EOT
表示帧结束。
当数据在传输中出现差错时,帧定界符的作用非常明显。假定发送端在尚未发送完一帧时出现故障,中断了发送。随后恢复正常,于是重头开发发送刚才未发送完成的帧。由于使用了帧定界符,接收端就知道前面的数据是不完整的帧(只有SOT
而无EOT
)。
1.2.2 透明传输
由于帧的开始和结束的标记使用专门指明的控制字符,因此,帧的数据部分中的任何8比特组成一定不允许和用作帧定界符的比特编码一样,否则会出现帧定界错误。
- 当传输的帧是用文本文件组成的帧时,其数据部分不会出现类似
SOT
或EOT
的控制字符。 - 当传输的帧是非ASCII码的文本文件时,就可能会出现部分字符与
SOT
或EOT
类似的情况。
为了能解决此问题,到达帧的透明传输。就必须在发送端的数据链路层中,将数据中出现控制字符SOT
或EOT
的前面插入一个转义字符ESC
(十六进制 1B,二进制00011011)。这种方法称为字节填充或字符填充。
接收端在接收到帧数据后,就会将数据中的转义字符移除,还原真实的帧数据部分。
1.2.3 差错检测
1.2.3.1 比特差错
现实的通信链路都不会是理想的。也就是说,比特在传输过程中可能会产生差错:1可能会变成0,而0也可能变成1。这就是比特差错。
数据通信中,接收端需要检测在传输过程中是否发生差错,常用的技术有:
- 奇偶校验(Parity Check);
- 校验和(Checksum);
- 循环冗余检验CRC(Cyclic Redundancy Check),目前数据链路层广泛使用;
它们都是发送端对消息按照某种算法计算出校验码,然后将校验码和消息一起发送到接收端。接收端对接收到的消息按照相同算法得出校验码,再与接收到的校验码比较,以判断接收到消息是否正确。
这种为了进行检错而添加的冗余码常称为帧校验序列FCS(Frame Check Sequence)。
注意:循环冗余校验CRC和帧检验序列FCS不是一个概念,CRC是一种检错方法,而FCS是添加在数据后面的冗余码,在检错方法上可以选用CRC,但也可不选CRC。
一个完整的帧包括:
[帧首部]+[帧的数据部分]+[FCS校验码]+[帧尾部]
1.2.3.2 传输差错
上小节中的CRC只能做到对帧的无差错接受,即凡是接收端数据链路层接受的帧均无差错。
但是在实际传输过程中,除了比特差错还可能包括一些传输差错,例如:
- 帧丢失 - 丢失部分帧。发送[#1]-[#2]-[#3],接受到[#1]-[#3],丢失[#2]。
- 帧重复 - 部分帧重复发送。发送[#1]-[#2]-[#3],接受到[#1]-[#2]-[#2]-[#3],收到2个[#2]。
- 帧失序 - 部分帧的顺序颠倒。发送[#1]-[#2]-[#3],接受到[#1]-[#3]-[#2],后发送帧[#3]先到达。
对于通信质量较差的无线传输链路,数据链路层使用确认和重传机制,保证为上层提供可靠传输的服务。
对于通信质量良好的有线传输链路,数据链路层协议不使用确认和重传机制,即不要求为上层提供可靠的传输服务。如果传输出现差错,则有上层协议负责处理(如 TCP协议)。
2 点对点协议
2.1 高级数据链路控制HDLC
在之前通信线路质量较差的年代,为了能实现可靠的数据链路传输,一般都使用高级数据链路控制HDLC(High-level Data Link Control)协议。但是现在HDLC已经很少使用了,故而不做说明了。
2.2 点对点协议PPP
互联网用户通常都要连接到某个ISP才能接入互联网,PPP协议就是用户计算机和ISP进行通信时所使用的数据链路层协议。也是目前使用最广泛的数据链路层协议。
PPP(Point to Point Protocol)点对点协议,是提供在点到点链路上传递、封装网络层数据包的一种数据链路层协议,主要用于支持全双工的同异步链路上,并按照顺序传递数据包。
设计目的主要是用来通过拨号或专线方式建立点对点连接发送数据,使其成为各种主机、网桥和路由器之间简单连接的一种共通的解决方案。
2.2.1 PPP功能
- PPP具有动态分配IP地址的能力,允许在连接时刻协商IP地址;
- PPP支持多种网络协议,比如TCP/IP、NetBEUI、NWLINK等;
- PPP具有错误检测能力,但不具备纠错能力,所以PPP是不可靠传输协议;
- ppp支持数据压缩;
- PPP具有身份验证功能;
- PPP可以用于多种类型的物理介质上,包括RS232串口链路、电话线ISDN线路、移动电话和光纤(例如SDH),PPP也用于Internet接入;
2.2.2 PPP帧格式
下图就是PPP帧的格式示意图:
字节数 | 含义 | 说明 |
---|---|---|
1 | 标志字段F=0x7E | 定界符,如果0x7E出现在帧内部的话,需要出现问题,所以有两种解决方案: (1)在异步链路上使用字符填充,即把0x7E用0x7D5E替换 (2)在同步链路上使用零比特填充,即在连续的5个1之后填充一个0 |
1 | 地址字段A | 用于指定那个站正在处理,但是PPP只关心一个站,所以设置了0xFF(所有站) |
1 | 控制字段C | 用于帧序列和重传行为,PPP中没有用,设为固定值0x03 |
2 | 协议 | 指示在信息字段中封装的数据类型: (1)0x0021时,数据部分是IP数据报 (2)0xC021时,数据部分是LCP数据(链路控制协议) (3)0x8021时,数据部分是NCP(网络控制协议)数据 (4)0xC023 时,数据部分是PAP数据 (5)0xC025时: LCP中链路质量报告LQR (6)0xC223时,数据部分是CHAP数据 |
1500 | 数据部分 | 最大长度不能超过1500字节,1500字节大小等于PPP协议中配置参数选项MRU |
2 | FCS(校验) | 用于差错检测的冗余循环校验码 |
1 | 标志字段F=0x7E | 定界符 |
2.2.3 PPP协议的组成
PPP协议主要包括三部分:
- LCP(Link Control Protocol)链路控制协议;
- NCP(Network Control Protocol)网络控制协议
- PPP的扩展协议(如Multilink Protocol),比如认证协议,最常用的包括口令验证协议PAP(Password Authentication Protocol)和挑战握手验证协议CHAP(Challenge-Handshake Authentication Protocol)。
2.2.4 LCP
LCP(Link Control Protocol),用于PPP的链路协商,PPP连接的建立(Establish阶段)就是从交换LCP报文开始的,LCP协商阶段所有非LCP报文都会被静默丢弃(silently discarded),LCP协商完成后,LCP就进入LCP Opened状态,而PPP开启下一个状态。
LCP功能涉及:
- 自动协商封装格式选项(automatically agree upon the encapsulation format options);
- 数据包大小限制;
- 检测回环链路;
- 配置错误;
- 终结连接(terminate the link);
具体LCP协商机制就是不同的报文交换,也就是LCP Packets就决定了LCP的协商过程。
2.2.4.1 LCP帧格式
LCP帧格式:在PPP分组上进行简单的封装。
与PPP报文的区别就是在信息数据的封装格式区别。
LCP报文封装格式主要涉及以下3个字段:
- 代码域:给出请求或者响应的操作类型。
- 标识域:LCP请求帧的发送方提供的序列号,在生成一个回复(ACK,NACK,REJECT)时,这个字段通过复制响应分组请求中包含的值来构造,请求方可通过匹配标识符来识别相应请求的应答。
- 长度域:LCP分组的字节长度,不能超过最大接收单元(MRU),长度字段是LCP协议的一部分,PPP协议不提供这些字段。
- 配置/数据域:指明配置数据或协议具体数据信息。
2.2.4.2 LCP类型
根据代码域,LCP帧可以分为以下三大类型:
- 链路配置(Link Configuration packets)
代码域类型(十六进制,十进制) | 代码域说明 | 标识域 | 配置/数据域 |
---|---|---|---|
Configure-Request(0x01,1) | 用于请求打开连接 | 用于指示通信序列号,当Options字段内容发生改变或者收到一个合法的Configure-Request回复时,Identifier必须改变。当然,重传当前包不需要。 | Options字段是可变长字段,内容是对选项默认值的修改协商,默认值不需要包括在其中。也就是说若Options的内容为空,则发送端希望就按照默认的参数建立连接。 |
Configure-Ack (0x02,2) | 在收到Configure-Request包后,若包中的Options都是可以接受的,则必须回复一个Configure-Ack包,表示接受这组选项。 | 和收到的Configure-Request包中的Identifier一致,以指示回复的是哪个Request包 | Options与对应的Configure-Request包需严格匹配 |
Configure-Nak(0x03,3) | 在收到Configure-Request包后,若包中的Options都是可识别的,但其中的一些协商值不接受,则回复Configure-Nak,用建议选项表明部分拒绝。 | 和收到的Configure-Request包中的Identifier一致,以指示回复的是哪个Request包 | 回复的包中Options仅仅包括Configure-Request中不接受的Options,且这些Options的顺序不会改变。也就是仅仅将Configure-Request中不接受的Options中接受的配置协商剔除。非法的包会直接被丢弃。 |
Configure-Reject(0x04,4) | 在收到Configure-Request包后,若包中的Options有不可识别的,或者不可协商的,则回复Configure-Reject,表示完全拒绝一个或多个选项 | 和收到的Configure-Request包中的Identifier一致,以指示回复的是哪个Request包 | Options字段仅仅包括不可接受的配置选项,接受的Options被剔除。和Nak一样,其余Options顺序也不能改变。非法的包会直接被丢弃。 |
- 链路终止(Link Termination packets)
代码域类型(十六进制,十进制) | 代码域说明 | 标识域 | 配置/数据域 |
---|---|---|---|
Terminate-Request(0x05,5) | 用于关闭连接。希望关闭的一方会发送Terminate-Request,另一方收到后会回复Terminate-Ack,若没有收到另一方的回复,Terminate-Request会持续发送。 | ||
Terminate-Ack (0x06,6) | 响应关闭连接请求。 | Terminate-Ack中的值应和Terminate-Request中一致 |
- 链路维护(Link Maintenance packets)
代码域类型(十六进制,十进制) | 代码域说明 | 标识域 | 配置/数据域 |
---|---|---|---|
Code-Reject(0x07,7) | 当收到一个LCP包发现Code字段未知时(可能对端使用的协议版本不一致),就需要回复一个Code-Reject。 当对端收到Code-Reject,若其中指示的未知字段是协议要求的必须字段时,对端通常会报告问题并关闭连接,因为这类问题通常没法自动协商解决。 | 每发送一个Code-Reject,Identifier都需改变 | 完整包含收到LCP包中未知的部分 |
Protocol-Reject (0x08,8) | 当收到一个PPP包发现协议(Protocol)字段的内容未知/不支持时,就需要回复一个Protocol-Reject。 一旦接收到Protocol-Reject,必须立刻停止继续发送指定的协议相关包。 Protocol-Reject只允许在LCP Opened阶段发出/收到,在其他阶段发出/收到都会被丢弃。 | 每发送一个Protocol-Reject,Identifier都需改变 | 分为两个字段: (1)Rejected-Protocol:指示驳回(rejected)的协议 (2)Rejected-Information:包含被驳回的包的内容(去掉头和FCS) |
Echo-Request(0x09,9) | 用于链路检测,在LCP Opened阶段收到Echo-Request时,必须回复一个Echo-Reply。并且在LCP Opened阶段,必须有Request和Reply这个过程。 | 分为两个字段: (1)Magic-Number:用于链路检测 (2)Data | |
Echo-Reply(0x0A,10) | 响应链路检测请求 | Echo-Reply的Identifier必须和Echo-Request一致 | |
Discard-Request(0x0B,11) | 也是用于链路检测,向对端发送这个包,对端收到后直接丢弃。这个包也只能在LCP Opened阶段发出。用于性能测试,指示对方丢弃没有响应的分组 | ||
标识(0x0C,12) | 了解对方的系统类型 | ||
剩余时间(0x0D,13) | 指出链路保持建立的时间 |
2.2.4.3 LCP配置选项
配置选项(Configuration Option)在连接配置包(Link Configuration packets)类型中已经提到。它允许修改PPP默认的一些配置,如果Configure-Request包不提及这些配置,意味着使用PPP默认配置。
格式:
0 1 2
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Data...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Type:指示配置选项类型
- Length:配置选项的总长度(Type、Length和Data字段)
- Data:具体信息
一个LCP帧中可以包含多个LCP配置项
2.2.4.4 LCP配置选项类型
- Maximum-Receive-Unit (MRU)
这个配置选项是必须告知对端的,它表示本端允许收到的最大包大小。默认值为1500(字节)。- Type:值取1
- Length:值取4
- Maximum-Receive-Unit:指示MRU
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Maximum-Receive-Unit |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Authentication-Protocol
默认情况是不需要认证的。如果需要认证,这个配置选项也不应该在很早的Configure-Request包中就发出,因为保证链路能正常通信才是最重要的,所以在协商完一些基本参数后,才能开始协商认证这种事。- Type:值取3
- Length:值≥4
- Authentication-Protocol:有两种认证协议:c023 Password Authentication Protocol(PAP);c223 Challenge Handshake Authentication Protocol(CHAP)
- Data:也许需要传输一些附加数据
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Authentication-Protocol |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data...
+-+-+-+-+-+-+-+-+
- Quality-Protocol
协商使用链路质量检测(link quality monitoring)的方法,默认情况下链路质量检测不开启。- Type:值取4
- Length:值≥4
- Quality-Protocol:仅有一种协议,取值c025 Link Quality Report
- Data:也许需要传输一些附加数据
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Quality-Protocol |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data...
+-+-+-+-+-+-+-+-+
- Magic-Number
这个配置选项提供了一种方法用于检测回环或者其他的链路异常。默认情况下不协商,Magic-Number取0。需要协商时,会随机生成一个数,尽量保证这个数唯一,所以通常会将机器序列号、MAC地址等数作为种子来生成这个随机数。
当收到的Configure-Request含有Magic-Number配置选项时,将这个Magic-Number和最后一个发出去的Configure-Request包中的Magic-Number比较,如果数字相同,则链路很有可能出现环路。为了进一步确认,必须再发一个Configure-Nak包,含有重新生成的Magic-Number,以确定是否有环路,在未确认前,Configure-Request包停止发送。所以如果存在环路,会陷入一直发送Configure-Nak包的死循环。
Echo-Request、Echo-Reply和Discard-Request包都有Magic-Number字段,如果Magic-Number已经产生,那么这些包发送时就必须将此填入。- Type:值取5
- Length:值取6
- Magic-Number:Magic-Number
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Magic-Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Magic-Number(cont) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Protocol-Field-Compression (PFC)
提供了PPP协议字段的压缩协商。PPP包中的协议字段(Protocol)默认长度为2字节,通过协商可以减少到1字节。具体方案参考最近标准。- Type:值取7
- Length:值取2
0 1
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Address-and-Control-Field-Compression (ACFC)
提供了数据链路层地址和控制字段的压缩协商。这两个字段通常是固定的常数值,所以可以通过协商来压缩。具体方案参考最近标准。- Type:值取8
- Length:值取2
0 1
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2.2.4.5 LCP配置详细,LCP帧,PPP帧三者关系图
2.2.4.6 LCP协商过程
2.2.5 NCP
在LCP完成链路建立和认证之后,该链路每端都进入网络状态,并使用一个或者多个NCP进行网络层的相关协商。对于IPv4,NCP被称为IP控制协议(IPCP) 对于IPv6,NCP被称为IPV6CP。
(这里不详细展开了)
2.2.6 PPP验证
2.2.6.1 PAP
认证方式:一端发送明文口令至对等端,由对方认证。
PAP认证过程:
- 被验证方首先发起验证请求,两次握手验证
- 密码以明文传送,安全性较低
PAP包格式:
2.2.6.2 CHAP验证
CHAP是双方都把随机数+密码通过散列函数来运算,所以网路上只会监看到杂凑函数的种类及随机数,不会看到密码,安全性很高。
CHAP认证过程:
- 主验证方首先发起验证请求,三次握手验证
- 不发送密码,安全性比PAP高
CHAP包格式:
CHAP认证过程报文交换过程:
2.2.7 PPP工作状态时序图
当用户拨号接入IS 时,路由器的调制解调器对拨号做出确认,并建立一条物理连接(底层up)。PC机向路由器发送一系列的 LCP分组(封装成多个PPP帧)。
这些分组及其响应选择一些PPP参数,和进行网络层配置(此前如有PAP或CHAP验证先要通过验证),NCP给新接入的PC机分配一个临时的IP地址,使PC机成为因特网上的一个主机。
通信完毕时,NCP释放网络层连接,收回原来分配出去的IP地址。接着,LCP释放数据链路层连接。最后释放的是物理层的连接。
具体可以参考《计算机网络(第7版)-谢希仁》第3.2.3节