




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
本章我們介紹IP分組的結構和基本的IP處理過程,包括輸入、轉發和輸出。假定讀者熟悉IP協議的基本操作,其他IP的背景知識見卷1的第3、9和12章。RFC791[Postel1981a]是IP的官方規范,RFC1122[Braden1989a]中有RFC791的說明。第9章將討論選項的處理,第10章討論分片和重裝。圖8-1顯示了IP圖8-1IP在第4章中,我們看到網絡接口如何把到達的IP分組放到IP輸入隊列ipintrq中去,并如何調用一個軟件中斷。因為硬件中斷的優先級比軟件中斷的要高,所以在發生一次軟件中斷之前,有的分組可能會被放到隊列中。在軟件中斷處理中,ipintr函數不斷從ipintrq中IP把分組重裝為數據報,并通過函數調用把該數據報直接傳給適當的運輸層協議。如果分組沒有到達最后的目的地,并且如果主機被配置成一個路由器,則IP把分組傳給ip_forward。傳輸協議和ip_forward把要輸出的分組傳給ip_output,由ip_output完成IP首部、選擇輸出接口以及在必要時對分組分片。最終的分組被傳給合適的網絡接口輸出函數。當產生差錯時,IP丟棄該分組,并在某些條件下向分組的源站發出一個差錯報文。這些報文是ICMP(第11章)Net/3通過調用icmp_error發出ICMPicmp_error接收一個mbuf,其中包含差錯分組、發現的差錯類型以及一個選項碼,提供依賴于差錯類型的附加信息。 netinet/ip_input.cnetinet/ip_output.netinet/ip_cksum.c在IP8-3 structin_ifaddrstructroutestructifqueuestructipstat*IPIP分組的默認圖8-3IP收集的所有統計量都放在圖8-4描述的ipstat結構中。圖8-5顯示了由netstat-s命令得到的一些統計輸出樣本。統計是在主機啟動30天后收集的。 ???????圖8-4 ?分片丟失數(副本或空間不足??????????系統生成的數據報數(即沒有轉發的?丟棄的分組數—???圖8-4續 圖8-5IPips_noprotoICMP主機圖8-6顯示了IP組和Net/3收集的統計中的SNMP 圖8-6IP組中SNMP為了更準確地討論Internet協議處理,我們必須定義一些名詞。圖8-7顯示了在不同的IP的數據稱為報文。典型的報文包含一個運輸層首部和應用程序數據。圖8-7所示的傳輸協議是UDP。IP在報文的首部前加上它自己的首部形成一個數據報。如果在選定的網絡中,數據報的長度太大,IP就把數據報分裂成幾個分片,每個分片中含有它自己的IP8-7顯示了一個數據報被分成三個分片。當提交給數據鏈路層進行傳送時,一個IP分片或一個很小的無需分片的IP數據報稱為分IP只考慮它自己加上的IP首部,對報文本身既不檢查也不修改(除非進行分片)。圖8-8顯圖8-8包括ip結構(如圖8-9)中各成員的名字,Net/3通過該結構訪問IP47- 因為在存儲器中,比特字段的物理順序依機器和編譯器的不同而不同,所以由保證編譯器按照IP標準排列結構成員。從而,當Net/3把一個ip結構覆蓋到存儲器中的一個IP
UDP
鏈路層 幀
鏈路層 圖8- 015
圖8-8IP數據報,包括ip圖8-9ip圖8-9續IP分組的格式由版本ip_v指定,通常為4;首部長度ip_hl,通常以4字節單元度量;分組長度ip_len以字節為單位度量;傳輸協議ip_p生成分組內數據;ip_sum是檢驗和,檢測在發送中首部的變化。標準的IP首部長度是20個字節,所以ip_hl5。大于5表示IP選項緊跟在標準首部后。如ip_hl的最大值為15(24-1),允許最多40個字節的選項(20+40=60)。IP數據報的最大長度為65535(2161)字節,因為ip_len是一個16bit的字段。圖8-10是整個構成。圖8-10有選項的IP因為ip_hl是以4字節為單元計算的,所以IP選項必須常常被填充成4在第3、第4和第5章中,我們描述了示例的網絡接口如何對到達的數據報排隊以等待協議處理:以太網接口用以太網首部中的類型字段分路到達幀(見4.3節SLIP接口只處理IP分組,所以無需分用(見5.3節環回接口在looutputsa_family成員在以上情況中,當接口把分組放到ipintrq上排隊后,通過schednetisr調用一個軟中斷。當該軟中斷發生時,如果IP處理過程已經由schednetisr調度,則內核調用ipintr。在調用ipintr之前,CPU的優先級被改變成splnet。發;(3)分組重裝;(4)分用。在ipintr100-117標號nextipintr從ipintrq中移走分組,并對之加以處理直到整個隊列空為止。如果到函數最后控制失敗,goto把控制權傳回給next中最上面的函數。ipintr把分組阻塞在splimp內,避免當它訪問隊列時,運行網絡的中斷程序(例如slinput和ether_inp。 標號bad標識由于釋放相關mbuf并返回到next中處理循環的開始而自動丟棄的我們從圖8-12開始:把分組從ipintrq中取出,驗證它們的內容。損壞和有差錯的分組被自動丟棄。圖8-12續118-134 如果in_ifaddr表(見第6.5節)為空,則該網絡接口沒有指派IP地址,ipintr必須丟掉所有的IPipintr就無法決定該分組是否要到該系統。通常這是一種暫時情況,是當系統啟動時,接口正在運行但還沒有配置好時發生的。我們在6.3節中介紹了在ipintr訪問任何IP首部字段之前,它必須證實ip_v是4(IPVERSION)。RFC1122某種實現丟棄那些具有無法識別版本號的分組而不回顯信息。Net/2不檢查ip_v。目前大多數正在使用的IP實現,包括Net/2,都是在IP的版本4之后產生的,因此無需區分不同IP版本的分組。因為目前正在對IP進行修正,所以IEN119[Fogie197]RFC1190[opolcic1990]描述了使用P版本和驗協議。版本6還被選為下一個正式的IP標準IP6)。保留版本0和15,其他的沒有賦在C中,處理位于一個無類型存儲區域中數據的最簡單的方法是:在該存儲區域上覆蓋一2mbuf鏈把一個字節的邏輯序列,例如一個IP分組,儲存在多個物理mbuf中,各mbuf相互連接在一IP分組的首部,所以首部必須駐留在一段連續的存儲區內(也就是說,不能把首部分開放在不同的存儲器緩存區)135- 下面的步驟保證IP首部(包括選項)如果在第一個mbuf中的數據小于一個標準的IP首部(20字節),m_pullup會重新把該標準首部放到一個連續的存儲器緩存區上去。鏈路層不太可能會把最大的60字節)IP首部分在兩個mbufip_hl通過乘以4得到首部字節長度,并將其保存在hlen如果IP分組首部的字節數長度hlen小于標準首部(20字節)如果整個首部仍然不在第一個mbuf中(也就是說,分組包含了IP選項),則由檢驗和計算是所有Internet協議的重要組成。所有的協議均使用相同的算法由函數in_cksum完成),但應用于分組的不同部分。對IP來說,檢驗和只保證IP的首部(以及選項,如果有的話)。對傳輸協議,如UDP或TCP,檢驗和覆蓋了分組的數據部分和運輸層首部。147-150ipintr把由in_cksum計算出來的檢驗和保存首部的ip_sum字段中。一個未被破8.7節中看到的,在計算到達分組的檢驗和之前,必須對ip_sum清零。通過把in_cksum中的結果儲存在ip_sum中,就為分組轉發作好了準備(盡管還沒有減小TTL)。ip_output函數不依賴這項操作;它為轉發的分組重新計算檢驗和。如果結果非零,則該分組被自動丟棄。我們將在8.7節中詳細討論in_cksum151-160InternetNTOHS把IP首部中所有16bitip_len)、數據報標識符(ip_id)和分片偏移(ip_off)。如果兩種格式相同,則NTOHS是一個空的宏。在這里就轉換成主機字節序,以避免Net/3每次檢查該字段時必須進行一次轉換。161-177如果分組的邏輯長度(ip_len)比儲存在mbuf中的數據量(m_pkthdr.len)大,并且有些字節被丟失了,就必須丟棄該分組。如果mbuf比分組大,則去掉多余的字節。丟失字節的一個常見原因是因為數據到達某個沒有或只有很少緩存的串口設備,例如許多個人計算機。設備丟棄到達的字節,而IP丟棄最后的分組。IP分組的大小比以太網要分組的長度被保存在首部的原因之一;現在,有了完整的IP首部,分組的邏輯長度和物理長度相同,檢驗和表明分組的首部無損地到達。圖8-13顯示了ipintr的下一部分,調用ip_dooptions(見第9章)來處理IP選項,然后決定分組是否到達它最后的目的地。如果分組沒有到達最后目的地,Net/3會嘗試轉發該分組(如果系統被配置成路由器)。如果分組到達最后目的地,就被交付給合適的運輸層協議。圖8-13續
圖8-13(續178-186 通過對ip_nhops(見9.6節)清零,丟掉前一個分組的原路由。如果分組首部大于默認首部,它必然包含由ip_dooptions處理的選項。如果ip_dooptions0,ipintrip_dooptions通過轉發或丟棄分組完成對該分組的處理,ipintr9處理完選項后,ipintr通過把IP首部內的ip_dst與配置的所有本地接口的IP地址比較,以決定分組是否已到達最終目的地。ipintr必須考慮與接口相關的幾個廣播地址、一個或多187-261ipintr通過遍歷in_ifaddr(圖6-5),配置好的Interne地址表,來決定是否有與分組的目的地址的匹配。對清單中的每個in_ifaddr結構進行一系列的比較。要考慮4種常與某個接口地址的完全匹配(圖8-14中的第一行(圖8-14的中間4行與某個與接收接口相關的多播組之一的匹配(圖12-39)與兩個受限的廣播地址之一的匹配(圖8-14的最后一行)圖8-14顯示的是當分組到達我們的示例網絡里的主機sun上的以太網接口時要測試的地圖8- 對ia_subnet、ia_net和INADDR_ANY的測試不是必需的,因為它們表示的是4.2BSD使用的已經過時的廣播地址。但不幸的是,許多TCP/IP實現是從4.2BSD派生而來的,所以,在某些網絡中能夠識別出這些舊廣播地址可能十分重要。262- 如果ip_dst,就丟棄分組。否則,當分組到達的某個地址不是目的地址指定的接口時,主機會丟掉該分組。在這種情況下,Net/3將搜索整個in_ifaddr表;只考慮那些分配給接收接口的地址。RFC1122稱此為強端系統(stongndysem)對多主主機而言,很少出現分組到達接口地址與其目的地址不對應的情況,除非配置了特定的主機路由。主機路由強迫相鄰的路由器把多主主機作為分組的下一跳路由器。弱端系統(weakendsystem)模型要求該主機接收這些分組。實現人員可以隨意選擇兩種模型。Net/3實現弱端系統模型。最后,我們來看ipintr的最后一部分(圖8-15),在這里進行重裝和分用。我們略去了重裝的代碼,推遲到第10ip否則,ip指向一個已經到達目的地的完整數據報。325- 數據報中指定的協議被ip_p用ip_protox數組(圖7-22)映射到inetsw標。ipintr調用選定的protosw結構中的pr_input函數來處理數據報包含的運輸報文。當pr_inputipintr繼續處理ipintrq中的下一個分組。注意,運輸層對分組的處理發生在ipintr處理循環的內部。在IP和傳輸協議之間沒有到圖8-15續到達非最終目的地系統的分組需要被轉發。只有當ipforwarding非零(6.1節)或當分組中包含源路由(9.6節)時,ipintr才調用實現轉發算法的ip_forward函數。當分組中包含源ip_dooptions調用ip_forward,并且第2個參數srcrt設為1。圖8-16route46-49route結構有兩個成員:ro_rt,指向rtentry結構的指針;ro_dst,一個sockaddr結構,指定與ro_rt所指的路由項相關的目的地。目的地是在內核的路由表中用18章對rtentry結構和路由表有詳細的描述。我們分兩部分討論ip_forward。第一部分確定允許系統轉發分組,修改IP首部,并為分組選擇路由。第二部分處理ICMP重定向報文,并把分組交給ip_output進行發送。見圖8-17。 ip_froward的第1個參數是指向一個mbuf鏈的指針,該mbuf中包含了要被轉發的分組。如果第2個參數srcrt為非零,則分組由于源路由選項(見9.6節)正在被轉發。 M_BCAST標志置位。如果分組尋址是到以太網廣播地址,則ether_input(圖4-13)就把M_BCAST置位。不轉發鏈路層的廣播分組。RFC1122不允許以鏈路層廣播的方式發送一個尋址到單播IP地址的分組,并在對尋址到環回網絡的分組,in_canforward返回0。這些分組將被ipintr提交給ip_D尋址到Dip_mforwardip_forward處理。RFC791規定處理分組的所有系統都必須把生存時間(TTL)字段至少減去1,即使TTL是以秒計算的。由于這個要求,TTL通常被認為是對IP分組在被丟掉之前能經過的跳的個數的界限。從技術角度說,如果路由器持有分組超過1秒,就必須把ip_ttl減去多于1。圖8-17(續這就產生了一個問題:在Internet上,最長的路徑有多長?這個度量稱為網絡的直徑(diameter)。除了通過實驗外無法知道直徑的大小。[Olivier1994]中有37跳的路徑。減小 ip_forwardIP首部的ICMP差錯報文時,分組的標識符又應該是正確的順Net/3漏做了對已被ipintr轉換成主機字節序的ip_len的轉換。作者注意到在386上,這個小的漏洞允許交換了字節的值在ICMP差錯中的IP首部中。返回從運行在386上的SVR4(可能是Net/1碼)和AIX3.2(4.3BSDReno碼)返回的ICMP分組中可以觀察到這個小的漏洞。如果ip_ttl達到1(IPTTLDEC),則向發送方返回一個ICMP超時報文,并丟掉該分組。系統不接受TTL為0的IP數據報,但Net/3在即使出現這種情況時也能生成正確的ICMP差891-907 IP轉發算法把最近的路由緩存在全局route結構的ipforward_rt中,在可能時應用于當前分組。研究表明連續分組趨向于同一目的地址([Jain和Routhier1986]和[Mogul1991]),所以這種向后一個(one-behind)的緩存使路由查詢的次數最少。如果緩存為空(ipforward_rt)ipforward_rt中的路由,就取消前面的路由,ro_dstrtalloc為當前分組的目的地找一個新路由。如果找不到路由,則返回一個ICMP主機不可達差錯,并丟掉該分組。908-914ip_output要丟掉分組,所以m_copy復制分組的前64節,以便ip_forward發送ICMP差錯報文。如果調用m_copy失敗,ip_forwar并不終止。在這種情況下,不發送差錯報文。ip_ifmatrix記錄在接口之間進行路由選擇的分組的個 重定向報文。I網絡互連模型假定主機相對地并不知道整個互聯網的拓撲結構,把維護圖8-18路由器R1重定向主機HS使用路由器R2到達通常,管理員對主機的配置是:把到遠程網絡的分組發送到某個默認路由器上。在圖8-18中,主機S上1被配置成它的默認路由器。當S首次向HD發送分組時,它不知道2是合適的選擇,而把分組發給1。R1識別出差錯,就把分組轉發給2,并向HS發回一個重定向報S更新它的路由表,下一次發往H的分組就直接發給。RFC1122推薦只有路由器才發重定向報文,而主機在接收到ICMP重定向報文后必須更新它們的路由表(11.8節)。因為Net/3只在系統被配置成路由器時才調用ip_forward,所以Net/3采用RFC1122的推薦。915-929路由器識別重定向情況的規則很復雜。首先,只有在同一接口(rt_ifp和rcvif)上接收或重發分組時,才能應用重定向。其次,被選擇的路由本身必須沒有被ICMP重定向報文創建或修改過(RTF_DYNAMIC|RTF_MODIFIED),而且該路由也不能是到默認目的地的(0.0.0.0)。這就保證系統在末授權時不會生成路由選擇信息,并且不與其他系統共享自己的默認路由。通常,路由選擇協議使用特殊目的地址0.0.0.0定位默認路由。當到某目的地的某個路由不能使用時,與目的地0.0.0.0相關的路由就把分組定向到一個默認路由器上。全局整數ipsendredirects指定系統是否被授權發送重定向 (第8.9節)ipsendredirects的默認值為1。當傳給ip_forward的數srcrt指明系統是對分組路由選擇的源時,禁止系統重定向,因為假定源主機要覆蓋中間路由器的選擇。930-931 這個測試決定分組是否產生于本地子網。如果源地址的子網掩碼位和輸出接口的IP網絡中。如果源接口和輸出的接口位于同一網絡中,則該系統就不應該接收這個分組,因為源站可能已經把分組發給正確的第一跳路由器了。ICMP重定向報文告訴主機正確的第一跳目的地。如果分組產生于其他子網,則前一系統是個路由器,這個系統就不應該發重定向報文;差錯由路由選擇協議糾正。在任何情況下,都要求路由器忽略重定向報文。盡管如此,當被置位時(也就是說,當它被配置成路由器時),Net/3932-940ICMP重定向報文中包含正確的下一個系統的地址,如果目的主機不在直接相連的網絡上時,該地址是一個路由器的地址;當目的主機在直接相連的網絡中時,該地址是主機地址。RFC7924種類型:(1)(2)(3)TOS(4)TOS和主機。RFC1009推薦在任何時候都不發送網絡重定向報文,因為無法保證接收到重定向報文的主機能為目的網絡找到合適的子網掩碼。RFC1122推薦主機把網絡重定向看作是主機重定向,以避免二義性。Net3只發送主機重定向報文,并省略所有對TOS的考慮。在圖820圖8- 向很有用,但在一個子網化的互聯網中,由于重定向報文中沒有有關子網掩碼的信息,所以容易產生二義性。941-954ip_forward有一個路由,并決定是否需要ICMPIp_output把分組發送到路由ipforward_rt所指定的下一跳。IP_ALLOWBROADCAST標志位允許被轉發分組是個到某局域網的廣播。如果ip_output成功,并且不需要發送任何重定向報文,則丟掉分組的前64字節,ip_forward返回。955-983ip_forward可能會由于ip_output失敗或重定向而發送ICMP報文。如果沒有原始分組的復制()ip_forwardtype和code以前又被置位,但如果ip_outputswitch語句基于從ip_output返回的值重新設置新的ICMP類型和碼值。icmp_error發送該報文。來自失敗的ip_outputICMP報文將覆蓋任何重定向報文。處理來自ip_output的差錯的switch語句非常重要。它把本地差錯翻譯成適當的ICMP差錯報文,并返回給分組的源站。圖8-21對差錯作了總結。第11ICMP報當ip_output返回ENOBUFSNet/3通常生成ICMP源站抑制報文。RouterRequirements(路由器需求)RFC[Almquist和Kastenholz1994]不贊成源站抑制并要求路由器不產生這種報文。 IP輸出代碼從兩處接收分組:ip_forward圖81。讓inetsw0.pr_output能訪問到IP輸出操作似乎很有道理,但事實并非如此。標準的Internet傳輸協議(ICMP、IGMP、UDP和TCP)直接調用ip_output,而不查詢inetsw表。對標準Internet傳protosw結構不必具有一般性,因為調用函數并不是在與協議無關的情況下接入IP的。在第20pr_output接入IP。我們分三個部分描述ip_output:圖8-22顯示了ip_output(不 的到目的地的路由;flags,見圖8-23;imo,指向多播選項的指針,見第12章。IP_FORWARDING被ip_forward和ip_mforward圖8-22函數 圖8- send、sendto和sendmsg的MSG_DONTROUTE標志使IP_ROUTETOIF有效,并進行一次寫操作(見16.4),而SO_DONTROUTE插口選項使IP_ROUTETOIF有效,并在某個特定插口上進行任意的寫操作(見8.8節)。該標志被傳輸協議傳給ip_output。IP_ALLOWBROADCAST標志可以被SO_BROADCAST插口選項(見8.8節)設置,但只被UDP提交。原來的IP默認地設置IP_ALLOWBROADCAST。TCP不支持廣播,所以IP_ALLOWBROADCAST不能被TCP提交給ip_output。不存在廣播的預請求標志。構造IP 我們將在8.8節中看到,進程可以設置IP_OPTIONS插口選項來為一個插口指定IP選項。被轉發分組(IP_FORWARDING)或有預構首部(IP_RAWOUTPUT)分組的IP首部不能被ip_output修改。任何其他分組(UDP或TCP分組)需要有幾個IP首部字段被初始化。ip_output把ip_v設置成4IPVERSION),把DF位需要的ip_off清零,并設置成調用程序提供的值(見第10章),給來自全局整數的ip->ip_id賦一個唯一的標識符,把ip_id加1。ip_id(見7.8節)。ip_hl被設置成用32bit字度量的首部長度。IP首部的其他字段—長度、偏移、TL、協議、TOS和目的地址—已經被傳輸協議初(825。 對一個已轉發的分組(或一個有首部的原始IP分組),首部長度(以字節數度量)被保存在完成IP首部后,ip_output的下一個任務就是確定一條到目的地的路由。見圖8-24圖8-24ip_output(續圖8-24續77-99ip_output可能把一條在高速緩存中的路由作為ro參數來提供。在第24章中,我們將看到UDP和TCP維護一個與各插口相關的路由緩存。如果沒有路由,則ip_output把ro設如果高速緩存中的目的地不是去當前分組的目的地,就把該路由丟掉,新的目的地址放在dst中。100-114 IP_ROUTETOIF志(見8.8節)禁止對分組進行路由選擇。ip_output必須找到一個與分組中指定目的地網絡直接相連的接口。ifa_ifwithdstaddr搜索點到點接口,而in_ifwithnet搜索其他接口。如果任一函數找到與目的網絡相連的接口,就返回ENETUNREACH;否則,ifp統。通過這個方法,即使本地路由表不正確,也可以與其他路由器交換路由選擇信息。-2 如果分組正被路由選擇(IP_ROUTETOIF為關狀態c找到一條到指定地址的路由。如果沒找到路由,則ip_outpt回EHOSTUNREACH。如果ip_forward調用ip_output,就把EHOSTUNREACH差錯。如果某個傳輸協議調用,就把差錯傳回給進程(821。123-128ia被設成指向選定接口的地址(ifaddr結構),而ifp指向接口的ifnet結構。如果下一跳不是分組的最終目的地,則把dst改成下一跳路由器地址,而不再是分組最終目的地址。IP首部內的目的地址不變,但接口層必須把分組提交給dst,即下一跳路由器。ip_output的最后一部分如圖8-25所示,保證IP首部有一個有效源地址,然后把分組提交給與路由相關的接口。如果分組比接口的MTU大,就必須對分組分片,然后一片一片地發送。像前面的重裝代碼一樣,我們省略了分片代碼,并推遲到第10章再討論。圖8- 圖8-25續212-239 如果沒有指定ip_src,則ip_outpu選擇輸出接口的IP地址i作為源地址。這IP首部字段時做,因為那時還沒有選定路由。轉發的分組通常都有一個源地址,但是,如果發送進程沒有明確指定源地址,產生于本地主機的分組可能沒有源地址。如果目的IP地址是一個廣播地址,則接口必須支持廣播(IFF_BROADCAST,圖3-7)最后的測試是一個策略決定。IP協議規范中沒有明確禁止對廣播分組的分片。但是,要求分組適合接口的MTU,就增加了廣播分組被每個接口接收的機會,因為接如果這些條件都不滿足,就扔掉該分組,把EADDRNOTAVAIL、EACCES和EMSGSIZE返回給調用方。否則,設置輸出分組的M_BCAST,告訴接口輸出函數把該分組作為鏈路級廣播如果M_BCAST沒有清零,則對一個作為廣播到達的請求分組的應答將可能作為一個廣播被返回。我們將在第11章中看到,ICMP應答將以這種方式作為TCPRST分組(見26.9節)在請求分組內構造。 驗和與in_cksum(見8.7節)一起計算,把分組提交給所選接口的if_output函數。253- 大分組在被發送之前必須分片。這里我們省略這段代碼,推遲到第10339-34 ro為空,ipoutput可能會使用一個臨時的route結構(iproute)。如果需要,RTFREE發布iproute內的路由入口,并把引用計數減1。Bad處的代碼在返回前扔掉當前分組。引用計數是一個存儲器管理技術。程序員必須對一個數據結構的外部引用計數;當計數返回為0時,就可以安全地把存儲器返回給空存儲器池。引用計數要求程序員遵守一些規定,在恰當的時機增加或減小引用計數。Internet檢驗和:in_cksum([Kay和Pasquale1993])。mbuf數據結構的靈活性是Net/3中減少復制操作的主要方法。由于對硬件的依賴,所以檢驗和的有效計算相對較難。Net/3中有幾種in_cksum的實現(圖8-26)。 源文圖8-26在Net/3中的幾個in_cksum即使是可移植C實現也已經被相當好地優化了。RFC1071[Braden、Borman和Partridge1988]和RFC1141[Mallory和Kullberg1990]討論了Internet檢驗和函數的設計和實現。1141被RFC1624[Rijsinghani1994]修正。從RFC16bit的二進制反碼的和以及這個和的二進為檢驗檢驗和,對同一組字節計算它們的二進制反碼的和。如果結果為全1(在二進制0,見下面的解釋),則檢驗成功。簡而言之,當對用二進制反碼表示的整數進行加法運算時,把兩個整數相加后再加上進位就得到加法的結果。在二進制反碼運算中,只要把每一位求補就得到一個數的反。所以在0有兩種表示方法:全0,和全1。有關二進制反碼的運算和表示的詳細討論見[Mano1982]。檢驗和算法在發送分組之前計算出要放在IP首部檢驗和字段的值。為了計算這個值,先把首部的檢驗和字段設為0,然后計算整個首部(包括選項)的二進制反碼的和。把首部作為一個16bit整數數組來處理。讓我們把這個計算結果稱為a。因為檢驗和字段被明確設為0,所以a是除了檢驗和字段外所有IP首部字段的和。a的二進制反碼,用-a表示,被放在檢驗和字段如果在傳輸過程中沒有比特位被改變,則在目的地計算的檢驗和應該等于(a+-a)的二進制反碼。在二進制反碼運算中(a+-a)的和是-0(全1),而它的二進制反碼應該等于0(全0)。所以在目的地,一個沒有損壞分組計算出來的檢驗和應該總是為0。這就是我們在圖8-12中看到圖8-27IP1-16這里唯一提高性能之處在于累計sum高16bit的進位。當循環結束時,累計的進位被加在低16bit上,直到沒有其他進位發生。RFC1071稱此為延遲進位(deferredcarries)。在沒現在我們顯示Net/3的可移植C版本。它使用了延遲進位技術,作用于存儲在一個mbuf鏈中42-140mbufmbuf:用32bit整數的延遲進位對16bit字作加法。對奇數個字節的mbufmbuf的第一個字節配對。因為在大多數體系結構中,對16bit字的不對齊訪問是無效的,甚至會產生嚴重差錯,in_cksum繼續加上下一個對齊的字。當這種情況發生時,in_cksum總是很小心地交換字節,保證位于奇數和偶數位置的字節被放在單獨的和字節中,以滿足檢驗和算法的要求。93-115函數中的三個while16個字、4個字和1開的循環減小了循環的耗費,在某些體系結構中可能比一個直接循環要快得多。但代價是代碼長度和復雜性增大。圖8- IP檢驗和計算的一個優化的可移植C程圖8-28(續圖8-28續RFC1071提到兩個在Net/3中沒有出現的優化:聯合的有檢驗和的復制操作和遞增的檢驗和更新。對IP首部檢驗和來說,把復制和檢驗和操作結合起來并不像對TCP和UDP那么重要,因為后者覆蓋了更多的字節。在23.12[Partridge和Pink1993]報告了IP首部檢驗和的一個內聯版本比調用更一般的in_cksum函數要快得多,只需6~8個匯編指令就可以完成(標準的20字節IP首部)檢驗和算法設計允許改變分組,并在不重新檢查所有字節的情況下更新檢驗和。RFC1071對該問題進行簡明的討論。RFC1141和1624中有更詳細的討論。該技術的一個典型應用是在分組轉發的過程中。通常情況下,當分組沒有選項時,轉發過程中只有TTL字段發生變為了進一步提高效率,遞增的檢驗和也有助于檢測到被有差錯的軟件破壞的首部。如果遞增地計算檢驗和,則下一個系統可以檢測到被破壞的首部。但是如果不是遞增計算檢驗和,那么檢驗和中就包含了差錯的字節,檢測不到有問題的首部。UDP和TCP使用的檢驗和算法在最終目的主機檢測到該差錯。我們將在第23和25章看到UDP和TCP檢驗和包含了IP首部的32bit檢驗和的檢驗和函數,可參見sysvax/Net/3提供setsockopt和getsockopt兩個系統調用來訪問一些網絡互連的性質。這兩個系統調用支持一個動態接口,進程可用該動態接口來訪問某種網絡互連協議的一些性質,而標準系統調用通常不支持該協議。這兩個調用的原型是:intsetsockopt(ints,intlevel,intoptname,void*optval,intintgetsockopt(ints,intlevel,intoptname,constvoid*optval,int大多數插口選項只影響它們在其上發布的插口。與l參數相比,后者影響整個系統。setsockopt和getsockopt設置和獲取通信棧所有層上的選項。Net/3按照與s相關的論有關選項的實現。本章討論訪問IP 我們把本書中出現的所有插口選項總結在圖8-30中。該圖顯示了IPPROTO_IP級的選項。1optval指向變量的數據類型出現在第2列,第3列顯示的是處理該選項的選項名函數描述設置或獲取發出的數據報中的IPTOS設置或獲取發出的數據報中的IPTTL(只對UDP;還沒有實現32.8節中我們給出與SOCK_RAW插口一起使用的IPPROTO_IP431-447ip_ctloutput的第一個參數op,可以是PRCO_SETOPT或者PRCO_GETOPT。第二索的選項,m
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
評論
0/150
提交評論