点对点协议(PPP)完全详解
点对点协议(Point-to-Point Protocol,PPP)是数据链路层(OSI第二层)最核心的协议之一,它为在点对点链路上传输多协议数据包提供了标准方法。PPP最初是为两个对等节点之间的IP流量传输设计的,后来扩展到支持DECnet、IPX、AppleTalk等多种网络层协议。
一、历史背景:从SLIP到PPP
在PPP出现之前,串行线路IP协议(SLIP)是主要的点对点连接方案,于1984年制定(RFC 1055)。但SLIP存在严重缺陷:
| 缺陷 | 说明 |
|---|---|
| 无检错纠错功能 | 无法保证数据传输的正确性 |
| 仅支持IP | 不能承载其他网络层协议 |
| 需静态IP | 每方须事先知道对方IP地址,无法动态分配 |
| 无身份验证 | 不提供任何认证机制 |
| 非国际标准 | 从未被IETF采纳为正式标准 |
为解决SLIP的种种不足,IETF制定了PPP协议,规范于RFC 1661。PPP继承了SLIP的串行通信基础,同时大幅扩展了功能:支持多种网络协议、提供链路控制与协商机制、内置身份认证、具备错误检测能力。
二、PPP的三大核心组件
PPP采用分层模块化架构,主要由三部分组成:
1. 封装方法
PPP定义了一种通用的数据帧封装格式,能够在同一条链路上承载多种网络层协议的数据报。PPP帧结构如下:
| 字段 | 长度 | 含义 |
|---|---|---|
| Flag | 1字节 | 帧起始/结束标志,固定为0x7E |
| Address | 1字节 | 固定为0xFF(广播地址),点对点链路中无实际意义 |
| Control | 1字节 | 固定为0x03(无编号帧),表示不提供可靠传输 |
| Protocol | 1-2字节 | 核心字段,标识信息域承载的协议类型 |
| Information | 0-1500字节 | 实际数据载荷 |
| FCS | 2字节 | 帧校验序列,用于CRC差错检测 |
其中Protocol字段的典型取值尤为关键:
| 协议值 | 含义 |
|---|---|
0x0021 | IP数据报文 |
0x0057 | IPv6数据报文 |
0x8021 | IPCP(网络控制协议) |
0xC021 | LCP(链路控制协议) |
0xC023 | PAP认证报文 |
0xC223 | CHAP认证报文 |
2. 链路控制协议(LCP)
LCP(Link Control Protocol)是PPP协议中负责链路建立、配置、维护和终止的核心协议。LCP报文封装在PPP帧中,Protocol字段值为0xC021。
2.1 LCP的功能
LCP执行以下四项功能:
- 链路建立:通信双方通过交换配置报文,协商链路参数。
- 链路维护:在链路运行期间,持续检测链路状态。
- 链路质量检测:通过探测机制判断链路是否可用。
- 链路终止:通信结束时关闭链路。
2.2 LCP报文结构
每个LCP报文由固定头部和可选的Data字段组成:
- Code(1字节):标识报文类型。取值1至11,具体含义见下文。
- Identifier(1字节):序列号。请求报文和响应报文的Identifier值必须相同,用于将响应与对应的请求关联。
- Length(2字节):整个LCP报文的总长度(含头部),单位字节。
- Data(变长):携带配置参数选项。仅特定类型的报文包含此字段。
2.3 LCP报文类型
LCP共定义11种报文类型,按功能分为四组。
2.3.1 链路配置报文(Code 1–4)
| Code | 报文类型 | 方向 | 作用 |
|---|---|---|---|
| 1 | Configure-Request | 发起方 → 对端 | 发起配置协商,携带本端期望的配置参数列表 |
| 2 | Configure-Ack | 对端 → 发起方 | 完全接受对方请求中的所有参数 |
| 3 | Configure-Nak | 对端 → 发起方 | 拒绝部分参数,并在报文中给出建议的修改值 |
| 4 | Configure-Reject | 对端 → 发起方 | 拒绝某些参数选项,表示本端不识别或不支持这些选项 |
三种响应的处理逻辑:
- Ack:所有参数全部认可,该端的协商完成。
- Nak:参数值不被接受,但给出了建议值。发起方应根据建议值调整后重新发送Request。
- Reject:参数选项本身不被支持。发起方应移除被拒绝的选项后重新发送Request。
2.3.2 链路终止报文(Code 5–6)
| Code | 报文类型 | 方向 | 作用 |
|---|---|---|---|
| 5 | Terminate-Request | 任一方 | 请求关闭链路 |
| 6 | Terminate-Ack | 对端 | 确认链路关闭 |
2.3.3 链路维护与调试报文(Code 7–11)
| Code | 报文类型 | 方向 | 作用 |
|---|---|---|---|
| 7 | Code-Reject | 任一方 | 收到未知Code值的LCP报文时发送 |
| 8 | Protocol-Reject | 任一方 | 收到本端不支持的协议类型时发送 |
| 9 | Echo-Request | 任一方 | 探测链路状态,要求对端回复 |
| 10 | Echo-Reply | 对端 | 对Echo-Request的应答 |
| 11 | Discard-Request | 任一方 | 环回测试,用于排查链路问题 |
说明:Code=12(Link-Quality-Report)在RFC 1661中定义但未被广泛使用,实践中通常使用Echo机制替代链路质量检测。
2.4 配置参数选项
Configure-Request报文的Data字段携带一个或多个配置参数选项(Configuration Options),每个选项采用TLV(Type-Length-Value)编码:
- Type(1字节):选项类型编号。
- Length(1字节):该选项的总长度(含Type和Length字段本身)。
- Value(变长):具体的参数值。
2.4.1 完整配置选项列表
下表列出所有已定义的LCP配置选项(不含已废弃或未分配的类型):
| Type | 选项名称 | 长度 | 作用 |
|---|---|---|---|
| 1 | Maximum-Receive-Unit (MRU) | 4字节 | 本端能接收的最大PPP帧Information字段长度,默认1500字节 |
| 2 | Async-Control-Character-Map (ACCM) | 6字节 | 异步链路的控制字符转义映射表,用于处理XON/XOFF等控制字符 |
| 3 | Authentication-Protocol | ≥4字节 | 指定认证协议(PAP=0xC023,CHAP=0xC223),决定是否进入认证阶段 |
| 5 | Magic-Number | 6字节 | 32位随机数,用于检测链路环路 |
| 6 | Quality-Protocol | ≥4字节 | 指定链路质量监控协议,用于持续评估链路质量 |
| 7 | Protocol-Field-Compression (PFC) | 2字节 | 协议字段从2字节压缩为1字节 |
| 8 | Address-and-Control-Field-Compression (ACFC) | 2字节 | 省略PPP帧头部的Address(0xFF)和Control(0x03)字段 |
| 13 | Callback | ≥3字节 | 协商回拨机制,用于节约话费或安全认证 |
| 28 | Internationalization | ≥6字节 | 协商人类可读报文的字符集和语言(如UTF-8) |
Type 4和Type 9–12的状态说明:
- Type=4:在RFC 1172中标记为”未分配”(NOT ASSIGNED),从未被使用。
- Type=9:在早期的LCP文档中曾用于”密码认证”相关的实验性选项,未进入标准。
- Type=10至Type=12:在RFC 1661中定义为保留值,未分配具体用途。
- Type=6(Quality-Protocol)在RFC 1661中定义,但在实际部署中较少使用,多数实现使用Echo-Request/Reply替代链路质量检测。
- Type=13(Callback)在RFC 1661基础选项发布后补充定义(RFC 1570),用于请求对端回拨。
- Type=28(Internationalization)是1999年新增的选项(RFC 2477),用于协商显示给用户的信息所使用的语言和字符集。
说明:LCP选项采用可扩展设计,Type值由IANA统一维护,新选项可在不修改基础协议的情况下添加。
2.4.2 关键选项解析
(1)MRU(Type=1)
MRU指定本端能够接收的PPP帧Information字段的最大长度,默认值为1500字节。通信双方可以协商更小或更大的值(理论上限由物理介质决定)。发送方发送的PPP帧的Information字段长度不得超过对端声明的MRU值。
(2)认证协议(Type=3)
此选项决定链路建立后是否进入认证阶段,以及使用何种认证协议:
- Protocol =
0xC023:使用PAP认证。 - Protocol =
0xC223:使用CHAP认证。 - 若请求中携带此选项且对端支持,则链路建立后进入认证阶段。
- 若双方均未携带此选项,则跳过认证阶段。
(3)魔数(Type=5)
魔数是一个32位随机数,用于检测链路环路。每个端点独立生成一个随机魔数,通过LCP协商告知对方。当一端收到自己发送的PPP帧时(说明链路存在环路),魔数机制会检测到并触发链路重新协商。若两端魔数相同(极小概率冲突),其中一方重新生成。
(4)协议字段压缩(PFC,Type=7)
此选项不携带Value字段(Length=2)。双方协商启用后,PPP帧的Protocol字段从2字节压缩为1字节,节省1字节开销。此选项仅能对部分协议值生效(如0x0021可压缩为0x21),且通信双方必须都能正确解析压缩后的协议字段。
(5)地址与控制字段压缩(ACFC,Type=8)
此选项不携带Value字段(Length=2)。启用后,PPP帧头部固定的Address(0xFF)和Control(0x03)字段被省略,节省2字节开销。仅当链路两端都协商通过时才生效。
2.5 协商流程
LCP的协商是双向独立进行的。每端各自发送Configure-Request,并各自等待对端的响应。
单端协商流程:
- 发送端发送Configure-Request,携带本端的配置参数列表。
- 接收端检查参数:
- 全部接受 → 回复Configure-Ack,该端协商完成。
- 部分参数值不可接受 → 回复Configure-Nak,附上建议值。发送端调整参数后重新发送Request。
- 部分参数选项不可识别 → 回复Configure-Reject。发送端移除被拒绝的选项后重新发送Request。
- 重复上述过程,直到发送端收到Configure-Ack。
双向协商:两端各自独立执行上述流程。一端的协商完成并不影响另一端的协商进度。当两端均收到对方的Configure-Ack时,LCP进入Opened状态,链路协商阶段结束。
2.6 链路生命周期中LCP的位置
在PPP链路的完整生命周期中,LCP按以下时序工作:
- 物理层连接建立。
- LCP协商:交换Configure-Request/Ack,完成链路参数协商。
- 认证阶段(若协商了认证协议):执行PAP或CHAP认证。
- NCP协商:协商网络层参数(如IP地址)。
- 数据传输:正常通信。LCP在此阶段持续运行,定期发送Echo-Request探测链路存活状态。
- 链路终止:NCP先释放网络层连接,LCP交换Terminate-Request/Ack关闭链路层,最后物理层断开。
说明:LCP在整个链路生命周期中持续运行——协商阶段负责建立链路,数据传输阶段负责监控链路,异常发生时随时触发终止流程。
3. 网络控制协议族(NCP)
当LCP将链路层连接建立并完成认证后,NCP负责协商网络层协议的具体参数,使得同一条PPP链路能够承载多种不同的网络层协议。如果说LCP是建立链路的“总指挥”,NCP就是为不同网络层协议安排具体工作的“部门经理”。
3.1 NCP协议族概述
NCP不是一个单一的协议,而是一个协议家族。每种网络层协议都有专属的NCP,用来协商该协议所需的参数。
| 网络层协议 | 对应NCP | 主要协商内容 |
|---|---|---|
| IPv4 | IPCP(IP控制协议) | IP地址分配、TCP/IP头部压缩算法、DNS服务器地址 |
| IPv6 | IPv6CP | IPv6接口标识符、IPv6地址配置 |
| IPX(Novell) | IPXCP | IPX网络号 |
| AppleTalk | ATCP | AppleTalk节点ID、网络号范围 |
| DECnet | DNCP | DECnet地址 |
在当前的互联网环境下,IPCP是最重要、最常见的NCP。宽带拨号(PPPoE)拨通后,最关键的一步就是IPCP协商,它直接决定了你能否获取到IP地址并上网。
3.2 NCP的工作机制
NCP本质上是一个状态机,它遵循与LCP相同的协商逻辑(使用同样的Configure-Request/Ack/Nak/Reject报文),但协商的内容是网络层的特定参数。
协商流程如下:
- 发起请求:一端发送
Configure-Request报文,其中包含它期望使用的网络层参数值(例如请求一个IP地址)。 - 响应与协商:
- 完全接受(Ack):如果对端同意所有参数,直接回复确认,协商完成。
- 部分接受(Nak):如果对端认为某个参数不合适,会回复
Configure-Nak,并附带上建议的修改值。例如,客户端请求IP192.168.1.100,服务器回复Nak并建议192.168.1.50。 - 完全拒绝(Reject):如果对端根本不认识或不支持该参数选项,则回复
Configure-Reject。
- 重新协商:收到Nak或Reject后,发起方根据反馈调整参数,重新发起新的Request,直到双方达成一致(收到Ack)或协商失败。
3.3 重点剖析:IPCP(IP控制协议)
(1)IP地址协商——NCP最核心的功能
在拨号上网时代,客户端本身没有公网IP地址。当LCP链路建立且认证通过后,IPCP开始工作:
- 客户端发送
Configure-Request,其中IP地址字段填0.0.0.0,表示“请给我分配一个IP地址”。 - 运营商的接入服务器(NAS)收到请求后,从其空闲IP地址池中选择一个可用IP,通过
Configure-Nak报文将该IP地址“附上”并发回给客户端。 - 客户端收到Nak后,提取出建议的IP地址,用这个地址重新发起
Configure-Request。 - 服务器确认分配有效,回复
Configure-Ack,IP地址分配完成。
技术说明:IPCP协商过程中,两个端点各自独立协商自己的IP地址,每个端点都需要发送自己的请求。在实际的客户端-服务器场景中,往往只协商客户端的地址,服务器使用固定地址。
(2)DNS服务器地址协商
解决了IP地址,还需解决域名解析问题。在IPCP协商过程中,设备可以附带请求DNS服务器地址和WINS服务器地址(主要用于Windows网络)。RFC 1877定义了IPCP的DNS扩展选项:
- 主DNS服务器地址(Type 129)
- 备用DNS服务器地址(Type 130)
运营商通过Nak报文将主、备DNS的IP地址告知客户端。这就是为什么PPPoE拨号上网后,电脑能自动获取DNS而无需手动配置的原因。
(3)TCP/IP头部压缩协商
在早期的低速链路(如56K调制解调器)上,传输一个普通TCP数据包需要40字节的IP+TCP头部,对于小数据包来说开销极为巨大。
IPCP可以协商启用 Van Jacobson压缩算法(RFC 1144),将40字节的TCP/IP头部压缩到最少3-5个字节,大幅降低链路开销并提升网络响应速度。该算法通过缓存之前的数据包头部,只传输变化的字段来实现压缩。
3.4 NCP与其他协议的关系
NCP与DHCP的关系:
许多读者会将IPCP与DHCP(动态主机配置协议)混淆,两者虽然都分配IP地址,但存在本质区别:
| 对比维度 | IPCP | DHCP |
|---|---|---|
| 工作层次 | 数据链路层(第二层) | 应用层(第七层),基于UDP |
| 依赖关系 | 先决条件——必须在IPCP获取IP后才能建立IP网络 | 依赖已有IP网络才能通信 |
| 适用场景 | 点对点链路(拨号、PPPoE) | 广播式以太网局域网 |
| 分配范围 | 通常仅分配IP和DNS | 可分配IP、DNS、网关、租期等丰富参数 |
| 协议集成 | 内置于PPP协议栈中 | 独立的应用层服务 |
关键区别:在PPP链路上,必须先完成IPCP协商获取IP地址,之后设备才能基于该IP访问网络。IPCP是建立IP连接的基础,而DHCP是在IP网络建立后用于局域网内进一步分配的补充工具。
3.5 NCP与LCP的分工协作
LCP和NCP在PPP协议栈中分工明确、次序清晰:
| 阶段 | 负责协议 | 主要任务 |
|---|---|---|
| 物理层连接 | 物理介质 | 建立物理通信通道 |
| 链路协商 | LCP | 协商MRU、认证方式等链路参数 |
| 身份认证 | PAP/CHAP | 验证用户身份合法性 |
| 网络协商 | NCP | 协商IP地址、DNS等网络层参数 |
| 数据传输 | 上层协议 | 正常网络通信 |
| 链路终止 | NCP → LCP | 先释放网络层,再释放链路层 |
这种分层设计使得PPP具备了极强的扩展性——未来引入新的网络层协议时,只需为之定义一个新的NCP子协议,而无须修改底层的LCP和封装机制。
三、PPP工作流程:四个阶段
PPP连接经历以下阶段,每个阶段严格递进,认证失败则连接终止:
阶段1:物理层连接建立
设备通过调制解调器拨号、专线等方式建立物理连接。
阶段2:LCP链路协商
双方交换LCP配置报文,协商链路参数(MRU、认证协议、魔数等)。协商成功则进入下一阶段;失败则终止连接。
阶段3:身份认证(可选)
根据LCP协商选定的认证协议进行验证。此阶段只允许LCP、认证协议和链路质量检测的报文通过,其他数据包全部丢弃。认证通过后进入网络协商阶段;若失败则终止连接。
阶段4:NCP网络协商
PPP调用对应的NCP协商网络层参数。以IPCP为例,接入服务器从IP地址池分配空闲IP给用户,设备正式成为互联网主机。协商完成后,即可正常传输网络层数据。
链路终止
通信结束时,NCP首先释放网络层连接(收回IP地址),LCP再释放数据链路层连接,最后物理层连接断开。
四、安全机制:认证协议详解
PPP支持多种认证协议,核心区别在于安全性与握手方式。
PAP(密码认证协议)
| 特性 | 说明 |
|---|---|
| 握手次数 | 2次握手 |
| 密码传输 | 明文,无任何加密 |
| 安全性 | 极低,极易被窃听和重放攻击 |
| 适用场景 | 仅在完全可信的内部网络或对安全性无要求的环境 |
CHAP(挑战握手认证协议)
| 特性 | 说明 |
|---|---|
| 握手次数 | 3次握手 |
| 密码传输 | 永不传输明文,仅传输哈希值 |
| 机制 | 服务器发送随机挑战值,客户端用密码+挑战值计算MD5哈希并返回,服务器用相同算法验证 |
| 安全性 | 高,防止窃听和重放攻击 |
| 适用场景 | 任何需要安全认证的环境,是PAP的推荐替代方案 |
扩展认证协议(EAP)家族
Windows CE等系统还支持更先进的认证协议,包括:
- MS-CHAP:微软实现的CHAP变体,使用MD4哈希,支持密码过期通知
- MS-CHAP v2:MS-CHAP的改进版本,更强的双向认证
- EAP-TLS:基于TLS证书的强认证
- PEAP:受保护的EAP,在TLS隧道内封装EAP
五、变种协议:PPP的演进
PPP通过适配不同物理层,衍生出两个至今广泛应用的变种:
PPPoE(以太网上的PPP)
将PPP帧封装在以太网帧中,在广播式以太网上模拟点对点连接。目前是ADSL、光纤宽带最普遍的接入认证方式。PPPoE帧格式中,以太网类型字段在发现阶段填0x8863,会话阶段填0x8864,会话ID字段用于在以太网上区分不同用户。
PPPoA(ATM上的PPP)
将PPP帧封装在ATM信元中,主要用于ATM网络环境下的宽带接入。
六、不同物理介质上的PPP封装
PPP帧在不同物理线路上存在差异:
| 物理介质 | 成帧方式 | 透明传输方法 |
|---|---|---|
| 同步线路 | 使用HDLC UI帧,基于比特流 | 0比特插入(连续5个1后插入0) |
| 异步线路 | 面向字符的首尾标志 | 字符填充(0x7E→0x7D 0x5E,0x7D→0x7D 0x5D) |
| 以太网 | PPPoE帧格式 | 以PPPoE会话ID和发现阶段/会话阶段区分 |
总结
PPP作为数据链路层的基石协议,通过LCP+NCP的分层架构实现了链路控制与网络配置的解耦,使单一协议能适配多种物理介质和网络层协议。其中,NCP协议族是PPP灵活性和扩展性的核心体现——LCP负责打通“物理通道”,而NCP负责为每种网络协议配置专属的“参数环境”,两者分工明确、相互配合。其内置认证机制(CHAP)为安全连接提供了保障,而PPPoE等变种则让PPP在宽带时代继续发挥关键作用。尽管VPN等新技术层出不穷,PPP的设计思想——通过分层协商建立可靠连接——至今仍在网络协议设计中体现。