網絡層協議
- IP協議
- 基本概念
- 協議頭格式
- 網段劃分
- 特殊的IP地址
- IP地址的數量限制
- 私有IP地址和公網IP地址
- 路由
- IP協議頭格式后續
在復雜的網絡環境中確定一個合適的路徑
IP協議
承接上文,TCP協議并不會直接將數據傳遞給對方,而是交付給下一層協議,那么TCP協議扮演了什么角色呢?
先介紹IP地址的作用:
- 定位主機
- 具有將一個數據包跨網絡可靠地傳遞給對方的能力
IP地址有這個能力,但是并不一定能夠做到,有很大概率可以做到;此時TCP協議就為此出謀劃策,IP去執行,如此以來便能夠做到
所以TCP扮演策略,IP付出實際行動
路徑選擇中,目的IP非常重要,決定了路徑該如何走;
IP=目標網絡+目標主機
怎么理解目標網絡和目標主機呢?
舉個栗子
你打算去沈陽游玩,沈陽就是目標網絡;游玩地點比如故宮,故宮就是目標主機
基本概念
主機: 配有IP地址, 但是不進行路由控制的設備;
路由器: 即配有IP地址, 又能進行路由控制; 節點: 主機和路由器的統稱
協議頭格式
- 4位版本號(version): 指定IP協議的版本, 對于IPv4來說, 就是4
- 4位首部長度(header length): IP頭部的長度是多少個32bit, 也就是 length * 4 的字節數. 4bit表示最大的數字是15, 因此IP頭部最大長度是60字節
- 8位服務類型(Type Of Service): 3位優先權字段(已經棄用), 4位TOS字段, 和1位保留字段(必須置為0). 4位TOS分別表示: 最小延時, 最大吞吐量, 最高可靠性, 最小成本. 這四者相互沖突, 只能選擇一個. 對于ssh/telnet這樣的應用程序, 最小延時比較重要; 對于ftp這樣的程序, 最大吞吐量比較重要
- 16位總長度(total length): IP數據報整體占多少個字節
- 16位標識(id),3位標志,13位片偏移后面詳細介紹
- 8位生存時間(Time To Live, TTL): 數據報到達目的地的最大報文跳數. 一般是64. 每次經過一個路由, TTL -= 1, 一直減到0還沒到達, 那么就丟棄了. 這個字段主要是用來防止出現路由循環
- 8位協議: 表示上層協議的類型
- 16位頭部校驗和: 使用CRC進行校驗, 來鑒別頭部是否損壞
- 32位源地址和32位目標地址: 表示發送端和接收端
- 選項字段(不定長, 最多40字節)
協議最重要的兩個問題:
如何解包?
IP協議有4位首部長度,16位總長度;解包輕松完成
如何分用(交付)?
IP協議報頭中的8位協議表示上層的協議類型,分用也可輕松完成
網段劃分
IP地址分為兩個部分, 網絡號和主機號
- 網絡號: 保證相互連接的兩個網段具有不同的標識
- 主機號: 同一網段內, 主機之間具有相同的網絡號, 但是必須有不同的主機號
介紹網段劃分之前,先舉個栗子
有一天,你在校園里把自己的學生卡不小心給丟了,結果被張三給撿到;此時如果張三想要物歸原主,他有兩種做法:
第一種做法:見到一個同學就問對方這張學生卡是不是對方的,這種做法效率太低,不可取;
第二種做法:在學校每個學生都有學號來標識自己,學號被劃分幾部分:學院,專業,班級,人數;恰好學生卡上也有你的學號;張三并不知道你是什么學院的,所以他只能將證件交給學院的學生會,院學生會再將證件交到校學生會,本學院的成員肯定是知道此證件是本院的學生,最后將證件歸還給你,如此一來,效率大大提高
校學生會是目標網絡,院學生會就是目標主機;院學生會是目標網絡,學生就是目標主機
所以互聯網中每一臺主機都要隸屬于某一個子網,在子網中便可快速定位到每個主機
網段劃分就是為了劃分出每個子網,未來方便定位主機
- 不同的子網其實就是把網絡號相同的主機放到一起.
- 如果在子網中新增一臺主機, 則這臺主機的網絡號和這個子網的網絡號一致, 但是主機號必須不能和子網中的其他主機重復
通過合理設置主機號和網絡號, 就可以保證在相互連接的網絡中, 每臺主機的IP地址都不相同
那么問題來了, 手動管理子網內的IP, 是一個相當麻煩的事情
有一種技術叫做DHCP, 能夠自動的給子網內新增主機節點分配IP地址, 避免了手動管理IP的不便一般的路由器都帶有DHCP功能. 因此路由器也可以看做一個DHCP服務器
因為IP地址一共就43億多,所以為了提高利用率,提出了劃分方案, 稱為CIDR(Classless Interdomain Routing)
- 引入一個額外的子網掩碼(subnet mask)來區分網絡號和主機號
- 子網掩碼也是一個32位的正整數. 通常用一串 “0” 來結尾
- 將IP地址和子網掩碼進行 “按位與” 操作, 得到的結果就是網絡號
- 網絡號和主機號的劃分與這個IP地址是A類、B類還是C類無關
舉個栗子
IP地址 | 140.250.25.68 |
---|---|
子網掩碼 | 255.255.255.240 |
網絡號 | 140.250.25.68 |
子網地址范圍 | 140.250.25.64~140.250.25.79 |
計算過程
IP地址與子網掩碼做與運算可以得到網絡號, 主機號從全0到全1就是子網的地址范圍
特殊的IP地址
- 將IP地址中的主機地址全部設為0, 就成為了網絡號, 代表這個局域網
- 將IP地址中的主機地址全部設為1, 就成為了廣播地址, 用于給同一個鏈路中相互連接的所有主機發送數據包
- 127.*的IP地址用于本機環回(loop back)測試,通常是127.0.0.1
IP地址的數量限制
我們知道, IP地址(IPv4)是一個4字節32位的正整數. 那么一共只有 2的32次方 個IP地址, 大概是43億左右. 而TCP/IP協議規定, 每個主機都需要有一個IP地址
這意味著, 一共只有43億臺主機能接入網絡么?
實際上, 由于一些特殊的IP地址的存在, 數量遠不足43億; 另外IP地址并非是按照主機臺數來配置的, 而是每一個網卡都需要配置一個或多個IP地址
CIDR在一定程度上緩解了IP地址不夠用的問題(提高了利用率, 減少了浪費, 但是IP地址的絕對上限并沒有增加), 仍然不是很夠用. 這時候有三種方式來解決
- 動態分配IP地址: 只給接入網絡的設備分配IP地址. 因此同一個MAC地址的設備, 每次接入互聯網中, 得到的IP地址不一定是相同的
- NAT技術
- IPv6: IPv6并不是IPv4的簡單升級版. 這是互不相干的兩個協議, 彼此并不兼容; IPv6用16字節128位來表示一個IP地址; 但是目前IPv6還沒有普及
私有IP地址和公網IP地址
如果一個組織內部組建局域網,IP地址只用于局域網內的通信,而不直接連到Internet上,理論上 使用任意的IP地址都可以,但是RFC 1918規定了用于組建局域網的私有IP地址
- 10.*,前8位是網絡號,共16,777,216個地址
- 172.16.到172.31.,前12位是網絡號,共1,048,576個地址
- 192.168.*,前16位是網絡號,共65,536個地址
包含在這個范圍中的, 都成為私有IP, 其余的則稱為全局IP(或公網IP)
為了詳細理解私有IP和共有IP,先舉個栗子
如果家里想要連網,先要聯系附近的運營商來裝路由器,路由器裝好之后,需要先設置賬號和密碼,準備工作全部完成之后,便可找到自家的IP賬號輸入密碼聯通網路;家里面的各個設備連接網絡之后,也就組成了一個子網
結合上面的內容:
一般在一個子網中,管理子網中IP的設備通常是路由器
目標網絡和子網掩碼,子網中的主機都會被路由器管理;目標網絡和子網掩碼都是在路由器內部已經配置過的
路由器的作用分為三點:
- 轉發
- DHCP|組建局域網
- NAT
介紹一下數據路由的過程
假設從左側主機192.168.201/24(私網)向122.77.241.3/24(公網)發送數據,有了源IP和目的IP,數據很快便可傳遞到目的主機中,但是卻存在一個問題,公網和私網是不能同時出現的;而且如果目的主機進行應答,又該怎么辦呢?
路由器中存在兩個IP:LAN口(對內),WAN口(對外)
真實的路由過程如下
數據在經過路由器進行轉發時,目的IP不變,源IP會自動轉換為路由器的WAN口IP,反過來亦是如此;這個操作也稱為NAT計數;上圖只是一小部分子網,往上可以連接上城市,省份,國家和上面舉的例子(學生證丟失)一樣
- 一個路由器可以配置兩個IP地址, 一個是WAN口IP, 一個是LAN口IP(子網IP)
- 路由器LAN口連接的主機, 都從屬于當前這個路由器的子網中
- 不同的路由器, 子網IP其實都是一樣的(通常都是192.168.1.1). 子網內的主機IP地址不能重復. 但是子網之間的IP地址就可以重復
- 每一個家用路由器, 其實又作為運營商路由器的子網中的一個節點. 這樣的運營商路由器可能會有很多級, 最外層的運營商路由器, WAN口IP就是一個公網IP
- 子網內的主機需要和外網進行通信時, 路由器將IP首部中的IP地址進行替換(替換成WAN口IP), 這樣逐級替換, 最終數據包中的IP地址成為一個公網IP. 這種技術稱為NAT(Network Address Translation,網絡地址轉換)
抽象的圖解如下
路由
在復雜的網絡結構中, 找出一條通往終點的路線
路由的過程, 就是這樣一跳一跳(Hop by Hop) “問路” 的過程
所謂 “一跳” 就是數據鏈路層中的一個區間. 具體在以太網中指從源MAC地址到目的MAC地址之間的幀傳輸區間
舉個栗子
假如你下了火車,準備去學校,這時你只能通過問路的方式得知學校的地址;當你詢問一個陌生人時會有三種答案:不知道;不知道,但是告知你有人知道;不知道,但是知道到達學校過程中某一地點的地址
在網絡的路由中,只存在后面兩種情況
IP數據包的傳輸過程也和問路一樣
- 當IP數據包, 到達路由器時, 路由器會先查看目的IP
- 路由器決定這個數據包是能直接發送給目標主機, 還是需要發送給下一個路由器
- 依次反復, 一直到達目標IP地址
那么如何判定當前這個數據包該發送到哪里呢? 這個就依靠每個節點內部維護一個路由表
- destination:目標IP
- gateway:路由選擇
- genmask:子網掩碼
- flags:使用狀態
- Iface:接口
路由的過程
- 遍歷路由表
- 目的IP&路由表中的子網掩碼->確定報文的目標網絡
- 對比結果是否和目標IP相等
- 通過Iface接口發出報文
IP協議頭格式后續
網絡層的下一層數據鏈路層,MAC幀協議規定有效載荷不能超過1500字節(MTU)
網絡層并不能決定單個報文的大小,TCP決定單個報文的大小;數據鏈路層有規定只能接收那么多;網絡層只能夾在中間,提出解決方案
當IP報頭+IP有效載荷超過1500字節時:
IP分片和組裝,自己的IP層進行分片,對方的IP層進行組裝
- 16位標識(id): 唯一的標識主機發送的報文. 如果IP報文在數據鏈路層被分片了, 那么每一個片里面的這個id都是相同的
- 3位標志字段: 第一位保留(保留的意思是現在不用, 但是還沒想好說不定以后要用到). 第二位置為1表示禁止分片, 這時候如果報文長度超過MTU, IP模塊就會丟棄報文. 第三位表示"更多分片", 如果分片了的話, 最后一個分片置為1, 其他是0. 類似于一個結束標記
- 13位分片偏移(framegament offset): 是分片相對于原始IP報文開始處的偏移. 其實就是在表示當前分片在原報文中處在哪個位置. 實際偏移的字節數是這個值 * 8 得到的. 因此, 除了最后一個報文之外, 其他報文的長度必須是8的整數倍(否則報文就不連續了)
報文分片簡單,組裝是個大問題
如何得知報文被分片?
3位標志中如果更多分片位1,說明該標識的報文進行分片;如果更多分片為0,并且13位片偏移大于零也標識報文進行分片,除此之外都沒有分片
同一個報文的分片如何被識別出來?
16位標識
每個分片的位置,有沒有收全或者丟失?
更多分片為1,片偏移為0是第一個分片;更多分片為0,片偏移大于零是最后一個分片;當前的起始位置+分片自身長度=下一個報文中填充的分片的偏移量大小,如果對不上就說明分片丟失
如何進行正確的組裝?
按照片偏移進行升序排序即可
如何保證組裝的報文是正確的?
TCP/IP存在校驗和
分片這一操作并不妥善,對于TCP/UDP/IP一個報文被拆分為多份,任意一個分片丟失,都會造成組裝失敗,從而導致報文重新發送