




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、西安科技大學(xué)計算機(jī)學(xué)院網(wǎng)絡(luò)原理課程大作業(yè)計算機(jī)網(wǎng)絡(luò)課程大作業(yè)院(系):計算機(jī)學(xué)院專業(yè):計算機(jī)科學(xué)與技術(shù)姓名:班級:學(xué)號:指導(dǎo)教師: 2015年9月16日67任務(wù)一 幀封裝任務(wù)目的: 編寫程序,根據(jù)給出的原始數(shù)據(jù),組裝一個IEEE 802.3格式的幀(題目)默認(rèn)的輸入文件為二進(jìn)制原始數(shù)據(jù)(文件名分別為input1和input2)。 要求程序?yàn)槊钚谐绦?。比如,可?zhí)行文件名為framer.exe,則命令行形式如下:framer inputfileoutputfile,其中,inputfile為原始數(shù)據(jù)文件,outputfile為輸出結(jié)果。 輸出:對應(yīng)input1和input2得結(jié)果分別為outpu
2、t1和output2。任務(wù)要求: 編寫程序,根據(jù)給出的原始數(shù)據(jù),組裝一個IEEE 802.3格式的幀(題目)默認(rèn)的輸入文件為二進(jìn)制原始數(shù)據(jù)(文件名分別為input1和input2)。 要求程序?yàn)槊钚谐绦颉1热?,可?zhí)行文件名為framer.exe,則命令行形式如下:framer inputfileoutputfile,其中,inputfile為原始數(shù)據(jù)文件,outputfile為輸出結(jié)果。 修改并完善程序。輸出:對應(yīng)input1和input2得結(jié)果分別為output1和output2設(shè)計相關(guān)知識:幀:來源于串行線路上的通信。其中,發(fā)送者在發(fā)送數(shù)據(jù)的前后各添加特殊的字符,使它們成為一個幀。Eth
3、ernet從某種程度上可以被看作是機(jī)器之間的數(shù)據(jù)鏈路層連接。按802.3標(biāo)準(zhǔn)的幀結(jié)構(gòu)如下表所示(802.3標(biāo)準(zhǔn)的Ethernet幀結(jié)構(gòu)由7部分組成)802.3標(biāo)準(zhǔn)的幀結(jié)構(gòu)前導(dǎo)碼幀前定界符目的地址源地址長度字段數(shù)據(jù)字段校驗(yàn)字段7B1B(2/6B)(2/6B)(2B)(長度可變)(4B)其中,幀數(shù)據(jù)字段的最小長度為46B。如果幀的MAC數(shù)據(jù)少于46B,則應(yīng)將數(shù)據(jù)字段填充至46B。填充字符是任意的,不計入長度字段值中。在校驗(yàn)字段中,使用的是CRC校驗(yàn)。校驗(yàn)的范圍包括目的地址字段、源地址字段、長度字段、MAC數(shù)據(jù)字段。-以太網(wǎng)/IEEE 802.3幀的結(jié)構(gòu) 下圖所示為以太網(wǎng)/IEEE 802.3幀的基
4、本組成。 如圖所示,以太網(wǎng)和IEEE 802.3幀的基本結(jié)構(gòu)如下: 前導(dǎo)碼(Preamble):由0、1間隔代碼組成,可以通知目標(biāo)站作好接收準(zhǔn)備。 IEEE 802.3幀的前導(dǎo)碼占用7個字節(jié),緊隨其后的是長度為1個字節(jié)的幀首定界符(SOF)。以太網(wǎng)幀把SOF包含在了前導(dǎo)碼當(dāng)中,因此,前導(dǎo)碼的長度擴(kuò)大為8個字節(jié)。 幀首定界符(SOF:Start-of-Frame Delimiter):IEEE 802.3幀中的定界字節(jié),以兩個連續(xù)的代碼1結(jié)尾,表示一幀實(shí)際開始。 目標(biāo)和源地址(DA、SA):表示發(fā)送和接收幀的工作站的地址,各占據(jù)6個字節(jié)。其中,目標(biāo)地址可以是單址,也可以是多點(diǎn)傳送或廣播地址。 類
5、型(以太網(wǎng)):占用2個字節(jié),指定接收數(shù)據(jù)的高層協(xié)議。 長度L(IEEE 802.3):表示緊隨其后的以字節(jié)為單位的數(shù)據(jù)段的長度。 數(shù)據(jù)L(以太網(wǎng)):在經(jīng)過物理層和邏輯鏈路層的處理之后,包含在幀中的數(shù)據(jù)將被傳遞給在類型段中指定的高層協(xié)議。雖然以太網(wǎng)版本2中并沒有明確作出補(bǔ)齊規(guī)定,但是以太網(wǎng)幀中數(shù)據(jù)段的長度最小應(yīng)當(dāng)不低于46個字節(jié)。 數(shù)據(jù)(IEEE 802.3:LLCPDU邏輯鏈路層協(xié)議數(shù)據(jù)單元):IEEE 802.3幀在數(shù)據(jù)段中對接收數(shù)據(jù)的上層協(xié)議進(jìn)行規(guī)定。如果數(shù)據(jù)段長度過小,使幀的總長度無法達(dá)到64個字節(jié)的最小值,那么相應(yīng)軟件將會自動填充數(shù)據(jù)段,以確保整個幀的長度不低于64個字節(jié)。 LLCPD
6、U它的范圍處在46字節(jié)至1500字節(jié)之間。 最小LLCPDU長度46字節(jié)是一個限制,目的是要求局域網(wǎng)上所有的站點(diǎn)都能檢測到該幀,即保證網(wǎng)絡(luò)工作正常。如果LLCPDU小于46個字節(jié),則發(fā)送站的MAC子層會自動填充“0”代碼補(bǔ)齊。 802.3一個幀的長度計算公式: DA+SA+L+LLCPDU+FCS=6+6+2+(461500)+4=641518 即當(dāng)LLCPDU為46個字節(jié)時,幀最小,幀長為64字節(jié);當(dāng)LLCPDU為1500字節(jié)時,幀最大,幀長為1518字節(jié) 幀校驗(yàn)序列(FCS:Frame Check Sequence):該序列包含長度為4個字節(jié)的循環(huán)冗余校驗(yàn)值(CRC),由發(fā)送設(shè)備計算產(chǎn)生,
7、在接收方被重新計算以確定幀在傳送過程中是否被損壞。循環(huán)冗余編碼(CRC)是一種重要的線性分組碼、編碼和解碼方法,具有簡單、檢錯和糾錯能力強(qiáng)等特點(diǎn),在通信領(lǐng)域廣泛地用于實(shí)現(xiàn)差錯控制。CRC校驗(yàn)碼的檢錯能力很強(qiáng),不僅能檢查出離散錯誤,還能檢查出突發(fā)錯誤。利用CRC進(jìn)行檢錯的過程可簡單描述如下:在發(fā)送端根據(jù)要傳送的k位二進(jìn)制碼序列,以一定的規(guī)則產(chǎn)生一個校驗(yàn)用的r位監(jiān)督碼(CRC碼),附在原始信息的后邊,構(gòu)成一個新的二進(jìn)制碼序列(共k+r位),然后發(fā)送出去。在接收端,根據(jù)信息碼和CRC碼之間所遵循的規(guī)則進(jìn)行檢驗(yàn),以確定傳送中是否出錯。這個規(guī)則在差錯控制理論中稱為“生成多項(xiàng)式”。CRC的基本實(shí)現(xiàn)前導(dǎo)碼幀
8、前定界符目的地址源地址長度字段數(shù)據(jù)字段校驗(yàn)字段7B1B(2/6B)(2/6B)(2B)(長度可變)(4B)循環(huán)冗余校驗(yàn)碼的特點(diǎn):(1)CRC校驗(yàn)碼可檢測出所有單個錯誤。(2)CRC校驗(yàn)碼可檢測出所有奇數(shù)位錯誤。(3)CRC校驗(yàn)碼可檢測出所有雙位的錯誤(4)CRC校驗(yàn)碼可檢測出所有小于、等于校驗(yàn)位長度的突發(fā)錯誤。(5)CRC校驗(yàn)碼可以的概率檢測出長度為(K+1)位的突發(fā)錯誤。程序流程圖:任務(wù)分析: 填充幀頭部字段要完成一次幀封裝的過程,首先要完成的就是幀頭部的裝入,這一過程只要將簽到嗎、定界符、目的地址、源地址、長度字段的相應(yīng)數(shù)值按順序?qū)懭刖涂梢粤?。其中,長度字段的值即為要發(fā)送的數(shù)據(jù)的實(shí)際長度。
9、 填充數(shù)據(jù)字段在填充數(shù)據(jù)字段的過程中要注意的主要問題是數(shù)據(jù)字段的長度。802.3標(biāo)準(zhǔn)中規(guī)定了幀數(shù)據(jù)字段的最小長度為46B,最大長度為1500B。如果數(shù)據(jù)不足46B,則需要通過填充0來補(bǔ)足;若數(shù)據(jù)長度超過1500B,則的大獎超過部分封裝入下一個幀進(jìn)行發(fā)送。 CRC校驗(yàn)幀封裝的最后一步就是對數(shù)據(jù)進(jìn)行校驗(yàn),并將校驗(yàn)結(jié)果記入幀校驗(yàn)字段。程序流程圖:CRC計算流程圖:程序源代碼:#include<iostream.h>#include<fstream.h>#include<stdlib.h>void main(intargc,char*argv) /如果輸入命令行不正
10、確,則輸出提示后退出。if(argc!=3) cout<<endl<<"請按以下格式輸入:framerinputfileoutputfile"<<endl;exit(0); /打開指定的輸出文件,以二進(jìn)制方式打開并可讀可寫,如文件存在,則清除其內(nèi)容。fstream file(argv2,ios:out|ios:in|ios:binary|ios:trunc,0); for(inti=0;i<7;i+)file.put(char)0xaa);file.put(char)0xab);/寫入B的前導(dǎo)碼和B的幀前定界符。 char des_
11、add=char(0x00),char(0x00),char(0xE4),char(0x86),char(0x3A),char(0xDC);file.write(des_add,6);/寫入B的目的地址。 char sor_add=char(0x00),char(0x00),char(0x80),char(0x1A),char(0xE6),char(0x65);file.write(sor_add,6);/寫入B的源地址。 /創(chuàng)建輸入文件流并打開指定的輸入文件,以二進(jìn)制方式打開并可讀。ifstreaminfile(argv1,ios:in|ios:binary,0); int length=0
12、;infile.seekg(0,ios:end);/將讀指針移到文件末尾。 length=infile.tellg();/計算指針偏移量,即為輸入文件的長度。 unsigned char* data=new unsigned charlength;/創(chuàng)建字符指針并根據(jù)文件長度初始化。infile.seekg(0,ios:beg);/將讀指針移到文件開始。infile.read(data,length);/將文件數(shù)據(jù)讀入到字符指針data中。file.put(char(length>>8);file.put(char(length&0xff);/將文件長度值按照逆序?qū)懭氲捷敵?/p>
13、文件的長度字段中。file.write(data,length);/將data內(nèi)容寫入到輸出文件中。 /如果輸入文件長度不足B,則用補(bǔ)足B。 if(length<46) for(int j=length;j<46;j+)file.put(char(0x00); file.put(char(0x00);/將數(shù)據(jù)字段后添加個file.seekg(8,ios:beg);/將讀指針指向目的地址字段,從此處開始CRC計算 unsigned char ch;/ch用來保存讀入的字符。 unsigned char crc=char(0x00);/余數(shù)初始值為。 while(1)/進(jìn)行CRC計算
14、file.get(ch); if(ch=0xff)/判斷是否到了文件結(jié)尾,如果是,則退出循環(huán)。 break; for(i=0;i<8;i+)/對入讀入的字符的位分別處理。 if(0x80=(crc&(0x80)/當(dāng)前余數(shù)最高位為,需要進(jìn)行除法運(yùn)算。 crc=(crc<<1)&(0xff);/crc左移位,最低位補(bǔ)。crc=crc|(ch&0x80)>>7);/將輸入數(shù)據(jù)相應(yīng)的值遞補(bǔ)到余數(shù)末位。crc=crc(0x07);/進(jìn)行除法運(yùn)算,即與除數(shù)的低位相異或。 else/當(dāng)前余數(shù)的最高位為,不需要進(jìn)行除法運(yùn)算。 crc=(crc<<
15、;1)&(0xff);/crc左移位,最低位補(bǔ)。crc=crc|(ch&0x80)>>7);/將輸入數(shù)據(jù)相應(yīng)位的值遞補(bǔ)到余數(shù)末位。 ch=ch<<1;/讀到的字符左移位,使數(shù)據(jù)下一位作為輸入位。 file.clear();file.seekp(-1,ios:end);/將寫指針移到輸出文件的最后。file.put(crc);/寫入crc碼。file.close();infile.close();/關(guān)閉輸入文件和輸出文件。cout<<endl<<"數(shù)據(jù)幀文件"<<argv2<<"
16、封裝完成"<<endl;運(yùn)行結(jié)果:運(yùn)行結(jié)果如下所示:執(zhí)行framer.exe文件的結(jié)果如下所示:將ex1作為二進(jìn)制輸入文件,ex2作為輸出文件。 說明:ex1文件內(nèi)容為程序:#!/bin/bash#!/bin/bashyn=yif $yn = "n" ; then echo "OK" exit 0fi小結(jié):實(shí)現(xiàn)幀的封裝,主要是將幀的七個部分-前導(dǎo)碼、幀前定界符、目的地址、源地址、長度字段、數(shù)據(jù)字段和校驗(yàn)字段,一個一個按順序封裝的,最后使得一個幀的封裝得以完成。同時,在編寫程序的過程中,用到了很多的函數(shù),這些函數(shù)的運(yùn)用使得程序簡便而且
17、正確的運(yùn)行出來。任務(wù)二 解析IP數(shù)據(jù)包任務(wù)目的: 設(shè)計一個解析IP數(shù)據(jù)包的程序,并根據(jù)這個程序,說明IP數(shù)據(jù)包的結(jié)構(gòu)及IP協(xié)議的相關(guān)問題,從而對IP層的工作原理有更好的理解和認(rèn)識。任務(wù)要求:本實(shí)驗(yàn)的目標(biāo)是捕獲網(wǎng)絡(luò)中的IP數(shù)據(jù)包,解析數(shù)據(jù)包的內(nèi)容,見個結(jié)果顯示在標(biāo)準(zhǔn)輸出上,并同時寫入日志文件。程序的具體要求如下: 以命令行形式運(yùn)行:ipparselogfile,其中ipparse是程序名,而logfile則代表記錄結(jié)果的日志文件。 在標(biāo)準(zhǔn)輸出、和日志文件中寫入捕獲的IP包的版本、頭長度、服務(wù)類型、數(shù)據(jù)包總長度、數(shù)據(jù)包標(biāo)識、分段標(biāo)志、分段偏移值、生存時間、上層協(xié)議類型、頭校驗(yàn)和、源IP地址和目的I
18、P地址等內(nèi)容。 當(dāng)程序接收到鍵盤輸入Ctrl+C時退出。設(shè)計相關(guān)知識:IP數(shù)據(jù)報的格式說明IP協(xié)議都具有什么功能。其首部,版本目前廣泛使用的版本號為4;首部長度站4bit;服務(wù)類型占8bit,其中服務(wù)類型TOS子域占4位,優(yōu)先級子域占3位,另一位為保留位;總長度字段為2B,IP數(shù)據(jù)包的最大長度是65535B;標(biāo)識占16bit,它是一個計數(shù)器,用來產(chǎn)生數(shù)據(jù)報的標(biāo)識;標(biāo)志占3bit,其中最低為為MF,MF=1時為后面“還有分片”,MF=0表示這是數(shù)據(jù)報片中的最后一個,DF=0時,表示允許分片;片偏移以8個字節(jié)為偏移單位;生存時間字段記為TTL,單位為秒;協(xié)議段占8bit,用于指出次數(shù)據(jù)是使用何種協(xié)
19、議,典型的協(xié)議號有6:TCP,17:UDP,1:ICMP。本程序使用套接字socket編程,將網(wǎng)卡設(shè)為能夠接受流經(jīng)網(wǎng)卡的所有類型的數(shù)據(jù)包。首先,初始化套接字,然后監(jiān)聽數(shù)據(jù)包,解析數(shù)據(jù)包。SOCKET sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP)用來創(chuàng)建套接字,其參數(shù)為通信發(fā)生的區(qū)字段和套接字的類型。WSAIoctl(sock , IO_RCVALL ,&dwBufferInLen , sizeof(dwBufferInLen)函數(shù)用來把網(wǎng)卡設(shè)置為混雜模式。recv(sock,buffer,65535,0)函數(shù)用來接收經(jīng)過的IP包,其參數(shù)分別是套接字描
20、述符,緩沖區(qū)的地址,緩沖區(qū)的大小。typedefstruct IP_HEADip_head;用來定義IP頭部數(shù)據(jù)。setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)函數(shù)用來獲取本機(jī)IP地址htons()函數(shù)將無符號短整型轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序的數(shù)據(jù)本程序在windows環(huán)境下利用C+語言編寫。任務(wù)設(shè)計分析:為了獲取網(wǎng)絡(luò)中的IP數(shù)據(jù)包,必須對網(wǎng)卡進(jìn)行編程,我們使用套接字進(jìn)行編程。 使用套接字 接收數(shù)據(jù)包 定義IP頭部的數(shù)據(jù)結(jié)構(gòu) IP包的解析程序流程圖:具體程序代碼:#include<iostream>#include<winsock2.h&
21、gt;#include<ws2tcpip.h>#include<fstream>#include <windows.h>/#include <winsock.h>#pragma comment(lib,"ws2_32") /指定連接到網(wǎng)絡(luò)應(yīng)用和internet#define IO_RCVALL _WSAIOW(IOC_VENDOR,1) typedef struct IP_HEAD union /定義聯(lián)合 unsigned char Version; unsigned char HeadLen; ; unsigned char
22、 ServiceType; unsigned short TotalLen; unsigned short Identifier; union unsigned short Flags; unsigned short FragOffset; ; unsigned char TimeToLive; unsigned char Protocol; unsigned short HeadChecksum; unsigned int SourceAddr; unsigned int DestinAddr; unsigned char Options; ip_head; /定義IP頭部的數(shù)據(jù)結(jié)構(gòu)void
23、 main(int argc,char *argv) using namespace std; ofstream outfile("e:logfile.txt",ios:out);if(argc!=2) cout<<endl<<"請以下格式輸入命令行:PackParse packet_sum"<<endl; /packet_sum 為要分析IP包的個數(shù)。return; WSADATA WSAData; if(WSAStartup(MAKEWORD(2,2), &WSAData)!=0) cout<<
24、endl<<"WSASTartup初始化失敗"<<endl; return; SOCKET sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP); /三個參分別為通信發(fā)生的區(qū)字段,套接字的類型,與IP協(xié)議if(sock=INVALID_SOCKET) cout<<endl<<"創(chuàng)建Socket失敗!"<<endl; closesocket(sock); WSACleanup(); BOOL flag=TRUE; if(setsockopt(sock,IPPROTO_I
25、P,IP_HDRINCL,(char *) &flag,sizeof(flag)=SOCKET_ERROR) cout<<endl<<"setsockopt操作失敗:"<<WSAGetLastError()<<endl; closesocket(sock); WSACleanup(); char hostName128;/獲取主機(jī)名if(gethostname(hostName,100)=SOCKET_ERROR) cout<<endl<<"gethostname操作失敗:"
26、<<WSAGetLastError()<<endl; closesocket(sock); WSACleanup(); hostent *pHostIP; /獲取本地IPif(pHostIP=gethostbyname(hostName)=NULL) cout<<endl<<"gethostbyname操作失敗:"<<WSAGetLastError()<<endl; closesocket(sock); WSACleanup(); sockaddr_in host_addr;/ host_addr.si
27、n_family=AF_INET; host_addr.sin_port=htons(6000); host_addr.sin_addr=*(in_addr *)pHostIP->h_addr_list0; if(bind(sock,(PSOCKADDR)&host_addr,sizeof(host_addr)=SOCKET_ERROR) cout<<endl<<"bind操作失敗:"<<WSAGetLastError()<<endl; closesocket(sock); /綁定網(wǎng)卡WSACleanup();
28、DWORD dwBufferLen10; DWORD dwBufferInLen=1; DWORD dwBytesReturned=0; if(WSAIoctl(sock , IO_RCVALL ,&dwBufferInLen , sizeof(dwBufferInLen) , &dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL)=SOCKET_ERROR) cout<<endl<<"WSAIoctl操作失敗:"<<WSAGetLastError(
29、)<<endl; closesocket(sock); /將網(wǎng)卡設(shè)為混雜模式,以接受所有數(shù)據(jù)WSACleanup(); cout<<endl<<"開始解析IP包:"<<endl; char buffer65535; /設(shè)置緩沖區(qū)int packsum=atoi(argv1); /字符串轉(zhuǎn)換為整形for(int i=0;i<packsum;i+) if(recv(sock,buffer,65535,0)>0) /四個參數(shù)分別是套接字描述符,緩沖區(qū)的地址,緩沖區(qū)大小,附加標(biāo)志 ip_head ip=*(ip_head
30、*)buffer; cout<<"-"<<endl; cout<<"版本:"<<(ip.Version>>4)<<endl; /獲取頭部長度字段cout<<"頭部長度:"<<(ip.HeadLen&0x0f)*4)<<endl; /獲取頭部長度字段cout<<"服務(wù)類型:Priority"<<(ip.ServiceType>>5)<<", Se
31、rvice"<<(ip.ServiceType>>1)&0x0f)<<endl; /優(yōu)先級子域和TOS子域cout<<"總長度:"<<ip.TotalLen<<endl;/獲取總長度字段cout<<"標(biāo)識符:"<<ip.Identifier<<endl;/獲取標(biāo)識字段cout<<"標(biāo)志位:"<<(ip.Flags>>15)&0x01)<<",DF
32、= "<<(ip.Flags>>14)&0x01)<<",Mf="<<(ip.Flags>>13)&0x01)<<endl; /獲得標(biāo)志字段cout<<"片偏移:"<<(ip.FragOffset&0x1fff)<<endl; /獲取分段偏移字段cout<<"生存周期:"<<(int)ip.TimeToLive<<endl; /獲取生存時間字段cout<
33、<"協(xié)議:Protocol"<<(int)ip.Protocol<<endl; /獲取協(xié)議字段cout<<"頭部校驗(yàn)和:"<<ip.HeadChecksum<<endl; /獲取頭校驗(yàn)和字段cout<<"原地址:"<<inet_ntoa(*(in_addr *)&ip.SourceAddr)<<endl; /獲取源IP地址字段cout<<"目的IP地址:"<<inet_ntoa(*(
34、in_addr *)&ip.DestinAddr)<<endl; /獲取目的IP地址字段outfile<<"-"<<endl; outfile<<"版本:"<<(ip.Version>>4)<<endl; outfile<<"頭部長度:"<<(ip.HeadLen&0x0f)*4)<<endl; outfile<<"服務(wù)類型:Priority"<<(ip.S
35、erviceType>>5)<<", Service"<<(ip.ServiceType>>1)&0x0f)<<endl; outfile<<"總長度:"<<ip.TotalLen<<endl; outfile<<"標(biāo)識符:"<<ip.Identifier<<endl; outfile<<"標(biāo)志位:"<<(ip.Flags>>15)&
36、0x01)<<",DF= "<<(ip.Flags>>14)&0x01)<<",Mf="<<(ip.Flags>>13)&0x01)<<endl; outfile<<"片偏移:"<<(ip.FragOffset&0x1fff)<<endl; outfile<<"生存周期:"<<(int)ip.TimeToLive<<endl; outfi
37、le<<"協(xié)議:Protocol"<<(int)ip.Protocol<<endl; outfile<<"頭部校驗(yàn)和:"<<ip.HeadChecksum<<endl; outfile<<"原地址:"<<inet_ntoa(*(in_addr *)&ip.SourceAddr)<<endl; outfile<<"目的IP地址:"<<inet_ntoa(*(in_addr *)&
38、amp;ip.DestinAddr)<<endl; closesocket(sock); WSACleanup(); 程序運(yùn)行結(jié)果:程序編譯運(yùn)行后:以命令行形式運(yùn)行程序ipparse:同時在程序所在的文件夾中生成了名為logfile的txt文件,里面記錄了上面顯示的內(nèi)容。小結(jié):IP數(shù)據(jù)報的格式說明了IP協(xié)議都具有什么功能,因?yàn)橥耆恢廊绾问褂锰捉幼謘ocket()函,查閱了相關(guān)資料,了解了IP數(shù)據(jù)報的各種位與協(xié)議的概念和意義,通過解析IP數(shù)據(jù)包這個任務(wù),基本掌握了用套接字編程來實(shí)現(xiàn)獲取并解析IP數(shù)據(jù)包的方法。任務(wù)三 發(fā)送TCP數(shù)據(jù)包任務(wù)目的: 設(shè)計一個發(fā)送TCP數(shù)據(jù)包的程序,并根
39、據(jù)本設(shè)計說明TCP數(shù)據(jù)包的結(jié)構(gòu)以及TCP協(xié)議與IP協(xié)議的關(guān)系,使大家對TCP協(xié)議的工作原理有更深入的認(rèn)識。任務(wù)要求:本程序的功能是填充一個TCP數(shù)據(jù)包,并發(fā)送給目的主機(jī)。 以命令行形式運(yùn)行:SendTCPsource_ipsource_portdest_ipdest_port其中SendTCP為程序名;source_ip為源IP地址;source_port為源端口;dest_ip為目的IP地址;dest_port為目的端口。 其他的TCP頭部參數(shù)自行設(shè)定。 數(shù)據(jù)字段為“This is my homework of network!”. 成功發(fā)送后在屏幕上輸出“send OK”。課程設(shè)計分析:
40、使用原始套接字 定義IP頭部、TCP頭部和偽頭部的數(shù)據(jù)結(jié)構(gòu) 填充數(shù)據(jù)包 發(fā)送數(shù)據(jù)包設(shè)計思想:本課程設(shè)計的目標(biāo)是發(fā)送一個TCP數(shù)據(jù)包,可以利用原始套接字來完成這個工作。整個程序由初始化原始套接字和發(fā)送TCP數(shù)據(jù)包兩個部分組成。創(chuàng)建一個原始套接字,并設(shè)置IP頭選項(xiàng)SOCKET sock; sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP); 或者:sock=WSASoccket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED); 設(shè)置SOCK_RAW標(biāo)志,表示我們聲明的是一個原始套接字類型。為使用發(fā)送接
41、收超時設(shè)置,必須將標(biāo)志位置位置為WSA_FLAG_OVERLAPPED。在本課程設(shè)計中,發(fā)送TCP包時隱藏了自己的IP地址,因此我們要自己填充IP頭,設(shè)置IP頭操作選項(xiàng)。其中flag設(shè)置為ture,并設(shè)定 IP_HDRINCL 選項(xiàng),表明自己來構(gòu)造IP頭。注意,如果設(shè)置IP_HDRINCL 選項(xiàng),那么必須具有 administrator權(quán)限,要不就必須修改注冊表:HKEY_LOCAL_MACHINESystemCurrentControlSetServicesAfdParameter 修改鍵:DisableRawSecurity(類型為DWORD),把值修改為 1。如果沒有,就添加。BOOL
42、Flag=TRUE; setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&Flag, sizeof(Flag);int timeout=1000;setsockopt(sock, SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout, sizeof(timeout);在這里我們使用基本套接字SOL_SOCKET,設(shè)置SO_SNDTIMEO表示使用發(fā)送超時設(shè)置,超時時間設(shè)置為1000ms。構(gòu)造IP頭和TCP頭這里, IP頭和TCP頭以及TCP偽部的構(gòu)造請參考下面它們的數(shù)據(jù)結(jié)構(gòu)。計算校驗(yàn)和的子函數(shù)在填充數(shù)據(jù)包的
43、過程中,需要調(diào)用計算校驗(yàn)和的函數(shù)checksum兩次,分別用于校驗(yàn)IP頭和TCP頭部(加上偽頭部),其實(shí)現(xiàn)代碼如下: USHORT checksum(USHORT *buffer, int size) unsigned long cksum=0; while(size >1) cksum+=*buffer+; size -=sizeof(USHORT); if(size ) cksum += *(UCHAR*)buffer; cksum = (cksum>> 16) + (cksum& 0xffff); cksum += (cksum>>16); retu
44、rn (USHORT)(cksum); 程序流程圖:源程序代碼:#include <stdio.h>#include <winsock2.h>#include <ws2tcpip.h>#include <time.h>#include <windows.h>#include <string.h>#include <stdlib.h>#include <iostream.h>#pragma comment(lib,"ws2_32.lib")#define IPVER 4 /IP協(xié)議
45、預(yù)定#define MAX_BUFF_LEN 65500 /發(fā)送緩沖區(qū)最大值typedef struct ip_hdr /定義IP首部 UCHAR h_verlen; /4位首部長度,4位IP版本號UCHAR tos; /8位服務(wù)類型TOS USHORT total_len; /16位總長度(字節(jié))USHORT ident; /16位標(biāo)識USHORT frag_and_flags; /3位標(biāo)志位UCHAR ttl; /8位生存時間 TTL UCHAR proto; /8位協(xié)議 (TCP, UDP 或其他) USHORT checksum; /16位IP首部校驗(yàn)和ULONG sourceIP;
46、/32位源IP地址ULONG destIP; /32位目的IP地址IP_HEADER; typedef struct tsd_hdr /定義TCP偽首部 ULONG saddr; /源地址ULONG daddr; /目的地址UCHAR mbz; /沒用UCHAR ptcl; /協(xié)議類型USHORT tcpl; /TCP長度PSD_HEADER; typedef struct tcp_hdr /定義TCP首部 USHORT th_sport; /16位源端口USHORT th_dport; /16位目的端口ULONG th_seq; /32位序列號ULONG th_ack; /32位確認(rèn)號UCH
47、AR th_lenres; /4位首部長度/6位保留字UCHAR th_flag; /6位標(biāo)志位USHORT th_win; /16位窗口大小USHORT th_sum; /16位校驗(yàn)和USHORT th_urp; /16位緊急數(shù)據(jù)偏移量TCP_HEADER; /CheckSum:計算校驗(yàn)和的子函數(shù)USHORT checksum(USHORT *buffer, int size) unsigned long cksum=0; while(size >1) cksum+=*buffer+; size -=sizeof(USHORT); if(size) cksum += *(UCHAR*)
48、buffer; cksum = (cksum>> 16) + (cksum& 0xffff); cksum += (cksum>>16); return (USHORT)(cksum); int main(intargc, char* argv) WSADATA WSAData; SOCKET sock; IP_HEADER ipHeader; TCP_HEADER tcpHeader; PSD_HEADER psdHeader; char Sendto_BuffMAX_BUFF_LEN; /發(fā)送緩沖區(qū) unsigned short check_BuffMAX_
49、BUFF_LEN; /檢驗(yàn)和緩沖區(qū)const char tcp_send_data="This is my homework of networt,I am happy!" BOOL flag; intrect,nTimeOver; if (argc!= 5) printf("Useage: SendTcp soruce_ip source_port dest_ip dest_port n"); return false; if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0) printf("WSASt
50、artup Error!n"); return false; if(sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED)=INVALID_SOCKET) printf("Socket Setup Error!n"); return false; flag=true; if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag)=SO CKET_ERROR) printf("setsock
51、opt IP_HDRINCL error!n"); return false; nTimeOver=1000; if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver)=SOCKET_ERROR) printf("setsockopt SO_SNDTIMEO error!n"); return false; /填充IP首部ipHeader.h_verlen=(IPVER<<4 | sizeof(ipHeader)/sizeof(unsig
52、ned long); ipHeader.tos=(UCHAR)0; ipHeader.total_len=htons(unsigned short)sizeof(ipHeader)+sizeof(tcpHeader)+sizeof(tcp_send_data); ipHeader.ident=0; /16位標(biāo)識ipHeader.frag_and_flags=0; /3位標(biāo)志位ipHeader.ttl=128; /8位生存時間ipHto=IPPROTO_UDP; /協(xié)議類型ipHeader.checksum=0; /檢驗(yàn)和暫時為0ipHeader.sourceIP=inet_a
53、ddr(argv1); /32位源IP地址ipHeader.destIP=inet_addr(argv3); /32位目的IP地址 /計算IP頭部檢驗(yàn)和memset(check_Buff,0,MAX_BUFF_LEN);memcpy(check_Buff,&ipHeader,sizeof(IP_HEADER);ipHeader.checksum=checksum(check_Buff,sizeof(IP_HEADER); /構(gòu)造TCP偽首部psdHeader.saddr=ipHeader.sourceIP;psdHeader.daddr=ipHeader.destIP;psdHeade
54、r.mbz=0;psdHeader.ptcl=ipHto;psdHeader.tcpl=htons(sizeof(TCP_HEADER)+sizeof(tcp_send_data); /填充TCP首部tcpHeader.th_dport=htons(atoi(argv4); /16位目的端口號tcpHeader.th_sport=htons(atoi(argv2); /16位源端口號tcpHeader.th_seq=0; /SYN序列號tcpHeader.th_ack=0; /ACK序列號置為0 /TCP長度和保留位tcpHeader.th_lenres=(sizeof(tc
55、pHeader)/sizeof(unsigned long)<<4|0); tcpHeader.th_flag=2; /修改這里來實(shí)現(xiàn)不同的標(biāo)志位探測,2是SYN,1是/FIN,16是ACK探測等等tcpHeader.th_win=htons(unsigned short)16384); /窗口大小tcpHeader.th_urp=0; /偏移大小tcpHeader.th_sum=0; /檢驗(yàn)和暫時填為0 /計算TCP校驗(yàn)和memset(check_Buff,0,MAX_BUFF_LEN);memcpy(check_Buff,&psdHeader,sizeof(psdHea
56、der); memcpy(check_Buff+sizeof(psdHeader),&tcpHeader,sizeof(tcpHeader); memcpy(check_Buff+sizeof(PSD_HEADER)+sizeof(TCP_HEADER),tcp_send_data,sizeof(tcp_send_data);tcpHeader.th_sum=checksum(check_Buff,sizeof(PSD_HEADER)+sizeof(TCP_HEADER)+sizeof(tcp_send_data); /填充發(fā)送緩沖區(qū)memset(Sendto_Buff,0,MAX_B
57、UFF_LEN);memcpy(Sendto_Buff,&ipHeader,sizeof(IP_HEADER);memcpy(Sendto_Buff+sizeof(IP_HEADER),&tcpHeader,sizeof(TCP_HEADER);memcpy(Sendto_Buff+sizeof(IP_HEADER)+sizeof(TCP_HEADER),tcp_send_data,sizeof(tcp_send_data);intdatasize=sizeof(IP_HEADER)+sizeof(TCP_HEADER)+sizeof(tcp_send_data); /發(fā)送數(shù)據(jù)報的目的地址 SOCKADDR_IN dest; memset(&dest,0,sizeof(dest);dest.sin_family=AF_INET; dest.sin_addr.s_addr=inet_addr(argv3); dest.si
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年環(huán)保產(chǎn)業(yè)項(xiàng)目可行性研究評估報告
- 成人教育終身學(xué)習(xí)體系構(gòu)建與平臺運(yùn)營中的遠(yuǎn)程教育技術(shù)發(fā)展趨勢報告
- 工業(yè)互聯(lián)網(wǎng)平臺數(shù)字簽名技術(shù)規(guī)范與工業(yè)互聯(lián)網(wǎng)平臺數(shù)據(jù)治理報告
- 社會實(shí)踐自我鑒定總結(jié)范文
- 大型公司辦公室管理制度
- 泵站配電安全管理制度
- 2025年四川省遂寧市中考生物真題(原卷版)
- 土溪鎮(zhèn)三公經(jīng)費(fèi)管理制度
- 加裝電梯出入口管理制度
- 分公司勞務(wù)派遣管理制度
- 國家開放大學(xué)電大《生產(chǎn)管理》2024-2024期末試題及答案試卷號
- 初中生物中考全四冊復(fù)習(xí)知識點(diǎn)總結(jié)
- 2024年陜西省中考生物真題(含解析)
- 12J003《室外工程圖集》
- 浙江省杭州市濱江區(qū)2023-2024學(xué)年八年級下學(xué)期期末科學(xué)試題(解析版)
- 大學(xué)武術(shù)智慧樹知到期末考試答案章節(jié)答案2024年浙江大學(xué)
- 河南省許昌市2023-2024學(xué)年高一下學(xué)期期末考試生物試題(無答案)
- 農(nóng)產(chǎn)品購銷合同范本版
- 農(nóng)業(yè)工程概論智慧樹知到期末考試答案章節(jié)答案2024年昆明理工大學(xué)
- 中國古都西安英文介紹課件
- 《相遇問題》課件
評論
0/150
提交評論