物理层上就是数据链路层,也属于计算机网络的低层。像诸如以太网协议就是数据链路层的协议,本章进行详细介绍。
链路(link) - 是从一个结点到相邻结点的一段物理线路(有线或无线),而中间没有任何其他的交换结点。在进行数据通信时,两台计算机之间的通信路径往往要经过许多段这样的链路。可见链路只是一条路径的组成部分。
数据链路(data link) - 当需要一条线路上传送数据时,除了必须有一条物理线路外,还必须有一些必要的通信协议来控制这些数据的传输。把实现这些协议的硬件和软件加到链路上,就构成了数据链路。
现在最常用的方法就是使用网路适配器(即网卡,即包含硬件,也包括软件)来实现这些协议。一般的适配器都包括数据链路层和物理层这两层的功能。
帧–数据链路层的协议数据单元。
数据链路层把网络层下发的数据构成帧,然后发送到链路上。同时把从链路上接收到的帧中的数据取出并上发给网络层。
数据链路层使用的信道主要有以下两种类型:
针对每种信道,其帧的格式各不相同,稍后会详细介绍。
数据链路层协议有许多种,但有三个基本问题则是相同的。这三个问题分别是:
封装成帧(framing)就是将网络层下发的数据前后分别添加首部和尾部,这样就构成了一个帧。
所有在互联网上传送的数据都是以分组(即IP数据报)为传送单位,这个来自网络层的IP数据报传送到数据链路层就称为帧的数据部分。然后在帧的数据部分的前面和后面分别添加上首部和尾部,就构成一个完整的帧。这样的帧就是数据链路层的数据传送单位。
帧的长度 = 帧的数据部分长度 + 帧首部长度 + 帧尾部长度,而帧的数据部分的长度的最大上限为MTU(最大传送单元 Maxinum Transfer Unit)。
帧首部和尾部除了包含许多的控制信息,另外的作用就是帧定界(即确定帧的界限),帧定界可以使用特殊的帧定界符。
ASCII码是7位编码,一共可组成128个不同的ASCII码,其中可打印的有95个,而不可打印的控制字符33个。当帧的数据部分为可打印的ASCII码构成时,帧定界符是SOH
(十六进制01,二进制00000001)和EOT
(十六进制04,二进制00000100)。其中SOH
表示帧开始,EOT
表示帧结束。
当数据在传输中出现差错时,帧定界符的作用非常明显。假定发送端在尚未发送完一帧时出现故障,中断了发送。随后恢复正常,于是重头开发发送刚才未发送完成的帧。由于使用了帧定界符,接收端就知道前面的数据是不完整的帧(只有SOT
而无EOT
)。
由于帧的开始和结束的标记使用专门指明的控制字符,因此,帧的数据部分中的任何8比特组成一定不允许和用作帧定界符的比特编码一样,否则会出现帧定界错误。
SOT
或EOT
的控制字符。SOT
或EOT
类似的情况。为了能解决此问题,到达帧的透明传输。就必须在发送端的数据链路层中,将数据中出现控制字符SOT
或EOT
的前面插入一个转义字符ESC
(十六进制 1B,二进制00011011)。这种方法称为字节填充或字符填充。
接收端在接收到帧数据后,就会将数据中的转义字符移除,还原真实的帧数据部分。
现实的通信链路都不会是理想的。也就是说,比特在传输过程中可能会产生差错:1可能会变成0,而0也可能变成1。这就是比特差错。
数据通信中,接收端需要检测在传输过程中是否发生差错,常用的技术有:
它们都是发送端对消息按照某种算法计算出校验码,然后将校验码和消息一起发送到接收端。接收端对接收到的消息按照相同算法得出校验码,再与接收到的校验码比较,以判断接收到消息是否正确。
这种为了进行检错而添加的冗余码常称为帧校验序列FCS(Frame Check Sequence)。
注意:循环冗余校验CRC和帧检验序列FCS不是一个概念,CRC是一种检错方法,而FCS是添加在数据后面的冗余码,在检错方法上可以选用CRC,但也可不选CRC。
一个完整的帧包括:
[帧首部]+[帧的数据部分]+[FCS校验码]+[帧尾部]
上小节中的CRC只能做到对帧的无差错接受,即凡是接收端数据链路层接受的帧均无差错。
但是在实际传输过程中,除了比特差错还可能包括一些传输差错,例如:
对于通信质量较差的无线传输链路,数据链路层使用确认和重传机制,保证为上层提供可靠传输的服务。
对于通信质量良好的有线传输链路,数据链路层协议不使用确认和重传机制,即不要求为上层提供可靠的传输服务。如果传输出现差错,则有上层协议负责处理(如 TCP协议)。
在之前通信线路质量较差的年代,为了能实现可靠的数据链路传输,一般都使用高级数据链路控制HDLC(High-level Data Link Control)协议。但是现在HDLC已经很少使用了,故而不做说明了。
互联网用户通常都要连接到某个ISP才能接入互联网,PPP协议就是用户计算机和ISP进行通信时所使用的数据链路层协议。也是目前使用最广泛的数据链路层协议。
PPP(Point to Point Protocol)点对点协议,是提供在点到点链路上传递、封装网络层数据包的一种数据链路层协议,主要用于支持全双工的同异步链路上,并按照顺序传递数据包。
设计目的主要是用来通过拨号或专线方式建立点对点连接发送数据,使其成为各种主机、网桥和路由器之间简单连接的一种共通的解决方案。
RFC1661
字节数 | 含义 | 说明 |
---|---|---|
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 | 定界符 |
PPP协议主要包括三部分:
LCP(Link Control Protocol),用于PPP的链路协商,PPP连接的建立(Establish阶段)就是从交换LCP报文开始的,LCP协商阶段所有非LCP报文都会被静默丢弃(silently discarded),LCP协商完成后,LCP就进入LCP Opened状态,而PPP开启下一个状态。
LCP功能涉及:
具体LCP协商机制就是不同的报文交换,也就是LCP Packets就决定了LCP的协商过程。
LCP帧格式:在PPP分组上进行简单的封装。
LCP报文封装格式主要涉及以下3个字段:
根据代码域,LCP帧可以分为以下三大类型:
代码域类型(十六进制,十进制) | 代码域说明 | 标识域 | 配置/数据域 |
---|---|---|---|
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顺序也不能改变。非法的包会直接被丢弃。 |
代码域类型(十六进制,十进制) | 代码域说明 | 标识域 | 配置/数据域 |
---|---|---|---|
Terminate-Request(0x05,5) | 用于关闭连接。希望关闭的一方会发送Terminate-Request,另一方收到后会回复Terminate-Ack,若没有收到另一方的回复,Terminate-Request会持续发送。 | ||
Terminate-Ack (0x06,6) | 响应关闭连接请求。 | Terminate-Ack中的值应和Terminate-Request中一致 |
代码域类型(十六进制,十进制) | 代码域说明 | 标识域 | 配置/数据域 |
---|---|---|---|
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) | 指出链路保持建立的时间 |
配置选项(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...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
一个LCP帧中可以包含多个LCP配置项
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
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...
+-+-+-+-+-+-+-+-+
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...
+-+-+-+-+-+-+-+-+
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) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 1
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 1
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
在LCP完成链路建立和认证之后,该链路每端都进入网络状态,并使用一个或者多个NCP进行网络层的相关协商。对于IPv4,NCP被称为IP控制协议(IPCP) 对于IPv6,NCP被称为IPV6CP。
(这里不详细展开了)
认证方式:一端发送明文口令至对等端,由对方认证。
CHAP是双方都把随机数+密码通过散列函数来运算,所以网路上只会监看到杂凑函数的种类及随机数,不会看到密码,安全性很高。
当用户拨号接入IS 时,路由器的调制解调器对拨号做出确认,并建立一条物理连接(底层up)。PC机向路由器发送一系列的 LCP分组(封装成多个PPP帧)。
这些分组及其响应选择一些PPP参数,和进行网络层配置(此前如有PAP或CHAP验证先要通过验证),NCP给新接入的PC机分配一个临时的IP地址,使PC机成为因特网上的一个主机。
通信完毕时,NCP释放网络层连接,收回原来分配出去的IP地址。接着,LCP释放数据链路层连接。最后释放的是物理层的连接。
具体可以参考《计算机网络(第7版)-谢希仁》第3.2.3节