网络编程-Traceroute程序实例

上传人:文*** 文档编号:68860530 上传时间:2022-04-05 格式:DOC 页数:14 大小:302.50KB
返回 下载 相关 举报
网络编程-Traceroute程序实例_第1页
第1页 / 共14页
网络编程-Traceroute程序实例_第2页
第2页 / 共14页
网络编程-Traceroute程序实例_第3页
第3页 / 共14页
点击查看更多>>
资源描述
文档供参考,可复制、编制,期待您的好评与关注! 目录目录21. 问题描述32. 需求分析33. 系统设计33.1. 概要设计33.2. 详细设计53.2.1. Traceroute的实现原理54. 调试75. 总结86. 附录97. 参考文献148. 设计评语151. 问题描述本次课程设计,我们小组选择了课外的题目,经过讨论,最终我们决定我们小组的课题为:网络编程Traceroute程序的应用。Traceroute(路由追踪)是一个非常有用的网络工具。在命令提示符下,执行Traceroute程序,输入必要的参数后即可探测出到达网络中任何一台目标主机中途需要经过哪些路由器以及每个路由器的信息,比如IP地址等。在网络中进行多播通信或者遇到路由问题时,Traceroute获得的信息就非常有用。2. 需求分析路由是把信息从源穿过网络传递到目的地的行为,在传输过程中,遇到一系列的中间节点。这些中间节点构成了路由跟踪的依据。路由的话题早已在计算机界出现,但直到八十年代中期才获得商业成功,这一时间延迟的主要原因是七十年代的网络很简单,后来大型的网络才较为普遍。而路由跟踪是在路由的基础上提出的问题,是利用路由跟踪实用程序于确定 IP 数据报访问目标所采取的路径。 当我们不能通过网络访问目的设备时,网络运行者就需要判断是哪里出了问题。问题不仅仅会出现在最终目的设备,也可能出现在转发数据包的中间路由器。解决方法是,了解了 IP 数据报访问目标所采取的路径,将发现网络布网简单拓扑,确定路由断点即可解决网络故障。 操作系统中的 tracert 或 traceroute 路由跟踪程序,通过它可以查看到达目标地址所经过的路径。它的作用与 ping 有类似之处,使用 ping 可以检查是否连接,如果不通,一般不好准确判断哪一个节点出错,而使用 tracert 则可以准确判断出错的部分。路由跟踪程序随着网络的发展而发展,现已经较为成熟,不仅在操作系统上有路由跟踪程序,在中间设备也加入路由跟踪程序,如 cisco 扩展路由跟踪程序,提供详细的参数选择。 单、多线程路由跟踪程序都已经面世,实现方式也各不相同,如基于记录路由选项的,基于 UDP, 基于 ICMP Echo Request 的路由探测。 本课题主要基于UDP协议的路由探测方法。 系统实现路由的跟踪,每经过一个路由,要求得到经过该路由节点的地址,也就是说输入目标信息, 可以得到本地主机到目标经过的所有中间节点。这些中间节点用 IP 地址标识。并要求对跟踪跳数,每一跳等待时间可控。 为了让系统更加完善,首先要测试目标的连通性,系统中也要实现目标探测功能,即Ping 功能。 3. 系统设计3.1. 概要设计本次编写的Traceroute程序编写环境为在Linux系统下使用C语言进行编写。当完成编写后,使用gcc编译工具进行编译,测试无误后再次使用arm-linux-gcc进行编译,移植入开发板进行测试。由于Traceroute程序的运行需要有真实的网络环境,需要根据所需的环境来搭建并且配置路由器,在当前条件下,我们小组使用了Dynamips模拟器。实验所需的拓扑图如下:当在Linux系统下运行经过编译的Traceroute程序并输入需要进行追踪的IP地址,程序会显示出到达目标主机所经过的每一个路由器。Linux系统网络属性配置配置好linux系统中的网络属性,将IP地址设置为与R4同一网段,网关设置为10.0.0.1,即R4,运行经过编译的Traceroute程序并输入需要进行追踪的IP地址,程序会显示出到达目标主机所经过的每一个路由器。(详见测试结果)3.2. 详细设计3.2.1. Traceroute的实现原理Traceroute程序的实现主要涉及IP头部生存时间(time to live,TTL)字段的使用。设置TTL字段的目的是防止数据报由于选路错误或其他软硬件原因从而导致在网络中无休止的流动,它指定了数据报的生存时间。TTL的初始值由源主机设置,当一份数据报经过路由器时,处理该数据报的路由器都需要把TTL值减去数据报在路由器中停留的秒数。但事实上大多数路由器只是简单地将TTL值减1,因此TTL字段最终被实现为一个跳站计数器。当TTL字段的值被减为0时,路由器就不会转发该数据报,而是将其丢弃,并产生一份ICMP超时差错报文发往源主机以通知错误的发生。Traceroute程序的关键就在于返回的这份ICMP超时差错报文的源地址就是途径路由器的IP地址。由此,通过一次递增TTL字段的值,就可以得到一份数据报在其传输路径上所经过的路由信息。Traceroute程序在具体实现时,是令其向目的主机发送一个UDP数据包,并重复递增IP头部TTL字段的值。刚开始的时候TTL等于1,这样当该数据包抵达途中的第一个路由器时,TTL的值就被减为0,导致发送超时错误,因此该路由器会返回一个ICMP超时数据包到源主机。随后,主机将数据包的TTL值递增1,以便IP报文能传递到下一个路由器,下一个路由器将会生成ICMP超时数据包返回给源主机。依此类推,将返回的每一条ICMP超时消息都收集下来,便能知道中途都经过哪些路由器,直到最后到达目标主机。当TTL值递增的足够大,可达到目标主机的时候,便会返回一条ICMP“端口无法访问”的信息,因为目标主机没有在相应端口等待的进程。至此,Traceroute整个流程便完成了。实现Traceroute程序是可以采取一个简便的方法。只需将封装好的ICMP数据包发送到目标主机,TTL值初始化为1,此后每次发送的数据包都递增1,在TTL值减为0超时的时候,也会返回一条ICMP错误消息。程序中只需要一个ICMP类型的原始套接字即可实现。 开始使用UDP协议创建原始UDP包NNYYYN结束释放各种资源打印结果信息TTL +(初始为1)填充UDP数据包并发送有数据报到达?有预期数据报?超时,显示超时信息目的主机回应答或达到最大跳站值解析数据报并显示输出4. 调试对编写好的代码进行编译执行编译过后的程序,输入参数 运行程序,并输入参数:10.0.0.1,即追踪到目标主机为R1所经过的路由。根据程序运行结果,我们可以发现,在存在冗余链路存在的情况下,目标主机为R1所经过的路由器分别依次为:R4-R5-R3-R2-R1,而不是跳数更加少,距离更加短的R4-R3-R2-R1。分析其原因,在同时存在R4-R5-R3-R2-R1和R4-R3-R2-R1两条链路的情况下,因为R3、R4、R5之间的物理连接均通过FastEthernet(高速以太口)相连,而非R1、R2、R3、R4之间使用的Serial接口。两者相比,FastEthernet接口的出口代价远远小于Serial接口,因此运行在路由器上的EIGRP路由协议自动选择了链路中代价较小的一条链路。若此时断开R4-R5-R3这条链路,则追踪到达R1的路由应为R4-R3-R2-R1。当第二次对程序进行测试时,我们将R4的F0/1口手工关闭,即断开R4-R5-R3,并观察结果。对路由器R4的F0/1口执行关闭操作断开R4、R5、R3后追踪10.0.0.1的结果观察实验结果,我们发现追踪R1的路由时,途径的路由器为R4-R3-R2-R1,与我们测试前的预期相同。第三次测试时,我们选择的参数为一条网络中没有的地址,并观察结果。追踪网络中不存在的地址根据实验结果,当输入的参数为网络中不存在的地址时,程序显示出的下一条将永远为40.0.0.1,即R4。分析其原因,由于在设置linux系统中网卡属性时,手工配置了与R4同一网段的IP地址,并且将默认网关设置为10.0.0.1,即R4。因此在linux系统中,所有可以到达的地址皆由R4提供。而R4的路由表中并没有100.0.0.1的路由条目,因此该地址不可达,发送至100.0.0.1的任何数据包将在R4停留,直至存活时间为0后被丢弃。5. 总结经过两个礼拜的努力,本课程设计基本完成预定功能。本文从Linux与嵌入式系统中对于网络底层编程的角度说明路由跟踪系统的开发过程。在设计初期,我组为了设计出一个功能较为完整,在嵌入式Linux上实现网络的底层开发,我们通过查看了有关书籍和互联网,结合老师的意见和建议,最终确定本设计现有功能模块。在设计中,我们遇到许多技术上的问题,但通过查阅资料、网上论坛答疑、请教老师同学等各种方式,问题最终还是得到解决。由于时间和我组水平关系,设计中开发的功能还存在一些不足,比如路由器的模拟器只能运行在x86机器中而无法在ARM的处理器中运作。从整体来看,本课程设计还是有成功的一面,它实现了路由的跟踪,每经过一个路由,要求得到经过该路由节点的地址,也就是说输入目标信息, 可以得到本地主机到目标经过的所有中间节点。6. 附录代码:/*Internet路由跟踪程序 Traceroute 该程序使用UDP包发送一个试探数据报,连续递增改变数据报头的TTL值。TTL每一次“超时”,都会向我们返回一条ICMP消息(传输超时错误或目的端口不可到达错误),我们只要查看给我们发送ICMP消息的主机地址,即可知道该数据报经过了哪些主机(路由器)。 程序中使用了两个套接字,一个是普通的UDP数据报套接字,用IP_TTL选项来改变发送时的TTL值;另一个是原始套接字,用于接收返回来的ICMP消息。*/#include #include #include #include #include #include #include #include #include #include #include #define MAXPACKET65535/* IP包的最大大小*/#define UDPPACKETSIZE36/* UDP数据报的大小*/#define SRCPORT23156/*UDP包的源端口*/#define DSTPORT58127/*UDP包的目的端口*/*函数声明*/double deltaT(struct timeval *t1p,struct timeval *t2p);/*计算时间差*/int check_packet(u_char *buf,int cc); /*检查一个IP包是否期望的ICMP数据报*/void send_probe(int sndsock,struct sockaddr_in *whereto,int ttl); /*发送一个探测包*/*接收ICMP消息*/int wait_for_reply(int rcvsock,struct sockaddr_in *from,char *databuf,int buflen); /*主函数*/int main(int argc,char * argv)const int max_ttl=48;/*默认的最大跳数*/const int nprobes=3; /*默认的每跳探测次数*/处理命令行,合法的命令行格式为: tracert 主机名或主机IP地址*/if(argc!=2) fprintf(stderr,Usage: %s hostrn,argv0);exit(-1);struct hostent *host; /*主机名结构指针*/struct sockaddr_in haddr; /*远程主机地址结构*/struct sockaddr_in loc_addr; /*本机地址结构,用于绑定UDP服务于指定的端口*/bzero(&haddr,sizeof(haddr); /*填充目的主机地址结构*/haddr.sin_family=AF_INET;haddr.sin_addr.s_addr=inet_addr(argv1);haddr.sin_port=htons(DSTPORT);/*如果是主机名,则查询DNS解析*/if(haddr.sin_addr.s_addr=INADDR_NONE)if(NULL=(host=gethostbyname(argv1) fprintf(stderr,unknown host %srn,argv1);exit(-1);memcpy(&haddr.sin_addr,host-h_addr,host-h_length);/*填充本机地址结构*/loc_addr.sin_family=AF_INET;loc_addr.sin_addr.s_addr=htonl(INADDR_ANY);loc_addr.sin_port=htons(SRCPORT);int sndsock,rcvsock;/*创建UDP套接字*/if (sndsock = socket(AF_INET, SOCK_DGRAM, 0) 0) fprintf(stderr,traceroute: udp socketrn);exit(-1);/*创建RAW套接字,套接字的类型为IPPROTO_ICMP*/if (rcvsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) 0) fprintf(stderr,traceroute: raw socketrn);exit(-1);/*绑定UDP套接字于指定的端口*/if(bind(sndsock,(struct sockaddr*)&loc_addr,sizeof(loc_addr) fprintf(stderr,bind errorrn);exit(-1);fprintf(stdout, traceroute to %s (%s), argv1,inet_ntoa(haddr.sin_addr);fprintf(stdout, , %d hops max, %d byte packetsrn, max_ttl, UDPPACKETSIZE+sizeof(struct ip)+sizeof(struct udphdr);char databufMAXPACKET;/*接收ICMP数据报的缓冲区*/struct sockaddr_in from;/*远程主机地址结构*/int ttl;/循环改变发送的UDP数据报的TTL值,发送探测数据包*/for (ttl = 1; ttl = max_ttl; +ttl) u_long lastaddr = 0;/*记录上一个接收到的数据包的源地址*/int got_there = 0;/*记录是否到达了目的主机*/printf(%2d , ttl);fflush(stdout);int probe;/*每一跳(TTL值)循环发送nprobes个数据包*/for (probe = 0; probe 0) /*有数据可读,读取到指定的缓冲区中*/cc=recvfrom(rcvsock, databuf, buflen, 0, (struct sockaddr *)from, &fromlen);return(cc);/*函数: 向指定的地址发送一个UDP数据报sndsock: 发送数据报套接字whereto: 目的主机地址结构指针ttl: 发送数据包的TTL值*/void send_probe(int sndsock,struct sockaddr_in *whereto,int ttl)char databufUDPPACKETSIZE;/*发送数据包缓冲区(数据部分)*/bzero(databuf,sizeof(databuf);/*设置发送套接字的选项(IPPROTO_IP级,IP_TTL类型),更改IP包头中的TTL为指定值*/setsockopt(sndsock,IPPROTO_IP,IP_TTL,(char *)&ttl,sizeof(ttl);/*发送数据包(携带UDPPACKETSIZE个字节的零)*/int n = sendto(sndsock, databuf, sizeof(databuf), 0,(struct sockaddr *)whereto, sizeof(struct sockaddr);if(n!=UDPPACKETSIZE) fprintf(stderr,Error in sendtorn);/*函数: 检查一个返回的IP包是否为期待的ICMP数据报(TTL超时或者目的端口不可到达)buf: 数据缓冲区首地址cc: 缓冲区中数据大小*/int check_packet(u_char *buf,int cc)/*处理IP包头*/struct ip *ip= (struct ip *) buf;/*计算IP头大小*/int hlen = ip-ip_hl 2;/*从大小来判断是否是一个ICMP包*/if (cc icmp_type;/*ICMP消息类型*/u_char code=icp-icmp_code; /*ICMP消息代码*/*期待的ICMP消息只有两种:传输超时(TTL变为0),目的端口不可到达(已经到了目的主机)*/if(type=ICMP_TIMXCEED | type=ICMP_UNREACH) struct ip *hip=&icp-icmp_ip;hlen=hip-ip_hlip_p=IPPROTO_UDP & udp-dest=htons(DSTPORT) & udp-source=htons(SRCPORT)/*if(hip-ip_p=IPPROTO_UDP & udp-uh_dport=htons(DSTPORT) & udp-uh_sport=htons(SRCPORT)*/return 1;return 0;/*函数: 计算两个timeval结构表示的时间差值*/double deltaT(struct timeval *t1p,struct timeval *t2p)double dt;dt = (double)(t2p-tv_sec - t1p-tv_sec) * 1000.0 + (double)(t2p-tv_usec - t1p-tv_usec) / 1000.0;return (dt);7. 参考文献1. 吴功宜,董大凡,王珺,刘乾.计算机网络高级软件编程技术M 清华大学出版社 20052. 罗军舟,黎波涛,杨明等.TCP/IP协议及网络编程技术M 清华大学出版社 20043. 吴玉,李岚.基于网络数据获取技术的网络监听的检测和防范J.信息技术.2007(8):142-1434. 张思民.嵌入式系统设计与应用M清华大学出版社20085. 华清远见嵌入式培训中心.嵌入式LinuxC语言应用程序设计M.人民邮电出版社 20078. 设计评语14 / 14
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 管理文书 > 各类标准


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!