在 en0(MTU 1500)上抓到 4000 字节 UDP 数据报被拆成 3 个同 id 分片(偏移 0/1480/2960,MF 1/1/0,只有第一片带 UDP 头);lo0 上 40000 字节不分片;按公式 5% 丢包下 41 片的数据报只有约 12% 能送达;TCP 下载 303 个包里 302 个带 DF。
默认 TTL 64;抓包看 traceroute:UDP 探测 TTL 递增、端口 33435 起逐个加 1,路由器回 ICMP 11/0 并引用原包,目的地回 3/3;15 跳里 2 个全无应答、6 个多路径;自己用 IP_TTL 实现 traceroute;收到包的 TTL 估跳数与实测差 0~2。
抓包看 ping:类型 8/0、84 字节的 IP 包、载荷前 8 字节是发送时间戳;ICMP 校验和手算与抓包一致;ping 报的 RTT 比抓包多 0.08~0.5 ms;4000 字节载荷被分成 3 片;用非特权 ICMP 套接字自己发 echo。
抓包看 ICMP 差错报文:UDP 端口不可达(类型 3/3)引用 28 字节原包,connect 过的 UDP 才能收到错误;TCP 用 RST 拒绝、网关拒绝要 1005 ms(SYN 重发一次)、防火墙丢弃要等 3001 ms 超时;12 个目的地只有 4 个回差错;引用长度 28 与 40 字节两种;广播不回差错。
实测路径 MTU 发现:DF 置位的 1500 字节 UDP 在公网路径第 3 跳处得到 ICMP 3/4(下一跳 MTU 1492),≤1492 的全部到达;本机设了 DF 的超大包直接 EMSGSIZE;UDP 收到 3/4 后内核路由缓存没变;黑洞的后果用模拟说明。
手算 IPv4 头与 UDP 校验和并在 53 个真实包上核对全部通过;lo0 上校验和被卸载所以抓到的是 0;16 位字调换查不出来(CRC-32 查得出);增量更新公式在 53 个 TTL 和 18 个 NAT 改写上与整体重算一致;算出 0 的 UDP 校验和线上发 0xffff。
TOS 字节 = DSCP + ECN,IP_TOS 设的值在 lo0 和 en0 上原样出现;公网路径上 DSCP 被清成 0 而 ECN 位保留;SO_TRAFFIC_CLASS 不会自动打 DSCP;TCP 主动连接的 SYN 带 SEW,4 个主机全部接受 ECN;TOS 按套接字设置,不随连接继承。
用 STUN 实测本机出口的 NAT:外部看到的是公网地址、端口保留,与目的无关的映射;40 个套接字里 39 个保留端口(4500 被改成 3319);traceroute 看不到被改写的源地址;NAPT 表的纸面模型演示端口冲突、入站过滤和校验和更新。
14 段特殊用途地址合计 592,708,608 个(13.80%);Python 的 is_private 漏掉 100.64/10;往私有、文档、保留地址发包都走默认网关,169.254 和本网段未用地址先 ARP;127.0.0.2 绑不了也连不上,0.0.0.0 连的是本机;公网路径上有私有地址的路由器。
实测 ICMP 差错限速:本机对端口不可达最多每 100 ms 回一个(374,840 个包只回 31 个),echo 应答与 TCP RST 不受限;默认网关 100 个只回 3~4 个;时间戳 / 地址掩码请求不回应;net.inet.icmp 下没有限速 sysctl。
逐字节解码 lo0 上的 IPv6 头(40 字节固定,无校验和,ICMPv6 校验和覆盖伪头部);IPv6 头比 IPv4 头多 20 字节、MSS 差 20;流标签由内核按套接字生成;en0 上 25 秒 275 个 IPv6 包的跳数限制只有 255 与 1;手工构造的扩展头链用 tcpdump 与 scapy 解码。
本机 8 个接口共 9 个 IPv6 地址、全部是回环或链路本地(没有公网 IPv6);2001:db8::1 有 20936 种合法写法;链路本地地址必须带接口编号才能发送;ff02::1 ping 得到 146 个地址的应答;邻居里 80 / 172 个地址由 MAC 推出。