《TCP/IP 详解 卷1:协议》第 3 章:链路层
在体系结构中,我们知道:链路层(或数据链路层)包含为共享相同介质的邻居建立连接的协议和方法,同时,设计链路层的目的是为 IP 模块发送和接受 IP 数据报,链路层可用于携带支持 IP 的辅助性协议,例如 ARP。
TCP/IP 取得成功的的原因之一在于它能工作在几乎任意一种链路之上。不同的链路层依赖于其使用的网络硬件类型:有限局域网,例如以太网;城域网,例如有线电视、DSL 连接;有线语音网络,例如支持调制解调器的电话线;无线网络,如 WiFi(无线局域网);基于蜂窝技术的无线数据服务。在本章中,主要讨论以太网,以及如何使用点到点协议 (PPP)。
大多数链路层技术都有一个相关的协议,描述由网络硬件传输的 PDU(Protocol Data Unit,协议数据单元) 格式。在描述链路层数据单元时,我们通常使用术语帧(frame),来和那些更高层的 PDU 格式区别开来,如网络层和传输层的 PDU 分组(packet)和段(fragment)。帧通常支持可变帧长度,但有一个上限——最大传输单元(MTU,Maximum Transmission Unit),这是链路层的一个特点。
以太网、IEEE 802 局域网标准
以太网(Ethernet)这个术语通常指一套标准,由 DEC、Intel、Xerox 公司于 1980 年首次发布,在 1982 年加以修订。第一个常见格式的以太网,目前被称为 “10 Mb/s 以太网” 或 “共享以太网”,它被 IEEE 采纳成为 802.3 标准。这种网络的结构通常如下所示:
以太网包含如下概念和知识点:
CSMA/CD or MAC
基本共享以太网包含一个或多个站(station),它们都被连接到一个共享的电缆段上。标准需要每个以太网接口实现一种分布式算法。This common scheme is called carrier sense, multiple access with collision detection ,也就是CSMA/CD:带冲突检测的载波侦听多路访问。
-
CSMA/CD 协调哪些计算机可以访问共享的介质(电缆),不需要其他特殊协议或同步。有助于降低成本、促进以太网技术的普及。
-
“载波侦听”:一个站在发送自己的数据之前,首先检测目前网络上发送的信号,在网络空闲时,才发送自己的帧。
-
“碰撞检测”:如果其他站碰巧在发送,重叠的电信号被视为碰撞(collision)。在这种情况下,站可以检测(detect)到。如果检测到碰撞,会导致发送方等待一个随机时间,然后重新发送数据。
-
等待时间量的选择依据一个的概率分布。随后,如果再次检测到碰撞,每个碰撞会使等待时间长度加倍。最终每个站会得到机会转发,或者在尝试一定次数之后(传统以太网为 16)后超时。
-
只有当介质(medium)被确定为空闲状态时,链路层的 PDU 可以从一个站发送到其他一个或更多站。任何给定的时间内,网络中同一时刻只能有一个帧在传输。CSMA/CD 因此有另一个更正式的名字:介质访问控制协议,Medium Access Control。
-
以太网是一种广播网络。
以太网帧格式 / Frame Format
下面介绍交换机如何处理 PDU(Protocol Data Unit,协议数据单元)。
所有的以太网帧都基于一个共同的格式。
字段 | 长度(byte) | 内容 | 含义 |
---|---|---|---|
前导(Preamble) | 7 | 一般是一种公认的模式,典型值为 0xAA | 接收接口电路使用,以确定帧的到达时间并确定编码位之间的时间量(称为时钟恢复)。简单来说,就是用于同步。 |
帧起始分隔符(SFD) | 1 | 固定值:0xAB | 以太网帧开始的标志 |
目的MAC地址(DST) | 6 | 一个 MAC 地址 | 指明帧的接受者。目的地址也支持多个站点,例如广播(ARP协议)、组播(ICMPv6) |
源MAC地址(SRC) | 6 | 一个 MAC 地址 | 指明帧的发送者 |
长度或类型(Length/Type) | 2 | 常见值有 IPv4(0x0800)、IPv6(0x86DD)、ARP(0x0806) | 帧的数据字段的长度(长度或类型) |
标签(tag) | 最大482字节 | 如 QoS 指示符(服务质量) | 包含由其他 IEEE 标准定义的各种协议字段 |
有效载荷(payload) | 46~1500 | 略 | 存放高层 PDU 的地方。对于TCP/IP 是 IP 数据包 |
填充(女仆长のpad) | 可选 | 一定长度的连续 0 | 确保帧长度符合最小长度要求 |
循环冗余检验(FCS) | 4 | 见下文 | 对接收网卡提供判断是否传输错误的一种方法 |
帧检验序列/循环冗余检验
最后一个字段 FCS(Frame Check Sequence)提供了对帧完整性的检查。方法是:Cyclic Redundancy Check (CRC) 循环冗余检验。这篇文章介绍的很好,在这里引用一下:
CRC 算法的基本思想是将传输的数据当做一个位数很长的数。将这个数除以另一个数。得到的余数作为校验数据附加到原数据后面。(商是抛弃的)…… 为了进行CRC运算,也就是这种特殊的除法运算,必须要指定个被除数,在CRC算法中,这个被除数有一个专有名称叫做“生成多项式”。生成多项式的选取是个很有难度的问题,如果选的不好,那么检出错误的概率就会低很多。好在这个问题已经被专家们研究了很长一段时间了,对于我们这些使用者来说,只要把现成的成果拿来用就行了。
多项式的位宽(Width,简记为W),这个位宽不是多项式对应的二进制数的位数,而是位数减 1。按照 CRC 算法的要求,计算前要在原始数据后填上 W 个 0。
值得注意的是,CRC 使用的是 mod 2 二进制除法计算余数。与四则运算不同的是模2运算不考虑进位和借位,即模2加法是不带进位的二进制加法运算,模2减法是不带借位的二进制减法运算。该计算结果的反码放置在帧的 CRC 或 FCS 字段中。在接受到数据之后,接收方执行相同的算法,得到结果,判断与存放在 FCS 字段的值是否匹配。如果两者不匹配,帧可能在传输过程中受损,通常被丢弃。
网桥和交换机
IEEE 802.1d 标准规定了网桥的操作。 交换机本质上是高性能的网桥。
交换机
随着以太网技术的发展,更快的计算机和基础设施使得局域网速度不断提升。(速度从 10Mb/s 增加到 100Mb/s、10Gb/s 甚至更高)。
二十世纪九十年代初,共享电缆已经很大程度被双绞线(类似电话线)替代。随着快速以太网的发展(100Mb/s),最初基于竞争的 MAC 协议已经变得不流行。
- 局域网中的每个站之间的线路变成不共享,而是由以太网交换机(Ethernet Switch)实现了一个专用的星形拓扑结构。
- 交换机为以太网中的每个站提供同时发送和接受数据的能力。
- 每个站使用一条专用的线路连接到一个交换机端口(port),在这种情况下,以太网以全双工方式运行,不需要使用 CSMA/CD 算法。
- 交换机可以通过交换机端口级联(interconnect)来形成更大的以太网。这种端口叫做“上行(uplink)端口”
全双工、半双工
-
半双工(half duplex mode):使用一条共享的电缆,CSMA/AD,以太网最初被开发出来的时候就工作在半双工模式。
-
全双工(full duplex mode):交换式以太网。网络不再是单一的共享线路,而代之以很多链路的组合。减少了冲突检测电路的使用,增加了以太网的物理长度。
互连、MAC 学习
图中的交换机 A 和 B 互连,形成一个扩展的局域网。
下面介绍交换机的 MAC 学习(learn)过程:
- 每个网络单元都有自己的 MAC 地址。
- 每个网桥经过一段时间的对域外 MAC 地址的学习后,最终每个交换机会知道每个站可以由哪个端口到达。
- 每个交换机基于每个端口的列表被存储在一张被称为过滤数据库(filtering database)的表中。
- 当交换机(桥)首次打开时,其数据库为空,因此不知道其他站点的位置。 无论何时收到目的地为自己以外的站的帧,它将为此帧目的端口之外的每个端口创建一个副本,并从每个端口发送帧的副本。(好像与广播有些许差别
- why learn?如果交换机从未学习站的位置,每个帧都需要被交付到每个网段,这将导致显著的不必要开销。学习能力(learning capability)可以显著降低开销,这是交换机和网桥的一个基本功能。
- 由于站可能出现异动、网卡更换、MAC 地址改变等各种情况,所以过滤数据库中的一个 MAC 地址可以通过某端口访问这条信息也不能假设是永远正确的。
- 为了解决这个问题,过滤数据库使用一个计时器(通常是五分钟)。如果在这个有效期内,没有再次看到某条目的地址,则将这个条目删除。
生成树协议
我们知道了交换机的一个很重要的能力——MAC 地址学习能力。但由于可能存在端口交叉连接、交换机级联的可能性,可能会导致某些问题,看下图这个例子:
假设上图中的多个交换机刚刚被打开,它们的过滤数据库都为空。由于这个扩展以太网包括的 4 台交换机由冗余链路组成,会产生所谓广播风暴(broadcast storm)
- 当站点 S 发送一个帧时,交换机 B 在端口 7、8、9 复制该帧。
- 这些帧被交换机 A、D、C 接收,而交换机 A 依然会在 2、3 端口复制该帧,交换机 D、C 会在 20、22、13、14 生成更多副本。
- 这些副本在交换机之间来回双向传输,这导致了转发数据库的震荡(oscillate,体会与 collision 的区别),将会导致多余的流量倍增。
这时,需要一种协议来避免这种情况,就是生成树协议(Spanning Tree Protocol,STP)。
- 顾名思义,一个网络拓扑就是一个图,生成树就是包含所有节点而边集合没有形成回路。
- STP 是通过在每个网桥禁用某些端口来避免拓扑环路的。
- 一张图可能有多个生成树,而 STP 用于找出其中一个生成树。
- 生成树的形成和维护由多个网桥完成,所以是在每个网桥上运行一个分布式算法。
上面这个例子中,通过 STP,端口6、7、1、2、13、14、20 处于转发状态,其余端口被阻塞,预防了广播风暴。当然,STP 也能处理拓扑变化,会重新计算一个新的生成树。
STP 状态机
STP 状态机中,端口可能有五个状态:
状态 | 解释 | 状态转移 |
---|---|---|
阻塞(blocking) | 初始化后,端口会进入阻塞状态。不进行地址学习、数据转发、BPDU 发送。但会监控、接收BPDU | 监视接收到的BPDU,如果需要包含在根桥路径上,在这种情况下,端口转换到侦听状态。或者经过最大时间(MaxA),也会转变到侦听状态 |
侦听(listening) | 在侦听状态下,该端口现在允许发送BPDU,但不学习地址或转发数据。 | 在15秒的典型转发延迟(delay)后,端口进入学习状态。 |
学习(learning) | 这里允许执行除转发数据之外的所有过程。 | 等待一个转发延迟就可以进入转发状态。转发延迟内涵见 BPDU 的转发延迟字段。 |
转发(forwarding) | 活跃的交换机端口承载数据流量的正常状态 | 上述三个状态都有可能因为拓扑改变,而被阻塞。 |
禁用(disabled) | 顾名思义 | 由管理配置引起 |
端口角色
每个端口都扮演一个角色。
角色 | 定义 |
---|---|
根端口(root bridge) | 在生成树的边(edge)上,朝向根网桥的端口 |
指定端口(designated port) | 处于转发状态,作为从附加网段(attached segment)到根的最小路径上的端口 |
替代端口(Alternate port) | 与指定端口定义类似,但是达到根成本更高的端口。该类端口为当前"根端口"到"根网桥"提供一条替代路径。平时处于阻塞状态,在根端口失效时可以替代它 |
备份端口(backup port) | 该类端口为"指定端口"到达生成树叶提供一条备份路径,是指定端口的备份端口。仅当两个端口在一个由一个点对点链路组成的环路上连接时,或者当交换机有两个或多个到达共享LAN网段的连接时可以存在。在一个指定端口失效时用来接管。 |
我们主要需要理解根端口和指定端口。贴出英文,好好揣摩:
-
根端口:ports at the end of an edge on the spanning tree headed toward the root.
-
指定端口:ports in the forwarding state acting as the port on the least-cost path to the root from the attached segment.
BPDU
下面介绍网桥协议数据单元(BPDU,Bridge Protocol Data Unit),是 STP 形成、维护生成树过程中所使用的帧。
字段 | 长度(bytes) | 内容 | 含义 |
---|---|---|---|
前导 | 7 | 略 | 略,见 Ethernet,下同 |
帧起始标志 SFD | 1 | 略 | 略 |
DST | 6 | 总是被发送至 01:80:C2:00:00:00 | 链路层组、因特网组播寻址 |
SRC | 6 | 略 | 略 |
长度/类型(L/T) | 2 | 略 | 略 |
LLC/SNAP | 3 | 此头部由 802.1 定义,针对 BPDU 设置为常数 0x424203 | STP 用 LLC(逻辑链路控制)封装。并非所有 BPDU 都用 LLC/SNAP 封装,但这是很常见的选项 |
协议(Protocol identifier) | 2 | 生成树协议设置为 0x0000 | 协议 ID 号 |
版本(Protocol Version Identifier) | 1 | 0/2/3 | STP/RSTP/MSP 用于指出协议版本 |
类型(BPDU Type) | 1 | 与上一个字段,协议版本类似 | 略 |
标志(BPDU flags) | 1 | 见下面详解 | 略 |
根 ID(Root Identifier) | 8 | 发送发使用的根网桥标识符,详情见网桥 ID 字段 | 生成树以某个特定网桥作为根 |
根路径成本(Root Path Cost) | 4 | 到达根 ID 字段中指定的网桥的路径计算成本 | 用于计算生成树算法。 cost 是与链路传速速度成反比的。 |
网桥 ID(Bridge Identifier) | 8 | 交换机的 6 字节的 MAC 地址,以及前面一个 2 字节的优先级字段 | 优先级的值可以通过管理软件来设置,强制要求生成树以某个特定网桥为根网桥 |
端口 ID(Port identifier) | 2 | 端口标识符,即由发送帧给出的端口号。也有一个可配置的 1 字节的优先级字段 | 作用类似网桥 ID 字段中优先级的作用。 |
消息有效期(MsgA) | 2 | 一开始设置为 0 。任何接收 BPDU 的桥将在其非根端口上发送帧,该字段增加 1 | 此字段不像其他与时间相关的字段一样是一个固定值。实质上,该字段用作跳数,给出在接收BPDU之前已经处理的桥的数量。 |
最大有效期(MaxA) | 2 | 指出 BPDU 超时的期限,默认为 20 秒 | 在端口上接收到BPDU时,其包含的信息被保存在存储器中,并参与STP算法的执行中,直到被超时,超时是发生在(MaxA – MsgA)。如果在这个时间段内根端口没有接收到另一个 BPDU,根网桥被宣布“死亡”,重新开始根网桥选举过程。 |
欢迎时间(Hello Time) | 2 | 比如 2 秒 | 表示 BPDU 帧发送间隔 |
转发延迟(Forward Delay) | 2 | 典型为 15 秒 | 给出在学习和收听状态下等待所花费的时间。延迟是为了等待整个生成树的同步、MAC 表的刷新。 |
FCS | 4 | 略 | 略 |
1 byte 的 flag 字段的位分别定义为:
字段 | 长度(bit) | 定义 |
---|---|---|
TC(topology change) | 1 | 拓扑变化 |
P | 1 | 建议 |
端口角色 | 2 | 00 为未知,01 为替代or备份,10 为根端口,11 为指定端口 |
L | 1 | 处于学习状态? |
F | 1 | 处于转发状态? |
A | 1 | 协议,agreement |
TCA(topology change acknowledgement) | 1 | 拓扑变化确认 |
建立生成树
第一个工作是选举根网桥。根网桥是在网络中网桥 ID 标识符最小(优先级和 MAC 地址结合)的网桥。具体步骤:
- 当一个网桥初始化时,都假设自己是根网桥。用自己的网桥 ID 字段作为根 ID字段,发送 BPDU 消息。
- 如果某个网桥检测到一个 根 ID 更小的消息,则立即停止发送自己的帧,并基于接受到的那个更小的 ID 构造下一步要发送的 BPDU。
我们可以这么理解:一群猴子要选出一个猴王出来,一开始,所有猴子都觉得自己能当猴王。假设有三只猴子 A、B、C:
- B 先向 A 发出挑战(交换机 B 用自己的 ID 发送 BPDU 给 A)
- 然而可惜的是, B 失败了(交换机 A 发送过来的 BPDU 中根 ID 字段比自己的要小),这样 B 就会承认 A 比较厉害,此后不再会挑战 A 的权威。(之后是基于 A 的更小的 ID 构造 BPDU,而不是发送自己的网桥 ID 了)
- B 不仅向 A 俯首称臣了,还要向隔壁的 C 传达:A 是目前最厉害的猴子!(以后发送的 BPDU 中的根 ID 字段是 A 的 mac 地址)
- 如果“A 是目前最厉害的猴子”这个消息传遍整个了猴群,那么 A 就当选了猴王。
下面来看一个例子,这个例子里包括四台交换机,各有两个端口互连,路径成本标在路径上:
-
首先选择根网桥。假设这个例子中没有优先级,S1 的 MAC 地址最小,因此 S1 当选根桥(root bridge)。
-
选取每个网桥的根端口,考虑对象:网桥。选取方法:比较每一台交换机每个端口发出的 BPDU 的根路径成本,发出更小 BPDU 的那个端口就是根端口。
S2: 端口 1 收到的 BPDU 的 cost 为 19; 端口 2 的为 19 + 4 + 19 = 42
端口 1 成为根端口
S3: 端口 3: 19 + 19 = 38; 端口 4:19 + 4 = 23
端口 4 成为根端口
S4: 端口 5: 19 + 19 + 4 = 42; 端口 6: 19
端口 6 成为根端口
- 选每个网段的指定端口,考虑对象:每条链路。选取方法:比较每条链路两端发出的 BPDU 的 cost。
S1-S2 网段: 端口 8 发出的 BPDU 的 cost 为 0; 端口 1 发出的 cost 为 19 + 4 + 19 = 42
(这里,BPDU 不会逆着发,联想一下猴王的例子)
端口 8 成为指定端口
S1-S3 网段: 端口 7: 0; 端口 6: 19 + 19 + 4 = 42
端口 7 成为指定端口
S2-S3 网段: 端口 2: 19; 端口 3: 19 + 4 = 23
端口 2 成为指定端口
S3-S4 网段: 端口 5: 19; 端口 4: 19 + 19 = 38
端口 5 成为指定端口
下图是更新的状态:S1 当选根桥(root bridge)。端口 1、4、6 是根端口(蓝色圆圈);端口 2、5、7、8 是指定端口(红色正方形)。既不是根端口,也不是指定端口的,就阻塞(图中的端口 3)。自然,形成了一棵生成树。
现在再来体会以下根端口和指定端口的定义。
-
根端口是在生成树的边(edge)上,朝向根网桥的端口。我们可以联想 Prim 最小生成树算法,既然根端口是生成树边上朝向根网桥的端口,那么意味着根端口向整棵树的枝叶发消息的时候,往根端口发就可以了。
-
指定端口即作为从附加网段(attached segment)到根的最小路径上的端口。“附加的网段”可以想象成生成树扩张的状态。当叶节点需要向根网桥发送 BPDU(例如发送了拓扑改变),则往指定端口发就可以了。一句话总结,就是:
-
根端口就像是树中的 child 指针,指定端口就像是 parent 指针。
此外,还可以得出以下一些性质:
- 每个网络中只有一个根网桥;
- 每个非根网桥只有一个根端口;
- 每个网段只能有一个指定端口;
- 根网桥无根端口;
- 根网桥端口全为指定端口;
处理拓扑变化
STP 另一项重要的工作就是要能处理拓扑变化。虽然前述中提到 filter database 有适应拓扑变化的机制,不过需要五分钟的时间没有接受到某条地址,才会删除这条条目。
- 在 STP 中,当一个端口进入阻塞或转发状态时,意味着拓扑变化。
- 当网桥检测到一个变化,向根端口之外的端口发送拓扑变化通知 TCN BPDU,并它通知自己在树中的父网桥,直到根为止。
- 在到根的路径上的网桥不断转发 TCN BPDU。直到当根网桥接收到拓扑变化通知后,根网桥在后续的周期性配置消息中设置 TC 位,这种消息被网络中的所有网桥转发。
- 设置了 TC 位的 BPDU,允许网桥减小 filter database 中的计时器的有效期(用秒来代替推荐的五分钟)。这样,数据库里的有误条目被快速清除并重新学习(有一个术语描述这种操作,叫做老化),更新了拓扑视图。
快速生成树协议
传统 STP 的一个问题:
生成树是一个具有缓慢收敛时间的旧协议。如果未正确实施,可能会导致主要的网络中断。 阻止链接的想法是客户现在不能接受的一个适当的高可用解决方案。
拓扑变化之后,只能通过一段时间未检测到 BPDU 来检测。收敛时间(沿着生成树重新建立数据流的时间)可能很长。
- 为什么 STP 拓扑变化通知必须发回根端口?因为只有根端口能发 TC 置 1 的 BPDU。更新拓扑的机制是收到 TC BPUD 而老化数据库,更新拓扑。
IEEE 802.1W 改进了传统 STP,定义了快速生成树协议(Rapid Spanning Tree Protocol,RSTP)。
- 端口状态由五个减少到了三个:丢弃、学习、转发。
- STP 中,BPDU 通常由一个通知网桥或根网桥发送。RSTP 中,为了“保持活跃”,BPDU由所有网桥来发送。
- 主要改进是监视每个端口的状态。在 RSTP 中,检测到一次拓扑变化的交换机会发送一个表示拓扑变化的 BPDU。任何接收到它的交换机立即清除自己的过滤数据库。这个改变能显著影响协议的收敛时间。无需等待拓扑变化传递到根网桥再返回,而是立即清理相关条目。
说实话,第一次看到 RSTP 之后觉得这才是正常的思路啊?可能需要监控每个端口的状态需要更多的算法开销吧。
点到点协议
-
PPP,Point-to-Point Protocol,点到点协议【RFC1661】、【RFC1662】、【RFC2153】。
-
PPP是用于在两个节点之间建立直接连接的数据链路层通信协议。PPP 操作只关注一条链路的两端,不需要像 MAC 协议或者 Wi-Fi 那样处理共享资源访问的问题。
-
PPP用于多种类型的物理网络,包括串口线,电话线,中继线,移动电话,专用无线电链路以及SONET等光纤链路。
-
互联网服务提供商(ISP)经常使用 PPPoE(以太网上的点对点协议)建立数字用户线(DSL,Digital Subscriber Line)。可以说是实现互联网与客户的服务连接的“最后一公里”。
-
PPP 是一种协议集合,而不是一个单一的协议。
- 首先,它有支持建立链接的基本方法:逻辑链路控制(Link Control Protocol,LCP)。
- 一系列的网络控制协议(Network Control Protocol),NCP 用于建立了基本链路之后,为各种协议配置信息,建立链路层网络。
- 除此之外,它可以提供连接认证,传输加密和压缩。
PPP 基本帧格式
PPP 设计时,是基于高级数据链路控制(HDLC)建立的一种良好帧格式。
字段 | 长度(bytes) | 内容 | 含义 |
---|---|---|---|
标志(Flag) | 1 | 0x7E | 由两个固定的0x7E包围,指示帧的开始和结束 |
地址(Address) | 1 | 0xFF | 在HDLC中,地址字段将指定哪个站正在寻址。但是因为PPP只关心一个目的地,所以这个领域总是定义为值0xFF,广播地址。 |
控制(Control) | 1 | 0x03 | 用于指示帧排序和重传行为。但这些链路层的可靠性功能通常不是通过PPP实现的,控制字段被设置到固定值0x03 |
协议(Protocol) | 2 | 0x00000x00FF范围中的值包括大多数流行的**网络层协议**,0x80000xBFFF中的值指关联NCP的数据。0xC000~0XEFFF的协议值标识控制协议,如LCP。 | PPP帧的协议字段指示正在传输的数据的类型 |
数据(Data) | 不等 | 帧的有效载荷 | PPP控制、网络层数据 |
填充(Pad) | 不等 | 略 | 略 |
FCS | 2或4 | 略 | 略 |
标志(Flag) | 1 | 0x7E | 由两个固定的0x7E包围,指示帧的开始和结束 |
PPP 状态机
下面是 PPP 状态机:
- 链路不可用阶段。PPP链路都需从这个阶段开始和结束。
- 链路建立阶段。是PPP协议最关键和最复杂的阶段。这是在数据链路层进行。该阶段主要是发送一些配置报文来配置数据链路,这些配置的参数不包括网络层协议所需的参数。在这个阶段主要是通过LCP协议进行链路参数的配置。
- 验证阶段。多数情况下的链路两端设备是需要经过认证后才进入到网络层协议阶段,缺省情况下链路两端的设备是不进行认证的。在该阶段支持PAP 和 CHAP两种认证方式,验证方式的选择是依据在链路建立阶段双方进行协商的结果。
- 网络层协议阶段。一旦PPP完成了前面几个阶段,每种网络层协议(IP、IPX和AppleTalk)会通过各自相应的网络控制协议进行配置,每个NCP 协议可在任何时间打开和关闭。
- 网络终止阶段。PPP能在任何时候终止链路。当载波丢失、授权失败、链路质量检测失败和管理员人为关闭链路等情况均会导致链路终止。PPP 的除了不可用阶段,任何一种状态都可以立即进入网络终止阶段。
链路控制协议
链路控制协议(LCP)构成了互联网协议族中的点对点协议(PPP)的一部分。 在建立PPP通信时,发送和接收设备都发送LCP分组以确定随后的数据传输的标准。
LCP Frame 是在 PPP Frame 上进行了简单的封装。
字段 | 长度(bytes) | 内容 | 含义 |
---|---|---|---|
协议 | 2 | 0xC021 | 标识 LCP |
代码(Code) | 1 | 见下列 | 请求或响应的字段操作 |
标识(Ident) | 1 | 见下列 | 见下列 |
- 代码字段配置的操作类型有:配置请求(按排序从 0x01 递增到 0X0D)、配置ACK、配置NACK 、配置REJECT 、终止请求 、终止ACK 、代码REJECT 、协议REJECT 、回送请求 、回送应答 、放弃请求 、标识 、剩余时间。
- ACK 标识接受一组选项,NACK 表明部分拒绝。
- REJECT 完全拒绝一个或多个选项。
- 配置消息使得链路两端开始基本配置过程,建立商定的选项。
- 终止消息可以清除一条链路
- 回送可由 LCP 在一条活跃的链路上随时交换,验证对方的操作。
- 放弃请求,用于性能测试,指示对方丢弃没有相应的分组。
- 标识、剩余时间用于管理目的:了解对方的系统类型,指出链路建立的时间。
LCP 状态
LCP 用于建立 PPP 链路 ,商定各方选项。典型的过程包括:配置请求、配置确认、认证交换、数据交换、终止交换。因为 PPP 是一个包括很多部分的通用协议,所以一条链路的建立和终止之间可以发生很多其他种类的操作。
(下面引用自闲谈PPP协议)
- 配置请求:
一般而言在进入链路建立阶段时,通信双方无论哪一端都会连续发送几个配置请求报文(Config-Request报文),而这几个请求报文的数据域可能是完全一样的,而仅仅是它们的标识域不同罢了。通常一个配置请求报文的ID是从0x01开始逐步加1的,当对端接收到该配置请求报文后,无论使用何种报文(回应报文可能是Config-Ack、Config-Nak和Config-Reject三种报文中的一种)来回应对方,但必须要求回应报文中的ID(标识域)要与接收报文中的ID一致,当通信设备收到回应后就可以将该回应与发送时的进行比较来决定下一步的操作。
当接收Config-Request报文的一端能识别发送过来的所有配置参数选项且认可所有配置参数选项数据域的内容时,接收端将会给对端回一个Config-Ack报文并将配置请求报文中的配置参数选项原封不动的放置在Config-Ack报文的数据域内(根据协议的规定是不可改变配置参数选项的顺序)。当配置请求报文的发送端收到Config-Ack报后,则会从当前阶段进入到下一个阶段。
- 一旦底层协议表明一个关联变成活跃(例如调制解调器检测到载波),则认为这个链路已经被建立。然后,如果链接需要被认证(一般来说是要的),例如拨号到一个 ISP 时,需要一些额外的信息交换(用户名、密码),以验证链路上一方 or 双方的身份。
当接收Config-Request报文的一端能识别发送端所发送过来的所有配置参数选项,但对部分配置参数选项数据域中的内容不认可时,接收端将会给对端回应一个Config-Nak报文,(注意,是能够识别,只是对部分参数内容不认可,所以不是Config-Reject报文)。然而当接收端收到Config-Nak报文后,会重新发送Config-Request报文,而这个Config-Request报文与上一次所发送的Config-Request报文区别在于那些被对端不认可的配置参数选项的内容被填写到刚刚协商完后再次发送的Config-Request报文中。
当接收Config-Request报文的一端不能识别所有的发送端发送过来的配置参数选项时,此时接收端将会向对端回一个Config-Reject报文,该报文中的数据域只携带那些不能识别的配置参数选项(当配置参数选项的类型域不识别时)。当对端接收到Config-Reject报文后,同样会再次发送一个Config-Request报文,这个配置请求报文与上一次发送的区别在于将不可识别的那些配置参数选项给删除了。
- 链路终止
分为Terminate-Request和Terminate-Reply两种报文。LCP报文中提供了一种机制来关闭一个点对点的连接,想要关断链路的一端会持续发送Terminate-Request报文,直到收到一个Terminate-Reply为止。接收端一旦收到了一个Terminate-Request报文后,必须回应一个Terminate-Reply报文,同时等待对端先将链路断开后,再完成本端的所有断开的操作。LCP的链路终止报文的数据域与链路配置报文的数据域不一样,链路终止报文中无需携带各配置参数选项。对于链路终止报文也同样需要ID一致,当接收到Terminate-Reply报文才会做链路终止操作。
- 当底层协议或硬件表明一个关联停止(例如载波消失),或发生了链路终止请求,并从对方接收到确认终止响应,则这个链路已被终止。
魔术数字
如果一个工作站处于环回模式,这时会使点到点链路出现一个常见问题。魔术字(发送方选择的任意数字)是在链路建立过程中比较重要的一个参数,这个参数是在Config-Request里面被协商的,主要的作用是防止环路。LCP 通过发送魔术数字,查看是否立即返回相同类型的信息。如果是的话,视为检测到环回,并可能需要进行维护。
(下面引用自闲谈PPP协议)
协议为了避免双方可能产生同样的魔术字,从而导致通信出现不必要的麻烦,因此要求由设备采用一些随机方法产生一个独一无二的魔术字。一般来说魔术字的选择会采用设备的系列号、网络硬件地址或时钟。双方产生相同魔术字的可能性不能说是没有的,但应尽量避免……
我们知道魔术字产生的作用是用来帮助检测链路是否存在环路,当接收端收到一个Config-Request报文时,会将此报文与上一次所接收到的Config-Request进行比较,如果两个报文中所含的魔术字不一致的话,表明链路不存在环路。但如果一致的话,接收端认为链路可能存在环路,但不一定存在环路,还需进一步确认,方法是: 此时接收端将发送一个Config-Nak报文,并在该报文中携带一个重新产生的魔术字,而且此时在未接收到任何Config-Request或Config-Nak报文之前,接收端也不会发送任何的Config-Request报文。
- 链路实际不存在环路,而是由于对方产生了一样的魔术字,但实际这种情况出现的概率是很小的。当Config-Nak被原来的发送端接收到后,应该立即重新发送一个Config-Request报文(此报文中的魔术字为之前Nak报文中的,也就是第一次接收端收到的魔术字),当接收端接收到后,与上次比较,由于接收端已经在Nak报文中产生了一个不同的魔术字,此时接收端收到的Config-Request报文中的魔术字与上次配置请求报文中不一样,所以接收端可断定链路不存在环路。
- 链路实际上确实存在环路。在这条链路上就会不断的出现Config-Request、Config-Nak报文,而且魔术字一直是相同的。这样周而复始下去,接收端就会认为PPP链路存在环路的可能性在不断增加,当达到一定数量级时,就可认为此链路存在环路。(注意,不是第一次受到相同的魔术字就判断有环路的)
好了,基本上通过PPP闲谈,我们可以比较彻底的了解PPP协议的工作机制和特点,其实,会者不难,协议都是人制订的,只有简单易用的协议才会最终保留下来,就像TCP/IP打败OSI一样。所以,只要静下心来,没有什么高深的。
PPP 认证
在一条 PPP 链路处于网络状态前,通常需要使用某种认证机制,识别建立链路的对方身份。
- 最简单、安全性最低的认证方案就是密码认证协议(PAP)。非常简单,就是一方请求另一方发送一个明文密码。由于未加密,容易被轻易捕获。
- 查询 - 握手认证协议(CHAP)
其实CHAP的C代表Chanllenge的意思,即验证方会首先发起挑战:你把密码告诉我,这是第一次握手;然后被验证方才会将密码告知验证方,这是第二次握手;最后验证方反馈验证结果,这是第三次握手。而PAP则只有后两次握手,另外PAP的密码是明文,CHAP的是密文。
-
一个随机值从认证方发送到另一方。通过一种特殊的单向(不可逆)功能,将一个随机值和共享密钥(通常由密码生成)结合形成响应中的一个数字。在接受到这个响应之后,认证方能更可靠地验证对方密钥是否正确。不会以明文方式传输密钥或者密码。每次使用不同的随机值,窃听者即使可能捕捉到这个值,也无法通过重放来欺骗对方。
CHAP认证第一步:主认证方发送挑战信息【01(此报文为认证请求)、id(此认证的序列号)、随机数据、主认证方认证用户名】,被认证方接收到挑战信息,根据接收到主认证方的认证用户名到自己本地的数据库中查找对应的密码(如果没有设密码就用默认的密码),查到密码再结合主认证方发来的id和随机数据根据MD5算法算出一个Hash值。
CHAP认证第二步:被认证方回复认证请求,认证请求里面包括【02(此报文为CHAP认证响应报文)、id(与认证请求中的id相同)、Hash值、被认证方的认证用户名】,主认证方处理挑战的响应信息,根据被认证方发来的认证用户名,主认证方在本地数据库中查找被认证方对应的密码(口令)结合id找到先前保存的随机数据和id根据MD5算法算出一个Hash值,与被认证方得到的Hash值做比较,如果一致,则认证通过,如果不一致,则认证不通过。
CHAP认证第三步:认证方告知被认证方认证是否通过。
网络控制协议
在 LCP 完成链路建立和确认之后,该链路每端都进入网络状态。然后就可以开始使用一个或多个的 NCP(Network Control Protocol,NCP 网络控制协议)来进行网络层的相关协商。
典型的例如 IPCP(针对 IPv4 的标准 NCP)用于在一条链路上建立 IPv4 链接。包括一系列选项:IP 压缩、移动 IPv4等等。
PPPoE
对于大多数局域网和一些广域网连接,DHCP 提供了最基本的客户机系统的自动配置方式。对于广域网连接(常见的 DSL,Digital Subscriber Line 数字用户线路),常用另一种基于 PPP 的方式替代 DHCP。这种方法涉及在以太网中携带 PPP,因此称为 PPPoE(Point-to-point protocol over Ethernet)。
- PPPoE 用于广域网连接设备作为一个交换机或者网桥(DSL Modem,也就是所谓的调制解调器,不支持路由)而不是路由器的情况下。
- PPPoE 作为一些 ISP 建立连接的首选,也是建立用户连接到网络的“最后一公里”的首选。
- wiki: 2005年的一本网络书籍指出:“大多数DSL提供商使用PPPoE,它提供认证,加密和压缩。” PPPoE的典型应用包括利用 PPP 设施使用用户名和密码验证用户,主要通过PAP协议而较少通过CHAP。
PPPoE是由UUNET,Redback Networks(现爱立信)和RouterWare(现在的风河系统)开发的。【RFC 2516】
上图显示了一个典型的 ISP 使用 DSL 为客户提供服务。
- 用户将一台家用 PC 连接到 DSL 调制解调器,使用一个点到点的以太网络(使用一根电缆的以太网)
- DSL 提供一条点到点的数字链路。一般是与一条传统的模拟电话线同时工作。对物理电话线的同时使用是采取频分复用实现的。
- DSL 调制解调器有效地向 ISP 的接入集中器(access concentrator)上的 PPP端口提供桥接服务。将接入集线器将客户的调制解调器线路和 ISP 的网络设备互连。
- 一旦 DSL 调制解调器已经成功建立了一个低层的链接 ISP,PC 可以开始 PPPoE 交换。【RFC2516】
环回
在魔术数字提到的环回(loop)概念,可能一开始看起来很奇怪。不过在很多情况下,客户机可能希望用 Internet 协议来与同一计算机上的服务器通信。为了实现这个目标,大多是实现一种工作在网络层的环回能力。
- 使用一个虚拟的还回网络接口来实现。它像一个真正的网络接口,但实际上是一个由操作系统提供的专门的软件。
- 以 127 开头的 IPv4 地址就是为了这个目的而保留。类 UNIX 系统为环回接口分配的地址是
127.0.0.1
(IPv6 为::1
),分配的名称是 localhost。Linux 中,环回接口被称为 lo。 - 发送到环回接口的 IP 数据报不会出现在任何网络中。
- 大多数的实现有经过传输层和网络层对数据的完整处理流程,仅在数据报离开网络层时将其送回给网络层协议栈。
MTU
以太网帧有最小和最大尺寸。
-
最小帧要求有 64 字节,有效载荷长度最小为 48 长度。当有效载荷较短,就需要填充一些字节(都是 0),确保达到最小长度。
-
最小长度对使用 CSMA/CD 的以太网来说很重要,如果帧太小意味着传输速度过快。当某个站检测到碰撞时,可能会发生这个帧已经传输完的情况,不知道是哪个帧发生了冲突。
-
传统以太网最大帧长度是 1518 字节。选择这个值也是有折衷的:如果一个帧发生了错误,那么只需要重传 1.5 KB 就好。
因为以太网有最大长度限制,所以携带高层协议 PDU 的长度是有限制的。不仅是以太网,在很多链路层网络中都有这个特点。链路层的这种特征叫做最大传输单元(MTU)。
- 本地链路的 MTU 对会话期间数据报的大小有直接影响。
- 当两台主机跨越多种网络通信时,每种不同的链路可能有不同大小的 MTU。因此,在包含所有链路的整个网络路径上,最小的 MTU 叫做 路径 MTU。
- 如果 IP 需要发送一个数据报,大小大于链路层 MTU,则 IP 通过分片(slice)将数据报分解成较小的部分,使每个分片都小于 MTU。分片会在 IP 协议中详细讨论。
隧道基础
简单来说:隧道就是在高层(或同等层)分组携带底层的数据。
与链路层相关的攻击
攻击 TCP/IP 以下的层次一直是常见的做法:
- 早期,以太网是名副其实的共享电缆,使得任何一台连接到以太网的电脑可以“嗅探”别人的帧并检查其内容。在当时很多高层协议都包含明文密码等敏感信息,通过查看一个分组并解码就可以轻易获得密码。
- 一个目标是交换机的过滤数据库。如果 filtering database 被快速填充(例如被大量伪装的站快速填充),交换机就有可能被迫放弃合法条目,从而导致中断对合法站的服务。
- 使用 STP,一个站可以伪装成一个到根网桥最低路径上的站,从而吸引流量导向它。
- Wi-Fi 网络的窃听和伪装问题。
- 如果攻击者可以访问两个端点之间的信道,就有很多方式来攻击 PPP 网络。对于简单的认证机制 PAP,简单的嗅探就可以捕获密码,用于后续的非法访问。
参考链接
Wireshark 抓包实例
附上一个 ARP 包的例子来看看以太网帧:
生成树协议:
Something Else
另:使用 Wireshark 抓以太网包没有前导、SFD、FCS 字段,搜索后得到如下原因:
- 抓 preamble 没有意义。
- Wireshark 抓到的数据包是网卡 driver 给上来的,有些网卡 driver 会把帧后面的 4 字节的 FCS 去掉,不上传给 tcp/ip 协议栈,Wireshark 自然就看不到了。
查看 MAC 地址的方法:在 cmd 中输入
ipconfig /all
附上组会上分享的生成树板书: