TCP IP網(wǎng)絡(luò)數(shù)據(jù)流向分析_第1頁
TCP IP網(wǎng)絡(luò)數(shù)據(jù)流向分析_第2頁
TCP IP網(wǎng)絡(luò)數(shù)據(jù)流向分析_第3頁
TCP IP網(wǎng)絡(luò)數(shù)據(jù)流向分析_第4頁
TCP IP網(wǎng)絡(luò)數(shù)據(jù)流向分析_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

TCP/IP網(wǎng)絡(luò)數(shù)據(jù)流向分析茍先太[概述本分析主要關(guān)心接II層和協(xié)議層(網(wǎng)絡(luò)層和傳輸層)的數(shù)據(jù)流向,并主要針對IP協(xié)議族。對于其它協(xié)議在接口層以下的實現(xiàn)基本是相同的。2IP數(shù)據(jù)流的基本流向用戶用戶用戶1用戶1進(jìn)程1進(jìn)程進(jìn)程進(jìn)程1應(yīng)用層傳輸層UDPTCPICMP? ?用戶用戶用戶1用戶1進(jìn)程1進(jìn)程進(jìn)程進(jìn)程1應(yīng)用層傳輸層UDPTCPICMP? ?M"AIPipmtr() ip_outpi|t()IGMP網(wǎng)絡(luò)層接II層ARPaipintr()ipmtrq輸出接口隊列l(wèi)Ondsc_fhstqlestartO、slstartQ軸入接口隊列aipmuq\ether_niput()xslmputQ\硬件接口If_output(ethei_output或sloutput)、t^oprocQ媒體從上面的雙箭頭線,可以看出輸入、輸出(進(jìn)/出)數(shù)據(jù)在本地網(wǎng)結(jié)里的大概流向,此處無須繁敘。為了在討論時便于溝通,我們先在這里認(rèn)識幾個基本概念。鏈路層、接II層、硬件(有時沒有,如SLIP、PPP、IPLoopback)+網(wǎng)絡(luò)接I1+設(shè)備驅(qū)動程序,在不同的書上或不同地方叫法有些差別,我認(rèn)為它們在IP協(xié)議族里可以說是一個東西,都是IP以下的東西,實現(xiàn)對物理層的數(shù)據(jù)收發(fā)和對網(wǎng)絡(luò)層數(shù)據(jù)的輸入、輸出??戳嗽创a后,感覺if(interface)用得特別多,所以我們統(tǒng)一用接II層來描述好了。統(tǒng)一說話,省得在討論時一會說鏈路層,一會兒說驅(qū)動程序(并有時還認(rèn)為驅(qū)動程序不是鏈路層或不是接11層)等等。為了便于深刻認(rèn)識,給出下面簡單的定義:接口層:在本地網(wǎng)上發(fā)送和接受分組的硬件和軟件,它包括網(wǎng)絡(luò)硬件,有時沒有,如SLIP(為TTY電傳機虛設(shè)備)、PPP、環(huán)回便只有接口沒有硬件網(wǎng)結(jié)接II,指在硬件設(shè)備和驅(qū)動程序之間的接II設(shè)備驅(qū)動程序,和網(wǎng)絡(luò)層直接作用。接口函數(shù):屬于接II的用以完成接II初始化、數(shù)據(jù)處理等功能的函數(shù)。一般行如if.init,if_start,if_output,以if開頭并在接「I結(jié)構(gòu)里面定義的函數(shù)。輸入:數(shù)據(jù)從下層(物理層)往上層流向。輸出:數(shù)據(jù)從上層往下層(物理層)流向。對此認(rèn)識有限,歡迎指正。3輸入3.1接口層的輸入3.1.1認(rèn)識接口在進(jìn)行接II輸入之前,我們先認(rèn)識接II。我們只從和數(shù)據(jù)流有關(guān)的地方進(jìn)行簡單認(rèn)識。接II作為系統(tǒng)內(nèi)核的一部分,和系統(tǒng)一起初始化,(在sys/keriiliucmam.c里面完成)。為了便于對各種接II的統(tǒng)一管理,在if.h里為接II定義了通用的數(shù)據(jù)結(jié)構(gòu)ifhet和ifqueue,ifnet完成對接II的描述和對接II的管理,ifqueue里面存放接II需要操作的數(shù)據(jù)對象。Ifqueue結(jié)構(gòu)stiuctifqueue{stmctmbuf*ifq__head;stmctmbufmtifqjen;mtifq_maxlen;mtifq_drops;};這便是接I】里最著名的ifqueue接II隊列。在輸入的時候它作為IP的輸入隊列,名叫ipintrq,由ip_iiiput從里面讀取mbuf;輸出的時候叫iflsnd,由ip_output調(diào)用if_output回調(diào)函數(shù)往隊列里面插入。Ifiiet結(jié)構(gòu)structifiiet{char *if_name; 接「I名標(biāo)明接「I類型,比如en或者lostmct ifiiet*if_next; 用以連接所有接II的ifhet結(jié)構(gòu)*/stmctifaddr*if_addilist;每個接II支持的地址列表*/stmctifLdataif_data;接II的統(tǒng)計數(shù)據(jù)等信息*/

mt(mtunit);接II初始化函數(shù)*/mt(*ifLoutput)將傳輸?shù)姆纸M進(jìn)行排隊到iflsnd隊列mt(*if_stait)對接II的向物理層輸出進(jìn)行初始化,并啟動輸出stmctifqueueif_snd;接11輸出隊列ifnet是接II的核心數(shù)據(jù)結(jié)構(gòu),它包含接II的所有通用信息。每個接II都有一個】fhet表,系統(tǒng)所有的】fhet表連在一起形成ifiiet鏈表,以便系統(tǒng)的統(tǒng)一管理。3.1.2FreeBSD以太網(wǎng)接口輸入以以太網(wǎng)為例進(jìn)行說明其處理步驟:系統(tǒng)網(wǎng)絡(luò)初始化,cpu.startup()查照并初始化所有連接到系統(tǒng)的硬件設(shè)備,包括網(wǎng)絡(luò)接II初始化虛設(shè)備,如SLIP和環(huán)回接口的偽設(shè)備。調(diào)用pdevinit數(shù)組的每個pdev_attach0完成。ifinit()完成網(wǎng)絡(luò)接II的初始化。為接I】生成一個專用化ifnet結(jié)構(gòu),調(diào)用attach把其掛入接II鏈表。對以太網(wǎng)來說,調(diào)用if_attach,其專用的ifnet結(jié)構(gòu)叫l(wèi)e_softco數(shù)據(jù)來到接II,接II接收到一個完整的以太網(wǎng)幀時,接II產(chǎn)生中斷,Mintr被調(diào)用。leintr()檢測硬件,并旦如果有一個完整的以太網(wǎng)幀,就調(diào)用lereadOolereadO用m_devget()把這個幀從接「I移到mbuf鏈。ether.input()處理這個mbuf鏈,既一個分組。并將接收到的分組加入到接II隊列。具體實現(xiàn)為調(diào)用鏈路層分用函數(shù)do_protocol_with_type(type,pMbuf,&pDrvCtrl->idr,len)函數(shù),它根據(jù)以太網(wǎng)類型字段來進(jìn)行入隊和跳轉(zhuǎn)。確定隊列:caseETHERTYPE_IP:netlsr=NETISR.IP;IP輸入隊列arp輸入隊列inqIP輸入隊列arp輸入隊列break;caseETHERTYPE_ARP:netlsr=NETISR.ARP;inq=&arpintrq;break;分組入隊:spl=splimpO;把CPU的優(yōu)先級升到網(wǎng)絡(luò)設(shè)備驅(qū)動程序級if(IF_QFULL(inq))如果隊列滿就丟棄該分組IF_DROP(inq);m_freem(pMbuf);else否則就入隊

elseIF_ENQUEUE(inq,pMbuf):schednetisr(netlsr);sqlnet級別的軟中斷,不一定馬上執(zhí)行,因為CPU還沒有退出splimpsplx(spl);splx(spl);}將CPU的優(yōu)先級恢復(fù)到調(diào)用前的級別。如果該分組是IP分組,則schednetisr調(diào)用IP軟件中斷,并選擇IP輸入隊列ipintrq進(jìn)行處理。如果該分組是ARP分組,則schednetisr調(diào)用ARP軟件中斷,并選擇ARP輸入隊列arpintrq進(jìn)行處理。s到此,接口層完成輸入數(shù)據(jù)的處理。上面用到CPU的級別,一般是這樣確定網(wǎng)絡(luò)函數(shù)的運行級別:終端設(shè)備spltty級,當(dāng)終端設(shè)備的中斷發(fā)生時執(zhí)行??伞鲆該屨季W(wǎng)絡(luò)層協(xié)議以上的執(zhí)行級別.splimp接II層執(zhí)行級別,可以搶占網(wǎng)絡(luò)層協(xié)議以上的執(zhí)行.Spinet,網(wǎng)絡(luò)層、傳輸層執(zhí)行。SqlO,插II(socket)層執(zhí)行?3.2IP的輸入ip輸入由ipmti-()來完成:由ipintlt通數(shù)循環(huán)從接II層的IP輸入隊列ipintrq里讀取分組(獲得mbuf指針),直到為空:next: 循環(huán)s=splimp0; 防止在讀時發(fā)生ether^input或siinput執(zhí)行。IF_DEQUEUE(&ipintrq,m);讀出一個分組splx(s); 恢復(fù)CPU級別gotonext對于每個讀到的分組,進(jìn)行驗證是否丟棄。不丟棄的用ip.dooptions處理IP選項。選項處理完后,拿出IP首部的ip_dst和本地所有的接II地址(包括接II的broadcast.multicast、unicast)進(jìn)行比較,具體通過遍歷m_ifaddr地址表,查看其是否為本地分組。如果不是本地分組,看本地網(wǎng)是否設(shè)置ipfonvard,若沒有則丟棄它,若有則把分組路由到它的最終目的地。如果是本地分組,則需要進(jìn)行重新裝載的就ipReAssembleo完成后,用ip_protox進(jìn)行分用,及給相應(yīng)的傳輸層處理。(*inetsw[ip_protox[ip->ip_p]].pr_mput)(m,hlen);因為傳輸層的處理在ipintr的循環(huán)內(nèi)處理,所以網(wǎng)絡(luò)層和傳輸層之間沒有隊列存在。因為我們主要是做網(wǎng)絡(luò)設(shè)備開發(fā),所以輸入操作的分析暫時到此為止。3輸出3.1IP輸出ip_output傳輸層的tcp_outputQ和udp_output()都調(diào)用ip_output()進(jìn)行輸出。ip_output()使用回調(diào)函數(shù)ifloutput,完成輸出操作。調(diào)用形式為:(*ifp->if_output)(ifp,nL(structsockaddr*)dst,ro->io_rt);3.2接口層輸出3.2.1FreeBSD以太網(wǎng)的輸出欲輸出分組進(jìn)行屆接「1隊列入隊。以太網(wǎng)接口的iLoutput回調(diào)函數(shù)為ether_output()o入隊操作如下:s=splimp();if(IF_QFULL(&ifp->ifLsnd))(IF_DROP(&ifp->iOnd);splx(s);senden(ENOBUFS);}IF_ENQUEUE(&i^)->if_snd.m);將mbuf掛到接IIif_snd隊列&IFF_OACTIVE)=0)(*ifp->ifLstail)(ifp); @調(diào)用iflstart啟動輸出splx(s);從接II隊列里取出排隊的幀。從上面注有@標(biāo)記的行可以看出在ethei_ouput函數(shù)里放入一個分組后,馬上通過接「I的iflstart函數(shù)調(diào)用lestait啟動輸出操作。Lestail從隊列里取出一個幀,調(diào)用leput進(jìn)行發(fā)送。322路由器以太網(wǎng)的輸出分析到此,覺得FreeBSD和路由器在以太網(wǎng)接II的處理上差別多多,所以又專們看了路由器的以太網(wǎng)輸出處理,分析如下:欲輸出分組進(jìn)行入接II隊列。以太網(wǎng)接II的iCoutput回調(diào)函數(shù)由ipoutputQ實現(xiàn)真正的操作。參看ipProto.c語句:

pIfp->ifLoutput=ipOutput;在ipOutput()的入隊操作如下:s=spliinpO;if(IF_QFULL(&ifp->if_snd))(IF_DROP(&ifp->ifLsnd);splx(s);senden(ENOBUFS);}IF_ENQUEUE(&i^)->if_snd.m);將mbuf掛到接IIif_snd隊列if((ifp->iflflags&IFF_OACTIVE)=0)(*ifp->ifLstait)(ifp); @調(diào)用iflstart啟動輸出splx(s);從接II隊列里取出排隊的幀。從上面注有@標(biāo)記的行可以看出在ipouput()函數(shù)里放入―個分組后,馬上通過接II的ifLstart()。在mprliiterface.c里面接II初始化時,使用if(ipAttach(pCookie->devObject.unit,pCookie->devO)!=OK){)語句調(diào)用ipAttach()函數(shù)將if_start替換為ipTxStartupopDivCtrl->idr.ac_if.iflstait=(FUNCPTR)ipTxStaitup即以太網(wǎng)接II使用ipTxStamipO啟動發(fā)送操作。IpTxStamipQ執(zhí)行循環(huán)直到把iflsnd里面的所有包發(fā)送出去,實現(xiàn)如下:while(pDrvCtrl->idr.ac_if?ijsnd.ifqjiead)(IF_DEQUEUE(&pDivCtrl->idr.ac_if.ifLsnd.pMblk);從ifLsnd里取出1個if((etlierOutputHookRtn!=NULL)&&(*etlierOutputHookRtn)(&pDivCtrl->idi\(stnictether_header*)pMblk->m_data,pMblk->mJen))(continue;ijstatus=muxSend(pDrvCtrl.>pIpCookie,pMblk);調(diào)用muxSend進(jìn)行進(jìn)一步處理。++pDrvCtrl->idr.ac_if.if^opackets;)muxSend()調(diào)用pEnd接II函數(shù)表里的send函數(shù)進(jìn)行發(fā)送。(muxSend并沒有把數(shù)據(jù)真正的發(fā)送到線路上,而是放在了BD中或它自己的隊列上(繁忙時)。實現(xiàn)由pEnd->pFuncTable->send(pEnd,pNBuff)完成弓)由驅(qū)動程序的函數(shù)表里的send。函數(shù)完成線路輸出操作。在整個接口層的操作中有兩個隊列存在。323,由器廣域網(wǎng)口的輸出323,由器廣域網(wǎng)口的輸出針對HDLC協(xié)議,只從函數(shù)調(diào)用和數(shù)據(jù)流作簡單說明。輸出過程如下:1)執(zhí)行回調(diào)函數(shù)ifloutputo注意:此處并不進(jìn)行接口隊列入隊,由ChdlcDataFromUpper替換ifloutput回調(diào)函數(shù):i^)->ifLoutput=ChdlcDataFromUppero在ChdlcDataFromUpper里面調(diào)用Chdl

溫馨提示

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

最新文檔

評論

0/150

提交評論