diff options
author | deraadt <deraadt@openbsd.org> | 1995-12-14 01:45:19 +0000 |
---|---|---|
committer | deraadt <deraadt@openbsd.org> | 1995-12-14 01:45:19 +0000 |
commit | a17240f23138f53f8df246dc6d635a91bbea37fd (patch) | |
tree | 0efa6e902d306754512a5281106abc4637c61ed2 /usr.sbin/mrinfo | |
parent | use string.h (diff) | |
download | wireguard-openbsd-a17240f23138f53f8df246dc6d635a91bbea37fd.tar.xz wireguard-openbsd-a17240f23138f53f8df246dc6d635a91bbea37fd.zip |
from netbsd; update to mrouted 3.8
Diffstat (limited to 'usr.sbin/mrinfo')
-rw-r--r-- | usr.sbin/mrinfo/mrinfo.c | 250 |
1 files changed, 177 insertions, 73 deletions
diff --git a/usr.sbin/mrinfo/mrinfo.c b/usr.sbin/mrinfo/mrinfo.c index 20bd54fcf36..e8cfc4f091d 100644 --- a/usr.sbin/mrinfo/mrinfo.c +++ b/usr.sbin/mrinfo/mrinfo.c @@ -1,4 +1,4 @@ -/* $NetBSD: mrinfo.c,v 1.3 1995/10/03 23:20:45 thorpej Exp $ */ +/* $NetBSD: mrinfo.c,v 1.4 1995/12/10 11:00:51 mycroft Exp $ */ /* * This tool requests configuration info from a multicast router @@ -63,7 +63,7 @@ #ifndef lint static char rcsid[] = - "@(#) $NetBSD: mrinfo.c,v 1.3 1995/10/03 23:20:45 thorpej Exp $"; + "@(#) $NetBSD: mrinfo.c,v 1.4 1995/12/10 11:00:51 mycroft Exp $"; /* original rcsid: "@(#) Header: mrinfo.c,v 1.6 93/04/08 15:14:16 van Exp (LBL)"; */ @@ -74,6 +74,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 */ @@ -83,10 +88,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_t addr)); +void ask __P((u_int32_t dst)); +void ask2 __P((u_int32_t dst)); +int get_number __P((int *var, int deflt, char ***pargv, + int *pargc)); +u_int32_t 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_t addr; @@ -110,14 +127,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) @@ -133,7 +162,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) @@ -169,9 +198,9 @@ ask2(dst) * Process an incoming neighbor-list message. */ void -accept_neighbors(src, dst, p, datalen) - u_int32_t src, dst; - u_char *p; +accept_neighbors(src, dst, p, datalen, level) + u_int32_t src, dst, level; + u_char *p; int datalen; { u_char *ep = p + datalen; @@ -202,17 +231,22 @@ accept_neighbors(src, dst, p, datalen) } void -accept_neighbors2(src, dst, p, datalen) - u_int32_t src, dst; - u_char *p; +accept_neighbors2(src, dst, p, datalen, level) + u_int32_t 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); + printf("%s (%s) [version %d.%d", inet_fmt(src, s1), inet_name(src), + level & 0xff, (level >> 8) & 0xff); + if ((level >> 16) & NF_LEAF) { printf (",leaf"); } + if ((level >> 16) & NF_PRUNE) { printf (",prune"); } + if ((level >> 16) & NF_GENID) { printf (",genid"); } + if ((level >> 16) & NF_MTRACE) { printf (",mtrace"); } + printf ("]:\n"); while (p < ep) { register u_char metric; @@ -281,23 +315,6 @@ get_number(var, deflt, pargv, pargc) } } -u_int32_t -host_addr(name) - char *name; -{ - struct hostent *e; - u_int32_t addr; - - addr = inet_addr(name); - if ((int)addr == -1) { - e = gethostbyname(name); - if (e == NULL || e->h_length != sizeof(addr)) - return (0); - memcpy(&addr, e->h_addr_list[0], e->h_length); - } - return(addr); -} - void usage() { @@ -311,6 +328,14 @@ main(argc, argv) int argc; char *argv[]; { + int tries; + int trynew; + struct timeval et; + struct hostent *hp; + struct hostent bogus; + char *host; + int curaddr; + setlinebuf(stderr); if (geteuid() != 0) { @@ -343,11 +368,21 @@ main(argc, argv) if (argc > 1) usage(); if (argc == 1) - target_addr = host_addr(argv[0]); + host = argv[0]; else - target_addr = host_addr("127.0.0.1"); - - if (target_addr == 0) { + host = "127.0.0.1"; + + if ((target_addr = inet_addr(host)) != -1) { + hp = &bogus; + hp->h_length = sizeof(target_addr); + hp->h_addr_list = (char **)malloc(2 * sizeof(char *)); + hp->h_addr_list[0] = malloc(hp->h_length); + memcpy(hp->h_addr_list[0], &target_addr, hp->h_length); + hp->h_addr_list[1] = 0; + } else + hp = gethostbyname(host); + + if (hp == NULL) { fprintf(stderr, "mrinfo: %s: no such host\n", argv[0]); exit(1); } @@ -356,7 +391,10 @@ main(argc, argv) init_igmp(); - { /* Find a good local address for us. */ + /* Check all addresses; mrouters often have unreachable interfaces */ + for (curaddr = 0; hp->h_addr_list[curaddr] != NULL; curaddr++) { + memcpy(&target_addr, hp->h_addr_list[curaddr], hp->h_length); + { /* Find a good local address for us. */ int udp; struct sockaddr_in addr; int addrlen = sizeof(addr); @@ -376,14 +414,24 @@ main(argc, argv) } close(udp); our_addr = addr.sin_addr.s_addr; - } - - ask(target_addr); - - /* Main receive loop */ - for (;;) { + } + + tries = 0; + trynew = 1; + /* + * 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_t src, dst, group; struct ip *ip; @@ -393,8 +441,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); @@ -404,12 +460,19 @@ main(argc, argv) continue; } else if (count == 0) { log(LOG_DEBUG, 0, "Timed out receiving neighbor lists"); - if (--retries < 0) - exit(1); - if (target_level == 0) + if (++tries > retries) + break; + /* 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); + gettimeofday(&et, 0); + et.tv_sec += timeout; continue; } recvlen = recvfrom(igmp_socket, recv_buf, RECV_BUF_SIZE, @@ -434,19 +497,19 @@ main(argc, argv) iphdrlen = ip->ip_hl << 2; ipdatalen = ip->ip_len; if (iphdrlen + ipdatalen != recvlen) { - log(LOG_WARNING, 0, - "packet shorter (%u bytes) than hdr+data length (%u+%u)", - recvlen, iphdrlen, ipdatalen); - continue; + log(LOG_WARNING, 0, + "packet shorter (%u bytes) than hdr+data length (%u+%u)", + recvlen, iphdrlen, ipdatalen); + continue; } igmp = (struct igmp *) (recv_buf + iphdrlen); group = igmp->igmp_group.s_addr; igmpdatalen = ipdatalen - IGMP_MINLEN; if (igmpdatalen < 0) { - log(LOG_WARNING, 0, - "IP data field too short (%u bytes) for IGMP, from %s", - ipdatalen, inet_fmt(src, s1)); - continue; + log(LOG_WARNING, 0, + "IP data field too short (%u bytes) for IGMP, from %s", + ipdatalen, inet_fmt(src, s1)); + continue; } if (igmp->igmp_type != IGMP_DVMRP) continue; @@ -476,57 +539,98 @@ 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); } + } } + exit(1); } /* dummies */ -void accept_probe() +void accept_probe(src, dst, p, datalen, level) + u_int32_t src, dst, level; + char *p; + int datalen; { } -void accept_group_report() +void accept_group_report(src, dst, group, r_type) + u_int32_t src, dst, group; + int r_type; { } -void accept_neighbor_request2() +void accept_neighbor_request2(src, dst) + u_int32_t src, dst; { } -void accept_report() +void accept_report(src, dst, p, datalen, level) + u_int32_t src, dst, level; + char *p; + int datalen; { } -void accept_neighbor_request() +void accept_neighbor_request(src, dst) + u_int32_t src, dst; { } -void accept_prune() +void accept_prune(src, dst, p, datalen) + u_int32_t src, dst; + char *p; + int datalen; { } -void accept_graft() +void accept_graft(src, dst, p, datalen) + u_int32_t src, dst; + char *p; + int datalen; { } -void accept_g_ack() +void accept_g_ack(src, dst, p, datalen) + u_int32_t src, dst; + char *p; + int datalen; { } -void add_table_entry() +void add_table_entry(origin, mcastgrp) + u_int32_t origin, mcastgrp; { } void check_vif_state() { } -void accept_leave_message() +void accept_leave_message(src, dst, group) + u_int32_t src, dst, group; +{ +} +void accept_mtrace(src, dst, group, data, no, datalen) + u_int32_t src, dst, group; + char *data; + u_int no; + int datalen; { } -void accept_mtrace() +void accept_membership_query(src, dst, group, tmo) + u_int32_t src, dst, group; + int tmo; { } -void accept_membership_query() +void accept_info_request(src, dst, p, datalen) + u_int32_t src, dst; + u_char *p; + int datalen; +{ +} +void accept_info_reply(src, dst, p, datalen) + u_int32_t src, dst; + u_char *p; + int datalen; { } |