LV015-网关与跨网段通信
一、 网关的作用与配置前提
1. 什么是默认网关
上一篇给出了两条转发规则,其中第二条是"不同网段就交给网关"。于是问题来了:网关到底是什么?
一句话回答:默认网关是"我不认识的目的地,统统先交给它"的那台设备。
它的本质是路由表里的一条特殊表项——目的网络是 0.0.0.0/0(能匹配任何地址)的默认路由:
| 目的网络 | 掩码 | 下一跳 |
|---|---|---|
| 192.168.16.0 | /24 | 直连,不用下一跳 |
| 0.0.0.0 | /0 | 192.168.16.1(默认网关) |
PC 上看到的"默认网关"输入框,填的就是这条默认路由的下一跳地址。
2. 网关必须是同网段设备
这是配置网关时唯一的硬约束,理由还是"要发帧就得先知道 MAC":
- 要把包交给网关,就得把帧的目的 MAC 填成网关的 MAC;
- 要拿到网关的 MAC,就得对网关的 IP 发起 ARP;
- ARP 只在本网段内广播——跨网段的地址是 ARP 不到的。
所以 192.168.16.30/24 的板子,网关只能填 192.168.16.1 ~ 192.168.16.254 之间的地址。填一个 192.168.1.1 会直接导致"网关不可达",所有跨网段的访问全部失败。
反过来看,这也解释了为什么同网段通信根本不看网关:直连场景里板子和 PC 互为"直连路由",压根用不到默认路由。
二、 路由表与最长前缀匹配
1. 路由表长什么样
路由器(以及每一台配了网关的主机)内部都有一张路由表,每条表项是"目的网络 → 下一跳 / 出口":
| 目的网络 | 下一跳 | 出口 | 类型 |
|---|---|---|---|
| 192.168.16.0/24 | 直连 | 接口 A | 直连路由 |
| 192.168.1.0/24 | 192.168.16.1 | 接口 A | 静态/动态路由 |
| 0.0.0.0/0 | 运营商网关 | 接口 B | 默认路由 |
表里前两条说明了路由表的两种来源:接口配了地址就自动生成"直连路由",其余靠手工配置(静态)或协议学习(动态,比如 RIP、OSPF)。
2. 最长前缀匹配
当一个包要转发时,可能同时被多条表项匹配上,这时按最长前缀匹配(也叫最长掩码匹配)规则选择:
目的 IP = 192.168.16.30
候选 1: 192.168.16.0/24 前 24 位匹配 ✓
候选 2: 192.168.0.0/16 前 16 位匹配 ✓
候选 3: 0.0.0.0/0 匹配 ✓
规则: 谁的掩码长(前缀长)就用谁 ⇒ 选 192.168.16.0/24这条规则的直觉解释是:掩码越长,描述的范围越小、越精确。 默认路由 0.0.0.0/0 前缀长度为 0,是所有表项里最"偷懒"的一条,所以它永远排在最后——只有前面积累的精确表项都匹配不上时才会用到。
三、 跨网段转发时帧头发生了什么
1. IP 头不变、以太网头逐跳重写
这是理解路由器最关键的一点。路由器转发一个包时:
- IP 头里的源 IP、目的 IP 全程不变(除了 NAT 这种特殊情况,见第四节);
- 以太网头被整个换掉:源 MAC 换成路由器自己出接口的 MAC,目的 MAC 换成下一跳的 MAC。
对应到 TTL 字段,路由器还会把 TTL 减 1,减到 0 就丢弃并回 ICMP 超时报文——这是防止环路的基本保护。
| 位置 | 目的 MAC | 源 MAC | 目的 IP | 源 IP |
|---|---|---|---|---|
| PC 发出的帧 | 网关 | PC | 板子 | PC |
| 路由器转发出的帧 | 板子 | 路由器接口 A | 板子 | PC |
2. 用一次 ping 对照
跨网段 ping 时(板子在 192.168.16.0/24、PC 在 192.168.1.0/24、中间是路由器):
(1)PC 判断目的 IP 与自己不同网段,于是查默认路由,把帧发给自己网关的 MAC。
(2)PC 发起的 ARP 请求问的是网关的 MAC,而不是板子的 MAC——这一点最容易搞混。
(3)路由器收到帧,查路由表找到 192.168.16.0/24 直连,于是把帧从接口 A 发出去,换掉整个以太网头。
(4)板子收到请求,生成应答。目的 IP 192.168.1.100 与自己不同网段,于是交给自己的网关——这一步要求板子必须配了正确的网关。
(5)路由器反向转发回 PC,链路两端的 MAC 再次被重写。
这里有一个非常有辨识度的故障现象:如果板子没配网关(或配了一个不存在的地址),它能收到请求却发不出应答。表现就是"PC 一直超时,而板子串口日志显示确实收到了包"。看到这个现象,不要怀疑收包路径,直接去查网关配置。
四、 NAT:私有地址为什么能重复使用
1. 出门换地址
LV010 提到过私有地址(192.168.0.0/16 等)可以重复使用,原因就是 NAT(网络地址转换)。
家用路由器 WAN 口拿到的是一个公网地址,内网设备包里的私有源地址在出门时会被换成这个公网地址:
| 阶段 | 源 IP:端口 | 目的 IP:端口 |
|---|---|---|
| 内网主机发出 | 192.168.16.30:50000 | 93.184.216.34:80 |
| 路由器 NAT 后 | 公网地址:40001 | 93.184.216.34:80 |
2. 回包怎么找回来
NAT 不只是替换地址,还要记住映射关系:路由器内部维护一张 NAT 表,记录"公网地址:40001 ↔ 192.168.16.30:50000"。回包到了公网地址的 40001 端口,按表换回私有地址与端口,再交给内网主机。
这解释了 NAT 的两个特征:
(1)内网可以随便用重复的私有地址,因为出门就被换掉了,公网上看到的只有路由器的公网地址。
(2)外网无法主动发起连接。外网设备不知道该用什么地址去连一台内网机器——NAT 表里没有对应表项就没有映射,包会被丢掉。这也是为什么网络升级实验里必须由 PC 主动去连板子,而不是板子反过来连 PC。
五、 回到本工程:为什么本实验用不到网关
1. 直连与同交换机
本工程的两种接法(网线直连、都接在同一台交换机上)都是同一个网段:
| 角色 | 地址 |
|---|---|
| 板子 | 192.168.16.30/24 |
| PC | 192.168.16.100/24 |
两边互相访问走的是"直连路由",默认路由一次都用不到。所以:
- 网关填不填、填得对不对,都不影响 ping 与网络升级;
- 这也是为什么
lwip_comm.h里把网关配成192.168.16.1只是一个"备用值"。
2. 网关填错的后果与排查
既然用不到,为什么还要提醒?因为填一个不存在的网关会引入假故障:
| 现象 | 原因 |
|---|---|
| ping 板子正常,但 PC 访问别的网段失败 | PC 的默认路由被指向了一个不存在的设备 |
| PC 侧抓包看到 ICMP 重定向或"目标主机不可达" | 网关存在但路由表里没有回程路由 |
| 板子能收到请求但不回应答 | 板子配了不通的网关,应答交给了默认路由 |
排查建议只有一条:直连实验时把两边的网关留空。留空就没有默认路由,所有"跨网段"的访问会立刻以明确的错误失败,而不是卡在等待里。
六、 小结与参考资料
1. 本篇小结
- 默认网关的本质是路由表里
0.0.0.0/0这条默认路由的下一跳,PC 上的"网关"输入框填的就是它。 - 网关必须是同网段设备,因为要交给它就得先 ARP 到它的 MAC。
- 路由器选表项用最长前缀匹配:掩码越长越优先,默认路由永远垫底。
- 路由器转发时只改以太网头(逐跳重写 MAC)与 TTL,IP 源/目的地址全程不变。
- NAT 让私有地址可以重复使用,同时导致"外网无法主动连内网"。
- 本工程的两种接法都在同一网段,用不到网关;直连实验建议两边网关留空,避免引入假故障。
2. 参考资料
- 网络参数与静态网关:
lwip_comm.h - 路由与地址对照:
ip4_addr.c - 实验中的实际接法:LV020-网络通信实验 第一节
- 手册:
STM32F1 LWIP开发手册(DM9000版)_V1.1.pdf第 1.3 节
本文档由 markdowncli 技能辅助生成