2023年全國(guó)碩士研究生考試考研英語(yǔ)一試題真題(含答案詳解+作文范文)_第1頁(yè)
已閱讀1頁(yè),還剩15頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、<p><b>  課程設(shè)計(jì)任務(wù)書(shū)</b></p><p><b>  目錄</b></p><p><b>  1.實(shí)驗(yàn)?zāi)康?lt;/b></p><p><b>  2.實(shí)驗(yàn)要求</b></p><p><b>  3.預(yù)備知識(shí)</

2、b></p><p><b>  4.課程設(shè)計(jì)分析</b></p><p><b>  5.實(shí)現(xiàn)過(guò)程</b></p><p><b>  6.程序流程圖</b></p><p><b>  7.相關(guān)擴(kuò)展</b></p><p>

3、;<b>  8.實(shí)習(xí)體會(huì)</b></p><p><b>  9.參考文獻(xiàn)</b></p><p><b>  一.實(shí)驗(yàn)?zāi)康模?lt;/b></p><p>  設(shè)計(jì)一個(gè)解析IP數(shù)據(jù)包的程序,并根據(jù)這個(gè)程序,說(shuō)明IP數(shù)據(jù)包的結(jié)構(gòu)及IP協(xié)議的相關(guān)問(wèn)題,從而IP層的工作原理有更好的理解和認(rèn)識(shí).</p&g

4、t;<p>  二.實(shí)驗(yàn)要求 : </p><p>  本設(shè)計(jì)的目標(biāo)是捕獲網(wǎng)絡(luò)中數(shù)據(jù)包,解析數(shù)據(jù)包的內(nèi)容,將、結(jié)果顯示在標(biāo)準(zhǔn)輸出上,并同時(shí)寫(xiě)入日志文件.</p><p>  程序的具體要求如下:</p><p>  以命令行形式運(yùn)行:ipparse logfile,其中ipparse是程序名,而logfile則代表記錄結(jié)果的日志文

5、件.</p><p>  在標(biāo)準(zhǔn)輸出和日志文件中寫(xiě)入捕獲的IP數(shù)據(jù)包的版本,頭長(zhǎng)度,服務(wù)類型,數(shù)據(jù)包總長(zhǎng)度,數(shù)據(jù)包標(biāo)識(shí),分段標(biāo)志,分段偏移值,生存時(shí)間,上層協(xié)議類型,頭校驗(yàn)和,源IP地址和目的IP地址等內(nèi)容.</p><p>  當(dāng)程序接收到鍵盤輸入Ctrl+C時(shí)退出.</p><p><b>  三.預(yù)備知識(shí) </b></p>

6、<p>  互聯(lián)網(wǎng)絡(luò)層是TCP/IP協(xié)議參考模型中的關(guān)鍵部分.IP協(xié)議把傳輸層送來(lái)的消息組裝成IP數(shù)據(jù)包,并把IP數(shù)據(jù)包傳送給數(shù)據(jù)鏈層.IP協(xié)議在TCP/IP協(xié)議族中處于核心地位,IP協(xié)議制定了統(tǒng)一的IP數(shù)據(jù)包格式,以消除個(gè)通信子網(wǎng)中的差異,從而為信息發(fā)送方和接收方提供了透明的傳輸通道.編制本程序前,首先要對(duì)IP包的格式有一定了解,圖1給出了IP協(xié)議的數(shù)據(jù)包格式.</p><p>  IP數(shù)據(jù)包的第一

7、個(gè)字段是版本字段,其度是4位,表示所使用的IP協(xié)議的版本.目前的版本是IPV4,版本字段的值是4,下一代版本是IPV6,版本字段值是6.本程序主要針對(duì)版本是IPV4的數(shù)據(jù)包的解析.</p><p>  報(bào)頭標(biāo)長(zhǎng)字段為4位,它定義了以4B為一個(gè)單位的IP包的報(bào)文長(zhǎng)度.報(bào)頭中除了選項(xiàng)字段和填充域字段外,其他各字段是定長(zhǎng)的.因此,IP數(shù)據(jù)包的頭長(zhǎng)度在20—40B之間,是可變的.</p><p>

8、  0 4 8 16 19 24 31</p><p>  圖1 IP數(shù)據(jù)包的格式</p><p>  服務(wù)類型字段共8位,用于指示路由器如何處理該數(shù)據(jù)包.該字段長(zhǎng)度由4位服務(wù)類型(TOS)子域和3位優(yōu)先級(jí)子域組成,1位為保留位,該字段結(jié)構(gòu)如圖2所示.</p&

9、gt;<p>  B7 b6 b5 b4 b3 b2 b1 b0</p><p>  圖2 服務(wù)類型字段結(jié)構(gòu)</p><p>  優(yōu)先級(jí)共有8種,優(yōu)先級(jí)越高表明數(shù)據(jù)包越重要.表1中列出了各種優(yōu)先級(jí)所代表的意義.</p><p>  表一 優(yōu)先子域

10、的說(shuō)明</p><p>  在4位服務(wù)類型子域中b4,b3,b2,b1分別表示D(延遲),T(吞吐量),R(可靠性)與C(成本).表2列出了服務(wù)器類型自域的構(gòu)成.</p><p>  總長(zhǎng)度字段為2B,它定義了以字節(jié)為單位的數(shù)據(jù)包的總長(zhǎng)度.IP數(shù)據(jù)包的最大長(zhǎng)度為65535B.</p><p>  標(biāo)識(shí)字段的長(zhǎng)度為16位,用于識(shí)別IP數(shù)據(jù)包的編號(hào).每批數(shù)據(jù)都要有一個(gè)標(biāo)

11、識(shí)值,用于讓目的主機(jī)判斷新來(lái)的數(shù)據(jù)屬于哪個(gè)分組.</p><p>  報(bào)頭中的標(biāo)志字段如圖7-3所示.標(biāo)志字段共3位,最高位是0.禁止分片標(biāo)志DF(do not fragment)字段的值若為1,表示不能對(duì)數(shù)據(jù)包分片;若DF值為0,則表明可以分片.分片標(biāo)志MF(more fragment)的值為1,表示接收到的不是最后一個(gè)分片;若MF值為0,表示接收到的是最后一個(gè)分片.</p><p>

12、  片偏移字段共13位,說(shuō)明分片在整個(gè)數(shù)據(jù)包中的相對(duì)位置.片偏移值是以8B為單位來(lái)記數(shù)的,因此選擇的分片長(zhǎng)度應(yīng)該是8B的整數(shù)倍.</p><p>  生存時(shí)間(TTL)字段為8位,用來(lái)設(shè)置數(shù)據(jù)包在互聯(lián)網(wǎng)絡(luò)的傳輸過(guò)程的壽命,通常是用一個(gè)數(shù)據(jù)包可以經(jīng)過(guò)的最多的路由器跳步數(shù)來(lái)限定的.</p><p>  協(xié)議字段為8位,表示使用此IP數(shù)據(jù)包的高層協(xié)議類型,常用的協(xié)議號(hào)如表7-3所示.</p

13、><p>  表7-3 典型的協(xié)議號(hào)</p><p>  頭校驗(yàn)和字段為16位,用于存放檢查報(bào)頭錯(cuò)誤的校驗(yàn)碼。檢驗(yàn)的范圍是整個(gè)IP包的報(bào)頭。校驗(yàn)和按如下方法計(jì)算:</p><p>  1)將頭校驗(yàn)和的字段置為0。</p><p>  2)將報(bào)頭部分的所有數(shù)據(jù)以16位為單位進(jìn)行累加,累加方式是求異或。</p><p>  3

14、)將累加的結(jié)果取反碼,就是頭校驗(yàn)和。</p><p>  當(dāng)收到一個(gè)IP包時(shí),要檢查報(bào)頭是否出錯(cuò),就把報(bào)頭中的所有數(shù)據(jù)以16位為單位進(jìn)行累加,若累加的結(jié)果為0,則報(bào)文沒(méi)有出錯(cuò)。</p><p>  地址字段包括源地址和目的地址。源地址和目的地址的長(zhǎng)度都是32位,分別表示發(fā)送數(shù)據(jù)包的源主機(jī)和目的主機(jī)的IP地址。</p><p>  選項(xiàng)字段的長(zhǎng)度范圍為0~40B,主要

15、用于控制和測(cè)試。在使用選項(xiàng)字段的過(guò)程中,有可能出現(xiàn)報(bào)頭部分的長(zhǎng)度不是32位的整數(shù)倍的情況。如果出現(xiàn)這種情況,就需要通過(guò)填充位來(lái)湊齊。</p><p><b>  四.課程設(shè)計(jì)分析</b></p><p>  為了獲取網(wǎng)絡(luò)中的IP數(shù)據(jù)包,必須對(duì)網(wǎng)卡進(jìn)行編程,在這里我們使用套接字(socket)進(jìn)行編程。但是,在通常情況下,網(wǎng)絡(luò)通信的套接字程序只能響應(yīng)與自己硬件地址相匹配

16、的數(shù)據(jù)包或是以廣播形式出發(fā)的數(shù)據(jù)包。對(duì)于其他形式的數(shù)據(jù)包,如已到達(dá)網(wǎng)絡(luò)接口但卻不是發(fā)送到此地址的數(shù)據(jù)包,網(wǎng)絡(luò)接口在驗(yàn)證投遞地址并非自身地址之后將不引起響應(yīng),也就是說(shuō)應(yīng)用程序無(wú)法收取與自己無(wú)關(guān)的數(shù)據(jù)包。我們要想獲取流經(jīng)網(wǎng)絡(luò)設(shè)備的所有數(shù)據(jù)包,就需要將網(wǎng)卡設(shè)置為混雜模式。</p><p>  本程序主要由三部分構(gòu)成:初始化原始套接字,反復(fù)監(jiān)聽(tīng)捕獲數(shù)據(jù)包和解析數(shù)據(jù)包。下面就結(jié)合核心代碼對(duì)程序的具體實(shí)現(xiàn)進(jìn)行講解,同時(shí)使程序

17、流程更加清晰,去掉了錯(cuò)誤檢查等保護(hù)性代碼。</p><p><b>  使用原始套接字</b></p><p>  套接字分為三種,即流套接字(Stream Socket)、數(shù)據(jù)報(bào)套接字(Datagram Socket)和原始套接字(Raw Socket)。要進(jìn)行IP數(shù)據(jù)包的接受與發(fā)送,應(yīng)使用原始套接字。創(chuàng)建原始套接字的代碼如下:</p><p&g

18、t;  SOCKET sock;</p><p>  Sock=WSASoccet(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERRLAPPED);</p><p>  在WSASoccet函數(shù)中,第一個(gè)參數(shù)指定通信發(fā)生的區(qū)字段,AF_INET是針對(duì)Internet的,允許在遠(yuǎn)程主機(jī)之間通信。第二個(gè)參數(shù)是套接字的類型,AF_INET地址族下

19、,有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW三種套接字類型。在這里,我們?cè)O(shè)置為SOCK_RAW,表示我們聲明的是一個(gè)原始套接字類型。第三個(gè)參數(shù)依賴于第二個(gè)參數(shù),用于指定套接字所用的特定協(xié)議,這里使用IP協(xié)議。第四個(gè)參數(shù)為WSAPROTOCOL_INFO位,該位可以置空,永遠(yuǎn)置0。第六個(gè)參數(shù)是標(biāo)志位,WSA_FLAG_OVERRLAPPED表明可以使用發(fā)送接收超時(shí)設(shè)置,本課程設(shè)計(jì)也可以把這個(gè)標(biāo)志位設(shè)置為NULL,因?yàn)?/p>

20、本設(shè)計(jì)不用考慮超時(shí)情況。</p><p>  創(chuàng)建原始套接字后,IP頭就會(huì)包含在接收的數(shù)據(jù)中。然后,我們可以設(shè)置IP頭操作選項(xiàng),調(diào)用sotscockpot函數(shù)。其中flag設(shè)置為TRUE,并設(shè)定IP_HDRINCL選項(xiàng),表明用戶可以親自對(duì)IP頭進(jìn)行處理。</p><p>  BOOL flag=true;</p><p>  setsockopt (sock,IPP

21、ROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag));</p><p>  之后,使用如下代碼完成對(duì)socket的初始化工作</p><p><b>  /*獲取主機(jī)名*/</b></p><p>  char hostname[128];</p><p>  gethost

22、name(hostname, 100);</p><p>  /*獲取IP地址*/</p><p>  hostent *pHostIP;</p><p>  pHostIP=gethostbyname(hostname);</p><p>  /* 填充SOCKADDR_IN的結(jié)構(gòu)內(nèi)容*/</p><p>  soc

23、kaddr_in addr_in;</p><p>  addr_in.sin_addr= *(in_addr*)pHostIP->h_addr_list[0];</p><p>  addr_in.sin_family=AF_TNET;</p><p>  addr-in.sin_port=htons(6000);</p><p> 

24、 /* 綁定socket */</p><p>  bind(sock, (POSCKADDR)&addr_in,sizeof(addr_in));</p><p>  填寫(xiě)sockaddr_in的內(nèi)容時(shí),其地址值應(yīng)填寫(xiě)為本機(jī)IP地址可以通過(guò)gethostbyname()函數(shù)獲??;端口號(hào)可以隨便填寫(xiě),但不能與系統(tǒng)沖突;協(xié)議族應(yīng)填寫(xiě)為AF_INET。注意,sockaddr_in 結(jié)構(gòu)

25、的值必須是以網(wǎng)絡(luò)字節(jié)順序表示的值,而不能直接使用本機(jī)字節(jié)順序的值,使用htoms()函數(shù)可以將無(wú)符號(hào)短整型的主機(jī)數(shù)據(jù)轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)的順序的數(shù)據(jù)。最后使用bind()函數(shù)將socket綁定到本地網(wǎng)卡上。</p><p>  綁定網(wǎng)卡后,需要WSAIoctl()函數(shù)把網(wǎng)卡設(shè)置為混雜模式,使網(wǎng)卡能夠接收所有網(wǎng)絡(luò)數(shù)據(jù),其關(guān)鍵代碼如下:</p><p>  #define SIO_RCVALL_WS

26、AIOW(IOC_VENDOR,1)</p><p>  DWORD dwBufferLen[10];</p><p>  DWORD dwBufferInLen=1;</p><p>  DWORD dwBytesReturned=0;</p><p>  WSAIoctl(SnifferSocket,IO-RCVALL,&dwBu

27、fferInLen,sizeof(dwBufferInLen),&dwBufferLen,Sizeof(dwBufferLen),&dwByteReturned,NULL,NULL);</p><p>  如果接收的數(shù)據(jù)包中的協(xié)議類型和定義的原始套接字匹配,那么接收到的數(shù)據(jù)就拷貝到套接字中。因此,網(wǎng)卡就可以接收所有經(jīng)過(guò)的IP包。</p><p><b>  2.接

28、收數(shù)據(jù)包</b></p><p>  在程序中可使用RECV()函數(shù)接收經(jīng)過(guò)的IP包。該函數(shù)有四個(gè)參數(shù),第一個(gè)參數(shù)接收操作所用的套接字描述符;第二個(gè)參數(shù)接收到緩沖區(qū)的地址;第二個(gè)參數(shù)接收緩沖區(qū)的地址;第三個(gè)參數(shù)接收緩沖區(qū)的大小,也就是所要接收的字節(jié)數(shù);第四個(gè)參數(shù)是一個(gè)附加標(biāo)志,如果對(duì)所發(fā)送的數(shù)據(jù)沒(méi)特殊要求,直接設(shè)為0。因?yàn)镮P數(shù)據(jù)包的最大長(zhǎng)度是65536B,因此緩沖區(qū)的大小不能小于65535B。設(shè)置緩

29、沖區(qū)后,可利用循環(huán)來(lái)反復(fù)監(jiān)聽(tīng)接收IP包,用recv()函數(shù)接收功能的代碼如下:</p><p>  #dedine BUFFER_SIZE 65535</p><p>  Char buffer[BUFFER_SIZE]; //設(shè)置緩沖區(qū)</p><p>  While(true)</p><p>  {recv(sock,buffer,

30、BUFFER_SIZE,0); //j接收數(shù)據(jù)包</p><p><b>  ……..</b></p><p>  3.定義IP頭部的數(shù)據(jù)結(jié)構(gòu)</p><p>  程序需要定義一個(gè)數(shù)據(jù)結(jié)構(gòu)表示IP頭部。這個(gè)數(shù)據(jù)結(jié)構(gòu)應(yīng)該和圖7-1吻合,其代碼如下:</p><p>  typedef struct _IP_HEADE

31、R //定義IP頭</p><p><b>  {</b></p><p><b>  union</b></p><p><b>  {</b></p><p>  BYTE Version; //版本前4位</p><p>  BYTE HdrLe

32、n; //報(bào)頭標(biāo)長(zhǎng)(后四位),IP頭長(zhǎng)度</p><p><b>  };</b></p><p>  BYTE ServiceType;//服務(wù)類型</p><p>  WORD TotalLen; //總長(zhǎng)度</p><p>  WORD ID; //標(biāo)識(shí)</p><p><b>

33、;  union </b></p><p><b>  {</b></p><p>  WORD Flags; //標(biāo)志</p><p>  Word FragOff; //分段偏移</p><p><b>  };</b></p><p>  BYTE Ti

34、meToLive; //生命期</p><p>  BYTE Protiocol; //協(xié)議</p><p>  WORD HdrChksum; //頭校驗(yàn)和</p><p>  DWORD SrcAddr; //源地址</p><p>  DWORD DstAddr: //目的地址</p><p>  BYTE

35、 Options; //選項(xiàng)</p><p>  }IP_HEADER;</p><p>  這是我們只考慮IP頭部結(jié)構(gòu),不考慮數(shù)據(jù)部分。在捕獲IP數(shù)據(jù)包后,可以通過(guò)指針把緩沖區(qū)的內(nèi)容強(qiáng)制轉(zhuǎn)化為IP_HEADER數(shù)據(jù)結(jié)構(gòu)。</p><p>  IP_HEADER ip = *( IP_HEADER *)buffer;</p><p><

36、;b>  4.IP包的解析</b></p><p>  解析IP包的字段有兩種策略。針對(duì)長(zhǎng)度為8位、16位和32位的字段 (或子字段)時(shí),可以利用IP_HEADER的成員指教獲取。要解析長(zhǎng)度不是9位倍數(shù)的字段(或子字段)時(shí),可以利用C語(yǔ)言中的位移以及與、或操作完成。下面給出了通過(guò)IP_HEADER解析IP頭各個(gè)字段的代碼。</p><p>  /*獲取版本字段*/<

37、/p><p>  ip.Version>>4;</p><p>  /*獲取頭部長(zhǎng)度字段*/</p><p>  ip.HdrLen & 0x0f;</p><p>  /*獲取服務(wù)類型字段中的優(yōu)先級(jí)子域*/</p><p>  ip.ServiceType>>5;</p>&

38、lt;p>  /*獲取服務(wù)類型字段中的TOS子域*/</p><p>  (IP.sERVICEtYPE>>1)&0X0F;</p><p>  /*獲取總長(zhǎng)度字段*/</p><p>  ip.TotalLEN;</p><p>  /*獲取標(biāo)識(shí)字段*/</p><p><b> 

39、 ip.ID;</b></p><p>  /*解析標(biāo)識(shí)字段*/</p><p>  DF=(ip.Flags>>14) &0x01;</p><p>  MF=(ip.Flags>>13) &0X01;</p><p>  /*獲取分段偏移字段*/</p><p>

40、  ip.FragOff &0x1fff;</p><p>  /*獲取生存時(shí)間字段*/</p><p>  ip.TimeToLive;</p><p>  /*獲取協(xié)議字段*/</p><p>  ip.Protocol;</p><p>  /*獲取頭校驗(yàn)和字段*/</p><p>

41、;  ip.HdrChksum;</p><p>  /*解析源IP地址字段*/</p><p>  inet_ntoa(*(in_addr*)&ip.SrcAddr;</p><p>  /*解析目的的IP地址字段*/</p><p>  inet_ntoa(*(in_addr*)&ip.DstAddr);</p>

42、;<p><b>  5.參考程序流程圖</b></p><p>  圖7-4給出一個(gè)供參考的程序流程圖。 </p><p><b>  五.實(shí)現(xiàn)過(guò)程</b></p><p>  #include "stdafx.h"</p><p>

43、  #include "winsock2.h"</p><p>  #include "ws2tcpip.h"</p><p>  #include "stdio.h"</p><p>  typedef struct _IP_HEADER</p><p><b>  {&

44、lt;/b></p><p><b>  union</b></p><p><b>  {</b></p><p>  BYTE Version;</p><p>  BYTE HdrLen;</p><p><b>  };</b></p

45、><p>  BYTE ServiceType;</p><p>  WORD TotalLen;</p><p><b>  WORD ID;</b></p><p><b>  union</b></p><p><b>  {</b></p>

46、;<p>  WORD Flags;</p><p>  WORD Fragoff;</p><p><b>  };</b></p><p>  BYTE TimeToLive;</p><p>  BYTE Protocol;</p><p>  WORD HdrChksum;&

47、lt;/p><p>  DWORD SrcAddr;</p><p>  DWORD DstAddr;</p><p>  BYTE Options;</p><p>  }IP_HEADER;</p><p>  void getVersion(BYTE b,BYTE & version)</p>

48、<p><b>  {</b></p><p>  version =b>>4;</p><p><b>  }</b></p><p>  void getIHL(BYTE b,BYTE & result)</p><p><b>  {</b>

49、</p><p>  result = (b & 0x0f) *4;</p><p><b>  }</b></p><p>  char * parseServiceType_getProcedence(BYTE b)</p><p><b>  {</b></p><

50、p>  switch(b>>5)</p><p><b>  {</b></p><p><b>  case 7:</b></p><p>  return "Network Control";</p><p><b>  break;</b&

51、gt;</p><p><b>  case 6:</b></p><p>  return "Internet work Control";</p><p><b>  break;</b></p><p><b>  case 5:</b></p&

52、gt;<p>  return "CRITIC/ECP";</p><p><b>  break;</b></p><p><b>  case 4:</b></p><p>  return "Flash Override";</p><p>

53、;<b>  break;</b></p><p><b>  case 3:</b></p><p>  return "Falsh";</p><p><b>  break;</b></p><p><b>  case 2:</b&g

54、t;</p><p>  return "Immediate";</p><p><b>  break;</b></p><p><b>  case 1:</b></p><p>  return "Priority";</p><p&

55、gt;<b>  break;</b></p><p><b>  case 0:</b></p><p>  return "Routine";</p><p><b>  break;</b></p><p><b>  default :&l

56、t;/b></p><p>  return "Unknown"</p><p><b>  }</b></p><p><b>  }</b></p><p>  char * parseServiceType_getTOS(BYTE b)</p><

57、p><b>  {</b></p><p>  b=(b>>1)&0x0f;</p><p><b>  switch(b)</b></p><p><b>  {</b></p><p><b>  case 0:</b><

58、;/p><p>  return "Normal service";</p><p><b>  break;</b></p><p><b>  case 1:</b></p><p>  return "Minimize monetary cost";<

59、/p><p><b>  break;</b></p><p><b>  case 2:</b></p><p>  return "Maximize reliability";</p><p><b>  break;</b></p><

60、p><b>  case 4:</b></p><p>  return "Maximize throughput";</p><p><b>  break;</b></p><p><b>  case 8:</b></p><p>  retur

61、n "Minimize delay";</p><p><b>  break;</b></p><p><b>  case 15:</b></p><p>  return "Maximize security";</p><p><b>  b

62、reak;</b></p><p><b>  default:</b></p><p>  return "Unknown";</p><p><b>  }</b></p><p><b>  }</b></p><p&g

63、t;  void getFlags(WORD w,BYTE & DF, BYTE & MF)</p><p><b>  {</b></p><p>  DF=(w>>14)&0x01;</p><p>  MF=(w>>13)&0x01;</p><p><

64、b>  }</b></p><p>  void getFragoff(WORD w,WORD & fragoff)</p><p><b>  {</b></p><p>  fragoff=w&0x1ffff;</p><p><b>  }</b></p

65、><p>  char * getProtocol(BYTE Protocol)</p><p><b>  {</b></p><p>  switch (Protocol)</p><p><b>  {</b></p><p><b>  case 1:</

66、b></p><p>  return "ICMP";</p><p><b>  case 2:</b></p><p>  return "IGMP";</p><p><b>  case 4:</b></p><p>  

67、return "IP in IP ";</p><p><b>  case 6:</b></p><p>  return "TCP";</p><p><b>  case 8:</b></p><p>  return "EGP";&

68、lt;/p><p><b>  case 17:</b></p><p>  return "UPD";</p><p><b>  case 41:</b></p><p>  return "IPv6";</p><p><b&g

69、t;  case 46:</b></p><p>  return "OSPF";</p><p><b>  default:</b></p><p>  return "UNKNOWN";</p><p><b>  }</b></p&g

70、t;<p><b>  }</b></p><p>  void ipparse(FILE * file,char *buffer)</p><p><b>  {</b></p><p>  IP_HEADER ip=*(IP_HEADER *)buffer;</p><p>  f

71、seek(file,0,SEEK_END);</p><p>  BYTE version;</p><p>  getVersion(ip.Version,version);</p><p>  fprintf(file,"版本=%d\r\n",version);</p><p>  BYTE headerLen;<

72、;/p><p>  getIHL(ip.HdrLen,headerLen);</p><p>  fprintf(file,"頭長(zhǎng)度=%d(BYTE)\r\n",headerLen);</p><p>  fprintf(file,"服務(wù)類型=%s,%s\r\n");</p><p>  parseServ

73、iceType_getProcedence(ip.ServiceType);</p><p>  parseServiceType_getTOS(ip.ServiceType);</p><p>  fprintf(file,"數(shù)據(jù)報(bào)長(zhǎng)度=%d(BYTE)\r\n",ip.TotalLen);</p><p>  fprintf(file,&qu

74、ot;數(shù)據(jù)報(bào)ID=%d\r\n",ip.ID);</p><p>  BYTE DF,MF;</p><p>  getFlags(ip.Flags,DF,MF);</p><p>  fprintf(file,"分段標(biāo)志 DF=%d,MF=%d\r\n",DF,MF);</p><p>  WORD fragO

75、ff;</p><p>  getFragOff(ip.FragOff,fragOff);</p><p>  fprintf(file,"分段偏移值=%d\r\n",fragOff);</p><p>  fprintf(file," 生存期=%d(hops)\r\n",ip.TimeToLive);</p>

76、<p>  fprintf(file,"協(xié)議=%s\r\n",getProtocol(ip.Protocol));</p><p>  fprintf(file,"頭校驗(yàn)和=0x%0x\r\n",ip.HdrChksum);</p><p>  fprintf(file,"源IP地址=%s\r\n",inet-ntoa(

77、*(in-addr*)&ip.SrcAddr));</p><p>  fprintf(file,"目的IP地址=%s\r\n",inet_ntoa(*(in-addr*)&ip.DstAddr));</p><p>  fprintf(file,"__________________________________\r\n");&l

78、t;/p><p><b>  }</b></p><p>  int main(int argc,char *argv[])</p><p><b>  {</b></p><p>  if(argc!=2)</p><p><b>  {</b></

79、p><p>  printf("usage error!\n");</p><p>  return -1;</p><p><b>  }</b></p><p>  FILE * file;</p><p>  if((file=foopen(argv[1],"wb+

80、"))==NULL)</p><p><b>  {</b></p><p>  printf("fail to open file %s",argv{1});</p><p>  return -1;</p><p><b>  }</b></p>&l

81、t;p>  WSADATA wsData;</p><p>  if(WSAStartup(MAKEWORD(2,2),$WSdATA)!=0)</p><p><b>  {</b></p><p>  PRINTF("WSAStartup FAILED!\n");</p><p>  ret

82、urn -1;</p><p><b>  }</b></p><p>  SOCKET sock;</p><p>  if((sock=socket(AF_INET,SOCK_RAW,ippROTO_IP))==INVALID_SOCKET)</p><p><b>  {</b></p&

83、gt;<p>  PRINTF("CREATE socket failed!\n");</p><p>  return -1;</p><p><b>  }</b></p><p>  BOOL flag=TRUE;</p><p>  IF(setsockopt(sock,IPPR

84、OTO_IP,IP_HDRINCL,(CHAR*)&FLAG,sizeof(flag))==SOCKET_ERROR)</p><p><b>  {</b></p><p>  printf("setsockopt failed!\n");</p><p>  return -1;</p><p

85、><b>  }</b></p><p>  char hostName[128];</p><p>  if(gethostname(hostName,100)==SOCKET_ERROR)</p><p><b>  {</b></p><p>  printf("gethost

86、name failed!\n");</p><p>  return -1;</p><p><b>  }</b></p><p>  hostent * pHostIP;</p><p>  if(pHostIP=gethostbyname(hostName))==NULL)</p><

87、p><b>  { </b></p><p>  printf("gethostbyname failed!\n");</p><p>  return -1;</p><p><b>  }</b></p><p>  sockaddr_in addr_in;</p

88、><p>  addr_in.sin_addr=*(in_addr*)pHostIP->h_addr_list[0];</p><p>  addr_in.sin_family=AF_INET;</p><p>  addr_in.sin_port=htone(6000);</p><p>  if(bind(sock,(PSOCKADDR

89、)&addr_in,sizeof(addr_in))==SOCKET_ERROR)</p><p><b>  {</b></p><p>  printf("bind failed");</p><p>  return -1;</p><p><b>  }</b>&

90、lt;/p><p>  DWORD dwValue=1;</p><p>  #define IO_RCVALL_WSAIOW(IOC_VENDOR,1)</p><p>  DWORD dwBufferLen[10];</p><p>  DWORD dwBufferInLen=1;</p><p>  DWORD dw

91、BytesReturned=0;</p><p>  if(WSAIoctl(sock,IO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),</p><p>  &dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL)==</p><p>

92、;  NULL,NULL)==SOCKET_ERROR)</p><p><b>  {</b></p><p>  printf("icotlsocket failed\n");</p><p>  return -1;</p><p><b>  }</b></p>

93、;<p>  #define BUFFER_SIZE 65535</p><p>  char buffer[BUFFER_SIZE];</p><p>  printf("開(kāi)始解析\n\n");</p><p>  while(true)</p><p><b>  {</b><

94、/p><p>  int size=recv(sock,buffer,BUFFER_SIZE,0);</p><p>  if(size>0)</p><p><b>  { </b></p><p>  ipparse(stdout,buffer);</p><p>  ipparse(fil

95、e,buffer); </p><p><b>  }</b></p><p><b>  }</b></p><p>  fclose(file);</p><p><b>  return 0:</b></p><p><b>  }&l

96、t;/b></p><p><b>  六.程序流程圖:</b></p><p><b>  N</b></p><p><b>  Y</b></p><p><b>  七.相關(guān)擴(kuò)展</b></p><p>  本程序設(shè)計(jì)

97、也可以利用Winpcap完成,部分核心代碼的簡(jiǎn)略提示如下。</p><p>  獲取所有存在的網(wǎng)絡(luò)設(shè)備的鏈表。</p><p>  Pcap_if_t *alldevs; //網(wǎng)絡(luò)設(shè)備結(jié)構(gòu)鏈表</p><p>  Char errbuf[PCAP_ERRBUF_SIZE]; //錯(cuò)誤信息</p><p>  /*所有網(wǎng)絡(luò)設(shè)備

98、的信息以鏈表形式存在alldevs中*/</p><p>  pcap_findalldevs(&alldevs,errbuf);</p><p>  2) 從鏈表中選擇物理Ethernet卡后,用混雜模式打開(kāi),調(diào)用的函數(shù)為pcap_open_live(const char*device,int snaplen,int promisc,int to_ms,char*errbuf).

99、在這個(gè)函數(shù)中,第一個(gè)參數(shù)為要打開(kāi)的設(shè)備名稱,這里是Ethernet卡,可以從設(shè)備鏈表alldevs中選出。第二個(gè)參數(shù)應(yīng)為捕獲的數(shù)據(jù)包長(zhǎng)度,填入65535以保證在鏈路層的整個(gè)數(shù)據(jù)包都被捕獲。第三個(gè)參數(shù)為打開(kāi)模式,填入1表明用混雜模式打開(kāi)網(wǎng)卡。最后兩個(gè)參數(shù)本別為讀入超時(shí)的時(shí)間和保存錯(cuò)誤信息。</p><p><b>  編譯、設(shè)置過(guò)濾器。</b></p><p>  ch

100、ar packet_filter[]=”ip”;</p><p>  pcap_compile(adhandle,&fcode,packet_filter,1,netmask);//編譯過(guò)濾器</p><p>  pcap_setfilter(adhandle,&fcode); //設(shè)置過(guò)濾器</p><p>  adhandle參數(shù)為

101、網(wǎng)卡描述符,fcode參數(shù)是一個(gè)BPF偽匯編程序,packet_filter參數(shù)用于設(shè)置的過(guò)濾規(guī)則,在這里我們只需要捕獲IP包。</p><p>  4) 可利用pcap_loop函數(shù)捕獲數(shù)據(jù)包。對(duì)于捕獲的數(shù)據(jù)包,去掉數(shù)據(jù)鏈路層的14B的頭部后才是真正的IP包信息。利用winpcap編程和利用socket編程在處理IP包上并沒(méi)有太大區(qū)別,我們依然可以使用7。4節(jié)中采用的數(shù)據(jù)結(jié)構(gòu)IP——HEADER來(lái)保存、解析IP

102、頭部信息。</p><p><b>  八.實(shí)習(xí)體會(huì)</b></p><p>  通過(guò)這次實(shí)驗(yàn),了解到關(guān)于計(jì)算機(jī)網(wǎng)絡(luò)數(shù)據(jù)傳送及處理過(guò)程中,軟件起到了巨大的作用。熟悉了VC++在計(jì)算機(jī)網(wǎng)絡(luò)方面的應(yīng)用,是一次難得的機(jī)會(huì)。</p><p>  同學(xué)們的默鍥配合和合作精神是實(shí)驗(yàn)成功的必要條件,而謹(jǐn)慎對(duì)待事物的態(tài)度是成功的關(guān)鍵。</p>&

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論