路由器網路中資料包傳輸分析

clown_發表於2016-10-15

  本篇介紹一個基礎的知識,關於資料包在路由器中是如何進行傳輸和交換的,只要明白這點,那麼對你配置出一個好的網路環境會有很大的幫助。

  一、輸入的問題

  1、原始套介面可以接收到任何TCP或UDP報文。

  2、要想接收到原始套介面,首先要接收的資料包必須有一個完整的、正確的IP頭,否則不能透過ip_rcv()中的包頭檢查和檢驗和驗證。

  3、在原始套介面接收的資料包過程中,核心會對接收的IP包進行校驗和驗證,但不會對IP包以後的任何欄位進行檢測和驗證。如,我們建立原始套介面時,所指定的protocol引數為IPPROTO_TCP,核心也不會進行TCP校驗和驗證,而是直接把IP頭中協議欄位為TCP的所有資料包都複製一份,提交給該原始套介面。

  4、用原始套介面接收到的TCP包都是進行了IP重組以後,TCP排序以前的報文。

  5、如果在建立原始套介面時,所指定的protocol引數不為零,(socket的第三個引數),則接收到的資料包的協議欄位應該與之匹配。否則該資料包不傳遞給該套介面。

  6、如果此原始套介面上繫結了一個本地IP地址,那麼接收到的資料包的目的IP地址應該與該繫結的IP地址相匹配,否則該資料包將不傳遞到該套介面。

  7、如果此原始套介面透過connect指定了一個對方IP地址,那麼接收到的資料包的源IP地址應與該以連線地址相匹配,否則該資料包不傳遞給該套介面。

  8、如果一個原始套介面以protocol引數為0的方式建立,並且未呼叫connect或bind,那麼對於核心傳遞給原始套介面的每一個原始資料包,該套介面都會收到一份複製。

  9、原始套介面接收不到任何的ARP或RARP協議型別的套介面,因為net_rx_action()會把ARP或RARP協議型別的資料包傳遞給ARP的接收函式類處理,不會傳遞給IP層的接收函式ip_rcv()。

  10、原始套介面並不是可以接收到任何的ICMP型別的資料包,因為有些ICMP型別的資料包在傳遞給原始套介面之前已經被系統所響應,並不再向上層傳遞。

  11、如果對方的資料包分片了,由於原始套介面的接收是在IP上層,所以會接收到重組以後的原始IP包。

  二、輸出的問題

  1、普通輸出通常透過sendto或sendmsg並指定目的IP地址來完成,如果套介面已經連線,也可以呼叫write、writev或send。

  2、如果IP_HDRINCL選項未設定,則核心寫的資料起始地址是IP頭部之後的第一個位元組。因為這種情況下,核心將構造IP頭部,並將它安在來自程式資料之前。核心將IPv4頭部的協議欄位設定成使用者在呼叫socket函式時所給的第三個引數。

  3、如果IP_HDRINCL選項已設定,則核心寫的資料其實地址是IP頭部的第一個位元組。使用者所提供的資料必須包括IP頭部。此時程式構造除了以下兩項以外的整個IP頭部:IPv4標示欄位可以設為0,要求核心設定該值。而且僅當該欄位為0時,核心才為其設定,IPv4頭部校驗和由核心來計算和儲存。

  4、如果建立原始套介面時指定了協議型別,即第三個引數protocol,那也並不是說只能發該型別的資料包。如,即使將protocol指定為 IPPROTO_TCP,也可以傳送使用者自己組裝的UDP報文,不過此時如果IP_HDRINCL選項未設定,那麼核心將會在IP頭的協議欄位指明後面的報文為TCP報文(不過此時卻為UDP報文)。

  等資料包傳送到對方TCP層,一般說來會因為找不到合適的TCP套介面接收該資料包而被丟棄。不過該包可以在目標主機的原始套介面上接收到。

  5、正如前面所述,任何時候,IP頭的校驗和都是由核心來設定的。

  6、核心任何時候那會都不會對IP包以後的欄位進行校驗和驗證。如,即使我們指定第三個引數protocol為IPPROTO_TCP,在資料傳送時核心也不會對進行TCP校驗和計算和驗證。

  7、如果IP_HDRINCL選項已設定,按照常規,我們應該組建自己的IP頭,但是即使我們沒有組建IP頭,用sendto或sendmsg 並指定目的IP地址來傳送資料是照樣可以完成的。但是這樣的資料包在目標機上用原始套介面是接收不到的,因為在ip_rcv()中要對IP頭進行驗證,並且要分析校驗和,所以該包會被丟棄,不過在鏈路層應該能夠接收到該資料包。

  8、如果設定了IP_HDRINCL選項,並且資料包超長,那麼資料會被丟棄,並會返回出錯碼EMSGSIZE。如果未設定IP_HDRINCL選項,並且資料包超長,那麼資料包會被分片。

  正是因為資料包具上述的結構,安裝了TCP/IP協議的電腦之間才能相互通訊,在使用基於TCP/IP協議的網路時,網路中其實傳遞的就是資料包。

相關文章