⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 traceroute.c

📁 实现了traceroute的功能
💻 C
字号:
#include <stdio.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/udp.h>#include <netinet/ip_icmp.h>#include <netinet/in.h>#include <netinet/ip.h>#include <errno.h>#include <signal.h>#include <setjmp.h>#define BUFFER_SIZE 1500int ttl = 0;static sigjmp_buf jmpbuf;static void recvfrom_alarm(int signo) { 	printf("*");        alarm(3);        siglongjmp(jmpbuf, 1);}int main(int argc, char *argv[]){        int max_ttl=30;//最大TTL        u_short sport=30000;//本机端口	        u_short dport=32768+666;//宿端口	int myflag= 1;	const char *message = "Hello Linux World!";//发送的字符串        int len=strlen(message);//字符串长度        int    i,j,  packetsize,  sockfd,  number,  clilen;	struct in_addr src_addr,des_addr;	struct hostent *host;	struct sockaddr_in cliaddr,servaddr;	struct udphdr *udp;	struct iphdr  *ip,*ip_header;	struct icmphdr *icmp;        struct timeval t1,t2;	double rtt;        char recvbuf[BUFFER_SIZE] , packet[BUFFER_SIZE], ipstr[INET_ADDRSTRLEN],iptr[INET_ADDRSTRLEN];        if(argc != 2)	{	  printf("usage :traceroute hostname \n");	  exit(1);	}	src_addr.s_addr = htonl(INADDR_ANY);	if((host=gethostbyname(argv[1])) == NULL)//get host by name	{		perror("gethostbyname");		exit(1);	}	memcpy((void*)&des_addr,host->h_addr,sizeof(struct in_addr));	if(inet_ntop(AF_INET,&(des_addr),iptr,INET_ADDRSTRLEN) == NULL)  	{	  perror("inet_ntop");	  exit(1);  	}  	  	printf("traceroute to %s (%s) %d hop max %d bytes packets\n",argv[1],iptr,max_ttl,len);	if((sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0)	{		perror("socket");		exit(1);	}	if(setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,(char*)&myflag,sizeof(myflag))<0)	{		perror("setsockopt");		exit(1);	}		packetsize = sizeof(struct iphdr) + sizeof(struct udphdr) + strlen(message);//计算发送包的大小	        signal(SIGALRM,recvfrom_alarm);	alarm(3);	for (ttl=1;ttl <=max_ttl;ttl++)	  {            //创建ip头	   ip_header = (struct iphdr *)packet;           bzero((char*)(ip_header),sizeof(struct iphdr));           ip_header->ihl = 5;           ip_header->version = 4;           ip_header->id = htons(getpid());           ip_header->ttl = ttl;            ip_header->protocol = IPPROTO_UDP;           ip_header->daddr = des_addr.s_addr;                	   //为剩余空间清零	   bzero((packet + sizeof(struct udphdr) + sizeof(struct iphdr)),BUFFER_SIZE-packetsize);	   printf("%2d",ttl);           fflush(stdout);	   //udp指针	   udp  =(struct udphdr*)(packet + sizeof(struct iphdr));	   //创建udp头           udp->source = htons(sport);	   udp->dest = htons(dport);	   udp->len = htons((sizeof(struct udphdr)+strlen(message))); 	   udp->check = 0;  	   //将Hello Linux World 拷贝到包中           memcpy((char*)udp+sizeof(struct udphdr),message,strlen(message));	   //连接准备工作	   bzero(&servaddr,sizeof(servaddr));	   servaddr.sin_family = AF_INET;	   servaddr.sin_port = htons(dport);	   servaddr.sin_addr = des_addr;   	  	   	   //时间戳           for(j=0;j<3;j++)	     {           gettimeofday(&t1,NULL);	   if(sendto(sockfd,packet,packetsize,0,(struct sockaddr *)&servaddr,sizeof(servaddr)) != packetsize)    		{		  perror("sendto");		  exit(1);    		}    			   if (sigsetjmp(jmpbuf, 1) != 0)	     continue;    		   number = recvfrom(sockfd,recvbuf, BUFFER_SIZE-1, 0, (struct sockaddr *)&cliaddr , &clilen);	  	 	   gettimeofday(&t2,NULL);	   t2.tv_sec = t2.tv_sec - t1.tv_sec;	   t2.tv_usec = t2.tv_usec - t1.tv_usec;	   rtt = t2.tv_sec*1000.0+ t2.tv_usec/1000.0;  	   printf("  %.3f ms",rtt);	     }		   recvbuf[number] = '\0';	   	   		   ip = (struct iphdr*)recvbuf;	   icmp = (struct icmphdr *)(recvbuf+sizeof(struct iphdr));	   udp = (struct udphdr *)(recvbuf + 2*sizeof(struct iphdr) + sizeof(struct icmphdr));	   printf("  %s  ",inet_ntop(AF_INET,(struct in_addr *)&(ip->saddr),ipstr,INET_ADDRSTRLEN));		   printf("\n");		   if(icmp->type==ICMP_TIME_EXCEEDED && icmp->code==ICMP_EXC_TTL)   		{   		continue;   		}	   if(icmp->type==ICMP_DEST_UNREACH && icmp->code==ICMP_PORT_UNREACH)   		{   		ip = (struct iphdr*)recvbuf;                break;       		}       	    	}   return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -