diff options
Diffstat (limited to 'sbin/routed/rtquery/rtquery.c')
-rw-r--r-- | sbin/routed/rtquery/rtquery.c | 218 |
1 files changed, 133 insertions, 85 deletions
diff --git a/sbin/routed/rtquery/rtquery.c b/sbin/routed/rtquery/rtquery.c index 82e768c0b235..2f484384e2e6 100644 --- a/sbin/routed/rtquery/rtquery.c +++ b/sbin/routed/rtquery/rtquery.c @@ -11,7 +11,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: + * must display the following acknowledgment: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors @@ -35,13 +35,7 @@ char copyright[] = "@(#) Copyright (c) 1982, 1986, 1993\n\ The Regents of the University of California. All rights reserved.\n"; -#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) -static char sccsid[] = "@(#)query.c 8.1 (Berkeley) 6/5/93"; -#elif defined(__NetBSD__) -static char rcsid[] = "$NetBSD$"; -#endif -#ident "$Revision: 1.11 $" - +#include <sys/cdefs.h> #include <sys/param.h> #include <sys/protosw.h> #include <sys/socket.h> @@ -61,6 +55,13 @@ static char rcsid[] = "$NetBSD$"; #include <bstring.h> #endif +#if !defined(sgi) && !defined(__NetBSD__) +static char sccsid[] __attribute__((unused))= "@(#)query.c 8.1 (Berkeley) 6/5/93"; +#elif defined(__NetBSD__) +__RCSID("$NetBSD: rtquery.c,v 1.10 1999/02/23 10:47:41 christos Exp $"); +#endif +#ident "$Revision: 2.17 $" + #ifndef sgi #define _HAVE_SIN_LEN #endif @@ -79,9 +80,9 @@ extern void MD5Final(u_char[MD5_DIGEST_LEN], MD5_CTX*); #define WTIME 15 /* Time to wait for all responses */ #define STIME (250*1000) /* usec to wait for another response */ -int s; +int soc; -char *pgmname; +const char *pgmname; union { struct rip rip; @@ -108,28 +109,33 @@ u_long keyid; struct timeval sent; /* when query sent */ +static char localhost_str[] = "localhost"; +static char *default_argv[] = {localhost_str, 0}; + static void rip_input(struct sockaddr_in*, int); -static int out(char *); -static void trace_loop(char *argv[]); -static void query_loop(char *argv[], int); +static int out(const char *); +static void trace_loop(char *argv[]) __attribute((__noreturn__)); +static void query_loop(char *argv[], int) __attribute((__noreturn__)); static int getnet(char *, struct netinfo *); static u_int std_mask(u_int); -static int parse_quote(char **, char *, char *, char *, int); +static int parse_quote(char **, const char *, char *, char *, int); +static void usage(void); -void +int main(int argc, char *argv[]) { int ch, bsize; char *p, *options, *value, delim; + const char *result; OMSG.rip_nets[0].n_dst = RIP_DEFAULT; OMSG.rip_nets[0].n_family = RIP_AF_UNSPEC; OMSG.rip_nets[0].n_metric = htonl(HOPCNT_INFINITY); pgmname = argv[0]; - while ((ch = getopt(argc, argv, "np1w:r:t:a:")) != EOF) + while ((ch = getopt(argc, argv, "np1w:r:t:a:")) != -1) switch (ch) { case 'n': not_trace = 1; @@ -150,13 +156,13 @@ main(int argc, wtime = (int)strtoul(optarg, &p, 0); if (*p != '\0' || wtime <= 0) - goto usage; + usage(); break; case 'r': not_trace = 1; if (rflag) - goto usage; + usage(); rflag = getnet(optarg, &OMSG.rip_nets[0]); if (!rflag) { struct hostent *hp = gethostbyname(optarg); @@ -166,8 +172,8 @@ main(int argc, herror(0); exit(1); } - bcopy(hp->h_addr, &OMSG.rip_nets[0].n_dst, - sizeof(OMSG.rip_nets[0].n_dst)); + memcpy(&OMSG.rip_nets[0].n_dst, hp->h_addr, + sizeof(OMSG.rip_nets[0].n_dst)); OMSG.rip_nets[0].n_family = RIP_AF_INET; OMSG.rip_nets[0].n_mask = -1; rflag = 1; @@ -178,47 +184,52 @@ main(int argc, trace = 1; options = optarg; while (*options != '\0') { - char *traceopts[] = { + /* messy complications to make -W -Wall happy */ + static char on_str[] = "on"; + static char more_str[] = "more"; + static char off_str[] = "off"; + static char dump_str[] = "dump"; + static char *traceopts[] = { # define TRACE_ON 0 - "on", + on_str, # define TRACE_MORE 1 - "more", + more_str, # define TRACE_OFF 2 - "off", + off_str, # define TRACE_DUMP 3 - "dump", + dump_str, 0 }; + result = ""; switch (getsubopt(&options,traceopts,&value)) { case TRACE_ON: OMSG.rip_cmd = RIPCMD_TRACEON; if (!value || strlen(value) > MAXPATHLEN) - goto usage; + usage(); + result = value; break; case TRACE_MORE: if (value) - goto usage; + usage(); OMSG.rip_cmd = RIPCMD_TRACEON; - value = ""; break; case TRACE_OFF: if (value) - goto usage; + usage(); OMSG.rip_cmd = RIPCMD_TRACEOFF; - value = ""; break; case TRACE_DUMP: if (value) - goto usage; + usage(); OMSG.rip_cmd = RIPCMD_TRACEON; - value = "dump/../table"; + result = "dump/../table"; break; default: - goto usage; + usage(); } - strcpy((char*)OMSG.rip_tracefile, value); - omsg_len += strlen(value) - sizeof(OMSG.ripun); + strcpy((char*)OMSG.rip_tracefile, result); + omsg_len += strlen(result) - sizeof(OMSG.ripun); } break; @@ -226,50 +237,48 @@ main(int argc, not_trace = 1; p = strchr(optarg,'='); if (!p) - goto usage; + usage(); *p++ = '\0'; if (!strcasecmp("passwd",optarg)) auth_type = RIP_AUTH_PW; else if (!strcasecmp("md5_passwd",optarg)) auth_type = RIP_AUTH_MD5; else - goto usage; + usage(); if (0 > parse_quote(&p,"|",&delim, - passwd,sizeof(passwd))) - goto usage; + passwd, sizeof(passwd))) + usage(); if (auth_type == RIP_AUTH_MD5 && delim == '|') { keyid = strtoul(p+1,&p,0); if (keyid > 255 || *p != '\0') - goto usage; + usage(); } else if (delim != '\0') { - goto usage; + usage(); } break; default: - goto usage; + usage(); } argv += optind; argc -= optind; - if ((not_trace && trace) || argc == 0) { -usage: fprintf(stderr, "%s: [-np1v] [-r tgt_rt] [-w wtime]" - " [-a type=passwd] host1 [host2 ...]\n" - "or\t-t {on=filename|more|off|dump}" - " host1 [host2 ...]\n", - pgmname); - exit(1); + if (not_trace && trace) + usage(); + if (argc == 0) { + argc = 1; + argv = default_argv; } - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) { + soc = socket(AF_INET, SOCK_DGRAM, 0); + if (soc < 0) { perror("socket"); exit(2); } /* be prepared to receive a lot of routes */ for (bsize = 127*1024; ; bsize -= 1024) { - if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, + if (setsockopt(soc, SOL_SOCKET, SO_RCVBUF, &bsize, sizeof(bsize)) == 0) break; if (bsize <= 4*1024) { @@ -283,6 +292,19 @@ usage: fprintf(stderr, "%s: [-np1v] [-r tgt_rt] [-w wtime]" else query_loop(argv, argc); /* NOTREACHED */ + return 0; +} + + +static void +usage(void) +{ + fprintf(stderr, + "usage: rtquery [-np1] [-r tgt_rt] [-w wtime]" + " [-a type=passwd] host1 [host2 ...]\n" + "\trtquery -t {on=filename|more|off|dump}" + " host1 [host2 ...]\n"); + exit(1); } @@ -305,13 +327,13 @@ trace_loop(char *argv[]) OMSG.rip_vers = RIPv1; } - bzero(&myaddr, sizeof(myaddr)); + memset(&myaddr, 0, sizeof(myaddr)); myaddr.sin_family = AF_INET; #ifdef _HAVE_SIN_LEN myaddr.sin_len = sizeof(myaddr); #endif myaddr.sin_port = htons(IPPORT_RESERVED-1); - while (bind(s, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) { + while (bind(soc, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) { if (errno != EADDRINUSE || myaddr.sin_port == 0) { perror("bind"); @@ -356,8 +378,7 @@ query_loop(char *argv[], int argc) OMSG.rip_nets[1] = OMSG.rip_nets[0]; NA0.a_family = RIP_AF_AUTH; NA0.a_type = RIP_AUTH_PW; - bcopy(passwd, NA0.au.au_pw, - RIP_AUTH_PW_LEN); + memcpy(NA0.au.au_pw, passwd, RIP_AUTH_PW_LEN); omsg_len += sizeof(OMSG.rip_nets[0]); } else if (auth_type == RIP_AUTH_MD5) { @@ -365,15 +386,17 @@ query_loop(char *argv[], int argc) NA0.a_family = RIP_AF_AUTH; NA0.a_type = RIP_AUTH_MD5; NA0.au.a_md5.md5_keyid = (int8_t)keyid; - NA0.au.a_md5.md5_auth_len = RIP_AUTH_PW_LEN; + NA0.au.a_md5.md5_auth_len = RIP_AUTH_MD5_LEN; NA0.au.a_md5.md5_seqno = 0; - NA0.au.a_md5.md5_pkt_len = sizeof(OMSG.rip_nets[1]); + cc = (char *)&NA2-(char *)&OMSG; + NA0.au.a_md5.md5_pkt_len = htons(cc); NA2.a_family = RIP_AF_AUTH; - NA2.a_type = 1; - bcopy(passwd, NA2.au.au_pw, sizeof(NA2.au.au_pw)); + NA2.a_type = htons(1); MD5Init(&md5_ctx); - MD5Update(&md5_ctx, (u_char *)&NA0, - (char *)(&NA2+1) - (char *)&NA0); + MD5Update(&md5_ctx, + (u_char *)&OMSG, cc); + MD5Update(&md5_ctx, + (u_char *)passwd, RIP_AUTH_MD5_LEN); MD5Final(NA2.au.au_pw, &md5_ctx); omsg_len += 2*sizeof(OMSG.rip_nets[0]); } @@ -393,13 +416,13 @@ query_loop(char *argv[], int argc) FD_ZERO(&bits); for (;;) { - FD_SET(s, &bits); + FD_SET(soc, &bits); delay.tv_sec = 0; delay.tv_usec = STIME; - cc = select(s+1, &bits, 0,0, &delay); + cc = select(soc+1, &bits, 0,0, &delay); if (cc > 0) { fromlen = sizeof(from); - cc = recvfrom(s, imsg_buf.packet, + cc = recvfrom(soc, imsg_buf.packet, sizeof(imsg_buf.packet), 0, (struct sockaddr *)&from, &fromlen); if (cc < 0) { @@ -418,6 +441,11 @@ query_loop(char *argv[], int argc) } if (sp == 0) { sp = malloc(sizeof(*sp)); + if (sp == 0) { + fprintf(stderr, + "rtquery: malloc failed\n"); + exit(1); + } sp->addr = from.sin_addr; sp->next = seen; seen = sp; @@ -429,7 +457,7 @@ query_loop(char *argv[], int argc) } if (cc < 0) { - if ( errno == EINTR) + if (errno == EINTR) continue; perror("select"); exit(1); @@ -465,7 +493,7 @@ query_loop(char *argv[], int argc) /* send to one host */ static int -out(char *host) +out(const char *host) { struct sockaddr_in router; struct hostent *hp; @@ -475,7 +503,7 @@ out(char *host) return -1; } - bzero(&router, sizeof(router)); + memset(&router, 0, sizeof(router)); router.sin_family = AF_INET; #ifdef _HAVE_SIN_LEN router.sin_len = sizeof(router); @@ -486,11 +514,11 @@ out(char *host) herror(host); return -1; } - bcopy(hp->h_addr, &router.sin_addr, sizeof(router.sin_addr)); + memcpy(&router.sin_addr, hp->h_addr, sizeof(router.sin_addr)); } router.sin_port = htons(RIP_PORT); - if (sendto(s, &omsg_buf, omsg_len, 0, + if (sendto(soc, &omsg_buf, omsg_len, 0, (struct sockaddr *)&router, sizeof(router)) < 0) { perror(host); return -1; @@ -563,8 +591,11 @@ rip_input(struct sockaddr_in *from, { struct netinfo *n, *lim; struct in_addr in; - char *name; + const char *name; char net_buf[80]; + u_char hash[RIP_AUTH_MD5_LEN]; + MD5_CTX md5_ctx; + u_char md5_authed = 0; u_int mask, dmask; char *sp; int i; @@ -594,10 +625,10 @@ rip_input(struct sockaddr_in *from, (IMSG.rip_vers != RIPv1 && IMSG.rip_vers != RIPv2) ? " ?" : "", size); if (size > MAXPACKETSIZE) { - if (size > sizeof(imsg_buf) - sizeof(*n)) { + if (size > (int)sizeof(imsg_buf) - (int)sizeof(*n)) { printf(" at least %d bytes too long\n", size-MAXPACKETSIZE); - size = sizeof(imsg_buf) - sizeof(*n); + size = (int)sizeof(imsg_buf) - (int)sizeof(*n); } else { printf(" %d bytes too long\n", size-MAXPACKETSIZE); @@ -679,22 +710,38 @@ rip_input(struct sockaddr_in *from, if (na->a_type == RIP_AUTH_MD5 && n == IMSG.rip_nets) { - (void)printf(" MD5 Authentication" + (void)printf(" MD5 Auth" " len=%d KeyID=%d" - " seqno=%d" + " auth_len=%d" + " seqno=%#x" " rsvd=%#x,%#x\n", - na->au.a_md5.md5_pkt_len, + ntohs(na->au.a_md5.md5_pkt_len), na->au.a_md5.md5_keyid, - na->au.a_md5.md5_seqno, + na->au.a_md5.md5_auth_len, + (int)ntohl(na->au.a_md5.md5_seqno), na->au.a_md5.rsvd[0], na->au.a_md5.rsvd[1]); + md5_authed = 1; continue; } (void)printf(" Authentication type %d: ", ntohs(na->a_type)); - for (i = 0; i < sizeof(na->au.au_pw); i++) + for (i = 0; i < (int)sizeof(na->au.au_pw); i++) (void)printf("%02x ", na->au.au_pw[i]); putc('\n', stdout); + if (md5_authed && n+1 > lim + && na->a_type == ntohs(1)) { + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, (u_char *)&IMSG, + (char *)na-(char *)&IMSG); + MD5Update(&md5_ctx, (u_char *)passwd, + RIP_AUTH_MD5_LEN); + MD5Final(hash, &md5_ctx); + (void)printf(" %s hash\n", + memcmp(hash, na->au.au_pw, + sizeof(hash)) + ? "WRONG" : "correct"); + } continue; } else { @@ -707,7 +754,7 @@ rip_input(struct sockaddr_in *from, } (void)printf(" %-18s metric %2d %-10s", - net_buf, ntohl(n->n_metric), name); + net_buf, (int)ntohl(n->n_metric), name); if (n->n_nhop != 0) { in.s_addr = n->n_nhop; @@ -762,11 +809,11 @@ getnet(char *name, /* Detect and separate "1.2.3.4/24" */ - if (0 != (mname = rindex(name,'/'))) { + if (0 != (mname = strrchr(name,'/'))) { i = (int)(mname - name); - if (i > sizeof(hname)-1) /* name too long */ + if (i > (int)sizeof(hname)-1) /* name too long */ return 0; - bcopy(name, hname, i); + memmove(hname, name, i); hname[i] = '\0'; mname++; name = hname; @@ -803,12 +850,13 @@ getnet(char *name, */ static int /* -1=bad */ parse_quote(char **linep, - char *delims, + const char *delims, char *delimp, char *buf, int lim) { - char c, *pc, *p; + char c, *pc; + const char *p; pc = *linep; @@ -822,7 +870,7 @@ parse_quote(char **linep, if (c == '\0') break; - if (c == '\\' && pc != '\0') { + if (c == '\\' && *pc != '\0') { if ((c = *pc++) == 'n') { c = '\n'; } else if (c == 'r') { |