一、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/zh-tw/n/151406.html
微信掃一掃
支付寶掃一掃