ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

PPP协议深度解析:从帧结构到LCP/NCP协商与排障实战

PPP协议深度解析:从帧结构到LCP/NCP协商与排障实战 PPP协议在计算机网络里属于那种平时不显山露水但一出问题就能让你抓瞎的角色。很多人学网络的时候把大量精力花在TCP/IP、HTTP、路由协议上对数据链路层的PPP往往一带而过觉得它就是个拨号时代的老古董。但真到了运营商专线对接、串口通信调试、或者排查链路层协商失败的时候PPP的细节就变成了绕不过去的坎。这篇文章面向的是网络方向的学生、刚入行的网络工程师以及需要和运营商打交道的运维人员我会把PPP从帧结构到LCP/NCP协商流程拆开讲清楚同时补上那些教材里不会写、但实际排障时特别管用的经验。读完你至少能做到看到PPP协商日志不慌知道卡在哪一步该查什么。1. 为什么数据链路层需要PPP这样一套协议1.1 从两根线连起来到能可靠传数据之间的鸿沟很多人对数据链路层的理解停留在把比特流变成帧这个层面觉得只要两端物理连通了数据自然就能传。实际完全不是这么回事。你拿一根串口线把两台设备连起来物理层确实通了但接下来要面对一堆问题帧的边界怎么界定传输出错了怎么发现两端速率、字符格式不一致怎么办如果这条链路上要跑多种网络层协议比如同时跑IP和IPX接收方怎么知道这个帧该交给谁处理PPPPoint-to-Point Protocol点对点协议就是为解决这一系列问题而设计的。它工作在数据链路层专门针对点对点这种拓扑——也就是链路上只有两个端点不存在共享介质和冲突问题。这个前提很重要正因为只有两个端点PPP不需要像以太网那样搞复杂的MAC地址寻址和CSMA/CD冲突检测它可以把精力放在链路建立、参数协商、多协议复用这些更关键的事情上。我经常用一个类比来解释物理层相当于把两条路修通了PPP相当于在这条路上制定了一套交通规则——什么颜色的车能上路协议类型、车速限制多少MRU、路况不好时怎么报告差错检测、路修好之前先开个会确认双方都准备好了LCP协商。没有这套规则路是通的但车没法有序地跑。1.2 PPP的三个核心组件缺一不可PPP不是一个单一协议而是一个协议族它由三个核心部分组成理解这三块是理解PPP的关键帧封装方式PPP定义了自己独特的帧格式用来在点对点链路上封装数据报。它借鉴了HDLC的帧结构但做了简化和标准化最典型的标志是帧头帧尾都用0x7E作为定界符。LCPLink Control Protocol链路控制协议负责链路的建立、配置、测试和拆除。你可以把它理解为谈判代表链路能不能用、用什么参数都是LCP谈出来的。NCPNetwork Control Protocol网络控制协议一族协议负责协商网络层协议的参数。最常见的是IPCPIP Control Protocol用来协商IP地址、DNS等。每种网络层协议都有对应的NCP。这三者的关系是层层递进的先有帧封装保证比特能成帧再有LCP把链路谈通最后有NCP把网络层参数谈好数据才能真正跑起来。任何一环出问题链路都起不来。实际排障时这个层次关系就是你的排查顺序。1.3 PPP和HDLC、以太网的边界在哪里初学者容易混淆PPP和HDLC因为两者帧结构长得很像。核心区别在于HDLC是ISO的标准有多种变体比如Cisco私有的HDLC通用性和互操作性不如PPPPPP是IETF的标准定义更严谨而且自带LCP/NCP这套协商机制这是HDLC不具备的。所以在异构设备互联、运营商场景里PPP的出场率远高于HDLC。至于PPP和以太网它们面对的场景根本不同。以太网是广播型网络多点共享需要MAC地址PPP是点对点两端直连不需要寻址。所以PPP帧里没有源/目的MAC地址字段取而代之的是协议类型字段。理解这个差异你就明白为什么PPP不能直接跑在以太网那种多播环境里虽然后来有PPPoE把PPP封装进以太网但那是另一回事。2. PPP帧结构里每个字段到底在干什么2.1 逐字段拆解PPP帧格式PPP帧的结构看起来简单但每个字段都有讲究。标准PPP帧不带地址控制字段压缩长这样字段长度作用Flag1字节定界符固定为0x7E标识帧的开始或结束Address1字节固定为0xFFPPP是点对点这个字段实际无意义但保留Control1字节固定为0x03表示无序号帧Protocol1-2字节标识载荷是什么协议LCP、IPCP、IP等Information可变载荷数据默认最大1500字节FCS2或4字节帧校验序列用于差错检测Flag1字节结束定界符0x7EAddress和Control字段固定值这件事很多人第一次看会觉得莫名其妙——既然固定为什么还要占两个字节这是历史遗留PPP从HDLC继承了这个结构。不过PPP允许通过LCP协商做ACFCAddress and Control Field Compression把这两个字节压掉省带宽。在低速链路上这个优化很有意义。Protocol字段是PPP帧的灵魂。它告诉接收方这个帧的载荷该交给谁。几个关键取值你需要记住0xC021LCP0x8021IPCP0x0021IP数据报0xC023PAP认证0xC223CHAP认证看到这些值你就能从抓包结果里一眼判断出当前链路协商到哪一步了。2.2 字节填充0x7E冲突是怎么解决的PPP帧用0x7E做定界符但载荷数据里完全可能出现0x7E这个字节。如果不管它接收方就会误以为帧提前结束了。PPP的解决办法是字节填充Byte Stuffing在载荷中遇到0x7E就替换成0x7D 0x5E遇到0x7D本身替换成0x7D 0x5D。0x7D是转义字符接收方看到它就知道下一个字节需要做异或0x20还原。这个机制在同步链路如SONET/SDH上不常用因为同步链路靠比特同步而不是字节定界但在异步链路如传统串口拨号上是标配。实际抓包时如果你看到一堆7D开头的字节对别慌那是正常的转义不是数据错误。提示异步链路上除了0x7E和0x7D小于0x20的控制字符也常被转义这是为了兼容某些对控制字符敏感的老式终端设备。这个行为可以通过LCP的ACCMAsync Control Character Map选项协商关闭能省不少带宽。2.3 FCS校验与差错处理的实际意义FCSFrame Check Sequence是PPP的差错检测手段默认用16位CRC也可以协商用32位。它的作用是让接收方判断这个帧在传输过程中有没有被破坏。注意PPP只做检错不做纠错——发现错误就丢弃重传交给上层比如TCP去处理。这个设计选择很务实链路层做纠错成本高、收益低而且点对点链路的误码率通常不高交给上层重传更经济。实际运维中如果你发现某条PPP链路上FCS错误计数持续增长基本可以锁定是物理层问题——线缆质量差、接头氧化、电磁干扰而不是PPP配置问题。这个判断经验能帮你快速定位方向。3. LCP协商链路能不能用全看这一步3.1 LCP报文类型与协商三阶段LCP是PPP里最核心的协商协议它的报文分三类链路配置报文Configure-Request、Configure-Ack、Configure-Nak、Configure-Reject用来协商链路参数。链路终止报文Terminate-Request、Terminate-Ack用来关闭链路。链路维护报文Code-Reject、Protocol-Reject、Echo-Request、Echo-Reply、Discard-Request用来维护和检测链路状态。LCP协商遵循一个经典的三阶段模型链路建立阶段Link Establishment双方互发Configure-Request协商参数。一方发Request另一方如果全部接受就回Ack如果有不接受的参数就回Nak建议改值或Reject拒绝该选项发起方调整后重发直到双方都Ack。认证阶段Authentication如果协商中要求认证就进入PAP或CHAP认证。认证不通过链路直接拆。网络层协议阶段Network-Layer Protocol认证通过后进入NCP协商比如IPCP协商IP地址。这个顺序是刚性的不能跳。实际排障时你看到日志卡在哪个阶段问题范围就缩小到那个阶段了。3.2 Configure-Request里的关键选项LCP Configure-Request里可以携带很多选项每个选项都有Type、Length、Value三个字段。几个最常打交道的MRUMaximum Receive Unit本端能接收的最大载荷长度默认1500。如果对端发的包超过这个值会被丢弃。跨运营商对接时MRU不一致是常见的隐性坑。Authentication-Protocol指定认证方式PAP0xC023或CHAP0xC223。这个选项一旦协商成功后续必须走认证流程。Magic-Number用来检测链路环回。如果收到的Magic-Number和自己发出去的一样说明链路被环回了。这个选项在排查链路起不来但物理正常时特别有用。ACCM异步控制字符映射前面提过用来协商哪些控制字符需要转义。协商过程中如果对端回Configure-Nak说明它不接受你提的某个值但愿意协商如果回Configure-Reject说明它根本不认识这个选项你得把这个选项去掉重发。理解Nak和Reject的区别很重要——Nak是值不行换一个Reject是这个选项我不支持别带了。3.3 认证阶段PAP和CHAP的本质区别认证是LCP协商的可选阶段但运营商场景几乎必开。两种方式PAPPassword Authentication Protocol明文传用户名密码两次握手。发起方发用户名密码接收方验证后回Accept或Reject。安全性差密码在链路上裸奔但配置简单。CHAPChallenge Handshake Authentication Protocol三次握手用MD5做摘要不传明文密码。流程是认证方发一个Challenge含随机数被认证方用密码随机数算MD5回传认证方自己也算一遍对比。CHAP还支持周期性重认证链路建立后还会再挑战安全性高得多。实际配置时CHAP有个经典坑双方密码必须完全一致且用户名映射要对。CHAP的摘要计算依赖密码任何一端密码错了摘要就对不上认证失败。而且CHAP的Challenge是认证方发起的所以谁认证谁这个方向要搞清楚配置里的ppp chap hostname和ppp chap password要配对。注意CHAP认证失败时日志里通常只显示CHAP authentication failed不会告诉你具体是密码错还是用户名错。排查时先确认两端密码字面完全一致包括大小写、特殊字符再检查用户名映射。我踩过好几次坑最后发现是密码里有个空格。4. NCP与IPCP网络层参数是怎么谈出来的4.1 NCP的通用框架与IPCP的特殊性NCP不是一个具体协议而是一个框架。每种网络层协议都有自己的NCP比如IP对应IPCPIPv6对应IPV6CP。它们的报文格式和LCP类似都是Configure-Request/Ack/Nak/Reject那套但协商的内容是网络层参数。IPCP是实际中最常打交道的它主要协商两件事IP地址一端通常是运营商侧给另一端分配IP地址。分配方发Configure-Request带自己的IP被分配方发Configure-Request请求0.0.0.0分配方回Nak并带上分配的地址被分配方用这个地址重发Request分配方Ack。DNS地址类似机制协商主备DNS。这个请求0.0.0.0然后被Nak回真实地址的流程是IPCP最容易被误解的地方。很多人看抓包看到Nak就以为出错了其实这是正常协商流程。判断是否正常要看Nak之后有没有用新地址重发Request并收到Ack。4.2 IP地址协商的完整报文交互把IPCP协商IP地址的过程完整走一遍你就能看懂大部分协商日志了客户端发Configure-RequestIP地址选项填0.0.0.0表示请给我分配一个。服务端回Configure-NakIP地址选项填它想分配的地址比如10.0.0.1。客户端用10.0.0.1重发Configure-Request。服务端回Configure-Ack。同时服务端也会发自己的Configure-Request带它的IP客户端回Ack。双方都Ack后IPCP进入Up状态IP数据报才能开始传。如果卡在第2步之后没有第3步说明客户端没接受分配的地址如果卡在第4步说明服务端没确认。这些细节在排查链路起来了但ping不通时非常关键。4.3 从LCP Up到IPCP Up之间发生了什么很多人以为LCP协商完链路就通了其实LCP Up只是链路层通了网络层还没通。中间还隔着认证和NCP。完整的链路建立时序是物理层Up → LCP协商 → LCP Up → 认证可选→ 认证通过 → NCP协商 → NCP Up → 数据可传这个时序图在你脑子里要清晰。实际排障时show interface看到LCP Open但IPCP Closed说明卡在NCP看到LCP Closed说明卡在LCP或物理层。这个判断能帮你省下大量瞎猜的时间。5. 实际排障PPP链路起不来的排查链路5.1 从物理层到网络层的逐层排查法PPP排障最忌讳一上来就改配置。正确做法是按层次往下查每一层确认无误再往下第一层物理层。查线缆、光模块、接口状态。show interface看物理层是否Up有没有CRC错误、帧错误计数增长。物理层不通后面全是白搭。第二层LCP。看LCP是否Open。如果LCP卡在协商中抓包看Configure-Request/Ack的交互。常见问题是MRU不匹配、认证方式不匹配、Magic-Number检测到环回。第三层认证。如果配了认证看认证是否通过。PAP看密码CHAP看密码和用户名映射。第四层NCP。看IPCP是否Open。常见问题是IP地址池耗尽、地址冲突、DNS协商失败。这个顺序不能乱。我见过太多人LCP都没Up就去查IP地址纯属浪费时间。5.2 几个高频故障场景与定位技巧场景一LCP一直停在Configure-Request收不到Ack。大概率是对端没收到你的Request或者对端配置了认证但你没配。抓包确认Request有没有发出去、对端有没有回。如果对端回了Reject看是哪个选项被拒了。场景二CHAP认证反复失败。先确认密码字面一致再确认用户名映射。如果用的是ppp chap hostname确认这个hostname在对端的用户数据库里存在。还有个隐蔽的坑某些设备CHAP默认用主机名做用户名如果两端主机名一样可能出问题。场景三IPCP协商到一半卡住。看是不是地址池问题。服务端地址池耗尽时会回Nak但不带有效地址客户端就一直重试。另外如果两端都配了固定IP且冲突也会卡。场景四链路Up了但ping不通。先确认IPCP是否真的Up再看路由。PPP链路通常是32位掩码的点对点链路对端地址就是下一跳不需要额外配路由。如果配了ACL检查ACL有没有放行。5.3 抓包分析PPP协商的实操要点抓PPP包和抓以太网包不太一样。在串口或Dialer接口上抓包需要指定接口。抓到包后重点看Protocol字段判断报文类型看Code字段判断是Request/Ack/Nak/Reject。分析时按时间顺序看报文交互重点关注Configure-Request发出后对端回的是什么Ack/Nak/Reject/无响应。如果是Nak看Nak里建议的值是什么本端有没有采纳。认证阶段看Challenge/Response的交互Response的摘要对不对这个没法直接看但可以看有没有Accept。NCP阶段看地址协商的完整流程。抓包是PPP排障的终极手段因为日志往往只告诉你结果抓包能告诉你过程。我建议每个网络工程师都熟练掌握在PPP接口上抓包和分析的技能。6. PPP在今天的网络里还有哪些用武之地6.1 运营商专线与串口通信场景虽然家庭拨号上网基本被光纤取代了但PPP在运营商专线接入里依然活跃。很多企业专线用的是PPP封装的串口或E1线路运营商侧通过PPP给企业分配IP。这种场景下PPP的认证、地址协商、链路检测机制都是刚需。串口通信场景也一样。工业控制、电力系统、交通信号等领域大量设备通过串口互联PPP是这些链路上跑IP的标准方式。这些场景往往链路速率低、环境恶劣PPP的轻量和健壮性正好合适。6.2 PPPoEPPP思想在以太网上的延续PPPoEPPP over Ethernet是把PPP帧封装进以太网帧的技术家庭宽带拨号用的就是它。它保留了PPP的LCP/NCP协商和认证机制同时适配以太网的多点环境。理解PPP是理解PPPoE的基础。PPPoE的协商流程和PPP几乎一样只是多了一层以太网封装和PPPoE的Discovery阶段。6.3 学PPP对理解其他链路层协议的价值PPP的很多设计思想是通用的分层协商LCP谈链路、NCP谈网络、状态机驱动、选项协商机制。你理解了PPP的协商模型再去看其他链路层协议比如某些无线链路的协商会发现套路是相通的。所以学PPP不只是学一个协议是学一种链路层协议的设计范式。我个人在实际工作中的体会是PPP这东西配置命令就那么几条背下来不难难的是理解它背后的协商逻辑和排障思路。真正让你在关键时刻不掉链子的不是记住ppp authentication chap这条命令而是知道CHAP认证失败时该从哪几个方向去查。把LCP和NCP的协商流程在脑子里跑通把抓包分析练熟PPP就不再是那个拨号时代的老古董而是你手里一件趁手的排障工具。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进