一、routetrace命令概述
routetrace命令是一种网络诊断工具,用于检测互联网协议(IP)数据包在从源到目标的传输过程中所经过的路由器。它在测量互联网连接的可用性和可靠性方面非常有用。
routetrace的工作原理是对目标主机进行一系列的ping测试,收集响应时间和具体路由信息,然后根据收集到的信息构建出网络拓扑图。这样,我们可以通过程序生成的路由路径追踪到主机,了解它的具体路径和连接状态等详细信息。
二、routetrace命令优点
1、显示网络层的路由
traceroute [destination]
routetrace命令可以帮助我们实时地获取到网络中的路由和网络延迟,以便我们更好地了解网络环境。
2、确定连接延迟的根本原因
traceroute [destination]
如果我们在网络传输过程中遇到了延迟问题,可以使用routetrace命令定位并确定延迟问题的根本原因,从而进一步解决问题。
3、灵活的定制
traceroute [destination] [-h max_hop] [-f first_hop] [-m max_ttl] [-q nqueries]
routetrace命令可以由用户按照自己的需求来设定参数,可以指定最大跳数(-h)、最小跳数(-f)、最大TTL值(-m)以及每个跳点的查询次数(-q),从而更好地定制符合自己需求的搜索路径。
三、routetrace命令注意事项
1、安全考虑
traceroute [destination]
在使用routetrace命令时,我们需要注意一定的安全问题,因为在指定ICMP数据报并在路由时遭遇限制数据包过滤器的情况下,此命令可以被黑客用来侵入目标主机。
2、路由器不稳定
traceroute [destination]
由于路由器可能有许多优化策略,从而可以造成路径的动态性和不稳定性,在进行无法保证准确度的情况下,可能会产生一些干扰。
3、路由器路由差异
traceroute [destination]
由于不同的路由器可能使用不同的路由算法,从而可能导致同一目标主机在不同的时间段,经过不同的路由器,路径或路由发生变化。
四、routetrace代码示例
#include
#include
#include
#include
#include
#include
void print_address(unsigned char* ip_address) {
printf("%d.%d.%d.%d\t",ip_address[0],ip_address[1], ip_address[2], ip_address[3]);
}
unsigned short calc_checksum(unsigned char* addr,int len) {
unsigned short* addr_p=(unsigned short*)addr;
unsigned int sum=0;
for(int i=0;i>16)+(sum&0xffff);
sum=(sum>>16)+(sum&0xffff);
return ~sum;
}
int main(int argc, char* argv[]) {
int seq=0;
int max_ttl=30;//最大跳数
struct sockaddr_in addr,from_addr;
addr.sin_port=htons(80);
addr.sin_family=AF_INET;
struct hostent* hent;
if((hent=gethostbyname(argv[1]))==0) {
herror("无法解析目标主机!");
return -1;
}
memcpy(&addr.sin_addr,hent->h_addr_list[0],sizeof(addr.sin_addr));
printf("正在追踪到 %s [%s] 的路径\n",argv[1],inet_ntoa(*((struct in_addr*)hent->h_addr_list[0])));
unsigned char send_packet[64];
unsigned char recv_packet[1024];
struct ip* ipq;
struct icmp* icmpq;
for(int ttl=1;ttlicmp_type=ICMP_ECHO;
icmpq->icmp_code=0;
icmpq->icmp_seq=seq++;
icmpq->icmp_id=getpid();
icmpq->icmp_cksum=calc_checksum(send_packet,sizeof(struct icmp));
int sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if(sockfd<0) {
printf("创建套接字失败\n");
return -1;
}
printf("%d\t",ttl);
for(int i=0;ih_addr_list[0])));
setsockopt(sockfd,IPPROTO_IP,IP_TTL,&ttl,sizeof(int));
struct timeval tv_val={1,0};
setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,&tv_val,sizeof(tv_val));//接收超时,防止卡死
socklen_t addr_len=sizeof(from_addr);
sendto(sockfd,send_packet,sizeof(send_packet),0,(struct sockaddr*)&addr,sizeof(addr));
int len=recvfrom(sockfd,recv_packet,sizeof(recv_packet),0,(struct sockaddr*)&from_addr,&addr_len);
if(len>0) {//接收成功
ipq=(struct ip*)recv_packet;
print_address((unsigned char*)&from_addr.sin_addr.s_addr); //打印源IP地址
printf("\t%.2lfms", (double)tv_val.tv_usec / 1000.0); //打印时间
if(ipq->ip_p==IPPROTO_ICMP) {
icmpq=(struct icmp*)(recv_packet+(ipq->ip_hl<icmp_type==ICMP_TIMXCEED&&icmpq->icmp_code==ICMP_TIMXCEED_INTRANS) {
printf("\t唯一跳点");
break;
}else if(icmpq->icmp_type==ICMP_ECHOREPLY&&icmpq->icmp_id==getpid()) {
printf("\t终点");
goto end;
}
} else {
printf("\t*");
}
} else {
printf("\t超时");
}
}
close(sockfd);
printf("\n");
}
end:
printf("\n");
return 0;
}
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/151406.html
微信扫一扫
支付宝扫一扫