路由跟踪程序仿真_第1页
路由跟踪程序仿真_第2页
路由跟踪程序仿真_第3页
路由跟踪程序仿真_第4页
路由跟踪程序仿真_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、集美大学计算机工程学院实验报告课程名称:TCP/IP协议与通信程序设计班级:实验成绩:实验项目名称:路由跟踪程序仿真学号:上机实践日期:2016-06-16实验项目编号:13组号:1上机实践时间: 2学时一、 实验目的了解利用原始套接字进行通信程序的编写,编译和执行二、 实验内容与设计思想基于原始套接字编写路由跟踪仿真程序,以跟踪获取本机的 IP 数据包到达集美大学教务处网站服务主机(210.34.129.66)所经历的路由器的IP地址,并在客户端显示出来。提示:本机程序向目标主机发送一个封装ICMP回显请求的数据报,初始化TTL为1,当该包到达途中第一个路由器时,TTL值减为0发生超时错误,

2、第一个路由器反馈源主机ICMP超时差错报文。依次将数据报的TTL值递增1,以便IP包能到达下一个路由器,如法炮制,直到数据报达到目地主机,目地主机将返回ICMP回显应答消息。源主机依次解析处理期间收到的ICMP报文就可以得出数据报从源主机到达目地主机途中所经过的路由器IP。三、 实验使用环境操作系统: Microsoft Windows XP SP2编程环境: Visual C+ 6.0四、实验步骤和调试过程源代码:#define WIN32_LEAN_AND_MEAN #include <winsock2.h> /使用原始套接字需要WinSock2的支持 #include <

3、;ws2tcpip.h> /进行IPPROTO_IP级别设置时用到 #include <stdio.h> #include <stdlib.h> #define ICMP_ECHO 8 /发送Ping请求时的ICMP报文类型 #define ICMP_ECHOREPLY 0 /接收Ping回复时的ICMP报文类型 #define ICMP_TIMEOUT 11 /ICMP超时报文类型 #define ICMP_MIN 8 /Minimum 8-byte ICMP packet (header) #define MAX_PACKET 1024 /Max ICMP p

4、acket size #define DEICMP_PACKSIZE 44 /Defaut ICMP PACKET SIZE char lpdest16; /用来存放目的IP地址 DWORD cStartTickCount; /用来存放发送包的起始时间 #pragma comment( lib, "ws2_32.lib" ) typedef struct _icmphdr /ICMP头部定义,被封装在IP包中 BYTE i_type; /报文类型 BYTE i_code; /代码 USHORT i_cksum; /校验和 USHORT i_id; /标识符 USHORT i

5、_seq; /序号 IcmpHeader; /初始化ICMP头部 void FillICMPData(char *icmp_data,int datasize) IcmpHeader *icmp_hdr=NULL; char *datapart=NULL; icmp_hdr=(IcmpHeader *)icmp_data; icmp_hdr->i_type=ICMP_ECHO; /request an ICMP echo icmp_hdr->i_code=0; icmp_hdr->i_id=(USHORT)GetCurrentProcessId(); icmp_hdr->

6、;i_cksum=0; icmp_hdr->i_seq=0; datapart=icmp_data+sizeof(IcmpHeader); memset(datapart,'E',datasize-sizeof(IcmpHeader); /校验和函数 USHORT checksum(USHORT *buffer,int size) unsigned long cksum=0; while(size>1) cksum+=*buffer+; size-=sizeof(USHORT); if(size) cksum+=*(UCHAR *)buffer; cksum=(ck

7、sum>>16)+(cksum & 0xffff); cksum+=(cksum>>16); return (USHORT)(cksum); int DecodeIPHeader(char *buf,int bytes,struct sockaddr_in *from) IcmpHeader *icmphdr=NULL; DWORD tick; static int icmpcount=1; unsigned short iphdrlen; /判断接收操作是否超时 if(!buf) printf("%2d: *.*.*.* Request timed

8、out.n",icmpcount+); return 1; tick=GetTickCount(); iphdrlen=(buf0 & 0x0f)*4; icmphdr=(IcmpHeader *)(buf+iphdrlen); if(bytes<iphdrlen+ICMP_MIN) printf("Too few bytes from %sn",inet_ntoa(from->sin_addr); return 0; /判断接收的ICMP报文是否为超时报文 if(icmphdr->i_type=ICMP_TIMEOUT&&

9、;icmphdr->i_code=0) printf("%2d: %-15s %4dmsn",icmpcount+,inet_ntoa(from->sin_addr),tick-cStartTickCount); return 0; /判断接收的ICMP报文是否为回复报文 else if(icmphdr->i_type=ICMP_ECHOREPLY&&icmphdr->i_id=GetCurrentProcessId() printf("%2d: %-15s %4dmsn",icmpcount+,inet_ntoa

10、(from->sin_addr),tick-cStartTickCount); printf("Trace complete!n"); return 1; /其他类型,表示不可达 else printf("%2d: Destination host is unreachable!n",icmpcount+); return 1; int main() WSADATA wsaData; SOCKET sockRaw=INVALID_SOCKET; struct sockaddr_in dest, from; int i,bread,fromlen=s

11、izeof(from),timeout=1000,ret; struct hostent *hp=NULL; char *icmp_data=NULL,*recvbuf=NULL; USHORT seq_no=0; printf("输入追踪的目的(IP/主机名):"); scanf("%s",lpdest); if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) printf("WSAStartup() failed:%dn",GetLastError(); return -1; /创建套接字 s

12、ockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED); if(sockRaw=INVALID_SOCKET) printf("WSASocket() failed:%dn",WSAGetLastError(); return -1; /对锁定套接字设置超时 bread=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout); if(bread=SOCKET_ERROR) prin

13、tf("setsockopt(SO_RCVTIMEO) failed:%dn",WSAGetLastError(); return -1; timeout=1000; bread=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout); if(bread=SOCKET_ERROR) printf("setsockopt(SO_SNDTIMEO) failed:%dn",WSAGetLastError(); return -1; /解析目标地址,将主机名转

14、化为IP地址 memset(&dest,0,sizeof(dest); dest.sin_family=AF_INET; if(dest.sin_addr.S_un.S_addr=inet_addr(lpdest)=INADDR_NONE) if(hp=gethostbyname(lpdest)!=NULL) memcpy(&(dest.sin_addr.S_un.S_addr),hp->h_addr_list0,hp->h_length); dest.sin_family=hp->h_addrtype; printf("dest.sin_addr=

15、%sn",inet_ntoa(dest.sin_addr); else printf("gethostbyname() failed:%dn",WSAGetLastError(); return -1; /Create the ICMP pakcet icmp_data= (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET); recvbuf = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET); if(!icmp_d

16、ata) printf("HeapAlloc() failed: %dn",GetLastError(); return -1; memset(icmp_data,0,MAX_PACKET); FillICMPData(icmp_data,DEICMP_PACKSIZE); printf("跳 IP地址 耗时n"); /开始发送/接收ICMP报文 for(i=1;i<=255;i+) int bwrote; /设置IP包的生存期 ret=setsockopt(sockRaw,IPPROTO_IP,IP_TTL,(char *)&i,size

17、of(int); if(ret=SOCKET_ERROR) printf("setsockopt(IP_TTL) failed:%dn",WSAGetLastError(); (IcmpHeader *)icmp_data)->i_cksum =0; (IcmpHeader *)icmp_data)->i_seq=seq_no+; /Sequence number of ICMP packets (IcmpHeader *)icmp_data)->i_cksum=checksum(USHORT *)icmp_data,DEICMP_PACKSIZE); /

18、发送ICMP包请求查询 cStartTickCount=GetTickCount(); bwrote=sendto(sockRaw,icmp_data,DEICMP_PACKSIZE,0,(struct sockaddr *)&dest,sizeof(dest); if(bwrote=SOCKET_ERROR) if(WSAGetLastError()=WSAETIMEDOUT) printf("timed outn"); continue; printf("sendto() failed:%dn",WSAGetLastError(); return -1; if(bwrote<DEICMP_PACKSIZE) printf("Wrote %d bytesn",bwrote); /接收ICMP回复包 bread=recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr *)&from,&fromlen); if(bread

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论