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

📄 traceroute.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
	ident = (getpid() & 0xffff) | 0x8000;	if ((pe = getprotobyname("icmp")) == NULL) {		Fprintf(stderr, "icmp: unknown protocol\n");		exit(10);	}	if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0) {		perror("traceroute: icmp socket");		exit(5);	}	if (options & SO_DEBUG)		(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,				  (char *)&on, sizeof(on));	if (options & SO_DONTROUTE)		(void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE,				  (char *)&on, sizeof(on));	if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {		perror("traceroute: raw socket");		exit(5);	}#ifdef SO_SNDBUF	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,		       sizeof(datalen)) < 0) {		perror("traceroute: SO_SNDBUF");		exit(6);	}#endif#ifdef IP_HDRINCL	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,		       sizeof(on)) < 0) {		perror("traceroute: IP_HDRINCL");		exit(6);	}#endif	if (options & SO_DEBUG)		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,				  (char *)&on, sizeof(on));	if (options & SO_DONTROUTE)		(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,				  (char *)&on, sizeof(on));	if (source) {		(void) bzero((char *)&from, sizeof(struct sockaddr));		from.sin_family = AF_INET;		from.sin_addr.s_addr = inet_addr(source);		if (from.sin_addr.s_addr == -1) {			Printf("traceroute: unknown host %s\n", source);			exit(1);		}		outpacket->ip.ip_src = from.sin_addr;#ifndef IP_HDRINCL		if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0) {			perror ("traceroute: bind:");			exit (1);		}#endif	}	Fprintf(stderr, "traceroute to %s (%s)", hostname,		inet_ntoa(to->sin_addr));	if (source)		Fprintf(stderr, " from %s", source);	Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen);	(void) fflush(stderr);	for (ttl = 1; ttl <= max_ttl; ++ttl) {		u_long lastaddr = 0;		int got_there = 0;		int unreachable = 0;		Printf("%2d ", ttl);		for (probe = 0; probe < nprobes; ++probe) {			int cc;			struct timeval tv;			struct ip *ip;			(void) gettimeofday(&tv, &tz);			send_probe(++seq, ttl);			while (cc = wait_for_reply(s, &from)) {				if ((i = packet_ok(packet, cc, &from, seq))) {					int dt = deltaT(&tv);					if (from.sin_addr.s_addr != lastaddr) {						print(packet, cc, &from);						lastaddr = from.sin_addr.s_addr;					}					Printf("  %d ms", dt);					switch(i - 1) {					case ICMP_UNREACH_PORT:#ifndef ARCHAIC						ip = (struct ip *)packet;						if (ip->ip_ttl <= 1)							Printf(" !");#endif						++got_there;						break;					case ICMP_UNREACH_NET:						++unreachable;						Printf(" !N");						break;					case ICMP_UNREACH_HOST:						++unreachable;						Printf(" !H");						break;					case ICMP_UNREACH_PROTOCOL:						++got_there;						Printf(" !P");						break;					case ICMP_UNREACH_NEEDFRAG:						++unreachable;						Printf(" !F");						break;					case ICMP_UNREACH_SRCFAIL:						++unreachable;						Printf(" !S");						break;					}					break;				}			}			if (cc == 0)				Printf(" *");			(void) fflush(stdout);		}		putchar('\n');		if (got_there || unreachable >= nprobes-1)			exit(0);	}}wait_for_reply(sock, from)	int sock;	struct sockaddr_in *from;{	fd_set fds;	struct timeval wait;	int cc = 0;	int fromlen = sizeof (*from);	FD_ZERO(&fds);	FD_SET(sock, &fds);	wait.tv_sec = waittime; wait.tv_usec = 0;	if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0)		cc=recvfrom(s, (char *)packet, sizeof(packet), 0,			    (struct sockaddr *)from, &fromlen);	return(cc);}send_probe(seq, ttl){	struct opacket *op = outpacket;	struct ip *ip = &op->ip;	struct udphdr *up = &op->udp;	int i;	ip->ip_off = 0;	ip->ip_p = IPPROTO_UDP;	ip->ip_len = datalen;	ip->ip_ttl = ttl;	up->uh_sport = htons(ident);	up->uh_dport = htons(port+seq);	up->uh_ulen = htons((u_short)(datalen - sizeof(struct ip)));	up->uh_sum = 0;	op->seq = seq;	op->ttl = ttl;	(void) gettimeofday(&op->tv, &tz);	i = sendto(sndsock, (char *)outpacket, datalen, 0, &whereto,		   sizeof(struct sockaddr));	if (i < 0 || i != datalen)  {		if (i<0)			perror("sendto");		Printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,			datalen, i);		(void) fflush(stdout);	}}deltaT(tp)	struct timeval *tp;{	struct timeval tv;	(void) gettimeofday(&tv, &tz);	tvsub(&tv, tp);	return (tv.tv_sec*1000 + (tv.tv_usec + 500)/1000);}/* * Convert an ICMP "type" field to a printable string. */char *pr_type(t)	u_char t;{	static char *ttab[] = {	"Echo Reply",	"ICMP 1",	"ICMP 2",	"Dest Unreachable",	"Source Quench", "Redirect",	"ICMP 6",	"ICMP 7",	"Echo",		"ICMP 9",	"ICMP 10",	"Time Exceeded",	"Param Problem", "Timestamp",	"Timestamp Reply", "Info Request",	"Info Reply"	};	if(t > 16)		return("OUT-OF-RANGE");	return(ttab[t]);}packet_ok(buf, cc, from, seq)	u_char *buf;	int cc;	struct sockaddr_in *from;	int seq;{	register struct icmp *icp;	u_char type, code;	int hlen;#ifndef ARCHAIC	struct ip *ip;	ip = (struct ip *) buf;	hlen = ip->ip_hl << 2;	if (cc < hlen + ICMP_MINLEN) {		if (verbose)			Printf("packet too short (%d bytes) from %s\n", cc,				inet_ntoa(from->sin_addr));		return (0);	}	cc -= hlen;	icp = (struct icmp *)(buf + hlen);#else	icp = (struct icmp *)buf;#endif	type = icp->icmp_type; code = icp->icmp_code;	if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||	    type == ICMP_UNREACH) {		struct ip *hip;		struct udphdr *up;		hip = &icp->icmp_ip;		hlen = hip->ip_hl << 2;		up = (struct udphdr *)((u_char *)hip + hlen);		if (hlen + 12 <= cc && hip->ip_p == IPPROTO_UDP &&		    up->uh_sport == htons(ident) &&		    up->uh_dport == htons(port+seq))			return (type == ICMP_TIMXCEED? -1 : code+1);	}#ifndef ARCHAIC	if (verbose) {		int i;		u_long *lp = (u_long *)&icp->icmp_ip;		Printf("\n%d bytes from %s to %s", cc,			inet_ntoa(from->sin_addr), inet_ntoa(ip->ip_dst));		Printf(": icmp type %d (%s) code %d\n", type, pr_type(type),		       icp->icmp_code);		for (i = 4; i < cc ; i += sizeof(long))			Printf("%2d: x%8.8lx\n", i, *lp++);	}#endif	return(0);}print(buf, cc, from)	u_char *buf;	int cc;	struct sockaddr_in *from;{	struct ip *ip;	int hlen;	ip = (struct ip *) buf;	hlen = ip->ip_hl << 2;	cc -= hlen;	if (nflag)		Printf(" %s", inet_ntoa(from->sin_addr));	else		Printf(" %s (%s)", inetname(from->sin_addr),		       inet_ntoa(from->sin_addr));	if (verbose)		Printf (" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));}#ifdef notyet/* * Checksum routine for Internet Protocol family headers (C Version) */in_cksum(addr, len)u_short *addr;int len;{	register int nleft = len;	register u_short *w = addr;	register u_short answer;	register int sum = 0;	/*	 *  Our algorithm is simple, using a 32 bit accumulator (sum),	 *  we add sequential 16 bit words to it, and at the end, fold	 *  back all the carry bits from the top 16 bits into the lower	 *  16 bits.	 */	while (nleft > 1)  {		sum += *w++;		nleft -= 2;	}	/* mop up an odd byte, if necessary */	if (nleft == 1)		sum += *(u_char *)w;	/*	 * add back carry outs from top 16 bits to low 16 bits	 */	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */	sum += (sum >> 16);			/* add carry */	answer = ~sum;				/* truncate to 16 bits */	return (answer);}#endif /* notyet *//* * Subtract 2 timeval structs:  out = out - in. * Out is assumed to be >= in. */tvsub(out, in)register struct timeval *out, *in;{	if ((out->tv_usec -= in->tv_usec) < 0)   {		out->tv_sec--;		out->tv_usec += 1000000;	}	out->tv_sec -= in->tv_sec;}/* * Construct an Internet address representation. * If the nflag has been supplied, give  * numeric value, otherwise try for symbolic name. */char *inetname(in)	struct in_addr in;{	register char *cp;	static char line[50];	struct hostent *hp;	static char domain[MAXHOSTNAMELEN + 1];	static int first = 1;	if (first && !nflag) {		first = 0;		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&		    (cp = index(domain, '.')))			(void) strcpy(domain, cp + 1);		else			domain[0] = 0;	}	cp = 0;	if (!nflag && in.s_addr != INADDR_ANY) {		hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);		if (hp) {			if ((cp = index(hp->h_name, '.')) &&			    !strcmp(cp + 1, domain))				*cp = 0;			cp = hp->h_name;		}	}	if (cp)		(void) strcpy(line, cp);	else {		in.s_addr = ntohl(in.s_addr);#define C(x)	((x) & 0xff)		Sprintf(line, "%lu.%lu.%lu.%lu", C(in.s_addr >> 24),			C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));	}	return (line);}

⌨️ 快捷键说明

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