IP數(shù)據(jù)包的捕獲與分析設(shè)計(jì)報(bào)告_第1頁(yè)
IP數(shù)據(jù)包的捕獲與分析設(shè)計(jì)報(bào)告_第2頁(yè)
IP數(shù)據(jù)包的捕獲與分析設(shè)計(jì)報(bào)告_第3頁(yè)
IP數(shù)據(jù)包的捕獲與分析設(shè)計(jì)報(bào)告_第4頁(yè)
IP數(shù)據(jù)包的捕獲與分析設(shè)計(jì)報(bào)告_第5頁(yè)
已閱讀5頁(yè),還剩19頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、CENTRAL SOUTH UNIVERSITY 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告題 目 IP數(shù)據(jù)包的捕獲與分析 學(xué)生姓名 胡 壯 班級(jí)學(xué)號(hào) 計(jì)科1106班 0909112924 指導(dǎo)教師 穆 帥 設(shè)計(jì)時(shí)間 2014年1月 目錄第一章 緒論31.1 課題研究的意義31.2 捕獲數(shù)據(jù)包的常用方法3第二章 系統(tǒng)需求分析42.1 課程設(shè)計(jì)題目與要求42.2 IP數(shù)據(jù)包格式62.3 程序流程圖72.4 實(shí)驗(yàn)環(huán)境9第三章 系統(tǒng)總體框架93.1 套接字模塊93.2 IP數(shù)據(jù)包的捕獲模塊93.3 IP數(shù)據(jù)包分析模塊93.4 輸出模塊9第四章 詳細(xì)設(shè)計(jì)與實(shí)現(xiàn)104.1 數(shù)據(jù)結(jié)構(gòu)的定義104.2 初始化工作114.3 套

2、接字的創(chuàng)建和設(shè)置124.4 數(shù)據(jù)包的捕獲與分析134.5 信息的輸出14第五章 程序運(yùn)行結(jié)果與分析155.1 程序運(yùn)行結(jié)果截圖155.2 程序中有待改進(jìn)的地方16第六章 總結(jié)17參考文獻(xiàn)17附 錄18第一章 緒論現(xiàn)如今,計(jì)算機(jī)網(wǎng)絡(luò)已經(jīng)徹徹底底地改變了人們的生活。大量的數(shù)據(jù)都是經(jīng)過(guò)計(jì)算機(jī)網(wǎng)絡(luò)傳輸?shù)?,而TCP/IP協(xié)議是計(jì)算機(jī)網(wǎng)絡(luò)中最重要的協(xié)議之一。計(jì)算機(jī)網(wǎng)絡(luò)中絕大多數(shù)數(shù)據(jù)都是以IP數(shù)據(jù)包的形式發(fā)送和接受的。所以IP數(shù)據(jù)包的捕獲是很多計(jì)算機(jī)安全技術(shù)的基礎(chǔ)。1.1 課題研究的意義計(jì)算機(jī)之間進(jìn)行通信時(shí),交互的所有信息都封裝在數(shù)據(jù)包中。因此,通過(guò)采集網(wǎng)絡(luò)數(shù)據(jù)并對(duì)其進(jìn)行相應(yīng)的分析,可以清楚地了解到進(jìn)行通信

3、的計(jì)算機(jī)的通信目的。首先,分析采集到的數(shù)據(jù)包,可以確定網(wǎng)絡(luò)是否受到攻擊入侵;其次,也可以使用采集到的數(shù)據(jù)包來(lái)分析網(wǎng)絡(luò)應(yīng)用程序可能出現(xiàn)的問(wèn)題的原因;此外,通過(guò)網(wǎng)絡(luò)數(shù)據(jù)采集和統(tǒng)計(jì)可以清楚的了解整個(gè)網(wǎng)絡(luò)在各個(gè)時(shí)段內(nèi)的網(wǎng)絡(luò)負(fù)載情況,從而判斷網(wǎng)絡(luò)使用得是否合理。除了以上談到的幾個(gè)方面以外,數(shù)據(jù)包采集分析還有其他很多用途.在研究IPv4網(wǎng)絡(luò)的同時(shí),我們還對(duì)IPv6協(xié)議進(jìn)行了初步的研究并通過(guò)對(duì)數(shù)據(jù)報(bào)的分析,了解了在不同網(wǎng)絡(luò)環(huán)境下IPv6數(shù)據(jù)包的封裝格式以及在網(wǎng)絡(luò)中的傳輸路徑。目前,在同一子網(wǎng)范圍內(nèi),可以通過(guò)鄰居計(jì)算機(jī)發(fā)現(xiàn)協(xié)議自動(dòng)配置主機(jī)的本地一鏈路IPv6地址,并獲取子網(wǎng)內(nèi)其他主機(jī)的通信地址,通過(guò)該地址可以

4、實(shí)現(xiàn)子網(wǎng)內(nèi)的主機(jī)間純IPv6環(huán)境下的通信。但由于現(xiàn)在整個(gè)因特網(wǎng)并不支持IM協(xié)議,因此IPv6數(shù)據(jù)包要在網(wǎng)間傳輸,必須通過(guò)基于雙協(xié)議棧的IPv4隧道(Tunnel)技術(shù),將EM數(shù)據(jù)報(bào)封裝在IPv4包頭中,并通過(guò)指定的支持IM協(xié)議的路由在Internet中傳送到目的地,再由目的主機(jī)進(jìn)行數(shù)據(jù)報(bào)解析。獲取IPv6數(shù)據(jù)報(bào)中的信息。1.2 捕獲數(shù)據(jù)包的常用方法目前常用的捕獲數(shù)據(jù)包的方法有原始套接字、LibPcap、WinPcap和JPcap等方法。它們各有特點(diǎn),實(shí)現(xiàn)起來(lái)有難有易,如何選擇取決于具體需求與程序員的喜好。下面分別對(duì)它們作簡(jiǎn)單介紹。套接字是網(wǎng)絡(luò)應(yīng)用編程接口。應(yīng)用程序可以使用它進(jìn)行網(wǎng)絡(luò)通信而不需要

5、知道底層發(fā)生的細(xì)節(jié)。有時(shí)需要自己生成一些定制的數(shù)據(jù)包或者功能并希望繞開(kāi)Socket提供的功能,原始套接字(RawSocket)滿(mǎn)足了這樣的要求。原始套接字能夠生成自己的數(shù)據(jù)報(bào)文,包括報(bào)頭和數(shù)據(jù)報(bào)本身的內(nèi)容。通過(guò)原始套接字,可以更加自如地控制Windows下的多種協(xié)議,而且能夠?qū)W(wǎng)絡(luò)底層的傳輸機(jī)制進(jìn)行控制。LibPcap是一種與系統(tǒng)無(wú)關(guān),采用分組捕獲機(jī)制的分組捕獲函數(shù)庫(kù),用于訪問(wèn)數(shù)據(jù)鏈路層,它在不同的平臺(tái)上采用統(tǒng)一的編程接口,使用LibPcap編寫(xiě)的程序可自由的跨平臺(tái)使用。同時(shí)LibPcap是一個(gè)獨(dú)立于系統(tǒng)接口的用戶(hù)級(jí)的抓包庫(kù),它為底層網(wǎng)絡(luò)監(jiān)聽(tīng)提供了可移植框架。它的應(yīng)用包括網(wǎng)絡(luò)統(tǒng)計(jì)集合、安全監(jiān)聽(tīng)

6、、網(wǎng)絡(luò)調(diào)試等。WinPcap是一個(gè)基于Win32的捕獲數(shù)據(jù)包和網(wǎng)絡(luò)分析的體系結(jié)構(gòu),它包括一個(gè)內(nèi)核級(jí)的包過(guò)濾器,一個(gè)底層的動(dòng)態(tài)鏈接庫(kù)(Packet.dll),一個(gè)高層并且與系統(tǒng)無(wú)關(guān)的庫(kù)(WPcap.dll,基于LibPcap0.6.2版本)。WinPcap是集成于Windows 95, 98, ME, NT, 2000和XP操作系統(tǒng)的設(shè)備驅(qū)動(dòng)程序,它可以從網(wǎng)卡捕獲或者發(fā)送原始數(shù)據(jù),同時(shí)能夠過(guò)濾并且存儲(chǔ)數(shù)據(jù)包。JPcap是一個(gè)能夠捕獲、發(fā)送網(wǎng)絡(luò)數(shù)據(jù)包的Java類(lèi)庫(kù)包。這個(gè)包用到了LibPcap和原始套接字API。JPcap支持Ethernet, IPv4, IPv6, ARP/RARP, TCP,

7、 UDP, ICMPv4協(xié)議。JPcap是一個(gè)Java類(lèi)集合,它為網(wǎng)絡(luò)數(shù)據(jù)包的捕獲提供接口和系統(tǒng)支持。其最初版本是2000年6月發(fā)布的JPcap0.01版,此后幾經(jīng)修改,到2003年4月發(fā)布了最新的JPcap0.4版。第二章 系統(tǒng)需求分析2.1 課程設(shè)計(jì)題目與要求本次實(shí)驗(yàn)的要求在網(wǎng)絡(luò)環(huán)境,使用VC+編寫(xiě)程序?qū)崿F(xiàn)捕獲網(wǎng)絡(luò)中的IP數(shù)據(jù)包,解析數(shù)據(jù)包的內(nèi)容,將結(jié)果顯示在標(biāo)準(zhǔn)輸出上,并同時(shí)寫(xiě)入日志文件。程序的具體要求如下:l)以命令行形式運(yùn)行:ipparse logfile,其中ipparse是程序名,而logfile則代表記錄結(jié)果的日志文件。2)在標(biāo)準(zhǔn)輸出和日志文件中寫(xiě)入捕獲的IP包的版本、頭長(zhǎng)度、

8、服務(wù)類(lèi)型、數(shù)據(jù)包總長(zhǎng)度、數(shù)據(jù)包標(biāo)識(shí)、分段標(biāo)志、分段偏移值、生存時(shí)間、上層協(xié)議類(lèi)型、頭校驗(yàn)和、源IP地址和目的IP地址等內(nèi)容。3)當(dāng)程序接收到鍵盤(pán)輸入CtrlC時(shí)退出。2.2 IP數(shù)據(jù)包格式只有先了解IP數(shù)據(jù)包的格式,才能對(duì)IP數(shù)據(jù)包進(jìn)行解析,下圖是IP數(shù)據(jù)包的格式:IP數(shù)據(jù)包由首部和數(shù)據(jù)兩部分組成。首部的前一部分是固定長(zhǎng)度,共 20 字節(jié),是所有IP數(shù)據(jù)報(bào)必須具有的。在首部的固定部分的后面是一些可選字段,其長(zhǎng)度是可變的,可選字段之后是數(shù)據(jù)部分。其中,首部固定部分中的各字段的長(zhǎng)度及意義如下:(1)版本占4位,指IP協(xié)議的版本。通信雙方使用的IP協(xié)議版本必須一致。目前廣泛使用的IP協(xié)議版本號(hào)為4(

9、即IPv4)。關(guān)于IPv6,目前還處于草案階段。(2)首部長(zhǎng)度占4位,可表示的最大十進(jìn)制數(shù)值是15。請(qǐng)注意,這個(gè)字段所表示數(shù)的單位是32位字長(zhǎng)(1個(gè)32位字長(zhǎng)是4字節(jié)),因此,當(dāng)IP的首部長(zhǎng)度為1111時(shí)(即十進(jìn)制的15),首部長(zhǎng)度就達(dá)到60字節(jié)。當(dāng)IP分組的首部長(zhǎng)度不是4字節(jié)的整數(shù)倍時(shí),必須利用最后的填充字段加以填充。因此數(shù)據(jù)部分永遠(yuǎn)在4字節(jié)的整數(shù)倍開(kāi)始,這樣在實(shí)現(xiàn)IP協(xié)議時(shí)較為方便。首部長(zhǎng)度限制為60字節(jié)的缺點(diǎn)是有時(shí)可能不夠用。但這樣做是希望用戶(hù)盡量減少開(kāi)銷(xiāo)。最常用的首部長(zhǎng)度就是20字節(jié)(即首部長(zhǎng)度為0101),這時(shí)不使用任何選項(xiàng)。(3)區(qū)分服務(wù)占8位,用來(lái)獲得更好的服務(wù)。這個(gè)字段在舊標(biāo)準(zhǔn)

10、中叫做服務(wù)類(lèi)型,但實(shí)際上一直沒(méi)有被使用過(guò)。1998年IETF把這個(gè)字段改名為區(qū)分服務(wù)DS(Differentiated Services)。只有在使用區(qū)分服務(wù)時(shí),這個(gè)字段才起作用。(4)總長(zhǎng)度總長(zhǎng)度指首部和數(shù)據(jù)之和的長(zhǎng)度,單位為字節(jié)??傞L(zhǎng)度字段為16位,因此數(shù)據(jù)報(bào)的最大長(zhǎng)度為216-1=65535字節(jié)。在IP層下面的每一種數(shù)據(jù)鏈路層都有自己的幀格式,其中包括幀格式中的數(shù)據(jù)字段的最大長(zhǎng)度,這稱(chēng)為最大傳送單元MTU(Maximum Transfer Unit)。當(dāng)一個(gè)數(shù)據(jù)報(bào)封裝成鏈路層的幀時(shí),此數(shù)據(jù)報(bào)的總長(zhǎng)度(即首部加上數(shù)據(jù)部分)一定不能超過(guò)下面的數(shù)據(jù)鏈路層的MTU值。(5)標(biāo)識(shí)(identifi

11、cation)占16位。IP軟件在存儲(chǔ)器中維持一個(gè)計(jì)數(shù)器,每產(chǎn)生一個(gè)數(shù)據(jù)報(bào),計(jì)數(shù)器就加1,并將此值賦給標(biāo)識(shí)字段。但這個(gè)“標(biāo)識(shí)”并不是序號(hào),因?yàn)镮P是無(wú)連接服務(wù),數(shù)據(jù)報(bào)不存在按序接收的問(wèn)題。當(dāng)數(shù)據(jù)報(bào)由于長(zhǎng)度超過(guò)網(wǎng)絡(luò)的MTU而必須分片時(shí),這個(gè)標(biāo)識(shí)字段的值就被復(fù)制到所有的數(shù)據(jù)報(bào)的標(biāo)識(shí)字段中。相同的標(biāo)識(shí)字段的值使分片后的各數(shù)據(jù)報(bào)片最后能正確地重裝成為原來(lái)的數(shù)據(jù)報(bào)。(6)標(biāo)志(flag)占3位,但目前只有2位有意義。標(biāo)志字段中的最低位記為MF(More Fragment)。MF=1即表示后面“還有分片”的數(shù)據(jù)報(bào)。MF=0表示這已是若干數(shù)據(jù)報(bào)片中的最后一個(gè)。標(biāo)志字段中間的一位記為DF(Dont Fragm

12、ent),意思是“不能分片”。只有當(dāng)DF=0時(shí)才允許分片。(7)片偏移占13位。片偏移指出:較長(zhǎng)的分組在分片后,某片在原分組中的相對(duì)位置。也就是說(shuō),相對(duì)用戶(hù)數(shù)據(jù)字段的起點(diǎn),該片從何處開(kāi)始。片偏移以8個(gè)字節(jié)為偏移單位。這就是說(shuō),每個(gè)分片的長(zhǎng)度一定是8字節(jié)(64位)的整數(shù)倍。(8)生存時(shí)間占8位,生存時(shí)間字段常用的的英文縮寫(xiě)是TTL(Time To Live),表明是數(shù)據(jù)報(bào)在網(wǎng)絡(luò)中的壽命。由發(fā)出數(shù)據(jù)報(bào)的源點(diǎn)設(shè)置這個(gè)字段。其目的是防止無(wú)法交付的數(shù)據(jù)報(bào)無(wú)限制地在因特網(wǎng)中兜圈子,因而白白消耗網(wǎng)絡(luò)資源。最初的設(shè)計(jì)是以秒作為T(mén)TL的單位。每經(jīng)過(guò)一個(gè)路由器時(shí),就把TTL減去數(shù)據(jù)報(bào)在路由器消耗掉的一段時(shí)間。若數(shù)

13、據(jù)報(bào)在路由器消耗的時(shí)間小于1秒,就把TTL值減1。當(dāng)TTL值為0時(shí),就丟棄這個(gè)數(shù)據(jù)報(bào)。后來(lái)把TTL字段的功能改為“跳數(shù)限制”(但名稱(chēng)不變)。路由器在轉(zhuǎn)發(fā)數(shù)據(jù)報(bào)之前就把TTL值減1.若TTL值減少到零,就丟棄這個(gè)數(shù)據(jù)報(bào),不再轉(zhuǎn)發(fā)。因此,現(xiàn)在TTL的單位不再是秒,而是跳數(shù)。TTL的意義是指明數(shù)據(jù)報(bào)在網(wǎng)絡(luò)中至多可經(jīng)過(guò)多少個(gè)路由器。顯然,數(shù)據(jù)報(bào)在網(wǎng)絡(luò)上經(jīng)過(guò)的路由器的最大數(shù)值是255.若把TTL的初始值設(shè)為1,就表示這個(gè)數(shù)據(jù)報(bào)只能在本局域網(wǎng)中傳送。(9)協(xié)議占8位,協(xié)議字段指出此數(shù)據(jù)報(bào)攜帶的數(shù)據(jù)是使用何種協(xié)議,以便使目的主機(jī)的IP層知道應(yīng)將數(shù)據(jù)部分上交給哪個(gè)處理過(guò)程。(10)首部檢驗(yàn)和占16位。這個(gè)字段

14、只檢驗(yàn)數(shù)據(jù)報(bào)的首部,但不包括數(shù)據(jù)部分。這是因?yàn)閿?shù)據(jù)報(bào)每經(jīng)過(guò)一個(gè)路由器,路由器都要重新計(jì)算一下首部檢驗(yàn)和(一些字段,如生存時(shí)間、標(biāo)志、片偏移等都可能發(fā)生變化)。不檢驗(yàn)數(shù)據(jù)部分可減少計(jì)算的工作量。(11)源地址占32位。為發(fā)送方的IP地址。(12)目的地址占32位。為接收方的IP地址。2.3 程序流程圖通過(guò)對(duì)實(shí)驗(yàn)題目和要求的分析,畫(huà)出程序流程圖如下:解析IP數(shù)據(jù)包N捕獲IP數(shù)據(jù)包結(jié)束接收到Ctrl+C?NN設(shè)置套接字創(chuàng)建原始套接字YY命令行參數(shù)正確?開(kāi)始Y加載WinSock動(dòng)態(tài)鏈接庫(kù)成功?2.4 實(shí)驗(yàn)環(huán)境本實(shí)驗(yàn)采用Windows操作系統(tǒng)平臺(tái),利用Windows提供的Windows Sockets

15、API實(shí)現(xiàn)IP數(shù)據(jù)包的捕獲與分析。采用WinSock 2.2版本,編程語(yǔ)言選用C+,編程工具采用Visual Studio 2010旗艦版。第三章 系統(tǒng)總體框架整個(gè)系統(tǒng)可以分為四個(gè)模塊,分別為套接字模塊、捕獲IP數(shù)據(jù)包模塊、解析IP數(shù)據(jù)包模塊和輸出模塊。下面分別作簡(jiǎn)要介紹。3.1 套接字模塊套接字模塊主要包括原始套接字的創(chuàng)建和原始套接字的設(shè)置。此模塊先創(chuàng)建一個(gè)原始套接字,然后將此套接字綁定到一個(gè)本機(jī)的網(wǎng)絡(luò)接口,再設(shè)置套接字使其能捕獲經(jīng)過(guò)此網(wǎng)絡(luò)接口的所有IP數(shù)據(jù)包。3.2 IP數(shù)據(jù)包的捕獲模塊此模塊主要負(fù)責(zé)捕獲IP數(shù)據(jù)包,然后將捕獲的數(shù)據(jù)包提交給IP數(shù)據(jù)包解析模塊。此模塊利用設(shè)置好的原始套接字捕

16、獲IP數(shù)據(jù)包,然后將數(shù)據(jù)包提交給解析模塊,直到鍵盤(pán)輸入ctrl+c時(shí)結(jié)束。3.3 IP數(shù)據(jù)包分析模塊此模塊主要負(fù)責(zé)對(duì)IP數(shù)據(jù)包進(jìn)行分析,即根據(jù)IP數(shù)據(jù)包的格式把信息從捕獲到的IP數(shù)據(jù)包中提取出來(lái),然后再提交給輸出模塊。3.4 輸出模塊此模塊負(fù)責(zé)輸出IP數(shù)據(jù)包信息的輸出,包括輸出到標(biāo)準(zhǔn)輸出和日志文件。第四章 詳細(xì)設(shè)計(jì)與實(shí)現(xiàn)4.1 數(shù)據(jù)結(jié)構(gòu)的定義本程序主要用到了兩個(gè)數(shù)據(jù)結(jié)構(gòu),一個(gè)是IP頭的結(jié)構(gòu)體,一個(gè)是常用IP協(xié)議號(hào)與協(xié)議名的映射。1. IP頭結(jié)構(gòu)體根據(jù)IP數(shù)據(jù)包的格式,定義IP頭結(jié)構(gòu)體如下:struct IPHead u_char ihl : 4; /頭長(zhǎng)度 u_char version : 4

17、; /版本 u_char tos; /服務(wù)類(lèi)型 u_short len; /IP包的總長(zhǎng)度 u_short id; /標(biāo)識(shí) u_short off; /分段偏移量 u_char ttl; /生存期 u_char protocol; /協(xié)議 u_short cksum; /頭校驗(yàn)和 struct in_addr saddr; /源IP地址 struct in_addr daddr; /目的IP地址;2. 常用IP協(xié)議號(hào)與協(xié)議名的映射為了通過(guò)協(xié)議號(hào)得到協(xié)議名,于是定義了一些常見(jiàn)的協(xié)議號(hào)與其協(xié)議名的映射關(guān)系,如下:pair<int, string> common_ip = make_pa

18、ir(1, "ICMP"), make_pair(2, "IGMP"), make_pair(3, "GGP"), make_pair(4, "IP in IP"), make_pair(6, "TCP"), make_pair(8, "EGP"), make_pair(17, "UDP"), make_pair(35, "IDPR"), make_pair(45, "IDRP"), make_pair(46, &q

19、uot;RSVP"), make_pair(47, "GRE"), make_pair(54, "NHRP"), make_pair(88, "IGRP"), make_pair(89, "OSPF"),;/常見(jiàn)的IP協(xié)議編號(hào)和名稱(chēng)const map<int, string> IP_PROTOCOL(common_ip, common_ip + 14);4.2 初始化工作1.命令行參數(shù)檢查if(argc != 2) cerr << "命令行參數(shù)錯(cuò)誤!" <

20、< endl; return 1; 如果命令行參數(shù)的數(shù)目不是2的話,說(shuō)明輸入有誤,需打印錯(cuò)誤信息,然后退出。2.初始化動(dòng)態(tài)鏈接庫(kù)WSADATA wsa_data;if(WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) cerr << "WSAStartup() error!" << endl; return 1;如果初始化失敗,則退出程序。4.3 套接字的創(chuàng)建和設(shè)置1. 套接字的創(chuàng)建創(chuàng)建一個(gè)原始套接字,用來(lái)捕獲數(shù)據(jù)包。SOCKET s = socket(AF_INET, SOCK_RAW, IPPR

21、OTO_IP);if (s = INVALID_SOCKET) WSACleanup(); cerr << "socket() error!" << endl; return 1; 如果創(chuàng)建失敗,則退出程序。2. 綁定本機(jī)地址將剛剛建立的套接字與本機(jī)IP地址綁定。struct sockaddr_in hostaddr;hostaddr.sin_family = AF_INET;hostaddr.sin_port = htons(0);hostaddr.sin_addr.s_addr = gethostid();if(bind(s, (sockaddr

22、 *)&hostaddr, sizeof(sockaddr) != 0) closesocket(s); WSACleanup(); cerr << "bind() error!" << endl; exit(-1);WinSock提供的bind()函數(shù)用于將一個(gè)套接字與一個(gè)地址綁定。綁定之后,原始套接字就能接收流經(jīng)該IP地址所屬網(wǎng)絡(luò)接口的全部IP數(shù)據(jù)包。3. 設(shè)置套接字為SIO_RCVALLDWORD in_buffer = 1, n_returned;int ret = WSAIoctl(s, SIO_RCVALL, &in_bu

23、ffer, sizeof(in_buffer), NULL, 0, &n_returned, NULL, NULL);if(ret != 0) closesocket(s); WSACleanup(); cerr << "WSAIoctl() error!" << endl; exit(-1);將套接字設(shè)置為SIO_RCVALL之后,套接字就能捕獲局域網(wǎng)內(nèi)所有的IP數(shù)據(jù)包,如果設(shè)置失敗,就退出程序。4.4 數(shù)據(jù)包的捕獲與分析前面的步驟完成之后就可以進(jìn)行數(shù)據(jù)包的捕獲了。主要用到WinSock提供的recv函數(shù),recv函數(shù)的原型為:size_t

24、 recv(SOCKET sockfd, void *buf, size_t len, int flags);recv()如果執(zhí)行成功,則捕獲的數(shù)據(jù)包存儲(chǔ)在buf中。主要代碼如下:for(; ;) int n_recv = recv(s, buf, sizeof(buf), 0); SYSTEMTIME cur_time; GetLocalTime(&cur_time); /獲得捕獲數(shù)據(jù)包的時(shí)間 if(n_recv > 0) IPHead *lp_iphead = (IPHead *)buf; char buf20; sprintf(buf, "%02d:%02d:%0

25、2d:%03d", cur_time.wHour, cur_time.wMinute, cur_time.wSecond, cur_time.wMilliseconds); /輸出到標(biāo)準(zhǔn)輸出 cout << "捕包時(shí)間t" << buf << endl; output_ip(lp_iphead, cout); cout << endl << endl; /輸出到文件 fout << "捕包時(shí)間t" << buf << endl; output_ip(

26、lp_iphead, fout); fout << endl << endl; fout.flush(); 其中,output_ip是一個(gè)自定義函數(shù),該函數(shù),將lp_iphead所向的IP信息輸出到輸出流fout。4.5 信息的輸出信息的輸出用函數(shù)output_ip函數(shù)完成,其定義如下:/*將IP數(shù)據(jù)包信息輸出到out流*ip_iphead為指向IPHead類(lèi)型的指針*/void output_ip(IPHead *lp_iphead, ostream &out) out << "版本tt" << (int)lp_ip

27、head->version << endl; out << "頭長(zhǎng)度tt" << (int)(lp_iphead->ihl * 4) << endl; out << "服務(wù)類(lèi)型t" << (int)lp_iphead->tos << endl; out << "總長(zhǎng)度tt" << lp_iphead->len << endl; out << "標(biāo)識(shí)tt" <

28、;< lp_iphead->id << endl; u_short unserved = (lp_iphead->off) >> 15; u_short DF = (lp_iphead->off) >> 14) & 0x0001; u_short MF = (lp_iphead->off) >> 13) & 0x0001; out << "標(biāo)志位tt" << unserved << DF << MF << endl; ou

29、t << "偏移量tt" << (lp_iphead->off) & 0x1fff) << endl; out << "生存期tt" << (int)lp_iphead->ttl << endl; out << "協(xié)議tt" << (int)lp_iphead->protocol; map<int, string>:const_iterator it = IP_PROTOCOL.find(lp_iphe

30、ad->protocol); if(it != IP_PROTOCOL.end() out << "(" << it->second << ")" << endl; out << "校驗(yàn)和tt" << lp_iphead->cksum << endl; out << "源IP地址t" << inet_ntoa(lp_iphead->saddr) << endl; out &

31、lt;< "目的IP地址t" << inet_ntoa(lp_iphead->daddr) << endl;第五章 程序運(yùn)行結(jié)果與分析5.1 程序運(yùn)行結(jié)果截圖標(biāo)準(zhǔn)輸出截圖:日志文件截圖:通過(guò)對(duì)大量輸出數(shù)據(jù)的分析,發(fā)現(xiàn)程序的輸出是正確的。5.2 程序中有待改進(jìn)的地方這個(gè)程序只能捕獲IPv4數(shù)據(jù)包,不能捕獲IPv6數(shù)據(jù)包。可以通過(guò)修改程序,讓這個(gè)程序既能捕獲IPv4數(shù)據(jù)包,又能捕獲IPv6數(shù)據(jù)包,那么這個(gè)程序就會(huì)更加的完善。還可以為這個(gè)程序設(shè)計(jì)一個(gè)圖形用戶(hù)界面,使程序更加美觀,更加易于使用。還可以為程序增加一個(gè)功能,讓程序能獲取數(shù)據(jù)包中的內(nèi)容

32、,可就需要對(duì)各種應(yīng)用程協(xié)議進(jìn)行解析(例如:TCP,UDP)。總之,只要多花點(diǎn)功夫,這個(gè)程序可以做的更好。第六章 總結(jié)本次課程設(shè)計(jì)讓我學(xué)會(huì)了很多的東西,其中,最值得一提的是:對(duì)IP協(xié)議有了比較深入的了解;學(xué)習(xí)了Windows socket。我選擇的課題是IP數(shù)據(jù)包的捕獲與分析。所以需要對(duì)IP數(shù)據(jù)包有非常深入的了解。這次實(shí)驗(yàn)中,我把IP協(xié)議學(xué)了好多遍,知道了IP頭中每一個(gè)字段的意思。對(duì)IP數(shù)據(jù)包的捕獲,我使用的是原始套接字,在Windows操作系統(tǒng)中實(shí)現(xiàn)的。在做實(shí)驗(yàn)的過(guò)程中,我把Windows socket大概學(xué)了一遍,重點(diǎn)學(xué)習(xí)了其中的原始套接字。在學(xué)習(xí)的過(guò)程中,對(duì)OSI七層模型有了更深的了解。對(duì)

33、Windows socket的學(xué)習(xí),讓我對(duì)網(wǎng)絡(luò)編程的基本方法和步驟有了一定的了解,相信這次的學(xué)習(xí)對(duì)我以后網(wǎng)絡(luò)編程的學(xué)習(xí)會(huì)很有幫助。我感覺(jué)Windows socket確實(shí)是一個(gè)很強(qiáng)大的工具,但是由于是C語(yǔ)言的接口,用起來(lái)也有一些的繁瑣。在學(xué)習(xí)計(jì)算機(jī)網(wǎng)絡(luò)這門(mén)課程的時(shí)候,我感覺(jué)這門(mén)課一點(diǎn)意思都沒(méi)有,全部都是理論知識(shí),感覺(jué)學(xué)了也沒(méi)有一點(diǎn)用。但是,在做課程設(shè)計(jì)的時(shí)候,我才發(fā)現(xiàn)上課學(xué)的那些理論知識(shí)也是非常有用的。如果沒(méi)有那些理論知識(shí)的支撐,要完成這次的課程設(shè)計(jì),不知道還有花多少時(shí)間。所以,這次課程設(shè)計(jì)的經(jīng)歷有一次告訴我,理論和實(shí)際相結(jié)合是非常重要的。每個(gè)學(xué)期課程設(shè)計(jì)的這段時(shí)間都是我收獲最多的一段時(shí)間,我享

34、受這段時(shí)間,也感激這段時(shí)間。最后,感謝實(shí)驗(yàn)老師這兩個(gè)星期的陪伴和指導(dǎo)。參考文獻(xiàn)(1) Andrew S.Tanenbaum,David J.Wetherall. 計(jì)算機(jī)網(wǎng)絡(luò)(第五版)M. 北京:清華大學(xué)出版社,2012.3(2) Bob Quinn,Dave Shute. Windows Sockets網(wǎng)絡(luò)編程M.北京:機(jī)械工業(yè)出版社,2012.8(3) MSDN. TCP / IP原始套接字. 附錄 程序源代碼頭文件:/*文件名:header.h*/#ifndef HEADER_H#define HEADER_H#include <iostream>#include <ma

35、p>#include <string>#include <utility>#include <WinSock2.h>using namespace std;int const MAX_IP_LEN = 65535;pair<int, string> common_ip = make_pair(1, "ICMP"), make_pair(2, "IGMP"), make_pair(3, "GGP"), make_pair(4, "IP in IP"), make_

36、pair(6, "TCP"), make_pair(8, "EGP"), make_pair(17, "UDP"), make_pair(35, "IDPR"), make_pair(45, "IDRP"), make_pair(46, "RSVP"), make_pair(47, "GRE"), make_pair(54, "NHRP"), make_pair(88, "IGRP"), make_pair(89,

37、"OSPF"),;const map<int, string> IP_PROTOCOL(common_ip, common_ip + 14); /常見(jiàn)的IP協(xié)議編號(hào)和名稱(chēng)struct IPHead u_char ihl : 4; /頭長(zhǎng)度 u_char version : 4; /版本 u_char tos; /服務(wù)類(lèi)型 u_short len; /IP包的總長(zhǎng)度 u_short id; /標(biāo)識(shí) u_short off; /分段偏移量 u_char ttl; /生存期 u_char protocol; /協(xié)議 u_short cksum; /頭校驗(yàn)和 struc

38、t in_addr saddr; /源IP地址 struct in_addr daddr; /目的IP地址;u_long gethostid(); /獲取本機(jī)地址void output_ip(IPHead *lp_iphead, std:ostream &out); /把IP信息輸出到流outvoid set_socket(SOCKET s); /設(shè)置套接字#endif源文件:/*文件名:main.cpp*/#include <iostream>#include <fstream>#include <winsock2.h>#include <m

39、stcpip.h>#include "header.h"#pragma comment(lib, "ws2_32.lib")using namespace std;int main(int argc, char *argv) if(argc != 2) cerr << "命令行參數(shù)錯(cuò)誤!" << endl; return 1; /初始化winsock的動(dòng)態(tài)鏈接庫(kù) WSADATA wsa_data; if(WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) cer

40、r << "WSAStartup() error!" << endl; return 1; /建立一個(gè)原始套接字 SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_IP); if (s = INVALID_SOCKET) WSACleanup(); cerr << "socket() error!" << endl; return 1; /設(shè)置套接字 set_socket(s); /打開(kāi)日志文件 ofstream fout(argv1); if(!fout) cerr

41、 << "fout.open() error!" << endl; return 1; /捕獲數(shù)據(jù)包,并進(jìn)行解析 /將結(jié)果寫(xiě)入標(biāo)準(zhǔn)輸出和日志文件中 char bufMAX_IP_LEN; for(; ;) int n_recv = recv(s, buf, sizeof(buf), 0); SYSTEMTIME cur_time; GetLocalTime(&cur_time); /獲得捕獲數(shù)據(jù)包的時(shí)間 if(n_recv > 0) IPHead *lp_iphead = (IPHead *)buf; char buf20; sprin

42、tf(buf, "%02d:%02d:%02d:%03d", cur_time.wHour, cur_time.wMinute, cur_time.wSecond, cur_time.wMilliseconds); /輸出到標(biāo)準(zhǔn)輸出 cout << "捕包時(shí)間t" << buf << endl; output_ip(lp_iphead, cout); cout << endl << endl; /輸出到文件 fout << "捕包時(shí)間t" << buf

43、 << endl; output_ip(lp_iphead, fout); fout << endl << endl; fout.flush(); WSACleanup(); return 0;/*set_socket完成對(duì)原始套接字s的設(shè)置*以使s能接收到所用的IP數(shù)據(jù)包*/void set_socket(SOCKET s) /將s綁定到本機(jī)地址上 struct sockaddr_in hostaddr; hostaddr.sin_family = AF_INET; hostaddr.sin_port = htons(0); hostaddr.sin_ad

44、dr.s_addr = gethostid(); if(bind(s, (sockaddr *)&hostaddr, sizeof(sockaddr) != 0) closesocket(s); WSACleanup(); cerr << "bind() error!" << endl; exit(-1); /將s設(shè)置為接受所有IP數(shù)據(jù)包 DWORD in_buffer = 1, n_returned; int ret = WSAIoctl(s, SIO_RCVALL, &in_buffer, sizeof(in_buffer), N

45、ULL, 0, &n_returned, NULL, NULL); if(ret != 0) closesocket(s); WSACleanup(); cerr << "WSAIoctl() error!" << endl; exit(-1); /*函數(shù):gethostid()*描述:獲得本機(jī)IP地址,使用如下算法:* 生成一個(gè)UDP socket* 連接這個(gè)UDP socket到任意的地址和端口* 使用getsockname()得到本地IP地址*/u_long gethostid() SOCKET s = socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(IPPORT_ECHO); addr.sin_addr.s_addr = inet_addr("128.127.50.1"); connect(s, (sockaddr*)&addr, sizeof(sockaddr); struct sockaddr_in hostaddr; /本機(jī)地址 int n_addr = sizeof(sockaddr); getsockname

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論