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

📄 scanroute.c

📁 Please unzip the file and make the file under linux with version 2.6 or above. The function is just
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <netdb.h>#include <sys/time.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/ip_icmp.h>#define __FAVOR_BSD#include <netinet/udp.h>#include <arpa/inet.h>enum {CMD_NAME, DST_IP};enum {ON, OFF};#define MAXHOSTNAMELEN 256#define BUFSIZE 512struct packet_udp{	struct ip ip;	struct udphdr udp;};void make_ip_header(struct ip *ip, int src_ip, int dst_ip, int ip_len);void make_udp_header(struct udphdr *udp);void tvsub(struct timeval *out, struct timeval *in);u_short checksum(u_short *data, int len);int main(int argc, char * argv[]){	struct packet_udp sendpacket;        /* UDP packet to be sent */	struct sockaddr_in send_sa;	int send_sd;	int recv_sd;	int len;	int ttl;	int i;	u_char buff[BUFSIZE];	struct timeval tvm0;        /* the time packet sent */	struct timeval tvm1;        /* the time packet received */	struct timeval tv;                /* (select)'s time out */	fd_set readfd;                        /* descriptor for (select) check */	int on = 1;	int dns_flg = ON;                /* whether to resolve host's domain name */	/* check arg "-n" */	if(argc == 3 && (strcmp(argv[1], "-n") == 0))	{		dns_flg = OFF;		argv[1] = argv[2];		argv[2] = NULL;		argc = 2;	}	if(argc != 2)	{		fprintf(stderr, "usage: %s [-n] dst_ip \n", argv[CMD_NAME]);		exit(EXIT_FAILURE);	}	memset((char *)&send_sa, 0, sizeof(struct sockaddr_in));	send_sa.sin_family = AF_INET;	/* convert domain name to IP */	if((send_sa.sin_addr.s_addr = inet_addr(argv[DST_IP])) == INADDR_NONE)	{		struct hostent *he;		if((he = gethostbyname(argv[DST_IP])) == NULL)		{			fprintf(stderr, "unknow host %s \n", argv[DST_IP]);			exit(EXIT_FAILURE);		}		send_sa.sin_family = he->h_addrtype;		memcpy((char*)&(send_sa.sin_addr), he->h_addr, sizeof(he->h_length));	}	/* open a RAW socket for UDP to send */	if((send_sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)	{		perror("socket(RAW)");		exit(EXIT_FAILURE);	}	if(setsockopt(send_sd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0)	{		perror("setsockopt(IPPROTO_IP, IP_HDRINCL)");		exit(EXIT_FAILURE);	}	/* open a RAW socket for ICMP to receive */	if((recv_sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)	{		perror("socket(SOCK_RAW)");		exit(EXIT_FAILURE);	}	/* generate a UDP packet */	len = sizeof(struct packet_udp);	memset((char*)&sendpacket, 0, sizeof(struct packet_udp));	make_udp_header(&(sendpacket.udp));	make_ip_header(&(sendpacket.ip), 0, send_sa.sin_addr.s_addr, len);	/* main routine */	printf("Scanroute %s \n", inet_ntoa(send_sa.sin_addr));	for(ttl = 1; ttl <= 64; ttl++)	{		printf("%2d: ", ttl);		fflush(stdout);		sendpacket.ip.ip_ttl = ttl;		for(i = 0; i < 3; i++)		{			/* send a UDP packet */			if(sendto(send_sd, (char*)&sendpacket, len, 0,				(struct sockaddr *)&send_sa, sizeof(send_sa)) < 0)			{				perror("sendto");				exit(EXIT_FAILURE);			}			/* store the time sent */			gettimeofday(&tvm0, (struct timezone *)0);			/* set time out */			tv.tv_sec = 3;			tv.tv_usec = 0;reread:			/* check descriptors using "select" */			FD_ZERO(&readfd);			FD_SET(recv_sd, &readfd);			if((select(recv_sd+1, &readfd, NULL, NULL, &tv)) > 0)			{				int hlen;        /* len of header */				struct icmp *icmp;				struct ip *ip;				struct hostent *host;				char hostip[256];				struct in_addr ipaddr;				/* receive a ICMP packet */				if(recvfrom(recv_sd, buff, BUFSIZE, 0, NULL, NULL) < 0)				{					perror("recvfrom");					exit(EXIT_FAILURE);				}				ip = (struct ip *)buff;				hlen = ip->ip_hl << 2;				if(ip->ip_p != IPPROTO_ICMP)					goto reread;				icmp = (struct icmp *)(buff + hlen);				/* don't receive unrelated packets */				if((icmp->icmp_type != ICMP_TIMXCEED					|| icmp->icmp_code != ICMP_TIMXCEED_INTRANS)					&& (icmp->icmp_type != ICMP_UNREACH_PORT))					goto reread;				/* store the time received packet */				gettimeofday(&tvm1, (struct timezone *)0);				tvsub(&tvm1, &tvm0);				memcpy(&ipaddr, &(ip->ip_src.s_addr), sizeof(ipaddr));				strcpy(hostip, inet_ntoa(*(struct in_addr *)&(ip->ip_src.s_addr)));				/* display IP and domain name */				if(dns_flg == OFF)					printf("% -15s", hostip);				else if((host= gethostbyaddr((char*)&ipaddr, 4, AF_INET)) == NULL)					printf("%-15s(%S)", hostip, hostip);				else					printf("%-15s(%S)", hostip, host->h_name);				printf(":RTT= %8.4fms", tvm1.tv_sec*1000.0 + tvm1.tv_usec/1000.0);				/* check whether reached dst host */				if(icmp->icmp_type == ICMP_UNREACH_PORT)				{					printf("\n Reach!\n");					goto exit;				}				else					break;			}			else			{				printf("?");				fflush(stdout);			}		}		printf(" \n");	}exit:	close(send_sd);	close(recv_sd);	return EXIT_SUCCESS;}void make_udp_header(struct udphdr *udp){	udp->uh_sport = htons(0);	udp->uh_ulen = htons((u_short)sizeof(struct udphdr));	udp->uh_dport = htons(33434);        /* port of traceroute */	udp->uh_sum = htons(0);}void make_ip_header(struct ip *ip, int src_ip, int dst_ip, int ip_len){	memset((char *)ip, 0, sizeof(struct ip));	/* generate an IP header */	ip->ip_v = IPVERSION;	ip->ip_hl = sizeof(struct ip) >> 2;	ip->ip_id = htons(0);	ip->ip_off = 0;#ifdef _linux	/* linux's RAW IP */	ip->ip_len = htons(ip_len);	ip->ip_off = htons(0);#else	/* BSD's RAW IP */	ip->ip_len = ip_len;	ip->ip_off = 0;#endif	ip->ip_ttl = 64;	ip->ip_p = IPPROTO_UDP;	ip->ip_src.s_addr = src_ip;	ip->ip_dst.s_addr = dst_ip;	/* calc the checksum */	ip->ip_sum = 0;	ip->ip_sum = checksum((u_short *)ip, sizeof(struct ip));}void tvsub(struct timeval *out, struct timeval * in){	if( (out->tv_usec -= in->tv_usec) < 0)	{		out->tv_sec --;		out->tv_usec += 1000000;	}	out->tv_sec -= in->tv_sec;}u_short checksum(u_short *data, int len){	u_long sum = 0; 	/* increase 2 bytes at one time */	for(; len > 1; len -= 2)	{		sum += *data++;		if(sum & 0x80000000)			sum = (sum & 0xffff) + (sum >> 16);	}	/* process if len is odd */	if(len == 1)	{		u_short i = 0;		*(u_char *)(&i) = * (u_char *)data;		sum += i;	}	/* process the overflow bit */	while(sum >> 16)		sum = (sum & 0xffff) + (sum >> 16);	return (sum == 0xffff) ? sum : ~sum;}       

⌨️ 快捷键说明

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