現(xiàn)在Internet使用的主流協(xié)議族是TCP/IP協(xié)議族,它是一個(gè)分層、多協(xié)議的通信體系。
TCP/IP協(xié)議族包含眾多協(xié)議,我們只詳細(xì)討論IP協(xié)議和TCP協(xié)議,因?yàn)樗鼈儗?duì)編寫網(wǎng)絡(luò)應(yīng)用程序有最直接的影響。如果想系統(tǒng)學(xué)習(xí)網(wǎng)絡(luò)協(xié)議,RFC(Request For Comments,評(píng)論請(qǐng)求)是首選資料。
TCP/IP協(xié)議族是一個(gè)四層協(xié)議系統(tǒng),自底而上分別是數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、應(yīng)用層。每層完成不同功能,且通過若干協(xié)議來實(shí)現(xiàn),上層協(xié)議使用下層協(xié)議提供的服務(wù):
數(shù)據(jù)鏈路層實(shí)現(xiàn)了網(wǎng)卡接口的網(wǎng)絡(luò)驅(qū)動(dòng)程序,以處理數(shù)據(jù)在物理媒介上的傳輸,不同的物理網(wǎng)絡(luò)具有不同的電氣特性,網(wǎng)絡(luò)驅(qū)動(dòng)程序隱藏了這些細(xì)節(jié),為上層協(xié)議提供一個(gè)統(tǒng)一的接口。
數(shù)據(jù)鏈路層常用的兩個(gè)協(xié)議是ARP協(xié)議(Address Resolve Protocol,地址解析協(xié)議)和RARP協(xié)議(Reverse Address Resolve Protocol,逆地址解析協(xié)議),它們實(shí)現(xiàn)了IP地址和機(jī)器物理地址(通常是MAC地址,以太網(wǎng)、令牌環(huán)、802.11無線網(wǎng)絡(luò)都使用MAC地址)之間的相互轉(zhuǎn)換。
網(wǎng)絡(luò)層使用IP地址尋址一臺(tái)機(jī)器,而數(shù)據(jù)鏈路層使用物理地址尋址一臺(tái)機(jī)器,因此網(wǎng)絡(luò)層必須先將目標(biāo)機(jī)器的IP地址轉(zhuǎn)換成其物理地址,才能使用數(shù)據(jù)鏈路層提供的服務(wù),這就是ARP協(xié)議的用途。RARP協(xié)議僅用于網(wǎng)絡(luò)上的某些無盤工作站,因?yàn)槿狈Υ鎯?chǔ)設(shè)備,無盤工作站無法記住自己的IP地址,但它們可以利用網(wǎng)卡上的物理地址來向網(wǎng)絡(luò)管理者(如服務(wù)器或網(wǎng)絡(luò)管理軟件)查詢自身IP地址。運(yùn)行RARP服務(wù)的網(wǎng)絡(luò)管理者通常存有該網(wǎng)絡(luò)上所有機(jī)器的物理地址到IP地址的映射。
網(wǎng)絡(luò)層實(shí)現(xiàn)數(shù)據(jù)包的選路和轉(zhuǎn)發(fā)。。WAN(Wide Area Network,廣域網(wǎng))通常使用眾多分級(jí)的路由器來連接分散的主機(jī)或LAN(Local Area Network,局域網(wǎng)),因此,通信的兩臺(tái)主機(jī)一般不是直接相連的,而是通過多個(gè)中間節(jié)點(diǎn)(路由器)連接的。網(wǎng)絡(luò)層的任務(wù)就是選擇這些中間節(jié)點(diǎn),以確定兩臺(tái)主機(jī)之間的通信路徑。同時(shí),網(wǎng)絡(luò)層對(duì)上層隱藏了網(wǎng)絡(luò)拓?fù)溥B接的細(xì)節(jié),使得在傳輸層和網(wǎng)絡(luò)應(yīng)用程序看來,通信的雙方是直接連接的。
網(wǎng)絡(luò)層最核心的是IP協(xié)議(Internet Protocol,因特網(wǎng)協(xié)議),IP協(xié)議根據(jù)數(shù)據(jù)包的目的IP地址來決定如何投遞它。如果數(shù)據(jù)包不能直接發(fā)送給目標(biāo)主機(jī),那么IP協(xié)議就為它尋找一個(gè)合適的下一跳(next hop)路由器,并將數(shù)據(jù)包交付給該路由器來轉(zhuǎn)發(fā),多次重復(fù)這一過程,直到數(shù)據(jù)包到達(dá)目的主機(jī),或由于發(fā)送失敗而被丟棄。IP協(xié)議通過逐跳(hop by hop)方式確定通信路徑。
網(wǎng)絡(luò)層另一個(gè)重要的協(xié)議是ICMP協(xié)議(Internet Control Message Protocol,因特網(wǎng)控制報(bào)文協(xié)議),它是IP協(xié)議的補(bǔ)充,用于檢測(cè)網(wǎng)絡(luò)連接。ICMP協(xié)議使用的報(bào)文格式如下圖:
其中8位類型字段用于區(qū)分ICMP報(bào)文類型,ICMP報(bào)文分為兩大類:
1.差錯(cuò)報(bào)文,主要用來回應(yīng)網(wǎng)絡(luò)錯(cuò)誤,如目標(biāo)不可到達(dá)(類型為3)、重定向(類型為5)。
2.查詢報(bào)文,用來查詢網(wǎng)絡(luò)信息。
有的ICMP報(bào)文類型還用8位代碼字段來進(jìn)一步細(xì)分,如重定向報(bào)文用值為0的8位代碼字段表示對(duì)網(wǎng)絡(luò)重定向,用代碼值為1的8位代碼字段表示對(duì)主機(jī)重定向。
ICMP報(bào)文使用16位校驗(yàn)和對(duì)整個(gè)報(bào)文(頭部+內(nèi)容)進(jìn)行循環(huán)冗余校驗(yàn)(Cyclic Redundancy Check,CRC),以檢驗(yàn)報(bào)文在傳輸過程中是否損壞。此處作者說ICMP校驗(yàn)和是通過CRC完成的,但實(shí)際上計(jì)算過程與IP首部的過程相同,并非CRC。
不同的ICMP報(bào)文類型有不同的正文內(nèi)容,ICMP報(bào)文格式參考RFC 792。
ICMP協(xié)議并非嚴(yán)格意義上的網(wǎng)絡(luò)層協(xié)議,因?yàn)樗褂锰幱谕粚拥腎P協(xié)議提供的服務(wù)(一般來說,上層協(xié)議使用下層協(xié)議)。
傳輸層為兩臺(tái)主機(jī)上的應(yīng)用程序提供端到端(end to end)的通信,傳輸層只關(guān)心通信的起始端和目的端,不在乎數(shù)據(jù)包的中轉(zhuǎn)過程:
上圖中垂直的實(shí)線箭頭表示TCP/IP協(xié)議族各層之間的實(shí)體通信,而水平的虛線箭頭表示邏輯通信線路。可見數(shù)據(jù)鏈路層(驅(qū)動(dòng)程序)封裝了物理網(wǎng)絡(luò)的電氣細(xì)節(jié);網(wǎng)絡(luò)層封裝了網(wǎng)絡(luò)連接的細(xì)節(jié);傳輸層則為應(yīng)用程序封裝了一條端到端的邏輯通信鏈路,它負(fù)責(zé)數(shù)據(jù)的收發(fā)、超時(shí)重連等。
傳輸層協(xié)議主要有3個(gè):
1.TCP協(xié)議(Transmission Control Protocol,傳輸控制協(xié)議):為應(yīng)用層提供可靠的、面向連接的、基于流的服務(wù)。TCP協(xié)議使用超時(shí)重傳、數(shù)據(jù)確認(rèn)等方式確保數(shù)據(jù)包被正確地發(fā)送到目的端,因此TCP服務(wù)是可靠的。使用TCP協(xié)議通信的雙方必須先建立TCP連接,并在內(nèi)核中為該連接維持一些必要的數(shù)據(jù)結(jié)構(gòu),如連接的狀態(tài)、讀寫緩沖區(qū)、定時(shí)器等。當(dāng)通信結(jié)束時(shí),雙方必須關(guān)閉連接以釋放這些內(nèi)核數(shù)據(jù)。TCP服務(wù)是基于流的,因此數(shù)據(jù)沒有邊界,它源源不斷從通信的一端流入另一端。發(fā)送端可以逐個(gè)字節(jié)地向數(shù)據(jù)流中寫入數(shù)據(jù),接收端也可以逐個(gè)字節(jié)地將它們讀出。
2.UDP協(xié)議(User Datagram Protocol,用戶數(shù)據(jù)報(bào)協(xié)議):為應(yīng)用層提供不可靠、無連接、基于數(shù)據(jù)報(bào)的服務(wù)。不可靠意味著UDP協(xié)議無法保證數(shù)據(jù)從發(fā)送端正確地傳送到目的端,如果數(shù)據(jù)在中途丟失,或目的端通過數(shù)據(jù)校驗(yàn)發(fā)現(xiàn)數(shù)據(jù)錯(cuò)誤而將其丟棄,則UDP協(xié)議只是簡(jiǎn)單地通知應(yīng)用程序發(fā)送失?。ㄗ髡叽颂幍谋硎鰬?yīng)該指的是已連接UDP套接字),因此使用UDP協(xié)議的應(yīng)用程序通常要自己處理數(shù)據(jù)確認(rèn)、超時(shí)重傳等邏輯。UDP協(xié)議是無連接的,即通信雙方不保持一個(gè)長(zhǎng)久的聯(lián)系,因此應(yīng)用每次發(fā)送數(shù)據(jù)都要指定接收端地址。每個(gè)UDP數(shù)據(jù)報(bào)都有一個(gè)長(zhǎng)度,接收端必須以該長(zhǎng)度為最小單位將其所有內(nèi)容一次性讀出,否則數(shù)據(jù)將被截?cái)?,只能讀取部分?jǐn)?shù)據(jù),剩余數(shù)據(jù)將丟失。
3.SCTP協(xié)議(Stream Control Transmission Protocol,流控制傳輸協(xié)議):是一種較新的傳輸層協(xié)議,它起初是為了在因特網(wǎng)上傳輸電話信號(hào)而設(shè)計(jì)的。
應(yīng)用層負(fù)責(zé)處理應(yīng)用程序的邏輯。數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層負(fù)責(zé)處理網(wǎng)絡(luò)通信細(xì)節(jié),這部分必須穩(wěn)定高效,因此它們都在內(nèi)核空間中實(shí)現(xiàn),而應(yīng)用層則在用戶空間實(shí)現(xiàn),因?yàn)樗?fù)責(zé)眾多邏輯,如文件傳輸、名稱查詢、網(wǎng)絡(luò)管理等,如果應(yīng)用層也實(shí)現(xiàn)在內(nèi)核中,會(huì)使內(nèi)核變得非常大。也有少數(shù)服務(wù)器程序是實(shí)現(xiàn)在內(nèi)核中的,這樣代碼就無須在用戶空間和內(nèi)核空間中來回切換(主要是數(shù)據(jù)的復(fù)制),極大地提升了工作效率,但這種代碼實(shí)現(xiàn)起來復(fù)雜,不夠靈活,且不便于移植,我們只討論用戶空間的網(wǎng)絡(luò)編程。
應(yīng)用層例子:
1.ping程序:它不是協(xié)議,它利用ICMP報(bào)文檢測(cè)網(wǎng)絡(luò)連接,調(diào)試網(wǎng)絡(luò)環(huán)境。
2.telnet協(xié)議:它是一種遠(yuǎn)程登錄協(xié)議,使我們能在本地完成遠(yuǎn)程任務(wù)。
3.OSPF(Open Shortest Path First,開放最短路徑優(yōu)先)協(xié)議:它是一種動(dòng)態(tài)路由更新協(xié)議,用于路由器之間的通信,以告知對(duì)方各自的路由信息。
4.DNS(Domain Name Service,域名服務(wù))協(xié)議:本協(xié)議提供機(jī)器域名到IP地址的轉(zhuǎn)換。
應(yīng)用層協(xié)議或程序可能跳過傳輸層直接使用網(wǎng)絡(luò)層提供的服務(wù),如ping程序和OSPF協(xié)議。應(yīng)用層協(xié)議或程序可以既使用TCP又使用UDP,如DNS協(xié)議。我們可通過/etc/services文件查看所有知名的應(yīng)用層協(xié)議,以及它們都使用哪些傳輸層服務(wù)。
通過封裝(encapsulation),上層協(xié)議能使用下層協(xié)議提供的服務(wù),應(yīng)用程序的數(shù)據(jù)在發(fā)送到物理網(wǎng)絡(luò)前,將沿著協(xié)議棧從上往下依次傳遞,每層協(xié)議都將在上層數(shù)據(jù)的基礎(chǔ)上加上自己的頭部信息(有時(shí)還包括尾部信息),以實(shí)現(xiàn)該層的功能,這個(gè)過程就稱為封裝:
經(jīng)過TCP封裝后的數(shù)據(jù)稱為TCP報(bào)文段(TCP message segment),或簡(jiǎn)稱TCP段。TCP協(xié)議為通信雙方維持一個(gè)連接,且在內(nèi)核中存儲(chǔ)相關(guān)數(shù)據(jù),這部分?jǐn)?shù)據(jù)中的TCP頭部信息和TCP內(nèi)核緩沖區(qū)中的數(shù)據(jù)一起構(gòu)成了TCP報(bào)文段:
當(dāng)發(fā)送端應(yīng)用程序使用send或write函數(shù)向一個(gè)TCP連接寫入數(shù)據(jù)時(shí),內(nèi)核中的TCP模塊首先把這些數(shù)據(jù)復(fù)制到與該連接對(duì)應(yīng)的TCP內(nèi)核發(fā)送緩沖區(qū)中,然后TCP模塊調(diào)用IP模塊提供的服務(wù),傳遞的參數(shù)包括TCP首部信息和TCP發(fā)送緩沖區(qū)中的數(shù)據(jù),即TCP報(bào)文段。
經(jīng)過UDP封裝后的數(shù)據(jù)稱為UDP數(shù)據(jù)報(bào)(UDP datagram),UDP對(duì)應(yīng)用程序數(shù)據(jù)的封裝與TCP類似,但UDP無須為應(yīng)用層數(shù)據(jù)保存副本,因?yàn)樗峁┑姆?wù)是不可靠的。當(dāng)一個(gè)UDP數(shù)據(jù)報(bào)被成功發(fā)送后,UDP內(nèi)核緩沖區(qū)中的該數(shù)據(jù)報(bào)就被丟棄了,如果應(yīng)用檢測(cè)到該數(shù)據(jù)報(bào)未被接收端正確接收,并打算重發(fā)此數(shù)據(jù)報(bào),則應(yīng)用需要重新從用戶空間將該數(shù)據(jù)報(bào)拷貝到UDP內(nèi)核發(fā)送緩沖區(qū)中。
經(jīng)過IP封裝后的數(shù)據(jù)稱為IP數(shù)據(jù)報(bào)(IP datagram)。IP數(shù)據(jù)報(bào)也包括頭部信息和數(shù)據(jù)部分,其中數(shù)據(jù)部分是一個(gè)TCP報(bào)文段、UDP數(shù)據(jù)報(bào)、ICMP報(bào)文。
經(jīng)過數(shù)據(jù)鏈路層封裝的數(shù)據(jù)稱為幀(frame),不同鏈路層,幀的類型也不同,如以太網(wǎng)上傳輸?shù)氖且蕴W(wǎng)幀(ethernet frame),而令牌環(huán)網(wǎng)上傳輸?shù)氖橇钆骗h(huán)幀(tokenring frame)。以太網(wǎng)幀的封裝格式如下圖:
以太網(wǎng)幀使用6字節(jié)的物理地址表示通信的雙方。4字節(jié)的CRC字段對(duì)幀的其他部分提供循環(huán)冗余校驗(yàn)。
幀的最大傳輸單元(Max Transmit Unit,MTU)是幀最多能攜帶的上層協(xié)議數(shù)據(jù)(如IP數(shù)據(jù)報(bào)),主要受到鏈路層類型的限制,以太網(wǎng)幀的MTU是1500字節(jié),因此過長(zhǎng)的IP數(shù)據(jù)報(bào)可能需要被分片傳輸。
幀才是最終在物理網(wǎng)絡(luò)上傳送的字節(jié)序列,至此封裝過程完成。
當(dāng)幀到達(dá)目的主機(jī)時(shí),將沿著協(xié)議棧自底向上依次傳遞,各層協(xié)議依次處理幀中本層負(fù)責(zé)的頭部數(shù)據(jù),以獲取所需信息,并最終將處理后的幀交給目標(biāo)應(yīng)用程序,這個(gè)過程稱為分用(demultiplexing),分用是依靠頭部信息中的類型字段實(shí)現(xiàn)的,RFC 1700定義了類型字段值對(duì)應(yīng)的協(xié)議,以下是以太網(wǎng)幀的分用過程:
由于IP、ARP、RARP協(xié)議都使用幀傳輸數(shù)據(jù),所有幀的頭部需要提供某個(gè)字段來區(qū)分它們。以以太網(wǎng)幀為例,它使用2字節(jié)的類型字段來標(biāo)識(shí)上層協(xié)議,如果主機(jī)接收到的以太網(wǎng)幀的類型字段的值為0x800,則幀的數(shù)據(jù)部分為IP數(shù)據(jù)報(bào),于是以太網(wǎng)驅(qū)動(dòng)程序就將幀交付給IP模塊;若類型字段值為0x806,則幀的數(shù)據(jù)部分為RARP請(qǐng)求或應(yīng)答報(bào)文,以太網(wǎng)驅(qū)動(dòng)程序就將幀交付給RARP模塊。
同樣,因?yàn)镮CMP、TCP、UDP都使用IP協(xié)議,所以IP數(shù)據(jù)報(bào)的頭部采用16位的協(xié)議字段來區(qū)分它們。
TCP報(bào)文段和UDP數(shù)據(jù)報(bào)通過其頭部中的16位端口號(hào)字段來區(qū)分上層應(yīng)用程序,如DNS協(xié)議對(duì)應(yīng)的端口號(hào)是53,HTTP協(xié)議(Hyper-Text Transfer Protol,超文本傳輸協(xié)議)對(duì)應(yīng)的端口號(hào)是80。所有知名應(yīng)用層協(xié)議使用的端口號(hào)都可在/etc/services文件中找到。
幀通過上述分用步驟后,最終將封裝前的原始數(shù)據(jù)送至目標(biāo)服務(wù)(如ARP服務(wù)、RARP服務(wù)、ICMP服務(wù)、應(yīng)用程序),這樣,在頂層目標(biāo)服務(wù)看來,封裝和分用似乎沒有發(fā)生過。
我們準(zhǔn)備以下測(cè)試網(wǎng)絡(luò):
包括兩臺(tái)主機(jī),以及一個(gè)連接到因特網(wǎng)的路由器,后文若沒有特別聲明,所有測(cè)試硬件指的都是該網(wǎng)絡(luò),我們將使用機(jī)器名來標(biāo)識(shí)測(cè)試機(jī)器。
以上測(cè)試網(wǎng)絡(luò)主要用于分析ARP協(xié)議、IP協(xié)議、ICMP協(xié)議、TCP協(xié)議、DNS協(xié)議,我們通過抓取該網(wǎng)絡(luò)上的以太網(wǎng)幀,查看其中的以太網(wǎng)幀頭部、IP數(shù)據(jù)報(bào)頭部、TCP報(bào)文段頭部以獲取網(wǎng)絡(luò)通信的細(xì)節(jié)。
對(duì)于路由器,我們僅列出了其LAN IP地址,而忽略了ISP(Internet Service Provoder,因特網(wǎng)服務(wù)提供商)給它分配的WAN IP地址,因?yàn)槿珪挠懻摬簧婕八?/p>
ARP協(xié)議能實(shí)現(xiàn)任意網(wǎng)絡(luò)層地址到任意物理地址的轉(zhuǎn)換,但本書僅討論從IP地址到以太網(wǎng)地址(MAC地址)的轉(zhuǎn)換。其工作原理是:主機(jī)向自己所在的網(wǎng)絡(luò)廣播一個(gè)ARP請(qǐng)求,該請(qǐng)求包括目標(biāo)機(jī)器的IP地址,此網(wǎng)絡(luò)上的其他機(jī)器都將收到這個(gè)請(qǐng)求,但只有被請(qǐng)求的機(jī)器會(huì)回應(yīng)一個(gè)ARP應(yīng)答,其中包含自己的物理地址。
以下是以太網(wǎng)ARP請(qǐng)求和應(yīng)答報(bào)文的格式:
上圖中各字段介紹:
1.硬件類型:物理地址的類型,值為1時(shí)表示MAC地址。
2.協(xié)議類型:網(wǎng)絡(luò)層地址的類型,值為0x800時(shí)表示IP地址。
3.硬件地址長(zhǎng)度、協(xié)議地址長(zhǎng)度:顧名思義,單位是字節(jié),對(duì)MAC地址來說,其長(zhǎng)度為6,對(duì)IPv4地址來說,其長(zhǎng)度為4。
4.操作:有4種操作類型,分別為ARP請(qǐng)求(值為1)、ARP應(yīng)答(值為2)、RARP請(qǐng)求(值為3)、RARP應(yīng)答(值為4)。
5.最后4個(gè)字段指定通信雙方的以太網(wǎng)地址和IP地址。發(fā)送端填充除目的端以太網(wǎng)地址外的其他3個(gè)字段,以構(gòu)建ARP請(qǐng)求并發(fā)送之。接收端發(fā)現(xiàn)該請(qǐng)求的目的端IP地址是自己,就把自己的以太網(wǎng)地址填進(jìn)去,然后交換兩個(gè)目的端地址和兩個(gè)發(fā)送端地址,以構(gòu)建ARP應(yīng)答并返回之(此時(shí)操作字段需要改為2)。
由上圖,ARP請(qǐng)求/應(yīng)答報(bào)文的長(zhǎng)度為28字節(jié),如果再加上共18字節(jié)的以太網(wǎng)幀頭部和尾部(見圖1-6),則一個(gè)攜帶ARP請(qǐng)求/應(yīng)答報(bào)文的以太網(wǎng)幀長(zhǎng)度為46字節(jié)。但有些實(shí)現(xiàn)要求以太網(wǎng)幀的數(shù)據(jù)部分長(zhǎng)度至少為46字節(jié),此時(shí)ARP請(qǐng)求/應(yīng)答報(bào)文將增加一些填充字段,以滿足長(zhǎng)度要求,此時(shí),一個(gè)攜帶ARP請(qǐng)求/應(yīng)答報(bào)文的以太網(wǎng)幀長(zhǎng)度為64字節(jié)。
以太網(wǎng)幀數(shù)據(jù)部分長(zhǎng)度至少為46字節(jié)的限制與碰撞檢測(cè)相關(guān),碰撞檢測(cè)要求幀在傳播介質(zhì)上的傳播時(shí)間足夠長(zhǎng),以便在數(shù)據(jù)發(fā)送期間可以檢測(cè)到碰撞。
通常ARP維護(hù)一個(gè)高速緩存,其中包含經(jīng)常訪問(如網(wǎng)關(guān)地址)或最近訪問的機(jī)器的IP地址到物理地址的映射,這樣就避免了重復(fù)的ARP請(qǐng)求,提高了發(fā)送包的速度。
Linux下可用arp命令來查看和修改ARP高速緩存,如ernest-laptop在某時(shí)刻的ARP緩存內(nèi)容如下(arp -a命令輸出):
其中第一項(xiàng)描述的是另一臺(tái)機(jī)器Kongming20(其IP地址和MAC地址都與圖1-8中描述的一致),第二項(xiàng)描述的是路由器。下面兩條命令分別刪除和添加一個(gè)ARP緩存項(xiàng):
我們從ernest-laptop上執(zhí)行telnet命令登錄Kongming20的echo服務(wù),并用tcpdump抓取這個(gè)過程中兩臺(tái)機(jī)器之間交換的以太網(wǎng)幀,操作過程如下(-i選項(xiàng)指定要抓取的接口,-e選項(xiàng)顯示以太網(wǎng)幀頭部信息,-n選項(xiàng)禁用主機(jī)名解析和端口號(hào)解析從而顯示數(shù)字形式的IP地址和端口號(hào),-t選項(xiàng)禁用每條輸出前的時(shí)間戳顯示,dst表示目的地址過濾,src表示源地址過濾):
在執(zhí)行telnet命令前,應(yīng)先清除ARP緩存中Kongming20對(duì)應(yīng)的項(xiàng),否則ARP通信不會(huì)執(zhí)行。當(dāng)執(zhí)行talnet命令,在兩臺(tái)通信主機(jī)前建立TCP連接后(telnet輸出"Connected to 192.168.1.109"后),輸入Ctrl+]以調(diào)出telnet程序的命令提示符,然后再telnet命令提示符后輸入quit,以退出telnet客戶端。ARP通信會(huì)在TCP連接建立前完成。tcpdump抓取到的數(shù)據(jù)包中,只有最靠前的兩個(gè)和ARP通信有關(guān),現(xiàn)將其列出(數(shù)據(jù)包前面的編號(hào)是作者加的):
tcpdump抓取的數(shù)據(jù)包是以太網(wǎng)幀。
第一個(gè)數(shù)據(jù)包中,ARP通信的源端物理地址是ernest-laptop的物理地址,目的端的物理地址是以太網(wǎng)廣播地址,用來表示整個(gè)LAN,該LAN上所有機(jī)器都會(huì)收到并處理這樣的幀。0x806是以太網(wǎng)幀頭部的類型字段的值,它表示分用的目標(biāo)是ARP模塊。該以太網(wǎng)幀長(zhǎng)度為42字節(jié)(實(shí)際是46字節(jié),tcpdump未統(tǒng)計(jì)以太網(wǎng)幀尾部4字節(jié)的CRC字段,未使用填充字節(jié)來滿足最小幀長(zhǎng)度),其中數(shù)據(jù)部分長(zhǎng)度為28字節(jié)?!癛equest”串表示這是ARP請(qǐng)求,“who-has 192.168.1.109 tell 192.168.1.108”串表示是ernest-laptop要查詢Kongming20的IP地址。
第二個(gè)數(shù)據(jù)包中,ARP通信的源端物理地址是Kongming20的物理地址,目的端的物理地址是ernest-laptop的物理地址?!癛eply”串表示這是ARP應(yīng)答,“192.168.1.109 is-at 08:00:27:53:10:67”串表示目標(biāo)機(jī)器Kongming20在報(bào)告ernest-laptop的物理地址。該以太網(wǎng)幀的長(zhǎng)度為60字節(jié)(實(shí)際64字節(jié),使用了填充字節(jié)來滿足最小幀長(zhǎng)度)。
下圖是以上ARP通信的過程:
關(guān)于上圖:
1.我們將兩次傳輸?shù)囊蕴W(wǎng)幀按圖1-6描述的以太網(wǎng)封裝格式繪制在上圖下半部分。
2.ARP請(qǐng)求和應(yīng)答時(shí)從以太網(wǎng)驅(qū)動(dòng)程序發(fā)出的,而非上圖這樣直接從ARP模塊發(fā)送到以太網(wǎng)上,因此我們將它用虛線表示,這是為了體現(xiàn)攜帶ARP數(shù)據(jù)的以太網(wǎng)幀和其他以太網(wǎng)幀(如攜帶IP數(shù)據(jù)報(bào)的以太網(wǎng)幀)的區(qū)別。
3.路由器也將接收到以太網(wǎng)幀1,因?yàn)樵搸且粋€(gè)廣播幀,但路由器并不會(huì)回應(yīng)其中的ARP請(qǐng)求。
我們通常使用機(jī)器的域名來訪問這臺(tái)機(jī)器,而非IP地址,域名查詢服務(wù)可將機(jī)器的域名轉(zhuǎn)換成IP地址。域名查詢服務(wù)有很多實(shí)現(xiàn)方式,如NIS(Network Information Service,網(wǎng)絡(luò)信息服務(wù))、DNS和本地靜態(tài)文件等。
DNS是一套分布式的域名服務(wù)系統(tǒng),每個(gè)DNS服務(wù)器上都存放著大量的機(jī)器名和IP地址的映射,且是動(dòng)態(tài)更新的。眾多網(wǎng)絡(luò)客戶端都使用DNS協(xié)議來向DNS服務(wù)器查詢目標(biāo)主機(jī)的IP地址。DNS查詢和應(yīng)答報(bào)文格式如下:
16為標(biāo)識(shí)字段用于標(biāo)記一對(duì)DNS查詢和應(yīng)答,以此區(qū)分一個(gè)DNS應(yīng)答是哪個(gè)DNS查詢的回應(yīng)。
16位標(biāo)志字段用于協(xié)商具體的通信方式以及反饋通信的狀態(tài),其結(jié)構(gòu)如下:
上圖中各字段含義如下:
1.QR:區(qū)分查詢和應(yīng)答報(bào)文,0表示這是一個(gè)查詢報(bào)文,1表示這是一個(gè)應(yīng)答報(bào)文。
2.opcode:定義查詢和應(yīng)答的類型,0表示標(biāo)準(zhǔn)查詢,1表示反向查詢(由IP地址獲得主機(jī)域名),2表示請(qǐng)求DNS服務(wù)器的狀態(tài)信息。
3.AA:授權(quán)應(yīng)答標(biāo)志,僅由應(yīng)答報(bào)文使用,1表示域名服務(wù)器是授權(quán)服務(wù)器。授權(quán)服務(wù)器是負(fù)責(zé)管理特定域名空間(用于組織和標(biāo)識(shí)域名的層次結(jié)構(gòu),類似于一個(gè)大的層次化命名空間)中域名解析信息的DNS服務(wù)器,授權(quán)服務(wù)器的響應(yīng)被視為權(quán)威性的答案,這意味著其響應(yīng)被認(rèn)為是最準(zhǔn)確和可信的。
4.TC:截?cái)鄻?biāo)志,僅當(dāng)DNS報(bào)文使用UDP服務(wù)時(shí)使用,由于UDP數(shù)據(jù)報(bào)有長(zhǎng)度限制,所以過長(zhǎng)的DNS報(bào)文將被截?cái)唷?表示DNS報(bào)文超過512字節(jié),并被截?cái)?。此處?12字節(jié)限制是出于性能原因,但現(xiàn)代DNS使用EDNS(Extension Mechanisms for DNS)以支持更大的數(shù)據(jù)包大小、更多的選項(xiàng)和擴(kuò)展功能。
5.RD:遞歸查詢標(biāo)志,1表示執(zhí)行遞歸查詢,即如果目標(biāo)DNS服務(wù)器無法解析某個(gè)主機(jī)名,則目標(biāo)DNS服務(wù)器將向其他DNS服務(wù)器繼續(xù)查詢,通常會(huì)先向根DNS服務(wù)器查詢,通常根DNS服務(wù)器不知道完整的域名解析路徑,于是根據(jù)要查詢的域名返回一個(gè)相對(duì)應(yīng)的頂級(jí)域名的DNS服務(wù)器(如對(duì)于example.com域名,會(huì)返回.com頂級(jí)域的DNS服務(wù)器地址),于是目標(biāo)DNS服務(wù)器再向該頂級(jí)域名DNS服務(wù)器查詢,這樣一級(jí)一級(jí)向下,直到找到目標(biāo)域名的授權(quán)域名服務(wù)器的IP地址,于是目標(biāo)DNS服務(wù)器再向目標(biāo)域名的授權(quán)域名服務(wù)器發(fā)出DNS查詢,從而獲取到目標(biāo)域名的IP地址,然后再返回給查詢者。2表示迭代查詢,即迭代查詢過程中,目標(biāo)DNS服務(wù)器的查詢過程,DNS客戶也可執(zhí)行迭代查詢過程中,目標(biāo)DNS服務(wù)器的查詢過程。兩種查詢方式見下圖:
6.RA:允許遞歸標(biāo)志,僅由應(yīng)答報(bào)文使用,1表示DNS服務(wù)器支持遞歸查詢。
7.zero:這3位未被使用,必須置0。
8.rcode:4位返回碼,表示應(yīng)答的狀態(tài),常用值有0表示無錯(cuò)誤,3表示域名不存在。
接下來的4個(gè)字段分別指出DNS報(bào)文的最后4個(gè)字段的資源記錄數(shù)目。對(duì)查詢報(bào)文而言,它一般包含1個(gè)查詢問題,而應(yīng)答資源記錄數(shù)、授權(quán)資源記錄數(shù)、額外資源記錄數(shù)均為0。對(duì)于應(yīng)答報(bào)文而言,應(yīng)答資源記錄數(shù)至少為1,而授權(quán)資源記錄數(shù)和額外資源記錄數(shù)可為0。
DNS查詢問題的格式:
上圖中,查詢名字段以一定格式封裝了要查詢的主機(jī)域名,16位查詢類型字段表示查詢操作的類型,常見的有以下幾種:
1.A查詢,值為1,表示獲取目標(biāo)主機(jī)的IP地址。
2.CNAME查詢,值為5,表示獲得目標(biāo)主機(jī)的別名。此處作者說CNAME查詢是為了獲得目標(biāo)主機(jī)的別名,實(shí)際上CNAME查詢是為了將一個(gè)域名(別名)映射到另一個(gè)域名(規(guī)范名稱,即FQDN,F(xiàn)ully Qualified Domain Name,完全限定域名),CNAME代表Canonical Name,即規(guī)范名稱。
3.PTR查詢,值為12,表示反向查詢(從IP地址查域名)。
上圖中,16位查詢類字段值通常為1,表示獲取因特網(wǎng)地址(IP地址)。
應(yīng)答字段、授權(quán)字段、額外信息字段都使用資源記錄(Resource Record,RR)格式:
上圖中,32位域名字段是該記錄中與資源對(duì)應(yīng)的域名,其格式和查詢問題中的查詢名字段相同。16位類型和16位類字段的含義也分別與DNS查詢問題中的16位查詢類型和16位查詢類字段相同。
32位生存時(shí)間字段表示該查詢記錄結(jié)果可被本地客戶端程序緩存多長(zhǎng)時(shí)間,單位是秒。
16位資源數(shù)據(jù)長(zhǎng)度字段和資源數(shù)據(jù)字段的內(nèi)容取決于16位類型字段,對(duì)類型A而言,資源數(shù)據(jù)字段是32位的IPv4地址,而16位資源數(shù)據(jù)長(zhǎng)度字段的值則為4(單位為字節(jié))。
DNS協(xié)議的更多細(xì)節(jié)可參考RFC文檔,DNS協(xié)議存在諸多RFC文檔,每個(gè)RFC文檔介紹其一個(gè)方面,如RFC 1035介紹域名的實(shí)現(xiàn)和規(guī)范,RFC 1886描述DNS協(xié)議對(duì)IPv6的擴(kuò)展支持。
我們要訪問DNS服務(wù),就必須先知道DNS服務(wù)器的IP地址。Linux使用/etc/resolv.conf文件來存放DNS服務(wù)器的IP地址,在機(jī)器ernest-laptop上,該文件內(nèi)容如下:
上圖中的兩個(gè)IP地址分別是首選DNS服務(wù)器地址和備選DNS服務(wù)器地址(系統(tǒng)會(huì)按順序訪問這些地址,因此第一行的是首選地址)。文件中的注釋告訴我們,這兩個(gè)DNS服務(wù)器地址是由網(wǎng)絡(luò)管理程序?qū)懭氲摹?/p>
Linux中的host程序也會(huì)訪問DNS服務(wù)器,下面是向首選DNS服務(wù)器(219.239.26.42)查詢www.baidu.com的IP地址:
host命令的輸出告訴我們,機(jī)器名www.baidu.com是www.a.shifen.com.的別名,且www.a.shifen.com.對(duì)應(yīng)兩個(gè)IP地址。host命令使用DNS協(xié)議同DNS服務(wù)器通信,其-t選項(xiàng)告訴DNS協(xié)議使用哪種查詢類型,此處使用的是A查詢,即通過機(jī)器域名獲取其IP地址(但實(shí)際上返回的資源記錄中還包括CNAME記錄)。
在ernest-laptop上運(yùn)行host命令查詢www.baidu.com的IP地址,并使用tcpdump抓取這一過程中LAN上傳輸?shù)囊蕴W(wǎng)幀,操作步驟如下(tcpdump的-s選項(xiàng)指定捕獲數(shù)據(jù)包的最大長(zhǎng)度,超出部分被丟棄;“port domain”串用來過濾數(shù)據(jù)包,表示只抓取使用domain服務(wù)的數(shù)據(jù)包):
tcpdump的輸出如下:
這兩個(gè)數(shù)據(jù)包開始的“IP”指出,他們后面的內(nèi)容描述的是IP數(shù)據(jù)報(bào)。tcpdump以“IP地址.端口號(hào)”的形式來描述通信的某一端,用“>”表示數(shù)據(jù)傳輸?shù)姆较?,?gt;”前面是源端,后面是目的端。可見,第一個(gè)數(shù)據(jù)包是測(cè)試機(jī)器ernest-laptop(IP地址為192.168.1.108)向其首選DNS服務(wù)器(IP地址為219.239.26.42)發(fā)送的DNS查詢報(bào)文(目標(biāo)端口53是DNS服務(wù)使用的端口),第二個(gè)數(shù)據(jù)包是服務(wù)器反饋的DNS應(yīng)答報(bào)文。
第一個(gè)數(shù)據(jù)包中,數(shù)值57428是DNS查詢報(bào)文的標(biāo)識(shí)值,因此該值也應(yīng)出現(xiàn)在DNS應(yīng)答報(bào)文中?!?”表示啟用遞歸查詢標(biāo)志?!癆?”表示使用A查詢?!皐ww.baidu.com”則是DNS查詢問題中的查詢名。括號(hào)中的數(shù)值31是DNS查詢報(bào)文的字節(jié)長(zhǎng)度。
第二個(gè)數(shù)據(jù)包中,“3/4/4”表示該報(bào)文中包含3個(gè)應(yīng)答資源記錄、4個(gè)授權(quán)資源記錄、4個(gè)額外信息記錄?!癈NAME www.a.shifen.com., A 119.75.218.77, A119.75.217.56”表示3個(gè)應(yīng)答資源記錄的內(nèi)容,其中CNAME表示緊隨其后的是機(jī)器的FQDN,A表示緊隨其后的記錄是IP地址。該應(yīng)答報(bào)文的長(zhǎng)度為226字節(jié)。
我們抓包時(shí)沒有開啟tcpdump的-x選項(xiàng)(以十六進(jìn)制格式顯示捕獲的數(shù)據(jù)包內(nèi)容)或-X選項(xiàng)(以十六進(jìn)制和ASCII文本混合格式顯示數(shù)據(jù)包內(nèi)容,它在-x選項(xiàng)的基礎(chǔ)上還提供了可讀的文本表示,使得數(shù)據(jù)包內(nèi)容更易于理解和分析),如果開啟了,會(huì)更清楚報(bào)文的具體字節(jié)內(nèi)容。
數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層協(xié)議是在內(nèi)核中實(shí)現(xiàn)的,因此操作系統(tǒng)需要實(shí)現(xiàn)一組系統(tǒng)調(diào)用,使得應(yīng)用程序能夠訪問這些協(xié)議提供的服務(wù),實(shí)現(xiàn)這組系統(tǒng)調(diào)用的API(Application Programming Interface,應(yīng)用程序編程接口)主要有兩套:socket和XTI,XTI現(xiàn)在基本不再使用,我們僅討論socket。
由socke定義的這組API提供以下功能:
1.將應(yīng)用程序數(shù)據(jù)從用戶緩沖區(qū)中復(fù)制到TCP/UDP內(nèi)核發(fā)送緩沖區(qū),以交付內(nèi)核來發(fā)送數(shù)據(jù)(如send函數(shù));或從內(nèi)核TCP/UDP接收緩沖區(qū)中復(fù)制數(shù)據(jù)到用戶緩沖區(qū),以讀取數(shù)據(jù)。
2.應(yīng)用程序可通過它們來修改內(nèi)核中各層協(xié)議的某些頭部信息或其他數(shù)據(jù)結(jié)構(gòu),從而精細(xì)地控制底層通信行為,比如可通過setsockopt函數(shù)來設(shè)置IP數(shù)據(jù)報(bào)在網(wǎng)絡(luò)上的存活時(shí)間。文章來源:http://www.zghlxwxcb.cn/news/detail-703755.html
socket是一套通用網(wǎng)絡(luò)編程接口,它不但可以訪問內(nèi)核中TCP/IP協(xié)議棧,還可訪問其他網(wǎng)絡(luò)協(xié)議棧(如X.25協(xié)議棧(一種早期的計(jì)算機(jī)網(wǎng)絡(luò)協(xié)議)、UNIX本地域協(xié)議棧等)。文章來源地址http://www.zghlxwxcb.cn/news/detail-703755.html
到了這里,關(guān)于Linux高性能服務(wù)器編程 學(xué)習(xí)筆記 第一章 TCP/IP協(xié)議族的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!