📄 traceroute.c
字号:
"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]);}#endifstatic inline intpacket_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq){ struct icmp *icp; u_char type, code; int hlen; struct ip *ip; ip = (struct ip *) buf; hlen = ip->ip_hl << 2; if (cc < hlen + ICMP_MINLEN) {#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE if (verbose) printf("packet too short (%d bytes) from %s\n", cc, inet_ntoa(from->sin_addr));#endif return (0); } cc -= hlen; icp = (struct icmp *)(buf + hlen); 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->source == htons(ident) && up->dest == htons(port+seq)) return (type == ICMP_TIMXCEED? -1 : code+1); }#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE if (verbose) { int i; u_long *lp = (u_long *)&icp->icmp_ip; printf("\n%d bytes from %s to %s: icmp type %d (%s) code %d\n", cc, inet_ntoa(from->sin_addr), inet_ntoa(ip->ip_dst), 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);}static void /* not inline */send_probe(int seq, int ttl){ struct opacket *op = outpacket; struct ip *ip = &op->ip; struct udphdr *up = &op->udp; int i; struct timezone tz; ip->ip_off = 0; ip->ip_hl = sizeof(*ip) >> 2; ip->ip_p = IPPROTO_UDP; ip->ip_len = datalen; ip->ip_ttl = ttl; ip->ip_v = IPVERSION; ip->ip_id = htons(ident+seq); up->source = htons(ident); up->dest = htons(port+seq); up->len = htons((u_short)(datalen - sizeof(struct ip))); up->check = 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); }}int#ifndef CONFIG_TRACEROUTEmain(argc, argv)#elsetraceroute_main(argc, argv)#endif int argc; char *argv[];{ extern char *optarg; extern int optind; struct hostent *hp; struct sockaddr_in from, *to; int ch, i, on, probe, seq, tos, ttl; int options = 0; /* socket options */ char *source = 0; int nprobes = 3; on = 1; seq = tos = 0; to = (struct sockaddr_in *)&whereto; while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF) switch(ch) { case 'd':#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG options |= SO_DEBUG;#endif break; case 'm': max_ttl = atoi(optarg); if (max_ttl <= 1) error_msg_and_die("max ttl must be >1."); break; case 'n': nflag++; break; case 'p': port = atoi(optarg); if (port < 1) error_msg_and_die("port must be >0."); break; case 'q': nprobes = atoi(optarg); if (nprobes < 1) error_msg_and_die("nprobes must be >0."); break; case 'r': options |= SO_DONTROUTE; break; case 's': /* * set the ip source address of the outbound * probe (e.g., on a multi-homed host). */ source = optarg; break; case 't': tos = atoi(optarg); if (tos < 0 || tos > 255) error_msg_and_die("tos must be 0 to 255."); break; case 'v':#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE verbose++;#endif break; case 'w': waittime = atoi(optarg); if (waittime <= 1) error_msg_and_die("wait must be >1 sec."); break; default: show_usage(); } argc -= optind; argv += optind; if (argc < 1) show_usage(); setlinebuf (stdout); memset(&whereto, 0, sizeof(struct sockaddr)); hp = xgethostbyname(*argv); to->sin_family = hp->h_addrtype; memcpy(&to->sin_addr, hp->h_addr, hp->h_length); hostname = (char *)hp->h_name; if (*++argv) datalen = atoi(*argv); if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket)) error_msg_and_die("packet size must be 0 <= s < %d.", MAXPACKET - sizeof(struct opacket)); datalen += sizeof(struct opacket); outpacket = (struct opacket *)xmalloc((unsigned)datalen); memset(outpacket, 0, datalen); outpacket->ip.ip_dst = to->sin_addr; outpacket->ip.ip_tos = tos; outpacket->ip.ip_v = IPVERSION; outpacket->ip.ip_id = 0; ident = (getpid() & 0xffff) | 0x8000; if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) perror_msg_and_die(can_not_create_raw_socket); s = create_icmp_socket();#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG if (options & SO_DEBUG) (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on));#endif if (options & SO_DONTROUTE) (void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on));#ifdef SO_SNDBUF if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen, sizeof(datalen)) < 0) perror_msg_and_die("SO_SNDBUF");#endif#ifdef IP_HDRINCL if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0) perror_msg_and_die("IP_HDRINCL");#endif#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG if (options & SO_DEBUG) (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on));#endif if (options & SO_DONTROUTE) (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on)); if (source) { memset(&from, 0, sizeof(struct sockaddr)); from.sin_family = AF_INET; from.sin_addr.s_addr = inet_addr(source); if (from.sin_addr.s_addr == -1) error_msg_and_die("unknown host %s", source); outpacket->ip.ip_src = from.sin_addr;#ifndef IP_HDRINCL if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0) perror_msg_and_die("bind");#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); 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, reset_timer; struct timeval t1, t2; struct timezone tz; struct ip *ip; (void) gettimeofday(&t1, &tz); send_probe(++seq, ttl); reset_timer = 1; while ((cc = wait_for_reply(s, &from, reset_timer)) != 0) { (void) gettimeofday(&t2, &tz); if ((i = packet_ok(packet, cc, &from, seq))) { reset_timer = 1; if (from.sin_addr.s_addr != lastaddr) { print(packet, cc, &from); lastaddr = from.sin_addr.s_addr; } printf(" %g ms", deltaT(&t1, &t2)); switch(i - 1) { case ICMP_UNREACH_PORT: ip = (struct ip *)packet; if (ip->ip_ttl <= 1) printf(" !"); ++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; } else reset_timer = 0; } if (cc == 0) printf(" *"); (void) fflush(stdout); } putchar('\n'); if (got_there || unreachable >= nprobes-1) return 0; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -