技術(shù)tcpip詳解卷2實(shí)現(xiàn)_第1頁(yè)
技術(shù)tcpip詳解卷2實(shí)現(xiàn)_第2頁(yè)
技術(shù)tcpip詳解卷2實(shí)現(xiàn)_第3頁(yè)
技術(shù)tcpip詳解卷2實(shí)現(xiàn)_第4頁(yè)
技術(shù)tcpip詳解卷2實(shí)現(xiàn)_第5頁(yè)
已閱讀5頁(yè),還剩56頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

本章我們介紹IP分組的結(jié)構(gòu)和基本的IP處理過程,包括輸入、轉(zhuǎn)發(fā)和輸出。假定讀者熟悉IP協(xié)議的基本操作,其他IP的背景知識(shí)見卷1的第3、9和12章。RFC791[Postel1981a]是IP的官方規(guī)范,RFC1122[Braden1989a]中有RFC791的說(shuō)明。第9章將討論選項(xiàng)的處理,第10章討論分片和重裝。圖8-1顯示了IP圖8-1IP在第4章中,我們看到網(wǎng)絡(luò)接口如何把到達(dá)的IP分組放到IP輸入隊(duì)列ipintrq中去,并如何調(diào)用一個(gè)軟件中斷。因?yàn)橛布袛嗟膬?yōu)先級(jí)比軟件中斷的要高,所以在發(fā)生一次軟件中斷之前,有的分組可能會(huì)被放到隊(duì)列中。在軟件中斷處理中,ipintr函數(shù)不斷從ipintrq中IP把分組重裝為數(shù)據(jù)報(bào),并通過函數(shù)調(diào)用把該數(shù)據(jù)報(bào)直接傳給適當(dāng)?shù)倪\(yùn)輸層協(xié)議。如果分組沒有到達(dá)最后的目的地,并且如果主機(jī)被配置成一個(gè)路由器,則IP把分組傳給ip_forward。傳輸協(xié)議和ip_forward把要輸出的分組傳給ip_output,由ip_output完成IP首部、選擇輸出接口以及在必要時(shí)對(duì)分組分片。最終的分組被傳給合適的網(wǎng)絡(luò)接口輸出函數(shù)。當(dāng)產(chǎn)生差錯(cuò)時(shí),IP丟棄該分組,并在某些條件下向分組的源站發(fā)出一個(gè)差錯(cuò)報(bào)文。這些報(bào)文是ICMP(第11章)Net/3通過調(diào)用icmp_error發(fā)出ICMPicmp_error接收一個(gè)mbuf,其中包含差錯(cuò)分組、發(fā)現(xiàn)的差錯(cuò)類型以及一個(gè)選項(xiàng)碼,提供依賴于差錯(cuò)類型的附加信息。 netinet/ip_input.cnetinet/ip_output.netinet/ip_cksum.c在IP8-3 structin_ifaddrstructroutestructifqueuestructipstat*IPIP分組的默認(rèn)圖8-3IP收集的所有統(tǒng)計(jì)量都放在圖8-4描述的ipstat結(jié)構(gòu)中。圖8-5顯示了由netstat-s命令得到的一些統(tǒng)計(jì)輸出樣本。統(tǒng)計(jì)是在主機(jī)啟動(dòng)30天后收集的。 ???????圖8-4 ?分片丟失數(shù)(副本或空間不足??????????系統(tǒng)生成的數(shù)據(jù)報(bào)數(shù)(即沒有轉(zhuǎn)發(fā)的?丟棄的分組數(shù)—???圖8-4續(xù) 圖8-5IPips_noprotoICMP主機(jī)圖8-6顯示了IP組和Net/3收集的統(tǒng)計(jì)中的SNMP 圖8-6IP組中SNMP為了更準(zhǔn)確地討論Internet協(xié)議處理,我們必須定義一些名詞。圖8-7顯示了在不同的IP的數(shù)據(jù)稱為報(bào)文。典型的報(bào)文包含一個(gè)運(yùn)輸層首部和應(yīng)用程序數(shù)據(jù)。圖8-7所示的傳輸協(xié)議是UDP。IP在報(bào)文的首部前加上它自己的首部形成一個(gè)數(shù)據(jù)報(bào)。如果在選定的網(wǎng)絡(luò)中,數(shù)據(jù)報(bào)的長(zhǎng)度太大,IP就把數(shù)據(jù)報(bào)分裂成幾個(gè)分片,每個(gè)分片中含有它自己的IP8-7顯示了一個(gè)數(shù)據(jù)報(bào)被分成三個(gè)分片。當(dāng)提交給數(shù)據(jù)鏈路層進(jìn)行傳送時(shí),一個(gè)IP分片或一個(gè)很小的無(wú)需分片的IP數(shù)據(jù)報(bào)稱為分IP只考慮它自己加上的IP首部,對(duì)報(bào)文本身既不檢查也不修改(除非進(jìn)行分片)。圖8-8顯圖8-8包括ip結(jié)構(gòu)(如圖8-9)中各成員的名字,Net/3通過該結(jié)構(gòu)訪問IP47- 因?yàn)樵诖鎯?chǔ)器中,比特字段的物理順序依機(jī)器和編譯器的不同而不同,所以由保證編譯器按照IP標(biāo)準(zhǔn)排列結(jié)構(gòu)成員。從而,當(dāng)Net/3把一個(gè)ip結(jié)構(gòu)覆蓋到存儲(chǔ)器中的一個(gè)IP

UDP

鏈路層 幀

鏈路層 圖8- 015

圖8-8IP數(shù)據(jù)報(bào),包括ip圖8-9ip圖8-9續(xù)IP分組的格式由版本ip_v指定,通常為4;首部長(zhǎng)度ip_hl,通常以4字節(jié)單元度量;分組長(zhǎng)度ip_len以字節(jié)為單位度量;傳輸協(xié)議ip_p生成分組內(nèi)數(shù)據(jù);ip_sum是檢驗(yàn)和,檢測(cè)在發(fā)送中首部的變化。標(biāo)準(zhǔn)的IP首部長(zhǎng)度是20個(gè)字節(jié),所以ip_hl5。大于5表示IP選項(xiàng)緊跟在標(biāo)準(zhǔn)首部后。如ip_hl的最大值為15(24-1),允許最多40個(gè)字節(jié)的選項(xiàng)(20+40=60)。IP數(shù)據(jù)報(bào)的最大長(zhǎng)度為65535(2161)字節(jié),因?yàn)閕p_len是一個(gè)16bit的字段。圖8-10是整個(gè)構(gòu)成。圖8-10有選項(xiàng)的IP因?yàn)閕p_hl是以4字節(jié)為單元計(jì)算的,所以IP選項(xiàng)必須常常被填充成4在第3、第4和第5章中,我們描述了示例的網(wǎng)絡(luò)接口如何對(duì)到達(dá)的數(shù)據(jù)報(bào)排隊(duì)以等待協(xié)議處理:以太網(wǎng)接口用以太網(wǎng)首部中的類型字段分路到達(dá)幀(見4.3節(jié)SLIP接口只處理IP分組,所以無(wú)需分用(見5.3節(jié)環(huán)回接口在looutputsa_family成員在以上情況中,當(dāng)接口把分組放到ipintrq上排隊(duì)后,通過schednetisr調(diào)用一個(gè)軟中斷。當(dāng)該軟中斷發(fā)生時(shí),如果IP處理過程已經(jīng)由schednetisr調(diào)度,則內(nèi)核調(diào)用ipintr。在調(diào)用ipintr之前,CPU的優(yōu)先級(jí)被改變成splnet。發(fā);(3)分組重裝;(4)分用。在ipintr100-117標(biāo)號(hào)nextipintr從ipintrq中移走分組,并對(duì)之加以處理直到整個(gè)隊(duì)列空為止。如果到函數(shù)最后控制失敗,goto把控制權(quán)傳回給next中最上面的函數(shù)。ipintr把分組阻塞在splimp內(nèi),避免當(dāng)它訪問隊(duì)列時(shí),運(yùn)行網(wǎng)絡(luò)的中斷程序(例如slinput和ether_inp。 標(biāo)號(hào)bad標(biāo)識(shí)由于釋放相關(guān)mbuf并返回到next中處理循環(huán)的開始而自動(dòng)丟棄的我們從圖8-12開始:把分組從ipintrq中取出,驗(yàn)證它們的內(nèi)容。損壞和有差錯(cuò)的分組被自動(dòng)丟棄。圖8-12續(xù)118-134 如果in_ifaddr表(見第6.5節(jié))為空,則該網(wǎng)絡(luò)接口沒有指派IP地址,ipintr必須丟掉所有的IPipintr就無(wú)法決定該分組是否要到該系統(tǒng)。通常這是一種暫時(shí)情況,是當(dāng)系統(tǒng)啟動(dòng)時(shí),接口正在運(yùn)行但還沒有配置好時(shí)發(fā)生的。我們?cè)?.3節(jié)中介紹了在ipintr訪問任何IP首部字段之前,它必須證實(shí)ip_v是4(IPVERSION)。RFC1122某種實(shí)現(xiàn)丟棄那些具有無(wú)法識(shí)別版本號(hào)的分組而不回顯信息。Net/2不檢查ip_v。目前大多數(shù)正在使用的IP實(shí)現(xiàn),包括Net/2,都是在IP的版本4之后產(chǎn)生的,因此無(wú)需區(qū)分不同IP版本的分組。因?yàn)槟壳罢趯?duì)IP進(jìn)行修正,所以IEN119[Fogie197]RFC1190[opolcic1990]描述了使用P版本和驗(yàn)協(xié)議。版本6還被選為下一個(gè)正式的IP標(biāo)準(zhǔn)IP6)。保留版本0和15,其他的沒有賦在C中,處理位于一個(gè)無(wú)類型存儲(chǔ)區(qū)域中數(shù)據(jù)的最簡(jiǎn)單的方法是:在該存儲(chǔ)區(qū)域上覆蓋一2mbuf鏈把一個(gè)字節(jié)的邏輯序列,例如一個(gè)IP分組,儲(chǔ)存在多個(gè)物理mbuf中,各mbuf相互連接在一IP分組的首部,所以首部必須駐留在一段連續(xù)的存儲(chǔ)區(qū)內(nèi)(也就是說(shuō),不能把首部分開放在不同的存儲(chǔ)器緩存區(qū))135- 下面的步驟保證IP首部(包括選項(xiàng))如果在第一個(gè)mbuf中的數(shù)據(jù)小于一個(gè)標(biāo)準(zhǔn)的IP首部(20字節(jié)),m_pullup會(huì)重新把該標(biāo)準(zhǔn)首部放到一個(gè)連續(xù)的存儲(chǔ)器緩存區(qū)上去。鏈路層不太可能會(huì)把最大的60字節(jié))IP首部分在兩個(gè)mbufip_hl通過乘以4得到首部字節(jié)長(zhǎng)度,并將其保存在hlen如果IP分組首部的字節(jié)數(shù)長(zhǎng)度hlen小于標(biāo)準(zhǔn)首部(20字節(jié))如果整個(gè)首部仍然不在第一個(gè)mbuf中(也就是說(shuō),分組包含了IP選項(xiàng)),則由檢驗(yàn)和計(jì)算是所有Internet協(xié)議的重要組成。所有的協(xié)議均使用相同的算法由函數(shù)in_cksum完成),但應(yīng)用于分組的不同部分。對(duì)IP來(lái)說(shuō),檢驗(yàn)和只保證IP的首部(以及選項(xiàng),如果有的話)。對(duì)傳輸協(xié)議,如UDP或TCP,檢驗(yàn)和覆蓋了分組的數(shù)據(jù)部分和運(yùn)輸層首部。147-150ipintr把由in_cksum計(jì)算出來(lái)的檢驗(yàn)和保存首部的ip_sum字段中。一個(gè)未被破8.7節(jié)中看到的,在計(jì)算到達(dá)分組的檢驗(yàn)和之前,必須對(duì)ip_sum清零。通過把in_cksum中的結(jié)果儲(chǔ)存在ip_sum中,就為分組轉(zhuǎn)發(fā)作好了準(zhǔn)備(盡管還沒有減小TTL)。ip_output函數(shù)不依賴這項(xiàng)操作;它為轉(zhuǎn)發(fā)的分組重新計(jì)算檢驗(yàn)和。如果結(jié)果非零,則該分組被自動(dòng)丟棄。我們將在8.7節(jié)中詳細(xì)討論in_cksum151-160InternetNTOHS把IP首部中所有16bitip_len)、數(shù)據(jù)報(bào)標(biāo)識(shí)符(ip_id)和分片偏移(ip_off)。如果兩種格式相同,則NTOHS是一個(gè)空的宏。在這里就轉(zhuǎn)換成主機(jī)字節(jié)序,以避免Net/3每次檢查該字段時(shí)必須進(jìn)行一次轉(zhuǎn)換。161-177如果分組的邏輯長(zhǎng)度(ip_len)比儲(chǔ)存在mbuf中的數(shù)據(jù)量(m_pkthdr.len)大,并且有些字節(jié)被丟失了,就必須丟棄該分組。如果mbuf比分組大,則去掉多余的字節(jié)。丟失字節(jié)的一個(gè)常見原因是因?yàn)閿?shù)據(jù)到達(dá)某個(gè)沒有或只有很少緩存的串口設(shè)備,例如許多個(gè)人計(jì)算機(jī)。設(shè)備丟棄到達(dá)的字節(jié),而IP丟棄最后的分組。IP分組的大小比以太網(wǎng)要分組的長(zhǎng)度被保存在首部的原因之一;現(xiàn)在,有了完整的IP首部,分組的邏輯長(zhǎng)度和物理長(zhǎng)度相同,檢驗(yàn)和表明分組的首部無(wú)損地到達(dá)。圖8-13顯示了ipintr的下一部分,調(diào)用ip_dooptions(見第9章)來(lái)處理IP選項(xiàng),然后決定分組是否到達(dá)它最后的目的地。如果分組沒有到達(dá)最后目的地,Net/3會(huì)嘗試轉(zhuǎn)發(fā)該分組(如果系統(tǒng)被配置成路由器)。如果分組到達(dá)最后目的地,就被交付給合適的運(yùn)輸層協(xié)議。圖8-13續(xù)

圖8-13(續(xù)178-186 通過對(duì)ip_nhops(見9.6節(jié))清零,丟掉前一個(gè)分組的原路由。如果分組首部大于默認(rèn)首部,它必然包含由ip_dooptions處理的選項(xiàng)。如果ip_dooptions0,ipintrip_dooptions通過轉(zhuǎn)發(fā)或丟棄分組完成對(duì)該分組的處理,ipintr9處理完選項(xiàng)后,ipintr通過把IP首部?jī)?nèi)的ip_dst與配置的所有本地接口的IP地址比較,以決定分組是否已到達(dá)最終目的地。ipintr必須考慮與接口相關(guān)的幾個(gè)廣播地址、一個(gè)或多187-261ipintr通過遍歷in_ifaddr(圖6-5),配置好的Interne地址表,來(lái)決定是否有與分組的目的地址的匹配。對(duì)清單中的每個(gè)in_ifaddr結(jié)構(gòu)進(jìn)行一系列的比較。要考慮4種常與某個(gè)接口地址的完全匹配(圖8-14中的第一行(圖8-14的中間4行與某個(gè)與接收接口相關(guān)的多播組之一的匹配(圖12-39)與兩個(gè)受限的廣播地址之一的匹配(圖8-14的最后一行)圖8-14顯示的是當(dāng)分組到達(dá)我們的示例網(wǎng)絡(luò)里的主機(jī)sun上的以太網(wǎng)接口時(shí)要測(cè)試的地圖8- 對(duì)ia_subnet、ia_net和INADDR_ANY的測(cè)試不是必需的,因?yàn)樗鼈儽硎镜氖?.2BSD使用的已經(jīng)過時(shí)的廣播地址。但不幸的是,許多TCP/IP實(shí)現(xiàn)是從4.2BSD派生而來(lái)的,所以,在某些網(wǎng)絡(luò)中能夠識(shí)別出這些舊廣播地址可能十分重要。262- 如果ip_dst,就丟棄分組。否則,當(dāng)分組到達(dá)的某個(gè)地址不是目的地址指定的接口時(shí),主機(jī)會(huì)丟掉該分組。在這種情況下,Net/3將搜索整個(gè)in_ifaddr表;只考慮那些分配給接收接口的地址。RFC1122稱此為強(qiáng)端系統(tǒng)(stongndysem)對(duì)多主主機(jī)而言,很少出現(xiàn)分組到達(dá)接口地址與其目的地址不對(duì)應(yīng)的情況,除非配置了特定的主機(jī)路由。主機(jī)路由強(qiáng)迫相鄰的路由器把多主主機(jī)作為分組的下一跳路由器。弱端系統(tǒng)(weakendsystem)模型要求該主機(jī)接收這些分組。實(shí)現(xiàn)人員可以隨意選擇兩種模型。Net/3實(shí)現(xiàn)弱端系統(tǒng)模型。最后,我們來(lái)看ipintr的最后一部分(圖8-15),在這里進(jìn)行重裝和分用。我們略去了重裝的代碼,推遲到第10ip否則,ip指向一個(gè)已經(jīng)到達(dá)目的地的完整數(shù)據(jù)報(bào)。325- 數(shù)據(jù)報(bào)中指定的協(xié)議被ip_p用ip_protox數(shù)組(圖7-22)映射到inetsw標(biāo)。ipintr調(diào)用選定的protosw結(jié)構(gòu)中的pr_input函數(shù)來(lái)處理數(shù)據(jù)報(bào)包含的運(yùn)輸報(bào)文。當(dāng)pr_inputipintr繼續(xù)處理ipintrq中的下一個(gè)分組。注意,運(yùn)輸層對(duì)分組的處理發(fā)生在ipintr處理循環(huán)的內(nèi)部。在IP和傳輸協(xié)議之間沒有到圖8-15續(xù)到達(dá)非最終目的地系統(tǒng)的分組需要被轉(zhuǎn)發(fā)。只有當(dāng)ipforwarding非零(6.1節(jié))或當(dāng)分組中包含源路由(9.6節(jié))時(shí),ipintr才調(diào)用實(shí)現(xiàn)轉(zhuǎn)發(fā)算法的ip_forward函數(shù)。當(dāng)分組中包含源ip_dooptions調(diào)用ip_forward,并且第2個(gè)參數(shù)srcrt設(shè)為1。圖8-16route46-49route結(jié)構(gòu)有兩個(gè)成員:ro_rt,指向rtentry結(jié)構(gòu)的指針;ro_dst,一個(gè)sockaddr結(jié)構(gòu),指定與ro_rt所指的路由項(xiàng)相關(guān)的目的地。目的地是在內(nèi)核的路由表中用18章對(duì)rtentry結(jié)構(gòu)和路由表有詳細(xì)的描述。我們分兩部分討論ip_forward。第一部分確定允許系統(tǒng)轉(zhuǎn)發(fā)分組,修改IP首部,并為分組選擇路由。第二部分處理ICMP重定向報(bào)文,并把分組交給ip_output進(jìn)行發(fā)送。見圖8-17。 ip_froward的第1個(gè)參數(shù)是指向一個(gè)mbuf鏈的指針,該mbuf中包含了要被轉(zhuǎn)發(fā)的分組。如果第2個(gè)參數(shù)srcrt為非零,則分組由于源路由選項(xiàng)(見9.6節(jié))正在被轉(zhuǎn)發(fā)。 M_BCAST標(biāo)志置位。如果分組尋址是到以太網(wǎng)廣播地址,則ether_input(圖4-13)就把M_BCAST置位。不轉(zhuǎn)發(fā)鏈路層的廣播分組。RFC1122不允許以鏈路層廣播的方式發(fā)送一個(gè)尋址到單播IP地址的分組,并在對(duì)尋址到環(huán)回網(wǎng)絡(luò)的分組,in_canforward返回0。這些分組將被ipintr提交給ip_D尋址到Dip_mforwardip_forward處理。RFC791規(guī)定處理分組的所有系統(tǒng)都必須把生存時(shí)間(TTL)字段至少減去1,即使TTL是以秒計(jì)算的。由于這個(gè)要求,TTL通常被認(rèn)為是對(duì)IP分組在被丟掉之前能經(jīng)過的跳的個(gè)數(shù)的界限。從技術(shù)角度說(shuō),如果路由器持有分組超過1秒,就必須把ip_ttl減去多于1。圖8-17(續(xù)這就產(chǎn)生了一個(gè)問題:在Internet上,最長(zhǎng)的路徑有多長(zhǎng)?這個(gè)度量稱為網(wǎng)絡(luò)的直徑(diameter)。除了通過實(shí)驗(yàn)外無(wú)法知道直徑的大小。[Olivier1994]中有37跳的路徑。減小 ip_forwardIP首部的ICMP差錯(cuò)報(bào)文時(shí),分組的標(biāo)識(shí)符又應(yīng)該是正確的順Net/3漏做了對(duì)已被ipintr轉(zhuǎn)換成主機(jī)字節(jié)序的ip_len的轉(zhuǎn)換。作者注意到在386上,這個(gè)小的漏洞允許交換了字節(jié)的值在ICMP差錯(cuò)中的IP首部中。返回從運(yùn)行在386上的SVR4(可能是Net/1碼)和AIX3.2(4.3BSDReno碼)返回的ICMP分組中可以觀察到這個(gè)小的漏洞。如果ip_ttl達(dá)到1(IPTTLDEC),則向發(fā)送方返回一個(gè)ICMP超時(shí)報(bào)文,并丟掉該分組。系統(tǒng)不接受TTL為0的IP數(shù)據(jù)報(bào),但Net/3在即使出現(xiàn)這種情況時(shí)也能生成正確的ICMP差891-907 IP轉(zhuǎn)發(fā)算法把最近的路由緩存在全局route結(jié)構(gòu)的ipforward_rt中,在可能時(shí)應(yīng)用于當(dāng)前分組。研究表明連續(xù)分組趨向于同一目的地址([Jain和Routhier1986]和[Mogul1991]),所以這種向后一個(gè)(one-behind)的緩存使路由查詢的次數(shù)最少。如果緩存為空(ipforward_rt)ipforward_rt中的路由,就取消前面的路由,ro_dstrtalloc為當(dāng)前分組的目的地找一個(gè)新路由。如果找不到路由,則返回一個(gè)ICMP主機(jī)不可達(dá)差錯(cuò),并丟掉該分組。908-914ip_output要丟掉分組,所以m_copy復(fù)制分組的前64節(jié),以便ip_forward發(fā)送ICMP差錯(cuò)報(bào)文。如果調(diào)用m_copy失敗,ip_forwar并不終止。在這種情況下,不發(fā)送差錯(cuò)報(bào)文。ip_ifmatrix記錄在接口之間進(jìn)行路由選擇的分組的個(gè) 重定向報(bào)文。I網(wǎng)絡(luò)互連模型假定主機(jī)相對(duì)地并不知道整個(gè)互聯(lián)網(wǎng)的拓?fù)浣Y(jié)構(gòu),把維護(hù)圖8-18路由器R1重定向主機(jī)HS使用路由器R2到達(dá)通常,管理員對(duì)主機(jī)的配置是:把到遠(yuǎn)程網(wǎng)絡(luò)的分組發(fā)送到某個(gè)默認(rèn)路由器上。在圖8-18中,主機(jī)S上1被配置成它的默認(rèn)路由器。當(dāng)S首次向HD發(fā)送分組時(shí),它不知道2是合適的選擇,而把分組發(fā)給1。R1識(shí)別出差錯(cuò),就把分組轉(zhuǎn)發(fā)給2,并向HS發(fā)回一個(gè)重定向報(bào)S更新它的路由表,下一次發(fā)往H的分組就直接發(fā)給。RFC1122推薦只有路由器才發(fā)重定向報(bào)文,而主機(jī)在接收到ICMP重定向報(bào)文后必須更新它們的路由表(11.8節(jié))。因?yàn)镹et/3只在系統(tǒng)被配置成路由器時(shí)才調(diào)用ip_forward,所以Net/3采用RFC1122的推薦。915-929路由器識(shí)別重定向情況的規(guī)則很復(fù)雜。首先,只有在同一接口(rt_ifp和rcvif)上接收或重發(fā)分組時(shí),才能應(yīng)用重定向。其次,被選擇的路由本身必須沒有被ICMP重定向報(bào)文創(chuàng)建或修改過(RTF_DYNAMIC|RTF_MODIFIED),而且該路由也不能是到默認(rèn)目的地的(0.0.0.0)。這就保證系統(tǒng)在末授權(quán)時(shí)不會(huì)生成路由選擇信息,并且不與其他系統(tǒng)共享自己的默認(rèn)路由。通常,路由選擇協(xié)議使用特殊目的地址0.0.0.0定位默認(rèn)路由。當(dāng)?shù)侥衬康牡氐哪硞€(gè)路由不能使用時(shí),與目的地0.0.0.0相關(guān)的路由就把分組定向到一個(gè)默認(rèn)路由器上。全局整數(shù)ipsendredirects指定系統(tǒng)是否被授權(quán)發(fā)送重定向 (第8.9節(jié))ipsendredirects的默認(rèn)值為1。當(dāng)傳給ip_forward的數(shù)srcrt指明系統(tǒng)是對(duì)分組路由選擇的源時(shí),禁止系統(tǒng)重定向,因?yàn)榧俣ㄔ粗鳈C(jī)要覆蓋中間路由器的選擇。930-931 這個(gè)測(cè)試決定分組是否產(chǎn)生于本地子網(wǎng)。如果源地址的子網(wǎng)掩碼位和輸出接口的IP網(wǎng)絡(luò)中。如果源接口和輸出的接口位于同一網(wǎng)絡(luò)中,則該系統(tǒng)就不應(yīng)該接收這個(gè)分組,因?yàn)樵凑究赡芤呀?jīng)把分組發(fā)給正確的第一跳路由器了。ICMP重定向報(bào)文告訴主機(jī)正確的第一跳目的地。如果分組產(chǎn)生于其他子網(wǎng),則前一系統(tǒng)是個(gè)路由器,這個(gè)系統(tǒng)就不應(yīng)該發(fā)重定向報(bào)文;差錯(cuò)由路由選擇協(xié)議糾正。在任何情況下,都要求路由器忽略重定向報(bào)文。盡管如此,當(dāng)被置位時(shí)(也就是說(shuō),當(dāng)它被配置成路由器時(shí)),Net/3932-940ICMP重定向報(bào)文中包含正確的下一個(gè)系統(tǒng)的地址,如果目的主機(jī)不在直接相連的網(wǎng)絡(luò)上時(shí),該地址是一個(gè)路由器的地址;當(dāng)目的主機(jī)在直接相連的網(wǎng)絡(luò)中時(shí),該地址是主機(jī)地址。RFC7924種類型:(1)(2)(3)TOS(4)TOS和主機(jī)。RFC1009推薦在任何時(shí)候都不發(fā)送網(wǎng)絡(luò)重定向報(bào)文,因?yàn)闊o(wú)法保證接收到重定向報(bào)文的主機(jī)能為目的網(wǎng)絡(luò)找到合適的子網(wǎng)掩碼。RFC1122推薦主機(jī)把網(wǎng)絡(luò)重定向看作是主機(jī)重定向,以避免二義性。Net3只發(fā)送主機(jī)重定向報(bào)文,并省略所有對(duì)TOS的考慮。在圖820圖8- 向很有用,但在一個(gè)子網(wǎng)化的互聯(lián)網(wǎng)中,由于重定向報(bào)文中沒有有關(guān)子網(wǎng)掩碼的信息,所以容易產(chǎn)生二義性。941-954ip_forward有一個(gè)路由,并決定是否需要ICMPIp_output把分組發(fā)送到路由ipforward_rt所指定的下一跳。IP_ALLOWBROADCAST標(biāo)志位允許被轉(zhuǎn)發(fā)分組是個(gè)到某局域網(wǎng)的廣播。如果ip_output成功,并且不需要發(fā)送任何重定向報(bào)文,則丟掉分組的前64字節(jié),ip_forward返回。955-983ip_forward可能會(huì)由于ip_output失敗或重定向而發(fā)送ICMP報(bào)文。如果沒有原始分組的復(fù)制()ip_forwardtype和code以前又被置位,但如果ip_outputswitch語(yǔ)句基于從ip_output返回的值重新設(shè)置新的ICMP類型和碼值。icmp_error發(fā)送該報(bào)文。來(lái)自失敗的ip_outputICMP報(bào)文將覆蓋任何重定向報(bào)文。處理來(lái)自ip_output的差錯(cuò)的switch語(yǔ)句非常重要。它把本地差錯(cuò)翻譯成適當(dāng)?shù)腎CMP差錯(cuò)報(bào)文,并返回給分組的源站。圖8-21對(duì)差錯(cuò)作了總結(jié)。第11ICMP報(bào)當(dāng)ip_output返回ENOBUFSNet/3通常生成ICMP源站抑制報(bào)文。RouterRequirements(路由器需求)RFC[Almquist和Kastenholz1994]不贊成源站抑制并要求路由器不產(chǎn)生這種報(bào)文。 IP輸出代碼從兩處接收分組:ip_forward圖81。讓inetsw0.pr_output能訪問到IP輸出操作似乎很有道理,但事實(shí)并非如此。標(biāo)準(zhǔn)的Internet傳輸協(xié)議(ICMP、IGMP、UDP和TCP)直接調(diào)用ip_output,而不查詢inetsw表。對(duì)標(biāo)準(zhǔn)Internet傳protosw結(jié)構(gòu)不必具有一般性,因?yàn)檎{(diào)用函數(shù)并不是在與協(xié)議無(wú)關(guān)的情況下接入IP的。在第20pr_output接入IP。我們分三個(gè)部分描述ip_output:圖8-22顯示了ip_output(不 的到目的地的路由;flags,見圖8-23;imo,指向多播選項(xiàng)的指針,見第12章。IP_FORWARDING被ip_forward和ip_mforward圖8-22函數(shù) 圖8- send、sendto和sendmsg的MSG_DONTROUTE標(biāo)志使IP_ROUTETOIF有效,并進(jìn)行一次寫操作(見16.4),而SO_DONTROUTE插口選項(xiàng)使IP_ROUTETOIF有效,并在某個(gè)特定插口上進(jìn)行任意的寫操作(見8.8節(jié))。該標(biāo)志被傳輸協(xié)議傳給ip_output。IP_ALLOWBROADCAST標(biāo)志可以被SO_BROADCAST插口選項(xiàng)(見8.8節(jié))設(shè)置,但只被UDP提交。原來(lái)的IP默認(rèn)地設(shè)置IP_ALLOWBROADCAST。TCP不支持廣播,所以IP_ALLOWBROADCAST不能被TCP提交給ip_output。不存在廣播的預(yù)請(qǐng)求標(biāo)志。構(gòu)造IP 我們將在8.8節(jié)中看到,進(jìn)程可以設(shè)置IP_OPTIONS插口選項(xiàng)來(lái)為一個(gè)插口指定IP選項(xiàng)。被轉(zhuǎn)發(fā)分組(IP_FORWARDING)或有預(yù)構(gòu)首部(IP_RAWOUTPUT)分組的IP首部不能被ip_output修改。任何其他分組(UDP或TCP分組)需要有幾個(gè)IP首部字段被初始化。ip_output把ip_v設(shè)置成4IPVERSION),把DF位需要的ip_off清零,并設(shè)置成調(diào)用程序提供的值(見第10章),給來(lái)自全局整數(shù)的ip->ip_id賦一個(gè)唯一的標(biāo)識(shí)符,把ip_id加1。ip_id(見7.8節(jié))。ip_hl被設(shè)置成用32bit字度量的首部長(zhǎng)度。IP首部的其他字段—長(zhǎng)度、偏移、TL、協(xié)議、TOS和目的地址—已經(jīng)被傳輸協(xié)議初(825。 對(duì)一個(gè)已轉(zhuǎn)發(fā)的分組(或一個(gè)有首部的原始IP分組),首部長(zhǎng)度(以字節(jié)數(shù)度量)被保存在完成IP首部后,ip_output的下一個(gè)任務(wù)就是確定一條到目的地的路由。見圖8-24圖8-24ip_output(續(xù)圖8-24續(xù)77-99ip_output可能把一條在高速緩存中的路由作為ro參數(shù)來(lái)提供。在第24章中,我們將看到UDP和TCP維護(hù)一個(gè)與各插口相關(guān)的路由緩存。如果沒有路由,則ip_output把ro設(shè)如果高速緩存中的目的地不是去當(dāng)前分組的目的地,就把該路由丟掉,新的目的地址放在dst中。100-114 IP_ROUTETOIF志(見8.8節(jié))禁止對(duì)分組進(jìn)行路由選擇。ip_output必須找到一個(gè)與分組中指定目的地網(wǎng)絡(luò)直接相連的接口。ifa_ifwithdstaddr搜索點(diǎn)到點(diǎn)接口,而in_ifwithnet搜索其他接口。如果任一函數(shù)找到與目的網(wǎng)絡(luò)相連的接口,就返回ENETUNREACH;否則,ifp統(tǒng)。通過這個(gè)方法,即使本地路由表不正確,也可以與其他路由器交換路由選擇信息。-2 如果分組正被路由選擇(IP_ROUTETOIF為關(guān)狀態(tài)c找到一條到指定地址的路由。如果沒找到路由,則ip_outpt回EHOSTUNREACH。如果ip_forward調(diào)用ip_output,就把EHOSTUNREACH差錯(cuò)。如果某個(gè)傳輸協(xié)議調(diào)用,就把差錯(cuò)傳回給進(jìn)程(821。123-128ia被設(shè)成指向選定接口的地址(ifaddr結(jié)構(gòu)),而ifp指向接口的ifnet結(jié)構(gòu)。如果下一跳不是分組的最終目的地,則把dst改成下一跳路由器地址,而不再是分組最終目的地址。IP首部?jī)?nèi)的目的地址不變,但接口層必須把分組提交給dst,即下一跳路由器。ip_output的最后一部分如圖8-25所示,保證IP首部有一個(gè)有效源地址,然后把分組提交給與路由相關(guān)的接口。如果分組比接口的MTU大,就必須對(duì)分組分片,然后一片一片地發(fā)送。像前面的重裝代碼一樣,我們省略了分片代碼,并推遲到第10章再討論。圖8- 圖8-25續(xù)212-239 如果沒有指定ip_src,則ip_outpu選擇輸出接口的IP地址i作為源地址。這IP首部字段時(shí)做,因?yàn)槟菚r(shí)還沒有選定路由。轉(zhuǎn)發(fā)的分組通常都有一個(gè)源地址,但是,如果發(fā)送進(jìn)程沒有明確指定源地址,產(chǎn)生于本地主機(jī)的分組可能沒有源地址。如果目的IP地址是一個(gè)廣播地址,則接口必須支持廣播(IFF_BROADCAST,圖3-7)最后的測(cè)試是一個(gè)策略決定。IP協(xié)議規(guī)范中沒有明確禁止對(duì)廣播分組的分片。但是,要求分組適合接口的MTU,就增加了廣播分組被每個(gè)接口接收的機(jī)會(huì),因?yàn)榻尤绻@些條件都不滿足,就扔掉該分組,把EADDRNOTAVAIL、EACCES和EMSGSIZE返回給調(diào)用方。否則,設(shè)置輸出分組的M_BCAST,告訴接口輸出函數(shù)把該分組作為鏈路級(jí)廣播如果M_BCAST沒有清零,則對(duì)一個(gè)作為廣播到達(dá)的請(qǐng)求分組的應(yīng)答將可能作為一個(gè)廣播被返回。我們將在第11章中看到,ICMP應(yīng)答將以這種方式作為TCPRST分組(見26.9節(jié))在請(qǐng)求分組內(nèi)構(gòu)造。 驗(yàn)和與in_cksum(見8.7節(jié))一起計(jì)算,把分組提交給所選接口的if_output函數(shù)。253- 大分組在被發(fā)送之前必須分片。這里我們省略這段代碼,推遲到第10339-34 ro為空,ipoutput可能會(huì)使用一個(gè)臨時(shí)的route結(jié)構(gòu)(iproute)。如果需要,RTFREE發(fā)布iproute內(nèi)的路由入口,并把引用計(jì)數(shù)減1。Bad處的代碼在返回前扔掉當(dāng)前分組。引用計(jì)數(shù)是一個(gè)存儲(chǔ)器管理技術(shù)。程序員必須對(duì)一個(gè)數(shù)據(jù)結(jié)構(gòu)的外部引用計(jì)數(shù);當(dāng)計(jì)數(shù)返回為0時(shí),就可以安全地把存儲(chǔ)器返回給空存儲(chǔ)器池。引用計(jì)數(shù)要求程序員遵守一些規(guī)定,在恰當(dāng)?shù)臅r(shí)機(jī)增加或減小引用計(jì)數(shù)。Internet檢驗(yàn)和:in_cksum([Kay和Pasquale1993])。mbuf數(shù)據(jù)結(jié)構(gòu)的靈活性是Net/3中減少?gòu)?fù)制操作的主要方法。由于對(duì)硬件的依賴,所以檢驗(yàn)和的有效計(jì)算相對(duì)較難。Net/3中有幾種in_cksum的實(shí)現(xiàn)(圖8-26)。 源文圖8-26在Net/3中的幾個(gè)in_cksum即使是可移植C實(shí)現(xiàn)也已經(jīng)被相當(dāng)好地優(yōu)化了。RFC1071[Braden、Borman和Partridge1988]和RFC1141[Mallory和Kullberg1990]討論了Internet檢驗(yàn)和函數(shù)的設(shè)計(jì)和實(shí)現(xiàn)。1141被RFC1624[Rijsinghani1994]修正。從RFC16bit的二進(jìn)制反碼的和以及這個(gè)和的二進(jìn)為檢驗(yàn)檢驗(yàn)和,對(duì)同一組字節(jié)計(jì)算它們的二進(jìn)制反碼的和。如果結(jié)果為全1(在二進(jìn)制0,見下面的解釋),則檢驗(yàn)成功。簡(jiǎn)而言之,當(dāng)對(duì)用二進(jìn)制反碼表示的整數(shù)進(jìn)行加法運(yùn)算時(shí),把兩個(gè)整數(shù)相加后再加上進(jìn)位就得到加法的結(jié)果。在二進(jìn)制反碼運(yùn)算中,只要把每一位求補(bǔ)就得到一個(gè)數(shù)的反。所以在0有兩種表示方法:全0,和全1。有關(guān)二進(jìn)制反碼的運(yùn)算和表示的詳細(xì)討論見[Mano1982]。檢驗(yàn)和算法在發(fā)送分組之前計(jì)算出要放在IP首部檢驗(yàn)和字段的值。為了計(jì)算這個(gè)值,先把首部的檢驗(yàn)和字段設(shè)為0,然后計(jì)算整個(gè)首部(包括選項(xiàng))的二進(jìn)制反碼的和。把首部作為一個(gè)16bit整數(shù)數(shù)組來(lái)處理。讓我們把這個(gè)計(jì)算結(jié)果稱為a。因?yàn)闄z驗(yàn)和字段被明確設(shè)為0,所以a是除了檢驗(yàn)和字段外所有IP首部字段的和。a的二進(jìn)制反碼,用-a表示,被放在檢驗(yàn)和字段如果在傳輸過程中沒有比特位被改變,則在目的地計(jì)算的檢驗(yàn)和應(yīng)該等于(a+-a)的二進(jìn)制反碼。在二進(jìn)制反碼運(yùn)算中(a+-a)的和是-0(全1),而它的二進(jìn)制反碼應(yīng)該等于0(全0)。所以在目的地,一個(gè)沒有損壞分組計(jì)算出來(lái)的檢驗(yàn)和應(yīng)該總是為0。這就是我們?cè)趫D8-12中看到圖8-27IP1-16這里唯一提高性能之處在于累計(jì)sum高16bit的進(jìn)位。當(dāng)循環(huán)結(jié)束時(shí),累計(jì)的進(jìn)位被加在低16bit上,直到?jīng)]有其他進(jìn)位發(fā)生。RFC1071稱此為延遲進(jìn)位(deferredcarries)。在沒現(xiàn)在我們顯示Net/3的可移植C版本。它使用了延遲進(jìn)位技術(shù),作用于存儲(chǔ)在一個(gè)mbuf鏈中42-140mbufmbuf:用32bit整數(shù)的延遲進(jìn)位對(duì)16bit字作加法。對(duì)奇數(shù)個(gè)字節(jié)的mbufmbuf的第一個(gè)字節(jié)配對(duì)。因?yàn)樵诖蠖鄶?shù)體系結(jié)構(gòu)中,對(duì)16bit字的不對(duì)齊訪問是無(wú)效的,甚至?xí)a(chǎn)生嚴(yán)重差錯(cuò),in_cksum繼續(xù)加上下一個(gè)對(duì)齊的字。當(dāng)這種情況發(fā)生時(shí),in_cksum總是很小心地交換字節(jié),保證位于奇數(shù)和偶數(shù)位置的字節(jié)被放在單獨(dú)的和字節(jié)中,以滿足檢驗(yàn)和算法的要求。93-115函數(shù)中的三個(gè)while16個(gè)字、4個(gè)字和1開的循環(huán)減小了循環(huán)的耗費(fèi),在某些體系結(jié)構(gòu)中可能比一個(gè)直接循環(huán)要快得多。但代價(jià)是代碼長(zhǎng)度和復(fù)雜性增大。圖8- IP檢驗(yàn)和計(jì)算的一個(gè)優(yōu)化的可移植C程圖8-28(續(xù)圖8-28續(xù)RFC1071提到兩個(gè)在Net/3中沒有出現(xiàn)的優(yōu)化:聯(lián)合的有檢驗(yàn)和的復(fù)制操作和遞增的檢驗(yàn)和更新。對(duì)IP首部檢驗(yàn)和來(lái)說(shuō),把復(fù)制和檢驗(yàn)和操作結(jié)合起來(lái)并不像對(duì)TCP和UDP那么重要,因?yàn)楹笳吒采w了更多的字節(jié)。在23.12[Partridge和Pink1993]報(bào)告了IP首部檢驗(yàn)和的一個(gè)內(nèi)聯(lián)版本比調(diào)用更一般的in_cksum函數(shù)要快得多,只需6~8個(gè)匯編指令就可以完成(標(biāo)準(zhǔn)的20字節(jié)IP首部)檢驗(yàn)和算法設(shè)計(jì)允許改變分組,并在不重新檢查所有字節(jié)的情況下更新檢驗(yàn)和。RFC1071對(duì)該問題進(jìn)行簡(jiǎn)明的討論。RFC1141和1624中有更詳細(xì)的討論。該技術(shù)的一個(gè)典型應(yīng)用是在分組轉(zhuǎn)發(fā)的過程中。通常情況下,當(dāng)分組沒有選項(xiàng)時(shí),轉(zhuǎn)發(fā)過程中只有TTL字段發(fā)生變?yōu)榱诉M(jìn)一步提高效率,遞增的檢驗(yàn)和也有助于檢測(cè)到被有差錯(cuò)的軟件破壞的首部。如果遞增地計(jì)算檢驗(yàn)和,則下一個(gè)系統(tǒng)可以檢測(cè)到被破壞的首部。但是如果不是遞增計(jì)算檢驗(yàn)和,那么檢驗(yàn)和中就包含了差錯(cuò)的字節(jié),檢測(cè)不到有問題的首部。UDP和TCP使用的檢驗(yàn)和算法在最終目的主機(jī)檢測(cè)到該差錯(cuò)。我們將在第23和25章看到UDP和TCP檢驗(yàn)和包含了IP首部的32bit檢驗(yàn)和的檢驗(yàn)和函數(shù),可參見sysvax/Net/3提供setsockopt和getsockopt兩個(gè)系統(tǒng)調(diào)用來(lái)訪問一些網(wǎng)絡(luò)互連的性質(zhì)。這兩個(gè)系統(tǒng)調(diào)用支持一個(gè)動(dòng)態(tài)接口,進(jìn)程可用該動(dòng)態(tài)接口來(lái)訪問某種網(wǎng)絡(luò)互連協(xié)議的一些性質(zhì),而標(biāo)準(zhǔn)系統(tǒng)調(diào)用通常不支持該協(xié)議。這兩個(gè)調(diào)用的原型是:intsetsockopt(ints,intlevel,intoptname,void*optval,intintgetsockopt(ints,intlevel,intoptname,constvoid*optval,int大多數(shù)插口選項(xiàng)只影響它們?cè)谄渖习l(fā)布的插口。與l參數(shù)相比,后者影響整個(gè)系統(tǒng)。setsockopt和getsockopt設(shè)置和獲取通信棧所有層上的選項(xiàng)。Net/3按照與s相關(guān)的論有關(guān)選項(xiàng)的實(shí)現(xiàn)。本章討論訪問IP 我們把本書中出現(xiàn)的所有插口選項(xiàng)總結(jié)在圖8-30中。該圖顯示了IPPROTO_IP級(jí)的選項(xiàng)。1optval指向變量的數(shù)據(jù)類型出現(xiàn)在第2列,第3列顯示的是處理該選項(xiàng)的選項(xiàng)名函數(shù)描述設(shè)置或獲取發(fā)出的數(shù)據(jù)報(bào)中的IPTOS設(shè)置或獲取發(fā)出的數(shù)據(jù)報(bào)中的IPTTL(只對(duì)UDP;還沒有實(shí)現(xiàn)32.8節(jié)中我們給出與SOCK_RAW插口一起使用的IPPROTO_IP431-447ip_ctloutput的第一個(gè)參數(shù)op,可以是PRCO_SETOPT或者PRCO_GETOPT。第二索的選項(xiàng),m

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論