diff options
Diffstat (limited to 'usr.sbin/mrouted/mrinfo.c')
-rw-r--r-- | usr.sbin/mrouted/mrinfo.c | 151 |
1 files changed, 116 insertions, 35 deletions
diff --git a/usr.sbin/mrouted/mrinfo.c b/usr.sbin/mrouted/mrinfo.c index 8f137d0f3e6a..f4ccc86eb6d8 100644 --- a/usr.sbin/mrouted/mrinfo.c +++ b/usr.sbin/mrouted/mrinfo.c @@ -61,7 +61,7 @@ #ifndef lint static char rcsid[] = - "@(#) $Id: mrinfo.c,v 3.5.1.1 1995/05/09 22:58:05 fenner Exp $"; + "@(#) $Id: mrinfo.c,v 3.6 1995/06/25 19:05:34 fenner Exp $"; /* original rcsid: "@(#) Header: mrinfo.c,v 1.6 93/04/08 15:14:16 van Exp (LBL)"; */ @@ -71,6 +71,11 @@ static char rcsid[] = #include <sys/time.h> #include "defs.h" #include <arpa/inet.h> +#ifdef __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif #define DEFAULT_TIMEOUT 4 /* How long to wait before retrying requests */ #define DEFAULT_RETRIES 3 /* How many times to ask each router */ @@ -80,10 +85,22 @@ int debug = 0; int nflag = 0; int retries = DEFAULT_RETRIES; int timeout = DEFAULT_TIMEOUT; -int target_level; +int target_level = 0; vifi_t numvifs; /* to keep loader happy */ /* (see COPY_TABLES macro called in kern.c) */ +char * inet_name __P((u_int32 addr)); +void ask __P((u_int32 dst)); +void ask2 __P((u_int32 dst)); +int get_number __P((int *var, int deflt, char ***pargv, + int *pargc)); +u_int32 host_addr __P((char *name)); +void usage __P((void)); + +/* to shut up -Wstrict-prototypes */ +int main __P((int argc, char *argv[])); + + char * inet_name(addr) u_int32 addr; @@ -107,14 +124,26 @@ inet_name(addr) * message and the current debug level. For errors of severity LOG_ERR or * worse, terminate the program. */ +#ifdef __STDC__ +void +log(int severity, int syserr, char *format, ...) +{ + va_list ap; + char fmt[100]; + + va_start(ap, format); +#else void -log(severity, syserr, format, a, b, c, d, e) +log(severity, syserr, format, va_alist) int severity, syserr; char *format; - int a, b, c, d, e; + va_dcl { + va_list ap; char fmt[100]; + va_start(ap); +#endif switch (debug) { case 0: if (severity > LOG_WARNING) @@ -130,7 +159,7 @@ log(severity, syserr, format, a, b, c, d, e) if (severity == LOG_WARNING) strcat(fmt, "warning - "); strncat(fmt, format, 80); - fprintf(stderr, fmt, a, b, c, d, e); + vfprintf(stderr, fmt, ap); if (syserr == 0) fprintf(stderr, "\n"); else if (syserr < sys_nerr) @@ -166,9 +195,9 @@ ask2(dst) * Process an incoming neighbor-list message. */ void -accept_neighbors(src, dst, p, datalen) - u_int32 src, dst; - u_char *p; +accept_neighbors(src, dst, p, datalen, level) + u_int32 src, dst, level; + u_char *p; int datalen; { u_char *ep = p + datalen; @@ -199,17 +228,17 @@ accept_neighbors(src, dst, p, datalen) } void -accept_neighbors2(src, dst, p, datalen) - u_int32 src, dst; - u_char *p; +accept_neighbors2(src, dst, p, datalen, level) + u_int32 src, dst, level; + u_char *p; int datalen; { u_char *ep = p + datalen; - u_int broken_cisco = ((target_level & 0xffff) == 0x020a); /* 10.2 */ + u_int broken_cisco = ((level & 0xffff) == 0x020a); /* 10.2 */ /* well, only possibly_broken_cisco, but that's too long to type. */ printf("%s (%s) [version %d.%d]:\n", inet_fmt(src, s1), inet_name(src), - target_level & 0xff, (target_level >> 8) & 0xff); + level & 0xff, (level >> 8) & 0xff); while (p < ep) { register u_char metric; @@ -308,6 +337,10 @@ main(argc, argv) int argc; char *argv[]; { + int tries = 0; + int trynew = 1; + struct timeval et; + setlinebuf(stderr); if (geteuid() != 0) { @@ -375,12 +408,20 @@ main(argc, argv) our_addr = addr.sin_addr.s_addr; } - ask(target_addr); + /* + * New strategy: send 'ask2' for two timeouts, then fall back + * to 'ask', since it's not very likely that we are going to + * find someone who only responds to 'ask' these days + */ + ask2(target_addr); + + gettimeofday(&et, 0); + et.tv_sec += timeout; /* Main receive loop */ for (;;) { fd_set fds; - struct timeval tv; + struct timeval tv, now; int count, recvlen, dummy = 0; register u_int32 src, dst, group; struct ip *ip; @@ -390,8 +431,16 @@ main(argc, argv) FD_ZERO(&fds); FD_SET(igmp_socket, &fds); - tv.tv_sec = timeout; - tv.tv_usec = 0; + gettimeofday(&now, 0); + tv.tv_sec = et.tv_sec - now.tv_sec; + tv.tv_usec = et.tv_usec - now.tv_usec; + + if (tv.tv_usec < 0) { + tv.tv_usec += 1000000L; + --tv.tv_sec; + } + if (tv.tv_sec < 0) + tv.tv_sec = tv.tv_usec = 0; count = select(igmp_socket + 1, &fds, 0, 0, &tv); @@ -401,9 +450,14 @@ main(argc, argv) continue; } else if (count == 0) { log(LOG_DEBUG, 0, "Timed out receiving neighbor lists"); - if (--retries < 0) + if (++tries > retries) exit(1); - if (target_level == 0) + /* If we've tried ASK_NEIGHBORS2 twice with + * no response, fall back to ASK_NEIGHBORS + */ + if (tries == 2 && target_level == 0) + trynew = 0; + if (target_level == 0 && trynew == 0) ask(target_addr); else ask2(target_addr); @@ -473,57 +527,84 @@ main(argc, argv) ask2(target_addr); } } else { - accept_neighbors(src, dst, (char *)(igmp + 1), - igmpdatalen); + accept_neighbors(src, dst, (u_char *)(igmp + 1), + igmpdatalen, ntohl(group)); exit(0); } break; case DVMRP_NEIGHBORS2: - accept_neighbors2(src, dst, (char *)(igmp + 1), - igmpdatalen); + accept_neighbors2(src, dst, (u_char *)(igmp + 1), + igmpdatalen, ntohl(group)); exit(0); } } } /* dummies */ -void accept_probe() +void accept_probe(src, dst, p, datalen, level) + u_int32 src, dst, level; + char *p; + int datalen; { } -void accept_group_report() +void accept_group_report(src, dst, group, r_type) + u_int32 src, dst, group; + int r_type; { } -void accept_neighbor_request2() +void accept_neighbor_request2(src, dst) + u_int32 src, dst; { } -void accept_report() +void accept_report(src, dst, p, datalen, level) + u_int32 src, dst, level; + char *p; + int datalen; { } -void accept_neighbor_request() +void accept_neighbor_request(src, dst) + u_int32 src, dst; { } -void accept_prune() +void accept_prune(src, dst, p, datalen) + u_int32 src, dst; + char *p; + int datalen; { } -void accept_graft() +void accept_graft(src, dst, p, datalen) + u_int32 src, dst; + char *p; + int datalen; { } -void accept_g_ack() +void accept_g_ack(src, dst, p, datalen) + u_int32 src, dst; + char *p; + int datalen; { } -void add_table_entry() +void add_table_entry(origin, mcastgrp) + u_int32 origin, mcastgrp; { } void check_vif_state() { } -void accept_leave_message() +void accept_leave_message(src, dst, group) + u_int32 src, dst, group; { } -void accept_mtrace() +void accept_mtrace(src, dst, group, data, no, datalen) + u_int32 src, dst, group; + char *data; + u_int no; + int datalen; { } -void accept_membership_query() +void accept_membership_query(src, dst, group, tmo) + u_int32 src, dst, group; + int tmo; { } |