欢迎来到天天文库
浏览记录
ID:50917148
大小:64.65 KB
页数:5页
时间:2020-03-15
《简单的ping6程序的实现内有代码.docx》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、Ping6程序的实现Ping6函数主要用于向一个节点发送回送请求报文并接收该节点回复的回送应答报文用于确定一个节点的可达性及往返时间延迟。回送请求报文格式如下:标识符和序列号由源节点产生,用于将请求报文和应答报文对应起来,其中数据可以是任意字节的任意数据。回送应答报文格式如下:回送应答报文的标识符和序列号及数据都是由请求报文中获得。在linux下ICMPv6的报文头结构如下:本程序中,报文简化为只包含消息类型、消息代码、数据报的ID、数据报的序列号及数据段几个部分。ICMPV6回送请求报文类型为128;IC
2、MPV6回送请求报文代码值为0;ICMPV6回送请求报文序列号通常为一个递增的数生成ICMPV6回送请求报文的ID用于对应回送应答报文,通常用进程的PID补充同时保存发送时间。inticmpv6_pack(intpack_num){inti,packsize;structicmp6_hdr*icmpv6;structtimeval*tval;icmpv6=(structicmp6_hdr*)sendbuf;icmpv6->icmp6_type=128;//消息类型为ICMPv6回显请求icmpv6->icm
3、p6_code=0;//code为0icmpv6->icmp6_cksum=0;//校验和初始值为0icmpv6->icmp6_seq=pack_num;//序列号icmpv6->icmp6_id=pid;//进程pidpacksize=8+datalen;gettimeofday(sendtime,NULL);//获取发送数据时间returnpacksize;}发送报文:将打包好的数据通过原始套接字发送到指定地址,使用sendto函数。每次发送成功后序列号增加1,即nsend++voidicmp6_sen
4、d(){intpacketsize;if(nsend5、from函数将接收到的数据存储到recvbuf中,将发送数据端的IP地址存储在recv_addr中,记录接收数据包的时间,调用unpack函数对数据包进行解包和数据分析。接收到一个报文后接收序列号并没有加1,而是在解包后确定数据包正确后加1,防止接收错误的报文导致丢包的情况。voidicmp6_recv(){intn,fromlen;fromlen=sizeof(recv_addr);while(nrecv6、vbuf,sizeof(recvbuf),0,(structsockaddr*)&recv_addr,&fromlen))<0)//接收报文{perror("recvfromerror");}gettimeofday(&recvtime,NULL);//保存接收数据包时间unpack(recvbuf,n);//解压数据包,并数据处理}}解压收到的报文:接收到报文后判断报文长度是不是太短,如果不是证明报文有效,需要判断报文的类型是否为回送应答报文即类型号是不是129,并核实其标识ID是否是本进程PID,确定报7、文正确后,接收序列号加1.通过接收报文的时间减去发送报文的时间,可以得到报文往返时间。最后是对返回信息进行显示,因为ipv6为128个字节,中间为0的位一般用::代替,为了显示美观,采用了标志位flag进行判断,达到显示标准ipv6地址格式的目的。intunpack(char*buf,intlen){inti;intiphdrlen;structip6*ip6;structicmp6_hdr*icmpv6;doublertt;intflag=0;icmpv6=(structicmp6_hdr*)(buf);8、//获得ICMPv6报文地址if(len<8){printf("ICMPpacker'slengthislessthan8");return(-1);}/*检查消息类型和进程号是否匹配*/if((icmpv6->icmp6_type==129)&&(icmpv6->icmp6_id==pid)){nrecv++;//判断数据有效,接收序列号加1different.tv_sec=recvtime.tv_sec
5、from函数将接收到的数据存储到recvbuf中,将发送数据端的IP地址存储在recv_addr中,记录接收数据包的时间,调用unpack函数对数据包进行解包和数据分析。接收到一个报文后接收序列号并没有加1,而是在解包后确定数据包正确后加1,防止接收错误的报文导致丢包的情况。voidicmp6_recv(){intn,fromlen;fromlen=sizeof(recv_addr);while(nrecv6、vbuf,sizeof(recvbuf),0,(structsockaddr*)&recv_addr,&fromlen))<0)//接收报文{perror("recvfromerror");}gettimeofday(&recvtime,NULL);//保存接收数据包时间unpack(recvbuf,n);//解压数据包,并数据处理}}解压收到的报文:接收到报文后判断报文长度是不是太短,如果不是证明报文有效,需要判断报文的类型是否为回送应答报文即类型号是不是129,并核实其标识ID是否是本进程PID,确定报7、文正确后,接收序列号加1.通过接收报文的时间减去发送报文的时间,可以得到报文往返时间。最后是对返回信息进行显示,因为ipv6为128个字节,中间为0的位一般用::代替,为了显示美观,采用了标志位flag进行判断,达到显示标准ipv6地址格式的目的。intunpack(char*buf,intlen){inti;intiphdrlen;structip6*ip6;structicmp6_hdr*icmpv6;doublertt;intflag=0;icmpv6=(structicmp6_hdr*)(buf);8、//获得ICMPv6报文地址if(len<8){printf("ICMPpacker'slengthislessthan8");return(-1);}/*检查消息类型和进程号是否匹配*/if((icmpv6->icmp6_type==129)&&(icmpv6->icmp6_id==pid)){nrecv++;//判断数据有效,接收序列号加1different.tv_sec=recvtime.tv_sec
6、vbuf,sizeof(recvbuf),0,(structsockaddr*)&recv_addr,&fromlen))<0)//接收报文{perror("recvfromerror");}gettimeofday(&recvtime,NULL);//保存接收数据包时间unpack(recvbuf,n);//解压数据包,并数据处理}}解压收到的报文:接收到报文后判断报文长度是不是太短,如果不是证明报文有效,需要判断报文的类型是否为回送应答报文即类型号是不是129,并核实其标识ID是否是本进程PID,确定报
7、文正确后,接收序列号加1.通过接收报文的时间减去发送报文的时间,可以得到报文往返时间。最后是对返回信息进行显示,因为ipv6为128个字节,中间为0的位一般用::代替,为了显示美观,采用了标志位flag进行判断,达到显示标准ipv6地址格式的目的。intunpack(char*buf,intlen){inti;intiphdrlen;structip6*ip6;structicmp6_hdr*icmpv6;doublertt;intflag=0;icmpv6=(structicmp6_hdr*)(buf);
8、//获得ICMPv6报文地址if(len<8){printf("ICMPpacker'slengthislessthan8");return(-1);}/*检查消息类型和进程号是否匹配*/if((icmpv6->icmp6_type==129)&&(icmpv6->icmp6_id==pid)){nrecv++;//判断数据有效,接收序列号加1different.tv_sec=recvtime.tv_sec
此文档下载收益归作者所有