tracer程序課程設計_第1頁
已閱讀1頁,還剩15頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、<p><b>  目 錄</b></p><p><b>  1 引言2</b></p><p>  1.1 課程設計目的2</p><p>  1.2 課程設計內(nèi)容2</p><p><b>  2課程設計原理3</b></p><p

2、>  2.1 ICMP的簡介和原理3</p><p>  2.2 traceroute程序的基本原理3</p><p>  2.3traceroute實現(xiàn)的功能3</p><p><b>  3 設計步驟4</b></p><p>  3.1 traceroute流程圖………………………………………..6&

3、lt;/p><p>  3.2 traceroute的核心程序…………………………………..7</p><p>  3.3traceroute程序運行結果………………...........................7</p><p><b>  4 心得結論8</b></p><p><b>  5 參考文

4、獻9</b></p><p><b>  6 程序清單9</b></p><p><b>  1 引 言</b></p><p>  Internet,是目前世界上最大的計算機網(wǎng)絡,更確切的說是網(wǎng)絡中的網(wǎng)絡,它由遍布全球的幾萬局域網(wǎng)和數(shù)百萬臺計算機組成,并通過用于異構網(wǎng)絡的TCP/IP協(xié)議進行網(wǎng)間通信?;ヂ?lián)

5、網(wǎng)中,信息的傳送是通過網(wǎng)中許多段的傳輸介質(zhì)和設備從一端到達另一端。每一個連接在Internet上的設備,如主機、路由器、接入服務器等一般情況下都會有一個獨立的IP地址。通過Traceroute我們可以知道信息從你的計算機到互聯(lián)網(wǎng)另一端的主機是走的什么路勁。當然每次數(shù)據(jù)包由某一同樣的出發(fā)點到達某一同樣的目的地走的路勁可能會不同,但基本上來說大部分時候所走的路由是相同的。隨著Internet(國際互聯(lián)網(wǎng))的發(fā)展,越來越多的服務通過網(wǎng)絡提供給

6、大眾,與此同時,針對互聯(lián)網(wǎng)的攻擊事件也越來越頻繁。所謂路由追蹤實際上就是在IP網(wǎng)絡上判斷從源到達目的所經(jīng)過的路由器的IP地址,其基本的實現(xiàn)手段都是向目的地發(fā)送數(shù)據(jù)包以獲取經(jīng)過的路由器的IP。由于Internet上的路由協(xié)議是動態(tài)的,所以每次形成的數(shù)據(jù)包從同一個出發(fā)點到達目的地的路由可能會不一樣,但由于路由算法有一定的穩(wěn)定性,在大部分時侯所走的路由會是相同的。</p><p>  1.1 課程設計目的</p&

7、gt;<p>  1.這次課程設計,主要為了加深同學們對計算機網(wǎng)絡網(wǎng)絡的理解和認識</p><p>  2.了解信息在計算機網(wǎng)絡與網(wǎng)絡之間的傳送和接收</p><p>  3.進一步加深了解網(wǎng)絡與網(wǎng)絡之間的協(xié)議</p><p>  4.理解網(wǎng)絡中的IP地址以及路由之間的相關命令。</p><p>  1.2 課程設計內(nèi)容<

8、;/p><p>  1.已知參數(shù):輸入:目的節(jié)點IP地址或主機名;輸出:從控制臺屏幕輸出IP報文由本機出發(fā)到達目的主機所經(jīng)過的路由信息。</p><p>  2.設計要求:通過原始套接字編程,實現(xiàn)Tracert的基本功能</p><p>  Ping功能:發(fā)送ICMP數(shù)據(jù)包到目標計算機,如有返回,顯示響應時間等</p><p>  路由探測功能:

9、依次Ping途經(jīng)的路由器或網(wǎng)關設備,依次顯示途經(jīng)路由器的響應時間。</p><p><b> ?。ㄔ黾拥墓δ埽?lt;/b></p><p>  2.1初始化Windows Sockets網(wǎng)絡環(huán)境;</p><p>  2.2解析命令行參數(shù),構造目的端socket地址;</p><p>  2.3定義IP、ICMP報文;<

10、;/p><p>  2.4接收ICMP差錯報文并進行解析</p><p><b>  2 設計原理</b></p><p>  raceroute是一個路由跟蹤命令,它通過ICMP協(xié)議和IP header中TTL(存活時間)來實現(xiàn)的。 具體而言就是:發(fā)送方發(fā)出一個TTL是1的IP Datagram (事實上每個數(shù)據(jù)包發(fā)送三次,大小為40字節(jié),包括本

11、機的IP 地址,目的主機的IP 地址以及時間戳),當經(jīng)由第一個路由器時,路由器將該數(shù)據(jù)包的TTL減1,發(fā)現(xiàn)此時的TTL為0,將數(shù)據(jù)包丟失,同時向源主機發(fā)送一個ICMP Time-to-Exceed 報文(包括源主機的IP 地址、路由地址以及路由的相關消息),源主機收到這個數(shù)據(jù)包后就知道了這個路由器在這條路徑上。同理發(fā)送第二個、第三個......第n個。源主機將每次IP數(shù)據(jù)報的TTL+1,直到某個數(shù)據(jù)報到達了目的地址,此時不知發(fā)回一個IC

12、MP Time-to-Exceed,而是發(fā)送一個數(shù)據(jù)報的響應報文。當源主機收到這樣一個報文后便知道數(shù)據(jù)包已經(jīng)到達了目的地。Traceroute提取發(fā) ICMP TTL到期消息設備的IP地址并作域名解析。每次 ,Traceroute都打印出一系列數(shù)據(jù),包括所經(jīng)過的路由設備的域名及 IP地址,三個包每次來回所花時間。Traceroute 有</p><p>  2.1 ICMP的簡介和原理</p>&

13、lt;p>  ICMP(Internet Control Message Protocol),即Internet控制報文協(xié)議, 它是TCP/IP協(xié)議族的一個子協(xié)議,屬于網(wǎng)絡層面向無連接的協(xié)議,主要用于在主機與路由器之間傳遞控制信息,包括報告錯誤、交換受限控制和狀態(tài)信息等。當遇到IP數(shù)據(jù)無法訪問目標、IP路由器無法按當前的傳輸速率轉(zhuǎn)發(fā)數(shù)據(jù)包等情況時,會自動發(fā)送ICMP消息。ICMP報文被包裝成IP數(shù)據(jù)包傳到數(shù)據(jù)鏈路層進行傳輸。通過I

14、CMP協(xié)議,主機和路由器可以報告錯誤并交換相關的狀態(tài)信息。ICMP對于TCP/IP協(xié)議的可靠運行是至關重要的。 ICMP報文結構如圖1所示:</p><p>  2.2 traceRoute程序的基本原理</p><p>  路由追蹤的主要原理是根據(jù)路徑上各路由器對數(shù)據(jù)報的存活時(Time to Live,TTL)做不同的處理,使其產(chǎn)生超時ICMP消息響應,反饋至源主機,從而獲得此跳路由器

15、或主機的IP。照此再發(fā)送下一個TTL經(jīng)過自增的數(shù)據(jù)報,直至獲得整個路由中各節(jié)點的IP或者接收到錯誤的消息。詳細過程描述如下:</p><p>  1) 置n = 1。假設該過程中共經(jīng)過M個路由器。</p><p>  2) 源主機S向目標主機D發(fā)送一個TTL為n的UDP數(shù)據(jù)報。并設定端口號(一般大于30 000) 。</p><p>  3) 路由器(或者網(wǎng)關、主機

16、) Rn 對接收到的數(shù)據(jù)報的TTL 值n做減1處理。</p><p>  4) 若n = 0,則丟棄UDP數(shù)據(jù)報,向源主機S發(fā)送ICMP超時報文。</p><p>  5) 若n ≥ 1,繼續(xù)向目標主機D發(fā)送經(jīng)過處理的數(shù)據(jù)報。</p><p>  6) 源主機S分析返回的ICMP報文, 從中提取出發(fā)送者Rn的地址IPn并做記錄。</p><p&

17、gt;  7) 若收到“端口不可達”的ICMP報文,則發(fā)送方即目標主機D,記錄其地址IPn,追蹤完成。</p><p>  8) 置n = n +1,繼續(xù)向目標主機D發(fā)送TTL為n的數(shù)據(jù)報。</p><p>  注意,這里使UDP數(shù)據(jù)報的端口號大于30000,是因為一般的應用程序不可能使用如此高的端口號。當然這并非絕對,若出現(xiàn)例外,則源主機會發(fā)現(xiàn)等待超時,于是隨機改變此UDP數(shù)據(jù)報的端口號

18、,再次發(fā)送。這樣最終可以在目標主機上找到一個空閑的端口號。另外,這里假設路由器和目標主機沒有被配置為“過濾ICMP”或者做了其他的非常規(guī)處理,如果被做了類似的配置,則上面的追蹤機制就無能為力了。</p><p>  2.3 traceRoute實現(xiàn)的功能</p><p>  IP數(shù)據(jù)報的首部由兩部分構成:固定部分和可變部分。固定部分的長度是20個字段,可變部分由許多選項構成,最長可達40

19、個字節(jié)。雖然選項并不是IP數(shù)據(jù)報的必需部分,但選項的處理卻是IP軟件的必需部分。</p><p>  在現(xiàn)在的TCP/IP協(xié)議中,只定義了六種選項,對于我們進行路由追蹤技術有用的是記錄路由選項,一個記錄路由選項是用來記錄處理IP數(shù)據(jù)報的互聯(lián)網(wǎng)路由器的IP地址。因為首部的最大長度是60個字節(jié),它包括20個字節(jié)的基本首部。這就意味著只剩下40個字節(jié)留下給選項部分,所以通過選項字段最多能夠記錄9個路由器的IP地址。源站

20、在選項中創(chuàng)建一個位標置(placeholder),用來填入所經(jīng)過的各路由器,圖2給出了記錄路由選項的格式。</p><p><b>  圖2 記錄路由選項</b></p><p>  向目的主機發(fā)送一個ICMP報文,這種方法只要求使用一個套接字。ICMP即Internet控制報文協(xié)議,是一種用于特殊用途的報文機制,可以使互聯(lián)網(wǎng)中的路由器或主機報告差錯或提供有關意外情況

21、的信息。盡管UDP和ICMP工作在TCP/IP的不同層次上,但他們的封裝是類似的。ICMP報文為兩級封裝ICMP報文放在IP數(shù)據(jù)報的數(shù)據(jù)部分,數(shù)據(jù)報則放在幀的數(shù)據(jù)中進行網(wǎng)絡傳輸(如圖3所示)ICMP報文與其他普通報文一樣,具有相同的路由選擇,并沒有特殊的優(yōu)先權和增加可靠性。通過路由選項的方法記錄路由的實現(xiàn)同UDP數(shù)據(jù)報是相似的,這里主要說明通過TTL方法的實現(xiàn)。</p><p>  圖3 ICMP報文的兩級封裝&

22、lt;/p><p>  3.1traceroute流程圖</p><p>  根據(jù)要求設計好的流程圖如圖4所示:</p><p><b>  圖4 流程圖</b></p><p>  3.2 traceroute的核心程序</p><p>  整個設計過程的核心程序代碼:</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)用錯誤!");</p><p><b>  return ;}</b></

32、p><p>  在運行程序后得到的對話框中輸入www.sina.com ,再單擊路由跟蹤,就可以詳細的觀察到路由整個的跟蹤過程,如圖5所示:</p><p>  3.3 traceroute程序運行結果</p><p><b>  圖5路由跟蹤示意圖</b></p><p><b>  4心得結論</b>

33、;</p><p>  在整個課程設計過程中,首先得仔細分析課程設計任務書,根據(jù)要求編寫好程序代碼,然后運行程序,分析得到的結果。在編寫代碼過程中,遇到許多問題。開始看到題目不知道該如何下手去做。編寫好的代碼,在VC++平臺上運行時,總是出現(xiàn)錯誤,最終在老師的幫助下,成功的解決了該問題。還有在宿舍運行tracert后一閃就沒了,也不知道是什么原因,上網(wǎng)查找了解到,必須得先運行CMD,然后在CMD里運行其他命令。成

34、功的運行tracert后,出現(xiàn)的一連串數(shù)字,不知道是什么意思,結合老師上課所講的東西并仔細分析才知道,192.168.20.45是IP地址,0ms是跳到下個IP地址所用的時間。從整體來說這次課程設計是成功的。但中間存在一些細節(jié)問題,程序代碼過于復雜,沒有很好的用語句解釋出程序中的代碼。每次課程設計都讓我們學到了很多書本上學不到的東西,如嚴謹?shù)淖鍪嘛L格,認真學習的態(tài)度,不懂要問的道理。</p><p><b&

35、gt;  5參考文獻</b></p><p>  [1]W Richard Stevens. TCP/ IP Illust rated ,Volum 1 :The Protocols[M]1 北京:機械工業(yè)出版社,2002.85296.</p><p>  [2]W Richard Stevens. UNIX Network ProgrammingVolum1Networkin

36、g APIs :Socket s and XTI ( Second</p><p>  Edition) (影印版) [M] . 北京: 清華大學出版社,2002.</p><p>  [3][日]井口信和. TCP/ IP 網(wǎng)絡工具篇[M] . 吳松芝,董江洪譯. 北京:科學出版社,2003. 1582162.</p><p>  [4]余青霓,王曉程,周鋼,等.

37、 網(wǎng)絡入侵檢測分析員手冊[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、梁濟仁,等. 網(wǎng)絡連通性測試與故障定位[J ].計算機應用,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; // 服務類型</p><p>  unsigned short

43、 total_len; // 報文總長度</p><p>  unsigned short ident; // 標識</p><p>  unsigned short frag_and_flags; // 偏移量</p><p>  unsigned char ttl; //

44、 壽命</p><p>  unsigned char proto; // 協(xié)議</p><p>  unsigned short checksum; // 首部校驗和</p><p>  unsigned int sourceIP; // 源站IP</p><p>  

45、unsigned int destIP; // 目的站IP</p><p><b>  };</b></p><p>  //ICMP首部數(shù)據(jù)結構</p><p>  struct ICMPHEADER</p><p><b>  {</b></p><

46、;p>  BYTE i_type; // 類型</p><p>  BYTE i_code; // 代碼</p><p>  USHORT i_cksum; // 首部校驗和</p><p>  USHORT i_id; // 標識<

47、/p><p>  USHORT i_seq; // 序列號</p><p>  ULONG timestamp; // 時間戳(選用)</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()出錯

50、!");</p><p><b>  }</b></p><p><b>  }</b></p><p>  CTracer::~CTracer()</p><p><b>  {</b></p><p>  //關閉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>  //輸入的地址為計算機名字</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點到現(xiàn)在

64、的毫秒數(shù),作時間戳</p><p>  icmpHeader->timestamp=GetTickCount();</p><p>  char* datapart=icmpData+sizeof(ICMPHEADER);</p><p>  memset(datapart,'*',size-sizeof(ICMPHEADER));</p

65、><p><b>  //填充校驗和</b></p><p>  icmpHeader->i_cksum =CheckSum(icmpData,size);</p><p><b>  }</b></p><p>  //設置數(shù)據(jù)報的壽命</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ù)據(jù)報壽命失敗!");</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></p><p>  BOOL CTracer::SendData(char* icmpData,int

69、 size)</p><p><b>  {</b></p><p>  //填充ICMP報頭</p><p>  FillICMPData(icmpData,size);</p><p><b>  //發(fā)送數(shù)據(jù)報</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ā)送超時");</p><p>

72、;  return TRUE;</p><p><b>  }</b></p><p>  AfxMessageBox("發(fā)送報文失敗!");</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></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)接收超時,判斷存在連接問題。</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 ("接收超時!");</p><p><b>  count++;</b></p><p>  return TRUE;</p><p><b>  }</b></p><p>  AfxMessageBox("接收數(shù)據(jù)報失敗!");</

79、p><p>  TerminateProcess(GetCurrentProcess(),-1);</p><p><b>  }</b></p><p>  return FALSE;</p><p><b>  }</b></p><p>  //處理接收到的數(shù)據(jù)報</

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ù)報長度不正確!");</p><p>  icmpHeader=(ICMPHEADER*)(pBuffer+20);</p><

83、p>  switch (icmpHeader->i_type)</p><p><b>  {</b></p><p><b>  //目的站點的返回</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>  //錯誤:主機不可達</p><p>  case ICMP_DESTUNREACH: </p><p><b>  {</b></p><p>  CString report;</p><

89、p>  report.Format("%2d %s 主機不可達",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>  //收到一個不是回應的報文</p><p><b>  default:</b></p><p><b>  {</b></p><p>  CString report;</p

91、><p>  report.Format("非回應報文");</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>  //設置窗口指針</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>  //設置超時選項</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("設置接收超時選項失敗!");</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("設置發(fā)送超時選項失敗!");</p><p>  TerminateProcess

103、(GetCurrentProcess(),-1);</p><p><b>  }</b></p><p>  //設置路由不查詢路由表選項</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("設置不查詢路由表選項失敗!");</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ù)據(jù)報的壽命&l

106、t;/p><p>  SetTTL(m_hSocket,ttl);</p><p><b>  //發(fā)送數(shù)據(jù)報</b></p><p>  if(SendData(icmpData,size)) continue; </p><p><b>  //接收數(shù)據(jù)報</b></p><p&

107、gt;  if(RecvData(icmpRcvBuf,&result)) continue; </p><p>  //處理接收到的數(shù)據(jù)報</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)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論