版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、<p><b> 目 錄</b></p><p><b> 1 引言2</b></p><p> 1.1 課程設(shè)計(jì)目的2</p><p> 1.2 課程設(shè)計(jì)內(nèi)容2</p><p><b> 2課程設(shè)計(jì)原理3</b></p><p
2、> 2.1 ICMP的簡介和原理3</p><p> 2.2 traceroute程序的基本原理3</p><p> 2.3traceroute實(shí)現(xiàn)的功能3</p><p><b> 3 設(shè)計(jì)步驟4</b></p><p> 3.1 traceroute流程圖………………………………………..6&
3、lt;/p><p> 3.2 traceroute的核心程序…………………………………..7</p><p> 3.3traceroute程序運(yùn)行結(jié)果………………...........................7</p><p><b> 4 心得結(jié)論8</b></p><p><b> 5 參考文
4、獻(xiàn)9</b></p><p><b> 6 程序清單9</b></p><p><b> 1 引 言</b></p><p> Internet,是目前世界上最大的計(jì)算機(jī)網(wǎng)絡(luò),更確切的說是網(wǎng)絡(luò)中的網(wǎng)絡(luò),它由遍布全球的幾萬局域網(wǎng)和數(shù)百萬臺計(jì)算機(jī)組成,并通過用于異構(gòu)網(wǎng)絡(luò)的TCP/IP協(xié)議進(jìn)行網(wǎng)間通信。互聯(lián)
5、網(wǎng)中,信息的傳送是通過網(wǎng)中許多段的傳輸介質(zhì)和設(shè)備從一端到達(dá)另一端。每一個(gè)連接在Internet上的設(shè)備,如主機(jī)、路由器、接入服務(wù)器等一般情況下都會有一個(gè)獨(dú)立的IP地址。通過Traceroute我們可以知道信息從你的計(jì)算機(jī)到互聯(lián)網(wǎng)另一端的主機(jī)是走的什么路勁。當(dāng)然每次數(shù)據(jù)包由某一同樣的出發(fā)點(diǎn)到達(dá)某一同樣的目的地走的路勁可能會不同,但基本上來說大部分時(shí)候所走的路由是相同的。隨著Internet(國際互聯(lián)網(wǎng))的發(fā)展,越來越多的服務(wù)通過網(wǎng)絡(luò)提供給
6、大眾,與此同時(shí),針對互聯(lián)網(wǎng)的攻擊事件也越來越頻繁。所謂路由追蹤實(shí)際上就是在IP網(wǎng)絡(luò)上判斷從源到達(dá)目的所經(jīng)過的路由器的IP地址,其基本的實(shí)現(xiàn)手段都是向目的地發(fā)送數(shù)據(jù)包以獲取經(jīng)過的路由器的IP。由于Internet上的路由協(xié)議是動態(tài)的,所以每次形成的數(shù)據(jù)包從同一個(gè)出發(fā)點(diǎn)到達(dá)目的地的路由可能會不一樣,但由于路由算法有一定的穩(wěn)定性,在大部分時(shí)侯所走的路由會是相同的。</p><p> 1.1 課程設(shè)計(jì)目的</p&
7、gt;<p> 1.這次課程設(shè)計(jì),主要為了加深同學(xué)們對計(jì)算機(jī)網(wǎng)絡(luò)網(wǎng)絡(luò)的理解和認(rèn)識</p><p> 2.了解信息在計(jì)算機(jī)網(wǎng)絡(luò)與網(wǎng)絡(luò)之間的傳送和接收</p><p> 3.進(jìn)一步加深了解網(wǎng)絡(luò)與網(wǎng)絡(luò)之間的協(xié)議</p><p> 4.理解網(wǎng)絡(luò)中的IP地址以及路由之間的相關(guān)命令。</p><p> 1.2 課程設(shè)計(jì)內(nèi)容<
8、;/p><p> 1.已知參數(shù):輸入:目的節(jié)點(diǎn)IP地址或主機(jī)名;輸出:從控制臺屏幕輸出IP報(bào)文由本機(jī)出發(fā)到達(dá)目的主機(jī)所經(jīng)過的路由信息。</p><p> 2.設(shè)計(jì)要求:通過原始套接字編程,實(shí)現(xiàn)Tracert的基本功能</p><p> Ping功能:發(fā)送ICMP數(shù)據(jù)包到目標(biāo)計(jì)算機(jī),如有返回,顯示響應(yīng)時(shí)間等</p><p> 路由探測功能:
9、依次Ping途經(jīng)的路由器或網(wǎng)關(guān)設(shè)備,依次顯示途經(jīng)路由器的響應(yīng)時(shí)間。</p><p><b> ?。ㄔ黾拥墓δ埽?lt;/b></p><p> 2.1初始化Windows Sockets網(wǎng)絡(luò)環(huán)境;</p><p> 2.2解析命令行參數(shù),構(gòu)造目的端socket地址;</p><p> 2.3定義IP、ICMP報(bào)文;<
10、;/p><p> 2.4接收ICMP差錯(cuò)報(bào)文并進(jìn)行解析</p><p><b> 2 設(shè)計(jì)原理</b></p><p> raceroute是一個(gè)路由跟蹤命令,它通過ICMP協(xié)議和IP header中TTL(存活時(shí)間)來實(shí)現(xiàn)的。 具體而言就是:發(fā)送方發(fā)出一個(gè)TTL是1的IP Datagram (事實(shí)上每個(gè)數(shù)據(jù)包發(fā)送三次,大小為40字節(jié),包括本
11、機(jī)的IP 地址,目的主機(jī)的IP 地址以及時(shí)間戳),當(dāng)經(jīng)由第一個(gè)路由器時(shí),路由器將該數(shù)據(jù)包的TTL減1,發(fā)現(xiàn)此時(shí)的TTL為0,將數(shù)據(jù)包丟失,同時(shí)向源主機(jī)發(fā)送一個(gè)ICMP Time-to-Exceed 報(bào)文(包括源主機(jī)的IP 地址、路由地址以及路由的相關(guān)消息),源主機(jī)收到這個(gè)數(shù)據(jù)包后就知道了這個(gè)路由器在這條路徑上。同理發(fā)送第二個(gè)、第三個(gè)......第n個(gè)。源主機(jī)將每次IP數(shù)據(jù)報(bào)的TTL+1,直到某個(gè)數(shù)據(jù)報(bào)到達(dá)了目的地址,此時(shí)不知發(fā)回一個(gè)IC
12、MP?。裕椋恚澹簦铮牛悖澹澹?,而是發(fā)送一個(gè)數(shù)據(jù)報(bào)的響應(yīng)報(bào)文。當(dāng)源主機(jī)收到這樣一個(gè)報(bào)文后便知道數(shù)據(jù)包已經(jīng)到達(dá)了目的地。Traceroute提取發(fā) ICMP TTL到期消息設(shè)備的IP地址并作域名解析。每次 ,Traceroute都打印出一系列數(shù)據(jù),包括所經(jīng)過的路由設(shè)備的域名及 IP地址,三個(gè)包每次來回所花時(shí)間。Traceroute 有</p><p> 2.1 ICMP的簡介和原理</p>&
13、lt;p> ICMP(Internet Control Message Protocol),即Internet控制報(bào)文協(xié)議, 它是TCP/IP協(xié)議族的一個(gè)子協(xié)議,屬于網(wǎng)絡(luò)層面向無連接的協(xié)議,主要用于在主機(jī)與路由器之間傳遞控制信息,包括報(bào)告錯(cuò)誤、交換受限控制和狀態(tài)信息等。當(dāng)遇到IP數(shù)據(jù)無法訪問目標(biāo)、IP路由器無法按當(dāng)前的傳輸速率轉(zhuǎn)發(fā)數(shù)據(jù)包等情況時(shí),會自動發(fā)送ICMP消息。ICMP報(bào)文被包裝成IP數(shù)據(jù)包傳到數(shù)據(jù)鏈路層進(jìn)行傳輸。通過I
14、CMP協(xié)議,主機(jī)和路由器可以報(bào)告錯(cuò)誤并交換相關(guān)的狀態(tài)信息。ICMP對于TCP/IP協(xié)議的可靠運(yùn)行是至關(guān)重要的。 ICMP報(bào)文結(jié)構(gòu)如圖1所示:</p><p> 2.2 traceRoute程序的基本原理</p><p> 路由追蹤的主要原理是根據(jù)路徑上各路由器對數(shù)據(jù)報(bào)的存活時(shí)(Time to Live,TTL)做不同的處理,使其產(chǎn)生超時(shí)ICMP消息響應(yīng),反饋至源主機(jī),從而獲得此跳路由器
15、或主機(jī)的IP。照此再發(fā)送下一個(gè)TTL經(jīng)過自增的數(shù)據(jù)報(bào),直至獲得整個(gè)路由中各節(jié)點(diǎn)的IP或者接收到錯(cuò)誤的消息。詳細(xì)過程描述如下:</p><p> 1) 置n = 1。假設(shè)該過程中共經(jīng)過M個(gè)路由器。</p><p> 2) 源主機(jī)S向目標(biāo)主機(jī)D發(fā)送一個(gè)TTL為n的UDP數(shù)據(jù)報(bào)。并設(shè)定端口號(一般大于30 000) 。</p><p> 3) 路由器(或者網(wǎng)關(guān)、主機(jī)
16、) Rn 對接收到的數(shù)據(jù)報(bào)的TTL 值n做減1處理。</p><p> 4) 若n = 0,則丟棄UDP數(shù)據(jù)報(bào),向源主機(jī)S發(fā)送ICMP超時(shí)報(bào)文。</p><p> 5) 若n ≥ 1,繼續(xù)向目標(biāo)主機(jī)D發(fā)送經(jīng)過處理的數(shù)據(jù)報(bào)。</p><p> 6) 源主機(jī)S分析返回的ICMP報(bào)文, 從中提取出發(fā)送者Rn的地址IPn并做記錄。</p><p&
17、gt; 7) 若收到“端口不可達(dá)”的ICMP報(bào)文,則發(fā)送方即目標(biāo)主機(jī)D,記錄其地址IPn,追蹤完成。</p><p> 8) 置n = n +1,繼續(xù)向目標(biāo)主機(jī)D發(fā)送TTL為n的數(shù)據(jù)報(bào)。</p><p> 注意,這里使UDP數(shù)據(jù)報(bào)的端口號大于30000,是因?yàn)橐话愕膽?yīng)用程序不可能使用如此高的端口號。當(dāng)然這并非絕對,若出現(xiàn)例外,則源主機(jī)會發(fā)現(xiàn)等待超時(shí),于是隨機(jī)改變此UDP數(shù)據(jù)報(bào)的端口號
18、,再次發(fā)送。這樣最終可以在目標(biāo)主機(jī)上找到一個(gè)空閑的端口號。另外,這里假設(shè)路由器和目標(biāo)主機(jī)沒有被配置為“過濾ICMP”或者做了其他的非常規(guī)處理,如果被做了類似的配置,則上面的追蹤機(jī)制就無能為力了。</p><p> 2.3 traceRoute實(shí)現(xiàn)的功能</p><p> IP數(shù)據(jù)報(bào)的首部由兩部分構(gòu)成:固定部分和可變部分。固定部分的長度是20個(gè)字段,可變部分由許多選項(xiàng)構(gòu)成,最長可達(dá)40
19、個(gè)字節(jié)。雖然選項(xiàng)并不是IP數(shù)據(jù)報(bào)的必需部分,但選項(xiàng)的處理卻是IP軟件的必需部分。</p><p> 在現(xiàn)在的TCP/IP協(xié)議中,只定義了六種選項(xiàng),對于我們進(jìn)行路由追蹤技術(shù)有用的是記錄路由選項(xiàng),一個(gè)記錄路由選項(xiàng)是用來記錄處理IP數(shù)據(jù)報(bào)的互聯(lián)網(wǎng)路由器的IP地址。因?yàn)槭撞康淖畲箝L度是60個(gè)字節(jié),它包括20個(gè)字節(jié)的基本首部。這就意味著只剩下40個(gè)字節(jié)留下給選項(xiàng)部分,所以通過選項(xiàng)字段最多能夠記錄9個(gè)路由器的IP地址。源站
20、在選項(xiàng)中創(chuàng)建一個(gè)位標(biāo)置(placeholder),用來填入所經(jīng)過的各路由器,圖2給出了記錄路由選項(xiàng)的格式。</p><p><b> 圖2 記錄路由選項(xiàng)</b></p><p> 向目的主機(jī)發(fā)送一個(gè)ICMP報(bào)文,這種方法只要求使用一個(gè)套接字。ICMP即Internet控制報(bào)文協(xié)議,是一種用于特殊用途的報(bào)文機(jī)制,可以使互聯(lián)網(wǎng)中的路由器或主機(jī)報(bào)告差錯(cuò)或提供有關(guān)意外情況
21、的信息。盡管UDP和ICMP工作在TCP/IP的不同層次上,但他們的封裝是類似的。ICMP報(bào)文為兩級封裝ICMP報(bào)文放在IP數(shù)據(jù)報(bào)的數(shù)據(jù)部分,數(shù)據(jù)報(bào)則放在幀的數(shù)據(jù)中進(jìn)行網(wǎng)絡(luò)傳輸(如圖3所示)ICMP報(bào)文與其他普通報(bào)文一樣,具有相同的路由選擇,并沒有特殊的優(yōu)先權(quán)和增加可靠性。通過路由選項(xiàng)的方法記錄路由的實(shí)現(xiàn)同UDP數(shù)據(jù)報(bào)是相似的,這里主要說明通過TTL方法的實(shí)現(xiàn)。</p><p> 圖3 ICMP報(bào)文的兩級封裝&
22、lt;/p><p> 3.1traceroute流程圖</p><p> 根據(jù)要求設(shè)計(jì)好的流程圖如圖4所示:</p><p><b> 圖4 流程圖</b></p><p> 3.2 traceroute的核心程序</p><p> 整個(gè)設(shè)計(jì)過程的核心程序代碼:</p><
23、;p> #include "stdafx.h"</p><p> #include "MyPing.h"</p><p> #include "Ping.h"</p><p> #include "MyPingDlg.h"</p><p> #if
24、def _DEBUG</p><p> #undef THIS_FILE</p><p> static char THIS_FILE[]=__FILE__;</p><p> #define new DEBUG_NEW</p><p><b> #endif</b></p><p>
25、void CPing::Ping(int timeout)</p><p> { m_hSocket = WSASocket (AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,WSA_FLAG_OVERLAPPED);</p><p> if (m_hSocket == INVALID_SOCKET) </p><p> {A
26、fxMessageBox("socket 創(chuàng)建失敗!");</p><p><b> return ;}</b></p><p> Start sending/receiving ICMP packets開始發(fā)送/接收ICMP的數(shù)據(jù)包</p><p> //static int nCount = 0;靜態(tài)的nCount
27、 = 0。</p><p> int nCount=0;</p><p><b> while(1) </b></p><p> {int bwrote;if (nCount++ == 4) </p><p><b> break;</b></p><p> ((I
28、cmpHeader*)icmp_data)->i_cksum = 0;</p><p> ((IcmpHeader*)icmp_data)->timestamp = GetTickCount();</p><p> ((IcmpHeader*)icmp_data)->i_seq = seq_no++;</p><p> ((IcmpHeade
29、r*)icmp_data)->i_cksum = </p><p> checksum((USHORT*)icmp_data, datasize);</p><p> bwrote = sendto(m_hSocket, icmp_data, datasize, 0, </p><p> (struct sockaddr*)&m_addrDest
30、, sizeof(m_addrDest));</p><p> if (bwrote == SOCKET_ERROR)</p><p> { if (WSAGetLastError() == WSAETIMEDOUT) </p><p> {m_dlg->m_result+="Timed out ! \r\n";</p>
31、<p> m_dlg->SetDlgItemText(IDC_EDIT2,m_dlg->m_result);</p><p> continue; }</p><p> AfxMessageBox("發(fā)送數(shù)據(jù)函數(shù)調(diào)用錯(cuò)誤!");</p><p><b> return ;}</b></
32、p><p> 在運(yùn)行程序后得到的對話框中輸入www.sina.com ,再單擊路由跟蹤,就可以詳細(xì)的觀察到路由整個(gè)的跟蹤過程,如圖5所示:</p><p> 3.3 traceroute程序運(yùn)行結(jié)果</p><p><b> 圖5路由跟蹤示意圖</b></p><p><b> 4心得結(jié)論</b>
33、;</p><p> 在整個(gè)課程設(shè)計(jì)過程中,首先得仔細(xì)分析課程設(shè)計(jì)任務(wù)書,根據(jù)要求編寫好程序代碼,然后運(yùn)行程序,分析得到的結(jié)果。在編寫代碼過程中,遇到許多問題。開始看到題目不知道該如何下手去做。編寫好的代碼,在VC++平臺上運(yùn)行時(shí),總是出現(xiàn)錯(cuò)誤,最終在老師的幫助下,成功的解決了該問題。還有在宿舍運(yùn)行tracert后一閃就沒了,也不知道是什么原因,上網(wǎng)查找了解到,必須得先運(yùn)行CMD,然后在CMD里運(yùn)行其他命令。成
34、功的運(yùn)行tracert后,出現(xiàn)的一連串?dāng)?shù)字,不知道是什么意思,結(jié)合老師上課所講的東西并仔細(xì)分析才知道,192.168.20.45是IP地址,0ms是跳到下個(gè)IP地址所用的時(shí)間。從整體來說這次課程設(shè)計(jì)是成功的。但中間存在一些細(xì)節(jié)問題,程序代碼過于復(fù)雜,沒有很好的用語句解釋出程序中的代碼。每次課程設(shè)計(jì)都讓我們學(xué)到了很多書本上學(xué)不到的東西,如嚴(yán)謹(jǐn)?shù)淖鍪嘛L(fēng)格,認(rèn)真學(xué)習(xí)的態(tài)度,不懂要問的道理。</p><p><b&
35、gt; 5參考文獻(xiàn)</b></p><p> [1]W Richard Stevens. TCP/ IP Illust rated ,Volum 1 :The Protocols[M]1 北京:機(jī)械工業(yè)出版社,2002.85296.</p><p> [2]W Richard Stevens. UNIX Network ProgrammingVolum1Networkin
36、g APIs :Socket s and XTI ( Second</p><p> Edition) (影印版) [M] . 北京: 清華大學(xué)出版社,2002.</p><p> [3][日]井口信和. TCP/ IP 網(wǎng)絡(luò)工具篇[M] . 吳松芝,董江洪譯. 北京:科學(xué)出版社,2003. 1582162.</p><p> [4]余青霓,王曉程,周鋼,等.
37、 網(wǎng)絡(luò)入侵檢測分析員手冊[Z].北京:人民郵電出版社,2000. 1012109.</p><p> [5]JAMES F.KUROSE, KEITH W.Ross Computer Networking A Top2Down Approach Featuring the Internet (影印版) [M].北京: 高等教育出版社,2001.</p><p> [6]李為民,趙迎新,
38、梁濟(jì)仁,等. 網(wǎng)絡(luò)連通性測試與故障定位[J ].計(jì)算機(jī)應(yīng)用,2004 ,24(增刊):47249.</p><p><b> 6程序清單</b></p><p> #include "stdafx.h"</p><p> #include "TraceRoute.h"</p><
39、p> #include "Tracer.h"</p><p> #include "TraceRouteDlg.h"</p><p> #ifdef _DEBUG</p><p> #undef THIS_FILE</p><p> static char THIS_FILE[]=__F
40、ILE__;</p><p> #define new DEBUG_NEW</p><p><b> #endif</b></p><p> //////////////////////////////////////////////////////////////////////</p><p> // Con
41、struction/Destruction</p><p> //////////////////////////////////////////////////////////////////////</p><p><b> //IP</b></p><p> struct IPHEADER</p><p>
42、 {unsigned int h_len:4; // 首部長度</p><p> unsigned int version:4; // 版本</p><p> unsigned char tos; // 服務(wù)類型</p><p> unsigned short
43、 total_len; // 報(bào)文總長度</p><p> unsigned short ident; // 標(biāo)識</p><p> unsigned short frag_and_flags; // 偏移量</p><p> unsigned char ttl; //
44、 壽命</p><p> unsigned char proto; // 協(xié)議</p><p> unsigned short checksum; // 首部校驗(yàn)和</p><p> unsigned int sourceIP; // 源站IP</p><p>
45、unsigned int destIP; // 目的站IP</p><p><b> };</b></p><p> //ICMP首部數(shù)據(jù)結(jié)構(gòu)</p><p> struct ICMPHEADER</p><p><b> {</b></p><
46、;p> BYTE i_type; // 類型</p><p> BYTE i_code; // 代碼</p><p> USHORT i_cksum; // 首部校驗(yàn)和</p><p> USHORT i_id; // 標(biāo)識<
47、/p><p> USHORT i_seq; // 序列號</p><p> ULONG timestamp; // 時(shí)間戳(選用)</p><p><b> };</b></p><p> CTracer::CTracer()</p><p&g
48、t;<b> {</b></p><p><b> m_nSeq=1;</b></p><p> icmpData=NULL;</p><p> icmpRcvBuf=NULL;</p><p> m_hSocket=INVALID_SOCKET;</p><p>
49、 //初始化socket</p><p> WSADATA wsaData;</p><p> if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)</p><p><b> {</b></p><p> AfxMessageBox("WSAStartup()出錯(cuò)
50、!");</p><p><b> }</b></p><p><b> }</b></p><p> CTracer::~CTracer()</p><p><b> {</b></p><p> //關(guān)閉Socket</p&
51、gt;<p> if (m_hSocket!=NULL)</p><p> closesocket(m_hSocket); </p><p> WSACleanup();</p><p><b> }</b></p><p> //CheckSum</p><p>
52、 USHORT CTracer::CheckSum(char* pBuffer,int size)</p><p><b> { </b></p><p> USHORT* buffer=(USHORT*)pBuffer;</p><p> unsigned long cksum=0;</p><p> whi
53、le(size > 1) </p><p><b> {</b></p><p> cksum += *buffer++;</p><p> size -= sizeof(USHORT);</p><p><b> }</b></p><p><b>
54、 if(size )</b></p><p> cksum += *(UCHAR*)buffer;</p><p> cksum = (cksum >> 16) + (cksum & 0xffff);</p><p> cksum += (cksum >> 16);</p><p> re
55、turn (USHORT)(~cksum);</p><p><b> }</b></p><p> //FillAddress</p><p> BOOL CTracer::FillAddress(char *addrDest)</p><p><b> {</b></p>
56、<p> memset(&m_addrDest,0,sizeof(m_addrDest));</p><p> m_addrDest.sin_family =AF_INET;</p><p> if(inet_addr(addrDest)==INADDR_NONE)</p><p><b> {</b></p&g
57、t;<p> //輸入的地址為計(jì)算機(jī)名字</p><p> HOSTENT* hp=NULL;</p><p> hp=gethostbyname(addrDest);</p><p><b> if(hp)</b></p><p><b> {</b></p>
58、<p> memcpy(&(m_addrDest.sin_addr),hp->h_addr,hp->h_length);</p><p> m_addrDest.sin_family =hp->h_addrtype ;</p><p><b> }</b></p><p><b> els
59、e</b></p><p><b> {</b></p><p> AfxMessageBox("獲取地址失敗!");</p><p> return FALSE;</p><p><b> }</b></p><p><b>
60、; }</b></p><p><b> else</b></p><p><b> {</b></p><p> m_addrDest.sin_addr.s_addr=inet_addr(addrDest);</p><p><b> }</b><
61、/p><p> return TRUE;</p><p><b> }</b></p><p> //FillICMPData</p><p> void CTracer::FillICMPData(char* icmpData,int size)</p><p><b> {&l
62、t;/b></p><p> memset(icmpData,0,size);</p><p> ICMPHEADER* icmpHeader=NULL;</p><p> icmpHeader=(ICMPHEADER*)icmpData;</p><p> icmpHeader->i_type =ICMP_ECHO;&l
63、t;/p><p> icmpHeader->i_code =0;</p><p> icmpHeader->i_id =(USHORT)GetCurrentProcessId();</p><p> icmpHeader->i_seq =m_nSeq++; </p><p> //GetTickCount返回從0點(diǎn)到現(xiàn)在
64、的毫秒數(shù),作時(shí)間戳</p><p> icmpHeader->timestamp=GetTickCount();</p><p> char* datapart=icmpData+sizeof(ICMPHEADER);</p><p> memset(datapart,'*',size-sizeof(ICMPHEADER));</p
65、><p><b> //填充校驗(yàn)和</b></p><p> icmpHeader->i_cksum =CheckSum(icmpData,size);</p><p><b> }</b></p><p> //設(shè)置數(shù)據(jù)報(bào)的壽命</p><p> BOOL CT
66、racer::SetTTL(SOCKET hSocket, int ttl)</p><p><b> {</b></p><p> int result;</p><p> result=setsockopt(hSocket,IPPROTO_IP,IP_TTL,(LPSTR)&ttl,sizeof(ttl));</p>
67、;<p> if(result==SOCKET_ERROR)</p><p><b> {</b></p><p> AfxMessageBox("設(shè)置數(shù)據(jù)報(bào)壽命失敗!");</p><p> TerminateProcess(GetCurrentProcess(),-1);</p>&l
68、t;p><b> }</b></p><p> return TRUE;</p><p><b> }</b></p><p><b> //發(fā)送數(shù)據(jù)報(bào)</b></p><p> BOOL CTracer::SendData(char* icmpData,int
69、 size)</p><p><b> {</b></p><p> //填充ICMP報(bào)頭</p><p> FillICMPData(icmpData,size);</p><p><b> //發(fā)送數(shù)據(jù)報(bào)</b></p><p> int result;<
70、/p><p> time1=GetTickCount();</p><p> result=sendto(m_hSocket,icmpData,size,0,(SOCKADDR*)&m_addrDest,sizeof(m_addrDest));</p><p> if(result==SOCKET_ERROR)</p><p>&l
71、t;b> {</b></p><p> if(WSAGetLastError()==WSAETIMEDOUT)</p><p><b> {</b></p><p> ((CTraceRouteDlg*)m_pWnd)->InfoAdd("發(fā)送超時(shí)");</p><p>
72、; return TRUE;</p><p><b> }</b></p><p> AfxMessageBox("發(fā)送報(bào)文失敗!");</p><p> TerminateProcess(GetCurrentProcess(),-1);</p><p><b> }</b&
73、gt;</p><p> return FALSE;</p><p><b> }</b></p><p><b> //接收數(shù)據(jù)報(bào)</b></p><p> BOOL CTracer::RecvData(char* icmpRcvBuf,int* presult)</p>&
74、lt;p><b> {</b></p><p> static int count=0;</p><p> //總共6次出現(xiàn)接收超時(shí),判斷存在連接問題。</p><p> if(count>5) </p><p><b> {</b></p>
75、<p> AfxMessageBox("連接存在問題!");</p><p> TerminateProcess(GetCurrentProcess(),-1);</p><p><b> }</b></p><p> int fromlen=sizeof(SOCKADDR);</p>&l
76、t;p> *presult=SOCKET_ERROR;</p><p> *presult=recvfrom(m_hSocket,icmpRcvBuf,MAX_PACKET,0,(SOCKADDR*)&m_addrFrom,&fromlen);</p><p> time2=GetTickCount(); </p><p> if(
77、*presult==SOCKET_ERROR)</p><p><b> {</b></p><p> if(WSAGetLastError()==WSAETIMEDOUT)</p><p><b> {</b></p><p> ((CTraceRouteDlg*)m_pWnd)->
78、InfoAdd ("接收超時(shí)!");</p><p><b> count++;</b></p><p> return TRUE;</p><p><b> }</b></p><p> AfxMessageBox("接收數(shù)據(jù)報(bào)失敗!");</
79、p><p> TerminateProcess(GetCurrentProcess(),-1);</p><p><b> }</b></p><p> return FALSE;</p><p><b> }</b></p><p> //處理接收到的數(shù)據(jù)報(bào)</
80、p><p> BOOL CTracer::DecodeICMP(char* pBuffer,int bytes,int ttl)</p><p><b> {</b></p><p> IPHEADER *ipHeader=NULL;</p><p> ICMPHEADER *icmpHeader
81、=NULL;</p><p> unsigned short ipHeaderLen;</p><p> HOSTENT *ph=NULL;</p><p> in_addr inaddr=m_addrFrom.sin_addr;</p><p> ipHeader=(IPHEADER*)pBuffer;</p>&l
82、t;p> ipHeaderLen=20;</p><p> if (bytes<ipHeaderLen+ICMP_MIN) </p><p> AfxMessageBox("接收數(shù)據(jù)報(bào)長度不正確!");</p><p> icmpHeader=(ICMPHEADER*)(pBuffer+20);</p><
83、p> switch (icmpHeader->i_type)</p><p><b> {</b></p><p><b> //目的站點(diǎn)的返回</b></p><p> case ICMP_ECHOREPLY: </p><p> ph=gethostbyaddr((
84、const char *)&inaddr,AF_INET, sizeof(in_addr));</p><p> if (ph != NULL)</p><p><b> {</b></p><p> CString report;</p><p> report.Format("%2d %s
85、 (%s)",ttl,ph->h_name,inet_ntoa(inaddr));</p><p> ((CTraceRouteDlg*)m_pWnd)->InfoAdd(report);</p><p><b> }</b></p><p> return TRUE;</p><p><
86、;b> break;</b></p><p> //中途路由器的返回</p><p> case ICMP_TIMEOUT: </p><p><b> {</b></p><p> CString report;</p><p> report.Format
87、("%2d %s %2d ms",ttl, inet_ntoa(inaddr),(time2-time1));</p><p> ((CTraceRouteDlg*)m_pWnd)->InfoAdd(report);</p><p> return FALSE;</p><p><b> break;</b>
88、</p><p><b> }</b></p><p> //錯(cuò)誤:主機(jī)不可達(dá)</p><p> case ICMP_DESTUNREACH: </p><p><b> {</b></p><p> CString report;</p><
89、p> report.Format("%2d %s 主機(jī)不可達(dá)",ttl,inet_ntoa(inaddr));</p><p> ((CTraceRouteDlg*)m_pWnd)->InfoAdd(report);</p><p> return TRUE;</p><p><b> break;</b
90、></p><p><b> }</b></p><p> //收到一個(gè)不是回應(yīng)的報(bào)文</p><p><b> default:</b></p><p><b> {</b></p><p> CString report;</p
91、><p> report.Format("非回應(yīng)報(bào)文");</p><p> ((CTraceRouteDlg*)m_pWnd)->InfoAdd(report);</p><p> return TRUE;</p><p><b> }</b></p><p>&l
92、t;b> }</b></p><p> return FALSE;</p><p><b> }</b></p><p> void CTracer::SetWnd(CDialog *pWnd)</p><p><b> {</b></p><p>
93、;<b> //設(shè)置窗口指針</b></p><p> m_pWnd=pWnd;</p><p><b> }</b></p><p> void CTracer::Trace(char *destAddress)</p><p><b> {</b></p&g
94、t;<p> int size=DEF_PACKET_SIZE+sizeof(ICMPHEADER);</p><p><b> //轉(zhuǎn)換地址</b></p><p> if (!FillAddress(destAddress)) return ;</p><p> //分配必要的內(nèi)存空間</p><p
95、> icmpData=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET);</p><p> icmpRcvBuf=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET);</p><p> if(!icmpData||!icmpRcv
96、Buf)</p><p><b> {</b></p><p> AfxMessageBox("分配內(nèi)存空間失敗!");</p><p> TerminateProcess(GetCurrentProcess(),-1);</p><p><b> }</b></p
97、><p> memset(icmpData,0,MAX_PACKET);</p><p> memset(icmpRcvBuf,0,MAX_PACKET);</p><p><b> //初始化套接字</b></p><p> m_hSocket=WSASocket(AF_INET,SOCK_RAW,IPPROTO_
98、ICMP,NULL,0,WSA_FLAG_OVERLAPPED);</p><p> if(m_hSocket==INVALID_SOCKET)</p><p><b> { </b></p><p> AfxMessageBox("套接字初始化失敗!");</p><p> Termin
99、ateProcess(GetCurrentProcess(),-1);</p><p><b> }</b></p><p><b> //設(shè)置超時(shí)選項(xiàng)</b></p><p> int nTimeOut=1000;</p><p> int result;</p><p
100、> result=setsockopt(m_hSocket,SOL_SOCKET,SO_RCVTIMEO,(char*)&nTimeOut,sizeof(nTimeOut));</p><p> if(result==SOCKET_ERROR)</p><p><b> { </b></p><p> AfxMessage
101、Box("設(shè)置接收超時(shí)選項(xiàng)失敗!");</p><p> TerminateProcess(GetCurrentProcess(),-1);</p><p><b> }</b></p><p> result=setsockopt(m_hSocket,SOL_SOCKET,SO_SNDTIMEO,(char*)&am
102、p;nTimeOut,sizeof(nTimeOut));</p><p> if(result==SOCKET_ERROR)</p><p><b> {</b></p><p> AfxMessageBox("設(shè)置發(fā)送超時(shí)選項(xiàng)失敗!");</p><p> TerminateProcess
103、(GetCurrentProcess(),-1);</p><p><b> }</b></p><p> //設(shè)置路由不查詢路由表選項(xiàng)</p><p> BOOL bDontRoute=TRUE;</p><p> result=setsockopt(m_hSocket,SOL_SOCKET,SO_DONTRO
104、UTE,(char*)&bDontRoute,sizeof(BOOL));</p><p> if(result==SOCKET_ERROR)</p><p><b> {</b></p><p> AfxMessageBox("設(shè)置不查詢路由表選項(xiàng)失敗!");</p><p> Te
105、rminateProcess(GetCurrentProcess(),-1);</p><p><b> }</b></p><p> for(int ttl=1;ttl<MAX_NOTES;ttl++)</p><p><b> {</b></p><p> //設(shè)定數(shù)據(jù)報(bào)的壽命&l
106、t;/p><p> SetTTL(m_hSocket,ttl);</p><p><b> //發(fā)送數(shù)據(jù)報(bào)</b></p><p> if(SendData(icmpData,size)) continue; </p><p><b> //接收數(shù)據(jù)報(bào)</b></p><p&
107、gt; if(RecvData(icmpRcvBuf,&result)) continue; </p><p> //處理接收到的數(shù)據(jù)報(bào)</p><p> if (DecodeICMP(icmpRcvBuf,result,ttl)) break;</p><p><b> }</b></p><p>
溫馨提示
- 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 網(wǎng)絡(luò)管理課程設(shè)計(jì)--基于packet tracer校園網(wǎng)絡(luò)設(shè)計(jì)
- 課程設(shè)計(jì)--unix程序設(shè)計(jì)課程設(shè)計(jì)
- 小鳥動畫程序課程設(shè)計(jì)
- 簡單畫圖程序-課程設(shè)計(jì)
- tcp傳輸程序課程設(shè)計(jì)
- 鍵盤監(jiān)聽程序課程設(shè)計(jì)
- 程序設(shè)計(jì)課程設(shè)計(jì)報(bào)告
- java課程設(shè)計(jì)-聊天程序
- 簡單畫圖程序課程設(shè)計(jì)
- c語言程序課程設(shè)計(jì)
- 程序設(shè)計(jì)課程設(shè)計(jì)報(bào)告
- java抽獎程序課程設(shè)計(jì)
- 數(shù)控程序編程課程設(shè)計(jì)
- java課程設(shè)計(jì)--java面向?qū)ο蟪绦蛟O(shè)計(jì)課程設(shè)計(jì)
- matlab程序設(shè)計(jì) 課程設(shè)計(jì)
- 網(wǎng)絡(luò)程序課程設(shè)計(jì)---實(shí)現(xiàn)網(wǎng)絡(luò)對時(shí)程序
- 程序設(shè)計(jì)課程設(shè)計(jì)--鏈表操作
- java課程設(shè)計(jì)聊天小程序
- 微機(jī)課程設(shè)計(jì)--指法練習(xí)程序
- 簡單畫圖程序課程設(shè)計(jì)報(bào)告
評論
0/150
提交評論