天天看點

轉載:uIP之ARP:位址解析協定

<b>第四章</b><b> ARP</b><b>:位址解析協定</b><b></b>

雖然資料鍊路層的第一道關卡是MAC位址,但基于TCP/IP的網絡主要使用IP位址來辨別主機而不使用MAC位址。比如要連接配接到别人的電腦或拷貝共享檔案,一般會說:“告訴我你電腦的IP”,而不是“告訴我你電腦的MAC”。從以太網幀結構知道,不知道對方網卡的MAC位址是無法正常通訊的,那主機是怎樣從IP位址上自動擷取到MAC位址呢?這就是這章要講的“位址解析協定”,以下簡稱其英文縮寫“ARP”。

<b>4</b><b>.</b><b>1 ARP</b><b>工作原理</b><b></b>

從對方的IP位址擷取MAC位址最簡單的方法是靜态映射,即手工建立IP位址和MAC位址的映射表。這種方法必須預先知道每個IP對應的網卡的MAC位址,并寫到程式裡,發送資料時先搜尋這張表,找到IP位址對應的MAC位址。靜态映射表内容如下:

IP位址

MAC位址

192.168.1.15

00-0B-6A-8E-3F-C2

192.168.6.82

00-1C-35-27-59-A8

靜态映射表有一定的局限性,如:一台電腦換過網卡後,查找得出的MAC位址就不正确,會導緻通訊不上;當對方電腦的IP位址改變後,雖然MAC位址沒有變,但映射關系變了,靜态映射表也必須手工改變。這樣,維護一張靜态映射表就很費勁。

為了避免手工維護映射表,設計人員使用ARP協定來實作位址的映射,由主機自己智能地維護一張動态映射表。具體是怎樣實作地呢?通過圖4-1可以形象的說明。假如MCU主機需要與IP為192.168.1.15的主機建立連接配接,但不知道其MAC位址,于是先在整個網絡廣播,查詢内“192.168.1.15“對應的MAC位址,由于是廣播(目的MAC位址是FF-FF-FF-FF-FF-FF),同一網絡上的所有主機都收到了這個請求。但隻有電腦A應答,因為它的IP就是192.168.1.15。MCU收到電腦A的應答後,将IP和MAC位址存放在動态映射表中,下次連接配接的時候就能直接查找動态表。

當然,動态映射表中,IP和MAC的映射關系并不是一成不變的,ARP還啟動一個定時器,當映射關系存在一定的時間(如1分鐘)後,會被清除掉,下次發送資料時還是需要通過ARP請求擷取它們的對應關系。這個過程稱為ARP表老化。

轉載:uIP之ARP:位址解析協定

圖4-1 ARP 工作原理

<b>4</b><b>.</b><b>2 ARP</b><b>分組結構</b><b></b>

轉載:uIP之ARP:位址解析協定

圖4-2 ARP 分組的封裝

ARP分組的具體結構如圖4-3。

0 8 16 24 31

硬體類型

協定類型

硬體長度

協定長度

操作

發送方MAC位址(6位元組中的0-3位元組)

發送方MAC位址(4-5位元組)

發送方IP位址(0-1位元組)

發送方IP位址(2-3位元組)

接收方MAC位址(0-1位元組)

接收方MAC位址(2-5位元組)

接收方IP位址(0-3位元組)

圖4-3 ARP 分組的格式

硬體類型:16位,定義運作ARP的實體網絡。對以太網來說固定為0001H。還有0002H為實驗以太網,0003H為業餘無線電,0004H為令牌網等等。

協定類型:16位,定義發送方提供的高層協定類型。對IPV4來說,固定為0800H。

硬體長度:8位,定義實體位址(MAC位址)的長度,以位元組為機關,對以太網來說,固定為06H。

協定長度:8位,定義邏輯位址(IP位址)的長度,以位元組為機關,對應以太網的IPV4,長度固定為04H。

操作:16位,定義ARP分組是請求還是應答。請求則為01H,應答為02H。

發送方/接收方MAC位址:48位(針對以太網)。

發送方/接收方IP位址:32位(針對以太網)。

了解ARP的分組的格式後,就可以将圖4-1 中ARP的工作原理用具體資料來表示,如圖4-4。

轉載:uIP之ARP:位址解析協定

圖4-4 ARP 分組的圖例

<b>4</b><b>.</b><b>2 ARP</b><b>的實作</b><b></b>

uIP協定棧實作ARP的檔案是Uip_arp.c,包含uip_arp_init(),uip_arp_timer(),uip_arp_update(),uip_arp_arpin(),uip_arp_out()5個函數。

<b>4.2.1 A</b><b>RP</b><b>初始化</b><b></b>

根據ARP分組的格式,uip頭部結構定義如下,為了便于管理,它包含了以太網幀的頭部uip_eth_hdr。

struct arp_hdr

{

struct uip_eth_hdr ethhdr; /*以太網首部,14位元組*/

u16_t hwtype; /*硬體類型,0x0001*/

u16_t protocol; /*協定類型,0x0800*/

u8_t hwlen; /*硬體長度,0x06*/

u8_t protolen; /*協定長度,0x04*/

u16_t opcode; /*操作碼,ARP請求:0x1;ARP應答:0x2*/

struct uip_eth_addr shwaddr; /*發送方MAC位址*/

u16_t sipaddr[2]; /*發送方IP位址*/

struct uip_eth_addr dhwaddr; /*接收方MAC位址*/

u16_t dipaddr[2]; /*接收方IP位址*/

};

前面說過,ARP協定的目的就是主機自動維護一張動态映射表,uIP對動态映射表的結構定義如下:

struct arp_entry

u16_t ipaddr[2]; /*IP位址*/

struct uip_eth_addr ethaddr; /*MAC位址*/

u8_t time; /*IP-MAC映射生成時間*/

表 4-2 uip的ARP動态映射表

映射生成時間

13

可以看到,它比靜态映射表多了一項time,主要用來老化ARP表,存放的是一個時間計數arptime,這個計數預設是每10秒加1,寫映射關系的時候取目前的arptime值存入time項。ARP動态映射表定義成一個全局變量arp_table ,在單片機的網路設計中,定義如下:static struct arp_entry xdata arp_table[UIP_ARPTAB_SIZE],其最多儲存的映射關系是UIP_ARPTAB_SIZE個,預設值是8,可修改。

ARP的初始化函數uip_arp_init()就是将動态映射表arp_table裡的IP位址項全部清零。使用的語句是:memset(arp_table[i].ipaddr, 0, 4);

<b>4.2.2 A</b><b>RP</b><b>分組的處理</b><b></b>

當收到的以太網幀的類型是0x0806時,調用void uip_arp_arpin(void)函數對收到的ARP分組進行處理。其實作流程圖見圖4-5。其中的更新動态映射表的功能由函數uip_arp_update()完成,流程圖見4-6。

轉載:uIP之ARP:位址解析協定

圖4-5 ARP分組的處理流程圖

轉載:uIP之ARP:位址解析協定

圖4-5 ARP更新動态映射表流程圖

<b>4.2.2 A</b><b>RP</b><b>動态映射表的老化</b>

函數void uip_arp_timer(void)執行動态映射表的老化功能,這個函數每10秒被調用一次,進入該函數時,時間計數arptime加1,同時與動态映射表裡的time項比較,當發現arptime - tabptr-&gt;time &gt;= 120時,将該項的IP清零。也就是說,動态映射表裡的映射關系在連續20分鐘内沒有重新整理的話将失效。

<b>4.2.2 A</b><b>RP</b><b>請求的自動發送</b>

前面的介紹可以知道,本機IP層的發送函數隻知道對方IP位址,而不知道對方的MAC位址,按分層的概念,它填充完IP頭部的資訊後就交給以太網幀處理。以太網幀的頭部需要填充目的MAC位址,源MAC位址,類型。其中源MAC位址是本機MAC,類型是IP 0x0800,均已知。目的MAC呢?首先要查動态映射表,找到接收方IP對應的MAC位址填充。若此時動态映射表中沒有映射關系,就必須按ARP請求的格式構造一個ARP請求分組發送給本地網路上的所有網絡裝置,擷取到IP對應的MAC位址後才能正常發送。這些功能由void uip_arp_out(void)函數完成。

本文轉自emouse部落格園部落格,原文連結:http://www.cnblogs.com/emouse/archive/2012/03/28/2421912.html,如需轉載請自行聯系原作者

繼續閱讀