LwIP之網絡技術基礎

一、協議模型

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數據幀封裝過程舉例:

             

發佈了208 篇原創文章 · 獲贊 91 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章