1. ARP的簡介
Address Resolution Protocol-地址解析協議
ARP為IP地址到對應的硬件地址之間提供動態映射。從邏輯Internet地址到對應的物理硬件地址需要進行翻譯。這就是ARP的功能。ARP的功能是在32 bit的IP地址和采用不同網絡技術的硬件地址之間提供動態映射。
2. ARP的應答流程
任何時候我們敲入下面這個形式的命令:
[html] view plain copy
% ftp bsdi //示例而已
都會進行以下這些步驟。這些步驟的序號如圖 4 - 2所示。
1) 應用程序FTP客戶端調用函數gethostbyname(3)把主機名(bsdi)轉換成32 bit的IP地址。這個函數在DNS(域名系統)中稱作解析器,我們將在第1 4章對它進行介紹。這個轉換過程或者使用DNS,或者在較小網絡中使用一個靜態的主機文件(/etc/hosts) 。
2) FTP客戶端請求TCP用得到的IP地址建立連接。
3) TCP發送一個連接請求分段到遠端的主機,即用上述 IP地址發送一份IP數據報(在第1 8章我們將討論完成這個過程的細節) 。
4) 如果目的主機在本地網絡上(如以太網、令牌環網或點對點鏈接的另一端) ,那么IP數據報可以直接送到目的主機上。如果目的主機在一個遠程網絡上,那么就通過 IP選路函數來確定位于本地網絡上的下一站路由器地址,并讓它轉發 IP數據報。在這兩種情況下,IP數據報都是被送到位于本地網絡上的一臺主機或路由器。
5) 假定是一個以太網,那么發送端主機必須把 32 bit的IP地址變換成48 bit的以太網地址。從邏輯Internet地址到對應的物理硬件地址需要進行翻譯。這就是 ARP的功能。ARP本來是用于廣播網絡的,有許多主機或路由器連在同一個網絡上。
6) ARP發送一份稱作ARP請求的以太網數據幀給以太網上的每個主機。這個過程稱作廣播,如圖 4 - 2中的虛線所示。 ARP請求數據幀中包含目的主機的IP地址(主機名為bsdi) ,其意思是“如果你是這個IP地址的擁有者,請回答你的硬件地址。 ”
7) 目的主機的ARP層收到這份廣播報文后,識別出這是發送端在尋問它的 IP地址,于是發送一個ARP應答。這個ARP應答包含IP地址及對應的硬件地址。
8) 收到ARP應答后,使ARP進行請求—應答交換的IP數據報現在就可以傳送了。
9) 發送IP數據報到目的主機。
3. ARP的分組格式
? 以太網報頭中的前兩個字段是以太網的源地址和目的地址。目的地址為全 1的特殊地址是廣播地址。電纜上的所有以太網接口都要接收廣播的數據幀。
? 兩個字節長的以太網幀類型表示后面數據的類型。對于 A R P請求或應答來說,該字段的值為0 x 0 8 0 6。
? 硬件類型字段表示硬件地址的類型。它的值為 1即表示以太網地址。
? 協議類型字段表示要映射的協議地址類型。它的值為 0 x 0 8 0 0即表示I P地址。它的值與包含I P數據報的以太網數據幀中的類型字段的值相同,這是有意設計的(參見圖 2 - 1) -忘了截過來了。
? 接下來的兩個1字節的字段,硬件地址長度和協議地址長度分別指出硬件地址和協議地址的長度,以字節為單位。對于以太網上I P地址的ARP請求或應答來說,它們的值分別為6和4。
? 操作字段(op)指出四種操作類型,它們是 ARP請求(值為1) 、ARP應答(值為2) 、RARP請求(值為3)和R ARP應答(值為4) (我們在第5章討論RARP) 。這個字段必需的,因為ARP請求和ARP應答的幀類型字段值是相同的。
? 接下來的四個字段是發送端的硬件地址(在本例中是以太網地址) 、發送端的協議地址(IP地址) 、目的端的硬件地址和目的端的協議地址。注意,這里有一些重復信息:在以太網的數據幀報頭中和ARP請求數據幀中都有發送端的硬件地址。
對于一個ARP請求來說,除目的端硬件地址外的所有其他的字段都有填充值。當系統收到一份目的端為本機的 ARP請求報文后,它就把硬件地址填進去,然后用兩個目的端地址分別替換兩個發送端地址,并把操作字段置為 2,最后把它發送回去。
--------------------------------以上內容整理于《TCP/IP協議詳解:卷1》----------------------------
理是那個那個理,但是過于抽象了,不過是基礎,看完上面再看實現,那感覺很爽的~~~
------------------------------------------以下內容產生于代碼及分析--------------------------------------
4. ARP的宏定義實現
以太網協議而非802.3協議,看ETH命名的頭名字就曉得了,地址位置可以結合兩個header算算就出來了
1 | // ******* ARP ******* |
5. ARP的實現函數
以太網的header在ARP的header之前,很簡單的,介紹先。
配置以太網的頭,為14字節:6字節目的mac地址+6字節源mac地址+2字節協議類型,如圖4-3
1 | // make a return eth header from a received eth packet |
展開就是這樣的,看看宏定義是否與此一一對應呢。
在判斷為arp請求之后,填充以太網的頭之后響應arp請求
1 | void make_arp_answer_from_request(unsigned char *buf) // fill the mac addresses: |
當然,響應ARP請求的前提是你得確定有人向你發出ARP請求(下面那個函數就是了),并且這個人是誰,你是要知道的(通過發送者的IP和MAC地址),這個很容易,本協議是將地址放在幾個全局變量里面的,大家就都知道了,雖然全局變量用起來很爽,但是對模塊化以及后期維護帶來的不便也是很大的。
檢查是否為合法的eth,并且只接受發給本機的arp數據,此函數在上面那個函數之前被調用,再下面的代碼就是演示的例程
1 | //檢查是否為合法的eth,并且只接受發給本機的arp數據 |
以上函數在別人向你發送任何請求之前都將被調用一次(原因是本協議只是實現了對IP和ARP的響應),所以需要在一個while死循環或者RTOS的一個thread/task/process里面。如下所示:
上層調用示例代碼
1 | /* |
6. ARP實驗調式
嗯,接者來看看在make_arp_answer_from_request函數里面加入串口調試信息來輸出arp請求者的ip和mac地址。
加入到 make_arp_answer_from_request中的調試代碼,用于輸出ARP請求者的信息
1 | #ifdef ARP_DEBUG |
PC端:測試arp請求需要先執行“arp -d”清楚本地的arp-ip對應列表,這樣PC機才會發送ARP請求
ps:enj28j60的MAC地址是軟件設定的,所以就不打碼了。
串口端:顯示調試信息而已
下面是我放著沒動它,局域網內就有其他主機來找我的嵌入式Web Server了,O(∩_∩)O~
--------------------------------------------以下是我看代碼看的不仔細的糾結,可跳過-----------------------------------------------
但是在實驗過程中發現如下情況是不會調用make_arp_answer_from_request函數的:PC機本地有arp-ip列表,就是ping過一次以后ping第二次的就不會去響應了,這個本來就是要如此的,希望結果就是這樣的,你要問我是誰(MAC地址是多少),然后我告訴你一次,你記住就ok了么。但是問題出在我們的協議棧實現代碼里面,本協議棧在通過eth_type_is_arp_and_my_ip判斷了是發給本機的數據包之后,就會調用arp響應的,沒有一個對以太網header的類型的判斷啊。怎么會自己變的智能了呢?
代碼如下
1 |
|
那么問題出在哪里呢?
1. 難道是進入make_arp_answer_from_request 函數,但是沒有發送出去么?當然也不會在enc28j60PacketSend(ETH_HEADER_LEN + ETH_ARP_PACKET_LEN, buf); 里面,因為沒有判別信息傳遞進去。(當然發不發,只要如函數之后就會有打印信息輸出到串口)
2. 那么就是eth_type_is_arp_and_my_ip 函數返回為0了;
但是ping命令還是可以得到響應的,哦,對了,還有ICMP(我本來就用的ping,都忘了,放在IP層),那么就好解釋了,第一次是由ARP+ICMP響應,第二次及之后的只有ICMP響應。所以現象還是符合原理解釋的。
但是,我用網頁去刷新和點亮LED等,走的肯定是IP包,ARP還是不響應。
回去看代碼,當時對自己就無語了
if(buf[ETH_TYPE_H_P] != ETHTYPE_ARP_H_V || buf[ETH_TYPE_L_P] != ETHTYPE_ARP_L_V)
是ARP啊,我以為是對IP和ARP都會響應,而且人家的函數名是eth_type_is_arp_and_my_ip ,我自己把它想成eth_type_is_arp_and_ip ,╮(╯▽╰)╭
代碼就在那里,自己SB了~~~
--------------------------------------------以上是我邊想邊實驗邊寫的過程-----------------------------------------------
硬件環境:STM32+ENC28J60
軟件環境:MDK4.70a
TCP/IP協議棧:開發者的網站已經關閉了,也沒有命名~~~
給出作者信息:
/*********************************************
* modified: 2007-08-08
* Author : awake
* Copyright: GPL V2
* http://www.icdev.com.cn/?2213/
* Host chip: ADUC7026
**********************************************/
上一篇:分析TCP/IP協議棧代碼之UDP(STM32平臺)
下一篇:分析TCP/IP協議棧代碼之IP & ICMP(STM32平臺)
推薦閱讀
史海拾趣