Net/3中ARP的實現是和路由表緊密關聯的,下圖顯示了我們描寫ARP要用到的1個例子。
下面,我們扼要概述圖中的有關要點。
1.llinfo_arp結構的雙向鏈表包括了每個ARP已知的硬件地址的少許信息。同名全局變量llinfo_arp是該鏈表的頭結點,圖中
沒有畫出第1位la_prev指針指向最后1項,最后1項的la_next指針指向第1項。該鏈表由ARP時鐘函數每一個5分鐘處理1次。
2.每個已知硬件地址的IP地址都對應1個路由表結點(rtentry結構)。llinfo_arp結構的la_rt指針成員用來指向相應的rtentry
結構,一樣地,rtentry結構的rt_llinfo指針成員指向llinfo_arp結構。
3.圖中的最左側第4個路由表結點則沒有llinfo_arp結構,該結點對應于本地以太網(140.252.13.32)的路由項。該結點的
rt_flags中設置了C比特,表明該結點是被用來復制成其他結點的。
4.rtentry結構中的rt_gateway指針成員指向1個sockaddr_dl結構變量。如果保存物理地址長度的結構sdl_alen成員為6,那末
sockaddr_dl結構就包括相應的硬件地址信息。
5.路由結點變量的rt_ifp成員的相應指針指向對應網絡裝備接口的ifnet結構。中間的兩個路由結點對應的是以太網上的其他主機,
這兩個結點都指向le_softc[0]。而右側的路由結點指向環回結構loif。由于rt_ifp.if_output指向輸出函數,所以目的為本地的數據
報被路由至環回接口。
6.每個路由結點還有指向相應的in_ifaddr結構的指針變量。
7.la_hold成員是指向mbuf鏈表的指針。當要想某個IP傳送數據報時,就需要廣播1個ARP要求。當內核等待ARP回答時,存
放該待發數據報的mbuf鏈的頭結點的地址信息就寄存在la_hold里。當收到ARP回答后,la_hold指向的mbuf鏈表中的IP數據
被發送出去。
8.路由表結點中rt_metric結構的變量rmx_expire寄存的是與對應ARP結點相干的定時信息,用來實現刪除超時ARP結點。
下圖顯示了ARP函數與其他內核函數的關系。
在以太網中傳送的ARP分組的格式以下圖所示:
結構ether_header定義了以太網幀首部;結構arphdr定義了其后的5個字段,其信息用于在任何類型的介質上傳送ARP要求
和回答;ether_arp結構除包括arphdr結構外,還包括源主機和目的主機的地址。
結構arphdr的定義以下圖所示:
下圖顯示了ether_arp結構的定義,其中包括了arphdr結構、源主機和目的主機的IP地址和硬件地址。
每一個ARP結點中,都有1個llinfo_arp結構,所有這些結構組成的鏈表的頭結點是作為全局變量分配的。我們常常把該鏈表
稱為ARP高速緩存。
該雙向鏈表的前兩項是由insque和remque兩個函數更新。
arpwhohas函數通常由arpresolve調用,用于廣播1個ARP要求。它還可由每一個以太網裝備驅動程序調用,在將IP地址賦予
該裝備接口時主動發送1個地址聯編信息(SIOCSIFADDR),主動發送地址聯編信息不但可以檢測在以太網中是不是存在IP
地址沖突,并可使其他機器更新其相應信息(免費ARP)。arpwhohas只是簡單調用下arprequest函數。
arprequest函數由arpwhohas函數調用,用于廣播1個ARP要求。該函數建立1個ARP分組,并將它傳送到接口的輸出函數。
下圖顯示了該函數建立的兩個數據結構mbuf和sockaddr。另外還有兩個函數中用到的指針eh和ea。
函數的大概處理流程以下:
1.分配和初始化mbuf。分配1個分組數據首部的嗎mbuf,并對兩個長度字段賦值。
2.初始化指針。給ea和eh兩個指針賦值,并將ether_arp結構的值賦值為0。
3.填充以太網幀首部。目的以太網地址設為以太網廣播地址,并將以太網幀類型設為ETHERTYPE_ARP。下圖顯示了不同
以太網幀類型字段的常量值。
4.填充ARP字段。填充ether_arp的所有字段,除ARP要求所要詢問的目的硬件地址。
5.填充sockaddr,并調用接口輸出函數。接口地址結構的sa_family成員的值設置為AP_UNSPEC,sa_number成員的值
設為16。調用接口輸出函數ether_output。
當ether_input函數接收到幀類型字段為ETHERTYPE_ARP的以太網幀時,產生有限級為NETISR_ARP的軟件中斷,并將
該幀關在ARP輸入隊列arpintrq的后面。當內核處理該軟件中斷時,調用arpintr函數。
函數的大概處理流程是:
只有當幀的硬件類型指明為以太網地址,并且幀的長度大于或等于arphdr結構的長度加上兩個硬件地址和兩個協議地址的
長度時,該幀才能被處理。如果協議地址的類型是ETHERTYPE_IP或ETHERTYPE_IPTRAILERS時,調用in_arpinput函數,
否則該幀被拋棄。
該函數由arpintr調用,用于處理接收到的ARP要求/回答。ARP本身的概念比較簡單,但是加上許多規則后,實現就比較
復雜,下面來看下兩種典型的情況。
1.如果收到了1個針對本機IP地址的要求,則發送1個回答。這是1種普遍情況,很明顯,我們將繼續從那個主機收到
數據報,隨后也會向它回送報文。所以,如果我們還沒有對應它的ARP結點,就應當添加1個ARP結點,由于這時候我們
已知道對方的IP地址和硬件地址。
2.如果收到1個ARP回答,那末此時ARP結點是完全的,因此就知道了對方的硬件地址,該地址寄存sockaddr_dl結構中,
所有發往該地址的數據被將被發送。
3.如果其他主機發送1個ARP要求或回答,其中發送方的IP地址與本機相同,那末肯定有1個主機配置有誤,Net/3將檢測
到該過失,并向管理員等級1個報文。
4.如果主機收到來自其他主機的要求或回答,對應的ARP結點早已存在,但硬件地址發送了變化,那末ARP結點將被更新。
5.主機可以被配置成代理ARPhttp://www.vxbq.cn/server/,這類情況下,主機可以代其他主機響應ARP要求,在回答中提供其他主機的硬件地址。
代理ARP回答中對應目的硬件地址的主機必須能夠把IP數據報發至ARP要求中指定的目的地址。
該函數的大概流程以下:
1.查找匹配的接口和IP地址。搜索本機的Internet地址鏈表(in_ifaddr結構的鏈表)。要記住1個接口可以有多個IP地址。
2.驗證發送方的硬件地址。如果發送方的硬件地址等于本機接口的硬件地址。那是由于收到了本機發送的要求,疏忽該分組。
如果發送方的硬件地址等于以太網的廣播地址,說明出錯了。記錄該過失,并拋棄該分組。
3.檢查發送方IP地址。如果發送方IP地址等于本本機正在使用的1個IP地址,在本機系統配置出了過失。
4.在路由表中搜索與發送方IP地址匹配的結點。arplookup函數在ARP高速緩存中查找符合發送方的IP地址。當ARP分組中
目的地址就是本機,總是要穿件ARP結點的。
5.更新已有結點或填充新的結點。只有當以下3個條件為真時,語句才履行:
a.找到1個已有的ARP結點或成功創建1個新的ARP結點。
b.ARP結點指向1個路由表結點。
c.路由表結點的re_gateway字段指向1個sockaddr_dl結構。
6.檢查發送方硬件地址是不是已改變。如果已改變,則記錄發送方硬件地址,更新最近解析的ARP結點。
7.如果是該ARP操作不是要求,那末拋棄接收到的分組。
8.產生1個對應于ARP要求的回答。只有當以下兩種情況時才會產生ARP回答:
a.本機就是該要求所要查找的目的主機。
b.本機是該要求所要查找的目的主機的ARP代理http://www.vxbq.cn/server/。
9.用以太網幀首部填充sockaddr。
10.將ARP回答傳送至接口輸出函數,并返回。
ARP結點1般是動態的,需要時創建,超時時自動刪除。也允許管理員創建永久性結點。
arp_rtrequest函數使arptimer函數第1次被調用,隨后arptimer每隔5分鐘使自己被調用1次。arptimer查看ARP結點鏈表
中的每個結點,如果不是1個永久結點,而且時間已超時,那末arptfree就刪除該結點。
ether_output函數調用arpresolve函數以取得對應某個IP地址的以太網地址。arpresolve函數利用llinfo_arp結構的la_hold
成員指針“保持”待發IP數據報,并發送1個ARP要求,收到ARP回答后,再將保持的IP數據報發送出去。
ARPresolve應避免ARP洪泛,也就是說,它不應在還沒有收到ARP回答時高速重復發送ARP要求,出現這類情況主要有兩個
緣由,第1,有多個IP數據報要發往同1個還沒有解析硬件地址的主機;第2,1個IP數據報的每一個分片都會作為獨立分組
調用ether_output。
Net/3采取以下方法來避免ARP泛洪。
1.Net/3不在同1秒內發送多個對應同1目的地的ARP要求。
2.如果在連續5個ARP要求(也就是5秒鐘)后還沒有收到回答,路由結點的RTF_REJECT標志置1,實現設為往后的20秒。
這會使ether_output在20秒內謝絕發往該目的地址的IP數據報。
3.20秒后,arpresolve會繼續發送該目的主機的ARP要求。
arplookup函數調用選路函數rtalloc1在Internet路由表中查找ARP結點,我們已看到過3次調用arplookup的情況:
1.在in_arpinput中,在接收到ARP分組后,對應源IP地址查找或創建1個ARP結點。
2.在in_arpinput中,接收到ARP要求后,查看是不是存在目的硬件地址的代理ARP結點。
4.在arpresolve中,查找或創建1個對應待發送數據報IP地址的ARP結點。
如果arplookup履行成功,則返回1個指向對應llinfo_arp結構的指針,否則返回1個空指針。
下一篇 簡析三層架構