ARP協議淺析(2):協議分析
上一章:ARP協議淺析(1):緣起
下一章:ARP協議淺析(3):付諸實踐
ARP協議原理方面的內容,來自於《手把手教你玩轉ARP包》。筆者進行了一些整理,想獲得更多信息參考RFC文檔和《TCP-IP詳解卷1:協議ARP章節,卷2:021.pdf》。
下面是ARP幀主要的格式目錄
爲何有ARP協議?
(1) IP-MAC映射
以太網設備比如網卡都有自己全球唯一的MAC地址,它們是以MAC地址來傳輸以太網數據包的,它們不可能識別IP包中的IP地址,實際上網卡把受到的包提交到協議棧的緩衝,成爲鏈路層包,再分離出IP層的包,再分離出TCP或UDP…。就像剝開竹筍,發送包則是相反的過程。
我們在以太網中進行IP通信的時候需要一個協議來建立IP地址與MAC地址的對應關係,以使IP數據包能發到一個確定的地方去。這就是ARP(Address Resolution Protocol,地址解析協議)。
講到此處,我們可以在命令行窗口中,輸入
arp -a
來看一下效果,類似於這樣的條目
210.118.45.100 00-0b-5f-e6-c5-d7 dynamic
就是我們電腦裏存儲的關於IP地址與MAC地址的對應關係,dynamic表示是臨時存儲在ARP緩存中的條目,過一段時間就會超時被刪除(具體時間不同操作系統不同)。
這樣一來,比如我們的電腦要和一臺機器比如210.118.45.1通信的時候,它會首先去檢查arp緩存,查找是否有對應的arp條目,如果沒有,它就會給這個以太網絡發ARP請求包廣播詢問210.118.45.1的對應MAC地址,當然,網絡中每臺電腦都會收到這個請求包,但是它們發現210.118.45.1並非自己,就不會做出相應,而210.118.45.1就會給我們的電腦回復一個ARP應答包,告訴我們它的MAC地址是xx-xx-xx-xx-xx-xx,於是我們電腦的ARP緩存就會相應刷新,多了這麼一條:
210.118.45.1 xx-xx-xx-xx-xx-xx dynamic
爲什麼要有這麼一個ARP緩存呢,試想一下如果沒有緩存,我們每發一個IP包都要發個廣播查詢地址,豈不是又浪費帶寬又浪費資源?
(2) 真真假假ARP
我們的網絡設備無法識別ARP包的真僞,而且也不能識別,基本的約定都是假的,會帶來災難。如果我們按照ARP的格式來發送數據包,只要信息有效計算機就會根據包中的內容做相應的反應。
這也是以太網可靠通信的基礎,但是如果我能操縱網卡設備發送數據和掌握包的格式,我可以做一些欺騙和搗亂。當然,筆者只是理論分析,並不提倡讀者這麼做。
ARP包的格式
一個ARP包是分爲兩個部分的,前面一個是物理幀頭或EtherHeader,後面一個纔是ARP幀或Arp-Frame。
首先,物理幀頭,它將存在於任何一個協議數據包的前面,我們稱之爲DLC Header,因爲這個幀頭是在數據鏈路層構造的,並且其主要內容爲收發雙方的物理地址,以便硬件設備識別。
表1 物理幀頭格式
DLC Header |
|||
字段 |
長度(Byte) |
默認值 |
備註 |
接收方MAC |
6 |
|
廣播時,爲 ff-ff-ff-ff-ff-ff |
發送方MAC |
6 |
|
|
Ethertype |
2 |
0x0806 |
0x0806是ARP幀的類型值 |
圖1是需要我們填充的物理幀頭的格式,我們可以看到需要我們填充的僅僅是發送端和接收端的物理地址罷了,是不是很簡單呢?
接下來我們看一下ARP幀的格式。
表2 ARP幀格式
ARP Frame |
|||
字段 |
長度(Byte) |
默認值 |
備註 |
硬件類型 |
2 |
0x1 |
以太網類型值 |
上層協議類型 |
2 |
0x0800 |
上層協議爲IP協議 |
MAC地址長度 |
1 |
0x6 |
以太網MAC地址長度爲6 |
IP地址長度 |
1 |
0x4 |
IP地址長度爲4 |
操作碼 |
2 |
|
0x1表示ARP請求包,0x2表示應答包 |
發送方MAC |
6 |
|
|
發送方IP |
4 |
|
|
接受方MAC |
6 |
|
|
接受方IP |
4 |
|
|
填充數據 |
18 |
|
因爲物理幀最小長度爲64字節,前面的42字節再加上4個CRC校驗字節,還差18個字節 |
我們可以看到需要我們填充的同樣也只是MAC,IP,再加上一個1或2的操作碼而已。
ARP包的填充
(1) 請求包的填充
比如我們的電腦MAC地址爲 aa-aa-aa-aa-aa-aa,IP爲 192.168.0.1
我們想要查詢 192.168.0.99的MAC地址,應該怎麼來做呢?
首先填充DLC Header,通過前面的學習我們知道,想要知道某個計算機對應的MAC地址是要給全網發送廣播的,所以接收方MAC肯定是 ffffffffffff,發送方MAC當然是自己啦,於是我們的DLC Header就填充完成了,如圖,加粗的是我們要手動輸入的值。
表3 ARP請求包中的DLC幀頭
DLC Header |
||
字段 |
長度(Byte) |
填充值 |
接收方MAC |
6 |
Ffffffffffff |
發送方MAC |
6 |
Aaaaaaaaaaaa |
Ethertype |
2 |
0x0806 |
接下來是ARP幀,請求包的操作碼當然是發送方的MAC以及IP當然填入我們自己的。然後要注意一下,這裏的接收方IP填入我們要查詢的那個IP地址,就是192.168.0.99了,而收方MAC填入任意值就行,不起作用。具體格式如下表。
表4 ARP請求包中 ARP幀
ARP Frame |
||
字段 |
長度(Byte) |
填充值 |
硬件類型 |
2 |
1 |
上層協議類型 |
2 |
0x0800 |
MAC地址長度 |
1 |
6 |
IP地址長度 |
1 |
4 |
操作碼 |
2 |
1 |
發送方MAC |
6 |
Aaaaaaaaaaaa |
發送方IP |
4 |
192.168.0.1 |
接收方MAC |
6 |
任意值 xxxxxxxxxxxx |
接收方IP |
4 |
192.168.0.99 |
填充數據 |
18 |
0 |
如果我們構造一個這樣的包發送出去,如果 192.168.0.99存在且是活動的,我們馬上就會收到一個192.168.0.99發來的一個響應包,我們可以查看一下我們的ARP緩存列表,是不是多了一項類似這樣的條目:
192.168.0.99 bb-bb-bb-bb-bb-bb
是不是很神奇呢?我們再來看一下ARP響應包的構造:
(2) 響應包的填充
有了前面詳細的解說,你肯定就能自己說出響應包的填充方法來了吧,所以我就不細說了,列兩個表就好了
比如說給 192.168.0.99(MAC爲 bb-bb-bb-bb-bb-bb)發一個ARP響應包,告訴它我們的MAC地址爲 aa-aa-aa-aa-aa-aa,就是如此來填充各個字段
表5 ARP響應包中 DLC Header內容
DLC Header |
||
字段 |
長度(Byte) |
填充值 |
接收方MAC |
6 |
Bbbbbbbbbbbb |
發送方MAC |
6 |
Aaaaaaaaaaaa |
Ethertype |
2 |
0x0806 |
表6 ARP響應包中ARP幀的內容
ARP Frame |
||
字段 |
長度(Byte) |
填充值 |
硬件類型 |
2 |
1 |
上層協議類型 |
2 |
0800 |
MAC地址長度 |
1 |
6 |
IP地址長度 |
1 |
4 |
操作碼 |
2 |
2 |
發送方MAC |
6 |
Aaaaaaaaaaaa |
發送方IP |
4 |
192.168.0.1 |
接收方MAC |
6 |
Bbbbbbbbbbbb |
接收方IP |
4 |
192.168.0.99 |
填充數據 |
18 |
0 |
這樣192.168.0.99的ARP緩存中就會多了一條關於我們192.168.0.1的地址映射。
在ARP協議相關的代碼中,大部分的工具是發送請求包(Request)和接受請求包,分析後填充正確格式的響應包(Response)。這個協議就是這麼工作的,下一章將分析一下具體的應用和重要的模塊與函數。
上一章:ARP協議淺析(1):緣起
下一章:ARP協議淺析(3):付諸實踐