Learning Objectives
- 說明路由器收到封包時,依目的 IP 查路由表決定從哪個介面、交給哪個下一跳
- 分辨直連網段、靜態路由與預設路由,並用指令加入靜態路由
- 用最長前綴比對判斷多條路由都符合時選哪一條
- 說明封包的回程也需要路由,並用 ping 的結果判斷問題出在去程還是回程
- 說明 TTL 每經過一台路由器減 1,以及 traceroute 怎麼利用 TTL 找出路徑
封包怎麼知道下一步往哪走
上一課看到:目的地不在同一個網段時,電腦把封包交給預設閘道,也就是路由器。 可是路由器接下來要往哪裡送?從系館到學校機房、再到網際網路上的某台伺服器,中間可能經過十幾台路由器, 每一台都只負責決定「下一步」,沒有任何一台知道整條路線。
這個決定靠的是路由表(routing table):一張「目的網段 → 從哪個介面送出、交給誰」的對照表。
| 目的網段 | 下一跳(next hop) | 送出的介面 | 怎麼來的 |
|---|---|---|---|
| 192.168.1.0/24 | 直連 | g0 | 介面設了 192.168.1.1/24,路由器自動知道 |
| 10.0.0.0/30 | 直連 | g1 | 同上 |
| 10.0.2.0/24 | 10.0.0.2 | g1 | 靜態路由:管理者手動加的 |
| 0.0.0.0/0 | 10.0.0.2 | g1 | 預設路由:其他都對不上時走這條 |
路由器收到封包時:
- 看封包的目的 IP
- 在路由表裡找出所有包含這個 IP 的網段
- 如果有好幾條,選前綴最長(範圍最小、最精確)的那一條
- 從那條路由的介面送出;如果有下一跳,先用 ARP(第 8 課)問到下一跳的 MAC
- 一條都對不上:丟掉封包,回報「目的地無法到達」給來源
最長前綴比對與預設路由
一個目的 IP 常常同時落在好幾條路由裡。例如路由表有:
| 目的網段 | 下一跳 |
|---|---|
| 0.0.0.0/0 | 10.0.0.2(往網際網路) |
| 192.168.0.0/16 | 10.0.0.6 |
| 192.168.50.0/24 | 10.0.0.10 |
目的是 192.168.50.20 時,三條都符合:/0 包含所有位址、/16 包含 192.168.x.x、/24 包含 192.168.50.x。
路由器選前綴最長的 /24,因為它描述的範圍最小、資訊最精確。這叫最長前綴比對(longest prefix match)。
| 目的 IP | 符合的路由 | 選哪一條 |
|---|---|---|
| 192.168.50.20 | /0、/16、/24 | /24 → 10.0.0.10 |
| 192.168.7.3 | /0、/16 | /16 → 10.0.0.6 |
| 8.8.8.8 | /0 | /0(預設路由) → 10.0.0.2 |
預設路由(default route)0.0.0.0/0 的前綴長度是 0,任何位址都符合,但它是最不精確的,所以只有其他路由都對不上時才會用到。
一般學校或家裡的路由器,通往網際網路的那條就是預設路由:外面有幾十萬個網段,不可能一條一條寫。
電腦的「預設閘道」其實就是電腦自己路由表裡的一條預設路由。
小測驗:查路由表
路由表有 10.0.0.0/8 → A、10.1.0.0/16 → B、10.1.2.0/24 → C、0.0.0.0/0 → D。目的 10.1.9.9 的封包交給誰?
同一張路由表,目的 172.16.0.1 的封包交給誰?
路由器的介面設了 192.168.1.1/24 之後,路由表會自動多出哪一條?
加靜態路由 route add 10.0.2.0/24 via 10.0.0.2 時,下一跳 10.0.0.2 必須滿足什麼條件,這條路由才會生效?
TTL 與 traceroute
如果路由設錯,形成 R1 → R2 → R1 → R2… 的迴圈,封包會永遠繞下去嗎?不會,因為 IP 標頭有一個欄位叫 TTL(Time To Live):
- 來源主機送出時設一個初始值(常見 64 或 128)
- 每經過一台路由器減 1
- 減到 0 時,那台路由器丟掉封包,並回一個 ICMP「逾時」(time exceeded)給來源
所以剛才的 ping 回覆顯示 ttl=62:PC2 送出時是 64,經過 R2、R1 兩台路由器,到 PC1 剩 62。
traceroute 巧妙地利用這個規則找出路徑:
| 送出的 TTL | 在哪裡變成 0 | 誰回報 |
|---|---|---|
| 1 | 第 1 台路由器 | 第 1 台路由器回「逾時」,於是知道它的位址 |
| 2 | 第 2 台路由器 | 第 2 台路由器 |
| 3 | 抵達目的地 | 目的地回覆 ping(echo reply),結束 |
每一行就是路徑上的一台設備。某一行一直出現 *,表示那一跳沒有回報(可能被防火牆擋掉 ICMP),不一定代表斷線。
Windows 的指令叫 tracert,Linux 與 macOS 叫 traceroute;實際的封包種類各家略有不同(有的用 UDP),原理相同。
小測驗:TTL 與排錯
主機送出 TTL 64 的封包,經過 4 台路由器後抵達目的地。目的地收到時,TTL 是多少?
traceroute 的第 3 行顯示 *,第 4 行之後都正常,最可能的原因是?
從 A ping B 不通,但從 B ping A 也不通;兩邊各自 ping 自己的閘道都通。最該先檢查什麼?
重點整理
- 路由器依目的 IP 查路由表,每一台只決定下一步;路由表有直連網段、靜態路由與預設路由。
- 多條路由都符合時,選前綴最長的那一條;預設路由
0.0.0.0/0最不精確,其他都對不上才用。 - 下一跳必須在直連網段裡;去程與回程各自都要有路由。
- TTL 每經過一台路由器減 1,到 0 就丟掉並回報;traceroute 依序送出 TTL 1、2、3… 的封包找出路徑。
這一課的路由都是手動加的。網路一大,手動維護會出錯、也跟不上線路故障。下一課講動態路由:路由器之間互相告訴對方自己知道哪些網段。