摘要
- RFC 3396 规定,同一 DHCPv4 选项代码的重复实例是一个逻辑值的连续片段;分段既可能来自 255 八位组上限,也可能来自重载字段中的剩余空间。
- 重组必须遵循 options、
file、sname的逻辑聚合顺序,而非字段在包中的物理顺序。切口本身没有语义,发送端合规也不能证明部署中的接收端确实完成重组。
一个包里的“先后”并不总由内存地址决定。DHCPv4 保留了 BOOTP 的旧字段,又允许这些字段在特定情况下承载选项,于是同一逻辑值可能散落在三个地方。RFC 3396 要求解析器忘掉眼前的物理排列,按照另一条顺序把它们接回去。
这份标准轨 RFC 于 2002 年 11 月发布。问题源自最朴素的长度编码:可变长选项由一个八位组的代码、一个八位组的长度和零至 255 个值八位组组成。一个实例的值再长,也无法越过 255。
RFC 2131 已经说过重复选项应当拼接,却没有完整说明拼接顺序,同时还保留了“除非选项文档另有规定,否则只能出现一次”的一般表述。RFC 3396 删除了这句话,并把重复同一代码重新定义为通用的重组输入,而不是一组等待各自解释的对象。
超长并非唯一分段原因。即使值短于 255,当前输出区剩余空间也可能不够,而另一个可承载选项的字段仍有空间。编码器此时必须采用规定算法,或完全不发送这个选项。单个实例不能跨过两个字段的边界。
三个位置来自 BOOTP 遗产:普通可选参数区是自然容器;当 DHCP 选项重载生效时,file 与 sname 也可改装为选项区。RFC 3396 把它们抽象为一个“聚合选项缓冲区”,顺序固定为普通 options、再 file、最后 sname。
规范特意加粗了一个事实:这不是字段在 DHCP 包里的物理顺序。聚合缓冲区只是一种逻辑视图,不能用来改写包格式。若解析器按结构体地址一路扫描,遇到相同代码就直接追加,得到的值可能顺序颠倒。
在逻辑缓冲区内,每片仍以普通可变长选项编码,使用同一代码,每片值不超过 255 个八位组,各片长度之和等于总长度。若一个选项分布到三个位置,第一片放普通区,第二片放 file,第三片放 sname,不因物理位置看起来更早或更晚而改变。
切口可以落在任意两个八位组之间。这份自由带来一项禁令:切口不得表达语义。它不代表一个域名结束、一条路由结束、一个子选项结束,也不是记录边界。它只说明前一个容器到头了,或长度字节容纳不了更多。
因此,解码器必须延迟解释。看到相同代码出现两次或更多次时,它要按聚合顺序连接值,再把结果作为一个选项处理。先逐片校验、解析或公开,会凭空制造发送端从未声明的对象结构。
机器对齐也属于接收端责任。发送端不必为了远端 CPU 选择舒服的切口。重组后,实现在复制和访问多字节值时要满足自己的体系结构要求。合法的网络切口可能恰好落在本机最别扭的位置。
规范用 Bootfile Name 选项 67 做了一个刻意简短的例子。/diskless/foo 可以在第七个值八位组后切成两段。/diskle 与 ss/foo 都不是独立的启动文件名;只有按顺序拼起来,原对象才重新出现。切口之所以合法,正因为它什么也不表示。
更重要的是部署警告。RFC 3396 明确记录,当时许多已部署 DHCP 代理没有实现选项拼接。发送端可以完全遵守新标准,却遇到只读一段、把多段当成不同对象或直接丢弃的接收端。编码合规不是解码成功的收据。
规范因此把选项分成“要求拼接”和“不要求拼接”两类。某个选项只有在自己的定义文档明确引用 RFC 3396 并要求实现时,才属于前者。发送端不应随意分段,除非别无选择、知道对端有能力,或管理员明确配置了这个假设。
若对端曾请求或提供至少一个要求拼接的选项,可以推定它支持机制。这个推定只是有限的互操作信号,并不证明所有长度、重载路径、内存处理和下游使用都正确。实现可以永不拆分普通选项;但只要支持任何要求拼接的选项,就必须能在接收时拼接两类选项的重复实例。
认证说明了“先成一体”的要求可以进入安全计算。RFC 3118 的 DHCP 认证选项本身也可能被拆分。在生成或验证 MAC 之前把认证字段置零时,实现必须能处理该字段跨越多个实例的情况。若代码把每片当完整记录,可能对错误表示做出看似严肃的验证。
后来,RFC 3397 的域搜索、RFC 3361 的 SIP 代理、RFC 3442 的无类别路由和 RFC 3925 的厂商标识结构,都以各自方式依赖长选项机制。它们定义的是应用语法;RFC 3396 定义的是语法生效之前,如何先得到唯一字节对象。
抓包证据因此必须分层。一份完整抓包能证明观察点见到了所有片段,却不能证明客户端识别重载、采用正确聚合顺序、保留重复项、处理对齐、验证认证并最终应用配置。这些动作需要分别取得运行收据。
RFC Editor 当前检索不到 RFC 3396 的匹配勘误。这说明编辑记录状态,不等于实现正确证书。该 RFC 本身正是为了修补早期规范的模糊处,并正视已经分化的软件现实。
Lu Heng 的“最小初始规范”原则解释了它为何只固定代码身份、逻辑顺序、连续性与切口无语义,而不规定每种实现的内存结构。“运行代码优先”则要求测试最难受的切口、真正跨越三个字段,并追踪值是否进入最终配置。
RFC 3396 把位置降为运输手段,把身份保留在重组之后。片段可以长短不一,字段可以物理错位,切口可以落在任何地方。解码器最重要的能力,是知道何时暂不理解:先还原一个对象,再问它意味着什么。
来源
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
