JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

IP 位址、子網路與 CIDR

一個 IP 位址,其實只是一個穿著「四段點分」外衣的 32 位元數字。一旦你看出網路部分在哪裡結束、主機部分又從哪裡開始,子網路遮罩、10.0.0.0/8 裡的那條斜線,以及路由器把數百萬個位址收進一行的做法,就會全部豁然開朗。

IP 位址是一個喬裝過的 32 位元數字

在第一篇裡,我們認識了網際網路協定,也看到每個 IP 資料報都帶著一個目的地位址,好讓路由器知道接下來該把它送往哪裡。現在,讓我們把那個位址本身拆開來看。一個 IPv4 位址看起來像 192.168.1.10,但這個親切的四段式寫法只是一套戲服。在它底下,它其實只是一個單一的 32 位元二進位數字——連成一排的 32 個 1 和 0。我們把這 32 個位元切成四組、每組 8 個(每一組稱為一個八位元組 octet),把每組寫成一個 0 到 255 的普通十進位數字,再用小數點黏起來。這就是「點分十進位」表示法的全部把戲:它讓一個 32 位元的數字變得人類看得懂。

因為每個八位元組是 8 個位元,它能容納 2^8 = 256 種不同的數值,這正是為什麼你永遠不會看到 192.168.1.256——8 個位元裡塞不下一個 256。整個位址總共 32 位元,於是整片位址空間共有 2^32 個位址,大約 43 億個。這個數字在 1980 年代聽起來大得驚人,可一旦每支手機、每台冰箱、每個門鈴都想要一個,就小得可笑了。把這些位址用光,正是接下來兩篇談 NAT 與 IPv6 的全部動機,所以請把這 43 億的天花板放在腦袋後面記著。

一個位址裡藏著兩個位址:網路部分與主機部分

這裡有一個貫穿整篇的最重要觀念:一個 IP 位址,其實是兩個位址焊在一起。左邊那一段位元命名一個「網路」——一個街區、一條街——而右邊那一段命名那個網路上某一台特定的「主機」——也就是那條街上的門牌號碼。這個切分恰恰就像一個郵政地址:城市與街道把你帶到正確的區域,門牌號碼則挑出那一扇門。在核心裡的路由器並不在乎你那一棟特定的房子;它只把封包導向正確的街道,這正是為什麼「依網路部分把位址分組」能讓路由具有可擴展性。

但網路部分在哪裡結束、主機部分又從哪裡開始呢?光看那四個數字本身,什麼也看不出來。這條界線是另外攜帶的,由一個搭檔數值負責,它叫做子網路遮罩。遮罩同樣是一個 32 位元的圖樣,但是一個整齊的圖樣:一連串的 1,後面接一連串的 0。遮罩裡每一個是 1 的位元位置,都是一個網路位元;每一個 0,都是一個主機位元。把位址對齊到它的遮罩底下,那條分界線就會跳出來。要剝出網路部分,路由器會把位址和遮罩做一次逐位元的 AND(且運算)——只要遮罩是 0 的地方,結果就被逼成 0,於是主機位元被抹掉,只留下網路部分。

Address  192.168.1.10   = 11000000 10101000 00000001 00001010
Mask     255.255.255.0  = 11111111 11111111 11111111 00000000
                          \------ network (24 bits) ----/ \host/

Address AND Mask -> network number:
                          11000000 10101000 00000001 00000000
                        = 192.168.1.0    (the network this host lives on)
Host part (the rightmost 8 bits)        = .10   (this specific host)
用一個 24 位元的遮罩切開 192.168.1.10:把位址與遮罩做 AND 運算,露出網路 192.168.1.0;剩下的 .10 就是主機。

從僵硬的類別到那條斜線:CIDR

早年,那條界線並不能自由地落在任何地方——當時的網際網路使用「分類定址(classful addressing)」,它強迫網路/主機的切分點,落在三個固定位置之一。A 類區塊把切分點固定在第 8 位元之後(約 1600 萬台主機),B 類在第 16 位元之後(約 6 萬 5 千台主機),C 類則在第 24 位元之後(只有 254 台主機)。問題出在中間尺寸殘酷地缺席。一個需要 2000 個位址的機構,對 C 類來說太大,於是被塞了一個有 6 萬 5 千個位址的 B 類,白白浪費掉 6 萬多個位址。把這種浪費乘上全世界,那 43 億的池子就以驚人的速度見底。

這個修補方案在 1993 年登場,就是無類別域間路由,大家通稱 CIDR(唸作「賽德」)。CIDR 丟掉了那三個僵硬的類別,讓界線能落在任意數量的位元之後。我們用你到處都見過的「斜線表示法」來寫它:一個像 10.0.0.0/8 的前綴,意思是「前 8 個位元是網路,其餘是主機」。斜線後面的數字,就只是網路位元的個數——也就是遮罩裡那串 1 的長度。所以 /24 就是上面例子裡的遮罩 255.255.255.0,/16 是 255.255.0.0,而 /8 是 255.0.0.0。斜線與點分遮罩說的是同一件事,只是兩種寫法。

現在讀一個前綴,是一道飛快的心算。在一個 /n 前綴下,網路位元被固定住,剩下的 32 − n 個位元自由地留給主機,所以這個區塊共有 2^(32−n) 個位址。一個 /24 有 2^8 = 256 個位址,一個 /26 有 2^6 = 64 個,一個 /16 有 2^16 = 65536 個。斜線後的數字愈小,網路位元愈少,區塊就愈大。在現實裡,每個區塊都有兩個位址被保留——全為 0 的主機(網路本身),以及全為 1 的主機(該網路的廣播位址)——所以一個 /24 給的是 254 台可用主機,而不是 256 台。值得記住,卻很容易忘記。

子網路切分:借用主機位元,把一個區塊切開

現在把這個想法反過來用。CIDR 讓你能做出任意大小的區塊,而子網路切分,就是把你已經擁有的一個區塊,切成數個更小區塊的動作。你的做法,是從主機部分借幾個位元、把它們升格成網路位元——也就是把界線往右滑。假設你公司握有 192.168.1.0/24,一個共 256 個位址的扁平網路,而你想要四個彼此分開的網路,工程、業務、訪客、印表機各一個。從主機那一側借 2 個位元(因為 2^2 = 4 正好給你四塊),於是遮罩就從 /24 長到了 /26。

  1. 工程拿到 192.168.1.0/26——網路號碼 .0,可用主機 .1 到 .62,廣播 .63。
  2. 業務拿到 192.168.1.64/26——網路號碼 .64,可用主機 .65 到 .126,廣播 .127。
  3. 訪客拿到 192.168.1.128/26——網路號碼 .128,可用主機 .129 到 .190,廣播 .191。
  4. 印表機拿到 192.168.1.192/26——網路號碼 .192,可用主機 .193 到 .254,廣播 .255。每個子網路有 2^(32−26) = 64 個位址,其中 62 個是可用主機。

為什麼要費事把一個整齊的網路切成四塊?因為一個子網路,是連結層憑自己跨不過去的一道邊界。回想連結層那一級講過的:一台普通的交換器,從來不會切開一個廣播網域——你灑出一個廣播,它就會抵達那個扁平網路上的每一個人。把區塊切成彼此分開的子網路,等於在各群之間放了一台路由器,於是訪客那一堆廣播閒聊永遠不會淹到工程那邊,而你也能在邊界上套用不同的規則。子網路切分,是一個機構在不向任何人多要位址的前提下,替它手上拿到的位址強加結構與隔離的辦法。

路由器為什麼愛 CIDR:一行收下百萬個位址

子網路切分把區塊拆開;CIDR 的另一項超能力,則是把它們黏起來。假設一家 ISP 擁有 256 個相鄰的 /24 網路,而它們的前 16 個位元全都相同。它不必向網際網路其餘部分宣告 256 條分開的路由,而是宣告一條摘要路由:單單一個 /16。其他地方的任何人只需要知道「要到達任何以那 16 個位元開頭的目的地,就把它送往這家 ISP」。把許多條具體前綴塌縮成一條更短前綴的做法,叫做「聚合(aggregation)」,這正是網際網路核心路由器能把整個世界裝進一張大小可控的轉送表、而不是塞進數十億筆條目的原因。

聚合製造了一個美妙的問題:一張轉送表裡,可能同時有好幾條前綴都符合同一個目的地。那條大的聚合 /16 可能說「去 ISP-A」,而它內部一條更具體的 /24 卻說「去 ISP-B」(也許是某個換了供應商、卻保留原本位址的客戶)。哪一行勝出?規則是最長前綴匹配:在所有符合的條目當中,路由器聽從網路位元最多的那一條——斜線最長、最具體的那條街。具體永遠勝過籠統。我們會在本級第五篇裡,把這次查表詳細追一遍;現在,你只要記住「挑出最具體的匹配」是路由器資料平面的核心就好。

然後還有 IPv6(一段預告)

上面所有的內容都屬於 IPv4,連同它那道硬邦邦的 43 億天花板。它的繼任者 IPv6,保留了你剛學到的每一個觀念——一個網路部分、一個主機部分、斜線後的前綴長度、最長前綴匹配——而只是把位址做得長很多:128 位元,而不是 32 位元。那是 2^128 個位址,一個大到難以感受的數字。對你而言,這裡的好消息是:CIDR 的思路可以整套搬過去——一個像 2001:db8::/32 的 IPv6 前綴,讀法一模一樣——前 32 個位元就是網路。接下來兩篇會正面迎戰位址耗盡這個故事,先談 NAT 這個權宜之計,再談 IPv6 裡真正的解法。

在你離開前,誠實地補一句但書:人們很容易以為更長的位址,就只是「更多裝置」,僅此而已。更深一層的好處在於,有了 128 位元,位址變得如此充裕,以至於每一台裝置都能再次擁有一個全球唯一、可被路由的位址——這恢復了 IPv4 因稀缺而悄悄打破的、最初的端到端設計。至於這個世界是否真的會那樣使用它們,是一個政策與部署的問題,而不是這些位元本身的性質。我們會謹慎地把「協定讓什麼成為可能」和「營運者選擇怎麼做」分開來看。