一、協議模型
TCP/IP協議模型(Transmission Control Protocol/Internet Protocol),包含了一系列構成互聯網基礎的網絡協議,是Internet的核心協議,通過20多年的發展已日漸成熟,並被廣泛應用於局域網和廣域網中,目前已成爲事實上的國際標準。TCP/IP協議簇是一組不同層次上的多個協議的組合,通常被認爲是一個四層協議系統,與OSI的七層模型相對應。
- 鏈路層
用來處理連接網絡的硬件部分。包括控制操作系統、硬件的設備驅動、網卡,及光纖等物理可見部分。
- 網絡層
用來規定通過怎樣的路徑把數據包傳送給對方計算機。
- 傳輸層
主要爲兩臺主機上的應用程序提供端到端的通信。
- 應用層
應用層負責處理特定的應用程序細節。
二、各層協議
各種協議在TCP/IP協議模型中所處的層次如下:
ARP:通過IP地址獲取MAC地址。
RARP:通過MAC地址獲取IP地址。
IP:儘快將數據包從一個主機傳送到另一個主機,不保證可靠性。
ICMP:IP層用它來與其他主機或路由器交換錯誤報文和其他重要信息。
IGMP:Internet組管理協議,用來把UDP數據報多播到多個主機。
UDP:簡單地將數據包從一個應用程序發送到另一個應用程序,不保證可靠性。
TCP:提供一個應用程序到另一個應用程序的可靠傳輸。
三、IP地址及分類
互聯網中採用一套獨立的編址技術,使任何主機的編址不受其物理環境的影響。設計人員爲每一臺主機分配了一個唯一的32bit整數地址,稱之爲IP地址。
目前IP地址採用了分類的概念,把所有地址劃分爲A、B、C、D、E五類。
其中,有一些特殊用途的IP地址
環回地址:127.x.x.x,通常使用127.0.0.1。
網絡地址:主機號全0的地址,如85.0.0.0、134.89.0.0、213.89.89.0等。
直接廣播地址:用於向所在網絡廣播消息。主機號全1的地址,如85.255.255.255、134.89.255.255、213.89.89.255等。
受限廣播地址:255.255.255.255,用於向本地網絡廣播消息。
不確定IP地址:0.0.0.0,表示整個網絡
錯誤地址:169.254.x.x,DHCP分配失敗時系統自動分配。
本網絡特定主機地址:網絡號全0的地址,如0.x.x.x、0.0.x.x、0.0.0.x。
/* 不確定IP地址(表示本機所有網絡接口IP地址)指針 */
#define IP_ADDR_ANY ((struct ip_addr *)&ip_addr_any)
/* 廣播IP地址指針 */
#define IP_ADDR_BROADCAST ((struct ip_addr *)&ip_addr_broadcast)
/* A類地址 */
#define IN_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0) //是否爲A類地址
#define IN_CLASSA_NET 0xff000000 //A類網絡地址掩碼
#define IN_CLASSA_NSHIFT 24 //A類網絡地址偏移量
#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET) //A類主機地址掩碼
#define IN_CLASSA_MAX 128 //A類網絡地址最大數
/* B類地址 */
#define IN_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL) //是否爲B類地址
#define IN_CLASSB_NET 0xffff0000 //B類網絡地址掩碼
#define IN_CLASSB_NSHIFT 16 //B類網絡地址偏移量
#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET) //B類主機地址掩碼
#define IN_CLASSB_MAX 65536 //B類網絡地址最大數
/* C類地址 */
#define IN_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL) //是否爲C類地址
#define IN_CLASSC_NET 0xffffff00 //C類網絡地址掩碼
#define IN_CLASSC_NSHIFT 8 //C類網絡地址偏移量
#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET) //C類主機地址掩碼
/* D類地址(組播) */
#define IN_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL) //是否爲D類地址
#define IN_CLASSD_NET 0xf0000000 //D類網絡地址掩碼
#define IN_CLASSD_NSHIFT 28 //D類網絡地址偏移量(高4位1110)
#define IN_CLASSD_HOST 0x0fffffff //D類主機地址掩碼
#define IN_MULTICAST(a) IN_CLASSD(a) //是否爲組播地址
/* 保留未用地址 */
#define IN_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) //是否爲保留未用地址
/* 廣播地址 */
#define IN_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) //是否爲廣播地址
四、子網劃分與子網掩碼
標準IP地址使用網絡號和主機號兩層地址結構,當大量個人用戶和小型局域網用戶接入互聯網,即使爲其分配一個C類網絡也會造成IP地址的大量浪費。隨着互聯網用戶的劇烈增長,IP地址的分配變得格外緊張,爲每個物理網絡分配一個網絡號的做法變得很不現實。
因此,通過子網掩碼的方式將網絡進一步劃分爲多個子網,將原來的二級結構變爲三級結構。如果按照下面的方式進行劃分一個B類網絡來,則可以在整個網絡中劃分出254個子網,每個子網可以有254臺主機。這樣做可以大大減少標準IP編址中地址浪費現象。
網掩和IP地址一樣是一個32位數,其對應網絡地址(包括網絡號和子網號)的所有位置都爲1,對應於主機地址的所有位置都爲。按照上圖這種方式劃分一個B類網絡時,子網掩碼爲255.255.255.0。
對於一個主機或者路由器,當接收到一個數據包時2。若要判斷髮送數據的源主機和自己是否在同一網絡時,可以將源IP地址和子網掩碼進行與運算,得到源主機網絡地址,並同樣的方式得到自己的網絡地址,然後進行比較。
/* 判斷網段是否相同 */
#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
(mask)->addr) == \
((addr2)->addr & \
(mask)->addr))
使用了子網掩碼之後,各個子網也同樣存在廣播地址。下面這段代碼用於判斷IP地址是否爲廣播地址
/* 判斷IP地址是不是廣播地址 */
u8_t ip_addr_isbroadcast(struct ip_addr *addr, struct netif *netif)
{
u32_t addr2test;
addr2test = addr->addr;
/* 全0或全1 */
if ((~addr2test == IP_ADDR_ANY_VALUE) || (addr2test == IP_ADDR_ANY_VALUE))
return 1;
/* 網絡接口不支持廣播 */
else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0)
return 0;
/* 本機地址 */
else if (addr2test == netif->ip_addr.addr)
return 0;
/* 子網廣播 */
else if (ip_addr_netcmp(addr, &(netif->ip_addr), &(netif->netmask)) && ((addr2test & ~netif->netmask.addr) == (IP_ADDR_BROADCAST_VALUE & ~netif->netmask.addr)))
return 1;
else
return 0;
}
五、NAT轉換協議
隨着互聯網的發送,IP地址短缺現象越來越嚴重,即使是擁有幾百臺的大型企業,也很難申請到幾個IP地址。爲了解決這個問題,產生了局域網技術。對於局域網外部來說,所有主機公用一個合法IP地址。但是在局域網內部,用戶使用專用IP進行相互通信。
NAT協議的功能簡單來說:數據發送到外部時,將局域網內部主機的IP地址轉換成一個外部公用的IP地址;數據從外部接收時,將外部公用的IP地址轉換成局域網內部主機的IP地址。
NAT最常見的實現方式是端口多路複用,它基於TCP或UDP協議端口號以及IP地址來實現。
例如:某公司IP地址爲222.178.197.21,局域網內部某主機IP地址爲192.168.1.178,該主機正在使用TCP協議與某外部服務器進行通信,該外部主機IP地址爲130.21.45.20。TCP雙方,內部主機TCP端口號爲1234,外部主機TCP端口號爲80。
具有NAT功能的路由器會在內部維護一個NAT轉換表,當路由器收到該分組時,會在表中爲連接(192.168.1.78:1234,130.21.45.20:80)分配一個路由器內部的端口,假設爲5678。數據發送到外部時,路由器會將數據包中的源IP和端口號,由192.168.1.78:1234改爲222.178.197.21:5678;數據從外部接收時,路由器會將數據包中的目的IP和端口號,由222.178.197.21:5678改爲192.168.1.78:1234。
這樣經過兩次NAT轉換,局域網用戶就實現了與外部網絡的數據交互。
六、數據包格式
Ethernet II幀格式
前導碼:由8個8‘b10101010構成。
以太網首部目的地址:目的設備的MAC物理地址。
源地址:發送設備的MAC物理地址。
類型:0x0800爲IP協議包,0x0806爲ARP協議包。
數據:數據長度最小爲46字節,不足46字節時,填充至46字節。
FCS: 就是CRC校驗值
其中,目的地址、源地址和類型,共同組成以太網首部
IP數據包和ARP數據包格式分別如下:
TCP數據幀封裝過程舉例: