Linux內(nèi)核鄰接子系統(tǒng)(arp協(xié)議)的工作原理(二)
ARP協(xié)議(工作在三層)
地址解析協(xié)議,即ARP(Address Resolution Protocol),是根據(jù)IP地址獲取物理地址的一個(gè)TCP/IP協(xié)議。主機(jī)發(fā)送信息時(shí)將包含目標(biāo)IP地址的ARP請(qǐng)求廣播到局域網(wǎng)絡(luò)上的所有主機(jī),并接收返回消息,以此確定目標(biāo)的物理地址;收到返回消息后將該IP地址和物理地址存入本機(jī)ARP緩存中并保留一定時(shí)間,下次請(qǐng)求時(shí)直接查詢ARP緩存以節(jié)約資源。地址解析協(xié)議是建立在網(wǎng)絡(luò)中各個(gè)主機(jī)互相信任的基礎(chǔ)上的,局域網(wǎng)絡(luò)上的主機(jī)可以自主發(fā)送ARP應(yīng)答消息,其他主機(jī)收到應(yīng)答報(bào)文時(shí)不會(huì)檢測(cè)該報(bào)文的真實(shí)性就會(huì)將其記入本機(jī)ARP緩存;由此攻擊者就可以向某一主機(jī)發(fā)送偽ARP應(yīng)答報(bào)文,使其發(fā)送的信息無(wú)法到達(dá)預(yù)期的主機(jī)或到達(dá)錯(cuò)誤的主機(jī),這就構(gòu)成了一個(gè)ARP欺騙。ARP命令可用于查詢本機(jī)ARP緩存中IP地址和MAC地址的對(duì)應(yīng)關(guān)系、添加或刪除靜態(tài)對(duì)應(yīng)關(guān)系等。相關(guān)協(xié)議有RARP、代理ARP。NDP用于在IPv6中代替地址解析協(xié)議。
代理ARP(proxy ARP):對(duì)于沒(méi)有配置缺省網(wǎng)關(guān)的計(jì)算機(jī)要和其他網(wǎng)絡(luò)中的計(jì)算機(jī)實(shí)現(xiàn)通信,網(wǎng)關(guān)收到源計(jì)算機(jī)的 ARP 請(qǐng)求會(huì)使用自己的 MAC 地址與目標(biāo)計(jì)算機(jī)的 IP地址對(duì)源計(jì)算機(jī)進(jìn)行應(yīng)答。**代理ARP就是將一個(gè)主機(jī)作為對(duì)另一個(gè)主機(jī)ARP進(jìn)行應(yīng)答。它能使得在不影響路由表的情況下添加一個(gè)新的Router,使得子網(wǎng)對(duì)該主機(jī)來(lái)說(shuō)變得更透明化。**同時(shí)也會(huì)帶來(lái)巨大的風(fēng)險(xiǎn),除了ARP欺騙,和某個(gè)網(wǎng)段內(nèi)的ARP增加,最重要的就是無(wú)法對(duì)網(wǎng)絡(luò)拓?fù)溥M(jìn)行網(wǎng)絡(luò)概括。代理ARP的使用一般是使用在沒(méi)有配置默認(rèn)網(wǎng)關(guān)和路由策略的網(wǎng)絡(luò)上的。
ARP協(xié)議是在RFC 826中定義的。在以太網(wǎng)中,硬件地址稱為MAC地址,長(zhǎng)48位。MAC地址必須是獨(dú)一無(wú)二的,但必須考慮這樣的情形,即可能會(huì)遇到并非獨(dú)一無(wú)二的MAC地址。導(dǎo)致這種情形的一種常見(jiàn)原因是,在大多數(shù)網(wǎng)絡(luò)接口上,系統(tǒng)管理員都可使用諸如ifconfig或ip等用戶空間工具配置MAC地址。 發(fā)送IPv4數(shù)據(jù)包時(shí),目標(biāo)IPv4地址是已知的,但需要?jiǎng)?chuàng)建以太網(wǎng)報(bào)頭,其中包含目標(biāo)MAC地址。根據(jù)給定IPv4地址確定MAC地址的工作由ARP協(xié)議完成,稍后你講看到這一點(diǎn)。如果MAC地址未知,就以廣播方式發(fā)送ARP請(qǐng)求,其中包含已知的IPv4地址。如果有主機(jī)配置了這個(gè)IPv4地址,它將使用單播ARP響應(yīng)進(jìn)行應(yīng)答。ARP表( arp_tbl)是一個(gè)neigh_table結(jié)構(gòu)實(shí)例。ARP報(bào)頭用結(jié)構(gòu)arphdr表示。
arphdr include\linux\if_arp.h
ar_hrd是硬件地址類型,對(duì)于以太網(wǎng)來(lái)說(shuō),其為0x01。關(guān)于可在ARP報(bào)頭中使用的硬件地址標(biāo)識(shí)符完整列表,請(qǐng)參閱include/uapi/linux/if_arp.h中的ARPHRD_XXX定義。 ar_pro是協(xié)議ID,對(duì)于IPv4來(lái)說(shuō),其為0x80。關(guān)于可使用的協(xié)議ID完整列表,請(qǐng)參閱include/uapi/linux/if_ether.h中的ETH_P_XXX定義。 ar_hln是硬件地址長(zhǎng)度,單位為字節(jié)。對(duì)于以太網(wǎng)地址來(lái)說(shuō),其為6字節(jié)。 ar_pln是協(xié)議地址長(zhǎng)度,單位為字節(jié)。對(duì)于IPv4地址來(lái)說(shuō),其為4字節(jié)。 ar_op是操作碼。ARP請(qǐng)求表示為ARPOP_REQUEST,ARP應(yīng)答表示為ARPOP_REPLY。 緊跟在ar_op后面的是發(fā)送方的硬件(MAC)地址和IPv4地址,以及目標(biāo)硬件(MAC)地址和IPv4地址。這些地址并非ARP報(bào)頭(結(jié)構(gòu)arphdr )的組成部分。在方法arp_process()中,通過(guò)讀取ARP報(bào)頭相應(yīng)的偏移量來(lái)提取它們。在討論方法arp_process()時(shí),你將看到這一點(diǎn)。下圖顯示了ARP以太網(wǎng)數(shù)據(jù)包的ARP報(bào)頭。

ARP包是前面是MAC首部 —— 目地MAC地址(8字節(jié))源MAC地址(8字節(jié))類型(2字節(jié))
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書(shū)籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書(shū)、實(shí)戰(zhàn)項(xiàng)目及代碼)? ??


ARP 解析 MAC 地址
首先,每臺(tái)主機(jī)都會(huì)在自己的ARP緩沖區(qū)(ARP Cache)中建立一個(gè) ARP列表,以表示IP地址和MAC地址的對(duì)應(yīng)關(guān)系。
當(dāng)源主機(jī)需要將一個(gè)數(shù)據(jù)包要發(fā)送到目的主機(jī)時(shí),會(huì)首先檢查自己 ARP列表中是否存在該 IP地址對(duì)應(yīng)的MAC地址,如果有﹐就直接將數(shù)據(jù)包發(fā)送到這個(gè)MAC地址;如果沒(méi)有,就向本地網(wǎng)段發(fā)起一個(gè)ARP請(qǐng)求的廣播包,查詢此目的主機(jī)對(duì)應(yīng)的MAC地址。此ARP請(qǐng)求數(shù)據(jù)包里包括源主機(jī)的IP地址、硬件地址、以及目的主機(jī)的IP地址。
網(wǎng)絡(luò)中所有的主機(jī)收到這個(gè)ARP請(qǐng)求后,會(huì)檢查數(shù)據(jù)包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此數(shù)據(jù)包;如果相同,該主機(jī)首先將發(fā)送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已經(jīng)存在該IP的信息,則將其覆蓋,然后給源主機(jī)發(fā)送一個(gè) ARP響應(yīng)數(shù)據(jù)包,告訴對(duì)方自己是它需要查找的MAC地址;
源主機(jī)收到這個(gè)ARP響應(yīng)數(shù)據(jù)包后,將得到的目的主機(jī)的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息開(kāi)始數(shù)據(jù)的傳輸。如果源主機(jī)一直沒(méi)有收到ARP響應(yīng)數(shù)據(jù)包,表示ARP查詢失敗。
發(fā)送 ARP報(bào)文 ARP 發(fā)送請(qǐng)求
請(qǐng)求是在哪里發(fā)送的呢?最常見(jiàn)的場(chǎng)景是在傳輸路徑中。在離開(kāi)網(wǎng)絡(luò)層(L3)進(jìn)人數(shù)據(jù)鏈路層(L2)之前。在方法ip_finish_output2()中,首先調(diào)用方法_ipv4_neigh_lookup_noref(),在ARP表中查找下一跳IPv4地址。如果沒(méi)有找到匹配的鄰居條目,就調(diào)用方法_neigh_create()來(lái)創(chuàng)建一個(gè)。
ARP發(fā)送報(bào)文
arp_solicit函數(shù),鄰居子系統(tǒng)調(diào)用solicit函數(shù)指針 (neigh_ops) 發(fā)送solicitation請(qǐng)求,在arp指針中這個(gè)函數(shù)指針被初始化為arp_solicit函數(shù)。
最終調(diào)用方法arp_send()來(lái)發(fā)送ARP請(qǐng)求。我們注意到最后一個(gè)參數(shù)(target_hw)為NULL,因?yàn)檫€不知道目標(biāo)硬件(MAC)地址。在調(diào)用arp_send()時(shí),如果參數(shù)target_hw為NULL,將以廣播方式發(fā)送ARP請(qǐng)求。
接收 ARP報(bào)文
arp_rcv函數(shù)被注冊(cè)到內(nèi)核中,當(dāng)有ARP協(xié)議報(bào)文調(diào)用arp_rcv處理。 某些情況下收到一個(gè)ARP報(bào)文可能導(dǎo)致發(fā)出一個(gè)ARP報(bào)文,這些情況是:
配置了網(wǎng)橋,網(wǎng)橋只是轉(zhuǎn)發(fā)報(bào)文到其他接口。
鄰居子系統(tǒng)對(duì)請(qǐng)求報(bào)文做出應(yīng)答。
在方法arp_process()中,只處理ARP報(bào)文請(qǐng)求和響應(yīng)(回復(fù))
對(duì)于ARP請(qǐng)求,將使用方法ip_route_input_noref()執(zhí)行路由選擇子系統(tǒng)查找。 如果ARP數(shù)據(jù)包是發(fā)送給當(dāng)前主機(jī)的(路由選擇條目的rt_type為RTN_LOCAL),就接著檢查一些條件(這將稍后介紹)。如果這些檢查都通過(guò)了,就使用方法arp_send()發(fā)回ARP應(yīng)答。 如果ARP數(shù)據(jù)包不是發(fā)送給當(dāng)前主機(jī)但需要進(jìn)行轉(zhuǎn)發(fā)的(路由選擇條目的rt_type為RTN_UNICAST),也需要檢查一些條件(也將在稍后介紹)。如果這些條件都滿足,就調(diào)用方法pneigh_lookup()在代理ARP表中進(jìn)行查找。 比如arp_process() 首先驗(yàn)證ARP報(bào)文頭和設(shè)備是否使能ARP功能。 arp_process函數(shù)只處理ARPOP_REPLY和ARPOP_REQUEST報(bào)文類型。
主機(jī)還不知道默認(rèn)網(wǎng)關(guān)的MAC地址,它會(huì)發(fā)起ARP的請(qǐng)求 主機(jī)生成一個(gè)包含目的地址為網(wǎng)關(guān)路由器 IP 地址(DHCP)的 ARP 查詢報(bào)文,將該 ARP 查詢報(bào)文放入一個(gè)具有廣播目的地址(的以太網(wǎng)幀中,并向交換機(jī)發(fā)送該以太網(wǎng)幀,交換機(jī)將該幀轉(zhuǎn)發(fā)給所有的連接設(shè)備,包括網(wǎng)關(guān)路由器。 默認(rèn)網(wǎng)關(guān)把它自己的MAC地址作為應(yīng)答回來(lái) Host1開(kāi)始封裝它的數(shù)據(jù)了,目的為默認(rèn)網(wǎng)關(guān)的MAC地址 Host1發(fā)出的數(shù)據(jù)通過(guò)MAC尋址送到了默認(rèn)網(wǎng)關(guān) 默認(rèn)網(wǎng)關(guān)收到數(shù)據(jù)之后(解封裝、提取出目的IP、查表)然后轉(zhuǎn)發(fā)出去(重新封裝,源/目的MAC地址都發(fā)送了轉(zhuǎn)換),最后就把這個(gè)數(shù)據(jù)發(fā)往Host4所在的EE網(wǎng)絡(luò)(當(dāng)然有可能也不知道Host4的MAC地址,這個(gè)時(shí)候網(wǎng)關(guān)一樣會(huì)發(fā)送ARP請(qǐng)求)
