網(wǎng)絡(luò)層(network layer)是實現(xiàn)互聯(lián)網(wǎng)的最重要的一層。正是在網(wǎng)絡(luò)層面上,各個局域網(wǎng)根據(jù)IP協(xié)議相互連接浇揩,最終構(gòu)成覆蓋全球的Internet。更高層的協(xié)議憨颠,無論是TCP還是UDP胳徽,必須通過網(wǎng)絡(luò)層的IP數(shù)據(jù)包(datagram)來傳遞信息。操作系統(tǒng)也會提供該層的socket爽彤,從而允許用戶直接操作IP包养盗。
IP數(shù)據(jù)包是符合IP協(xié)議的信息(也就是0/1序列),我們后面簡稱IP數(shù)據(jù)包為IP包淫茵。IP包分為頭部(header)和數(shù)據(jù)(Data)兩部分爪瓜。數(shù)據(jù)部分是要傳送的信息,頭部是為了能夠?qū)崿F(xiàn)傳輸而附加的信息(這與以太網(wǎng)幀的頭部功能相類似,如果對幀感到陌生匙瘪,可參看小喇叭一文)铆铆。
IP包的格式
IP協(xié)議可以分為IPv4和IPv6兩種。IPv6是改進版本丹喻,用于在未來取代IPv4協(xié)議薄货。出于本文的目的,我們可以暫時忽略兩者的區(qū)別碍论,只以IPv4為例谅猾。下面是IPv4的格式
IPv4包 我們按照4 bytes將整個序列折疊,以便更好的顯示
與幀類似,IP包的頭部也有多個區(qū)域税娜。我們將注意力放在紅色的發(fā)出地(source address)和目的地(destination address)坐搔。它們都是IP地址。IPv4的地址為4 bytes的長度(也就是32位)敬矩。我們通常將IPv4的地址分為四個十進制的數(shù)概行,每個數(shù)的范圍為0-255,比如192.0.0.1就是一個IP地址。填寫在IP包頭部的是該地址的二進制形式弧岳。
IP地址是全球地址凳忙,它可以識別”社區(qū)”(局域網(wǎng))和”房子”(主機)。這是通過將IP地址分類實現(xiàn)的禽炬。
IP class??? From????????? To??????????????? Subnet Mask
A?????????? 1.0.0.0?????? 126.255.255.255??? 255.0.0.0
B?????????? 128.0.0.0???? 191.255.255.255??? 255.255.0.0
C?????????? 192.0.0.0???? 223.255.255.255??? 255.255.255.0
每個IP地址的32位分為前后兩部分涧卵,第一部分用來區(qū)分局域網(wǎng),第二個部分用來區(qū)分該局域網(wǎng)的主機腹尖。子網(wǎng)掩碼(Subnet Mask)告訴我們這兩部分的分界線柳恐,比如255.0.0.0(也就是8個1和24個0)表示前8位用于區(qū)分局域網(wǎng),后24位用于區(qū)分主機桐臊。由于A胎撤、B晓殊、C分類是已經(jīng)規(guī)定好的断凶,所以當一個IP地址屬于B類范圍時,我們就知道它的前16位和后16位分別表示局域網(wǎng)和主機巫俺。
網(wǎng)卡與路由器
網(wǎng)絡(luò)協(xié)議概覽中說认烁,IP地址是分配給每個房子(計算機)的“郵編”。但這個說法并不精確介汹。IP地址實際上識別的是網(wǎng)卡(NIC, Network Interface Card)却嗡。網(wǎng)卡是計算機的一個硬件,它在接收到網(wǎng)路信息之后嘹承,將信息交給計算機(處理器/內(nèi)存)窗价。當計算機需要發(fā)送信息的時候,也要通過網(wǎng)卡發(fā)送叹卷。一臺計算機可以有不只一個網(wǎng)卡撼港,比如筆記本就有一個以太網(wǎng)卡和一個WiFi網(wǎng)卡。計算機在接收或者發(fā)送信息的時候骤竹,要先決定想要通過哪個網(wǎng)卡帝牡。
NIC
路由器(router)實際上就是一臺配備有多個網(wǎng)卡的專用電腦。它讓網(wǎng)卡接入到不同的網(wǎng)絡(luò)中蒙揣,這樣靶溜,就構(gòu)成在網(wǎng)絡(luò)協(xié)議概覽中所說的郵局。比如下圖中位于中間位置的路由器有兩個網(wǎng)卡,地址分別為199.165.145.17和199.165.146.3罩息。它們分別接入到兩個網(wǎng)絡(luò):199.165.145和199.165.146嗤详。
IP包接力
IP包的傳輸要通過路由器的接力。每一個主機和路由中都存有一個路由表(routing table)瓷炮。路由表根據(jù)目的地的IP地址断楷,規(guī)定了等待發(fā)送的IP包所應該走的路線。就好像下圖的路標崭别,如果地址是“東京”冬筒,那么請轉(zhuǎn)左;如果地址是“悉尼”茅主,那么請向右舞痰。
A real world routing table
比如我們從主機145.17生成發(fā)送到146.21的IP包:鋪開信紙,寫好信的開頭(剩下數(shù)據(jù)部分可以是TCP包诀姚,可以是UDP包响牛,也可以是任意亂寫的字,我們暫時不關(guān)心)赫段,注明目的地IP地址(199.165.146.21)和發(fā)出地IP地址(199.165.145.17)呀打。主機145.17隨后參照自己的routing table,里面有三行記錄:
145.17 routing table (Genmask為子網(wǎng)掩碼,Iface用于說明使用哪個網(wǎng)卡接口)
Destination??????? Gateway ? ? ? ? ? ? Genmask ? ? ? ? ? ? Iface
199.165.145.0????? 0.0.0.0???????????? 255.255.255.0?????? eth0
0.0.0.0???????? ?? 199.165.145.17????? 0.0.0.0???????????? eth0
這里有兩行記錄糯笙。
第一行表示贬丛,如果IP目的地是199.165.145.0這個網(wǎng)絡(luò)的主機,那么只需要自己在eth0上的網(wǎng)卡直接傳送(“本地社區(qū)”:直接送達)给涕,不需要前往router(Gateway 0.0.0.0 = “本地送信”)豺憔。
第二行表示所有不符合第一行的IP目的地,都應該送往Gateway 199.165.145.17够庙,也就是中間router接入在eth0的網(wǎng)卡IP地址(郵局在eth0的分支)恭应。
我們的IP包目的地為199.165.146.21,不符合第一行耘眨,所以按照第二行昼榛,發(fā)送到中間的router。主機145.17會將IP包放入幀的payload剔难,并在幀的頭部寫上199.165.145.17對應的MAC地址胆屿,這樣,就可以按照以太網(wǎng)與wifi協(xié)議中的方法在局域網(wǎng)中傳送了钥飞。
中間的router在收到IP包之后(實際上是收到以太協(xié)議的幀莺掠,然后從幀中的payload讀取IP包),提取目的地IP地址读宙,然后對照自己的routing table:
Destination??????? Gateway ? ? ? ? ? ? Genmask ? ? ? ? ? ? Iface
199.165.145.0????? 0.0.0.0???????????? 255.255.255.0?????? eth0
199.165.146.0????? 0.0.0.0???????????? 255.255.255.0?????? eth1
0.0.0.0???????? ?? 199.165.146.8 ??? ? 0.0.0.0???????????? eth1
從前兩行我們看到彻秆,由于router橫跨eth0和eth1兩個網(wǎng)絡(luò),它可以直接通過eth0和eth1上的網(wǎng)卡直接傳送IP包。
第三行表示唇兑,如果是前面兩行之外的IP地址酒朵,則需要通過eth1,送往199.165.146.8(右邊的router)扎附。
我們的目的地符合第二行蔫耽,所以將IP放入一個新的幀中,
在幀的頭部寫上199.165.146.21的MAC地址留夜,直接發(fā)往主機146.21匙铡。
(在Linux下,可以使用$route -n來查看routing table)
IP包可以進一步接力碍粥,到達更遠的主機鳖眼。IP包從主機出發(fā),根據(jù)沿途路由器的routing table指導嚼摩,在router間接力钦讳。IP包最終到達某個router,這個router與目標主機位于一個局域網(wǎng)中枕面,可以直接建立連接層的通信愿卒。最后,IP包被送到目標主機潮秘。這樣一個過程叫做routing(我們就叫IP包接力好了琼开,路由這個詞實在是混合了太多的意思)。
整個過程中唇跨,IP包不斷被主機和路由封裝入幀(信封)并拆開稠通,然后借助連接層,在局域網(wǎng)的各個NIC之間傳送幀买猖。整個過程中,我們的IP包的內(nèi)容保持完整滋尉,沒有發(fā)生變化玉控。最終的效果是一個IP包從一個主機傳送到另一個主機。利用IP包狮惜,我們不需要去操心底層(比如連接層)發(fā)生了什么高诺。
ARP協(xié)議
在上面的過程中,我們實際上假設(shè)了碾篡,每一臺主機和路由都能了解局域網(wǎng)內(nèi)的IP地址和MAC地址的對應關(guān)系虱而,這是實現(xiàn)IP包封裝(encapsulation)到幀的基本條件。IP地址與MAC地址的對應是通過ARP協(xié)議傳播到局域網(wǎng)的每個主機和路由开泽。每一臺主機或路由中都有一個ARP cache牡拇,用以存儲局域網(wǎng)內(nèi)IP地址和MAC地址如何對應。
ARP協(xié)議(ARP介于連接層和網(wǎng)絡(luò)層之間,ARP包需要包裹在一個幀中)的工作方式如下:主機會發(fā)出一個ARP包惠呼,該ARP包中包含有自己的IP地址和MAC地址导俘。通過ARP包,主機以廣播的形式詢問局域網(wǎng)上所有的主機和路由:我是IP地址xxxx剔蹋,我的MAC地址是xxxx旅薄,有人知道199.165.146.4的MAC地址嗎?擁有該IP地址的主機會回復發(fā)出請求的主機:哦泣崩,我知道少梁,這個IP地址屬于我的一個NIC,它的MAC地址是xxxxxx矫付。由于發(fā)送ARP請求的主機采取的是廣播形式猎莲,并附帶有自己的IP地址和MAC地址,其他的主機和路由會同時檢查自己的ARP cache技即,如果不符合著洼,則更新自己的ARP cache。
這樣而叼,經(jīng)過幾次ARP請求之后身笤,ARP cache會達到穩(wěn)定。如果局域網(wǎng)上設(shè)備發(fā)生變動葵陵,ARP重復上面過程液荸。
(在Linux下,可以使用$arp命令來查看ARP的過程脱篙。ARP協(xié)議只用于IPv4娇钱。IPv6使用Neighbor Discovery Protocol來替代ARP的功能。)
Routing Table的生成
我們還有另一個假設(shè)绊困,就是每個主機和路由上都已經(jīng)有了合理的routing table文搂。這個routint table描述了網(wǎng)絡(luò)的拓撲(topology)結(jié)構(gòu)。如果你了解自己的網(wǎng)絡(luò)連接秤朗,可以手寫自己主機的routing table煤蹭。但是,一個路由器可能有多個出口取视,所以routing table可能會很長硝皂。更重要的是,周圍連接的其他路由器可能發(fā)生變動(比如新增路由器或者路由器壞掉)作谭,我們就需要routing table能及時將交通導向其他的出口稽物。我們需要一種更加智能的探測周圍的網(wǎng)絡(luò)拓撲結(jié)構(gòu),并自動生成routing table折欠。
我們以北京地鐵為例子贝或。如果從機場前往朝陽門吼过,那么可以采取2號航站樓->>三元橋->>東直門->>朝陽門。2號航站樓和朝陽門分別是出發(fā)和目的主機傀缩。而三元橋和東直門為中間的兩個router那先。如果三元橋->>東直門段因為維修停運,我們需要更改三元橋的routing table赡艰,從而給前往朝陽門的乘客(IP包)指示:請走如下路線三元橋->>芍藥居售淡。然后依照芍藥居的routing table前往朝陽門(芍藥居->>東直門->>朝陽門)。
一種用來生成routing table的協(xié)議是RIP(Routing Information Protocol)慷垮。它通過距離來決定routing table揖闸,所以屬于distance-vector protocol。對于RIP來說料身,所謂的距離是從出發(fā)地到目的地途徑的路由器數(shù)目(hop number)汤纸。比如上面從機場到朝陽門,按照2號航站樓->>三元橋->>東直門->>朝陽門路線芹血,途徑兩個路由器贮泞,距離為2。我們最初可以手動生成三元橋的routing table幔烛。隨后啃擦,根據(jù)RIP協(xié)議,三元橋向周圍的路由器和主機廣播自己前往各個IP的距離(比如到機場=0饿悬,團結(jié)湖=0令蛉,國貿(mào)=1,望京西=1狡恬,建國門=2)珠叔。收到RIP包的路由器和主機根據(jù)RIP包和自己到發(fā)送RIP包的主機的距離,算出自己前往各個IP的距離弟劲。東直門與三元橋的距離為1祷安。東直門收到三元橋的RIP包(到機場的距離為0),那么東直門途徑三元橋前往機場的距離為1+0=1函卒。如果東直門自己的RIP記錄都比這個遠(比如東直門->>芍藥居->>三元橋->>機場 = 2)辆憔。那么東直門更改自己的routing table:前往機場的交通都發(fā)往三元橋而不是芍藥居。如果東直門自身的RIP記錄并不差报嵌,那么東直門保持routing table不變。上述過程在各個點不斷重復RIP廣播/計算距離/更新routing table的過程熊榛,最終所有的主機和路由器都能生成最合理的路徑(merge)锚国。
(RIP的基本邏輯是:如果A距離B為6,而我距離A為1玄坦,那么我途徑A到B的距離為7)
RIP出于技術(shù)上的原因(looping hops)血筑,認為距離超過15的IP不可到達绘沉。所以RIP更多用于互聯(lián)網(wǎng)的一部分(比如整個中國電信的網(wǎng)絡(luò))。這樣一個互聯(lián)網(wǎng)的部分往往屬于同一個ISP或者有同一個管理機構(gòu)豺总,所以叫做自治系統(tǒng)(AS,autonomous system)车伞。自治系統(tǒng)內(nèi)部的主機和路由根據(jù)通向外部的邊界路由器來和其它的自治系統(tǒng)通信。各個邊界路由器之間通過BGP(Border Gateway Protocol)來生成自己前往其它AS的routing table喻喳,而自治系統(tǒng)內(nèi)部則參照邊界路由器另玖,使用RIP來決定routing table。BGP的基本工作過程與RIP類似表伦,但在考慮距離的同時谦去,也權(quán)衡比如政策、連接性能等其他因素蹦哼,再決定交通的走向(routing table)鳄哭。
總結(jié)
我們一開始講述了IP包根據(jù)routing table進行接力的過程。為了順利實現(xiàn)接力纲熏,我們又進一步深入到ARP和RIP/BGP妆丘。這三個協(xié)議都協(xié)助了IP傳輸。ARP讓每臺電腦和路由器知道自己局域網(wǎng)內(nèi)IP地址和MAC地址的對應關(guān)系局劲,從而順利實現(xiàn)IP包到幀的封裝勺拣。RIP協(xié)議可以生成自治系統(tǒng)內(nèi)部合理的routing table。BGP協(xié)議可以生成自治系統(tǒng)外部的routing table容握。
在整個過程中宣脉,我們都將注意力放在了IP包大的傳輸過程中,而故意忽略一些細節(jié)剔氏。 而上面的IP接力過程適用于IPv6塑猖。
【TCP/IP詳解】系列教程
TCP-IP協(xié)議詳解(1)網(wǎng)絡(luò)協(xié)議概觀
TCP-IP協(xié)議詳解(2) 以太網(wǎng)與WiFi協(xié)議
TCP-IP協(xié)議詳解(3) IP/ARP/RIP/BGP協(xié)議
TCP-IP協(xié)議詳解(6) ICMP協(xié)議
TCP-IP協(xié)議詳解(8) TCP協(xié)議與流通信
TCP-IP協(xié)議詳解(13) DNS協(xié)議