diff options
Diffstat (limited to 'sbin/routed/rtquery')
-rw-r--r-- | sbin/routed/rtquery/Makefile | 5 | ||||
-rw-r--r-- | sbin/routed/rtquery/rtquery.8 | 85 | ||||
-rw-r--r-- | sbin/routed/rtquery/rtquery.c | 262 |
3 files changed, 208 insertions, 144 deletions
diff --git a/sbin/routed/rtquery/Makefile b/sbin/routed/rtquery/Makefile index adc9d15..d371d5d 100644 --- a/sbin/routed/rtquery/Makefile +++ b/sbin/routed/rtquery/Makefile @@ -1,10 +1,11 @@ -# From: @(#)Makefile 8.1 (Berkeley) 6/5/93 +# Make `routed` tools for BSD/OS +# $Revision: 2.15 $ # $Id$ PROG= rtquery MAN8= rtquery.8 LDADD+= -lmd DPADD+= ${LIBMD} -#COPTS= -g -DDEBUG -Wall +#COPTS= -g -DDEBUG -W -Wall -Wcast-align -Wcast-qual -Winline -Wpointer-arith -Wnested-externs -Wwrite-strings -Wunused .include <bsd.prog.mk> diff --git a/sbin/routed/rtquery/rtquery.8 b/sbin/routed/rtquery/rtquery.8 index 4c51c8f..1f16d59 100644 --- a/sbin/routed/rtquery/rtquery.8 +++ b/sbin/routed/rtquery/rtquery.8 @@ -1,4 +1,6 @@ -.\" $Id: rtquery.8,v 1.7 1997/06/13 20:58:09 max Exp $ +.\" $Revision: 2.17 $ +.\" $Id$ +.\" .Dd June 1, 1996 .Dt RTQUERY 8 .Os BSD 4.4 @@ -6,17 +8,16 @@ .Nm rtquery .Nd query routing daemons for their routing tables .Sh SYNOPSIS -.Nm rtquery +.Nm .Op Fl np1 .Op Fl w Ar timeout .Op Fl r Ar addr .Op Fl a Ar secret -.Ar host -.Ar -.Nm rtquery +.Ar host ... +.br +.Nm .Op Fl t Ar op -.Ar host -.Ar +.Ar host ... .Sh DESCRIPTION .Nm Rtquery is used to query a RIP network routing daemon, @@ -27,7 +28,8 @@ for its routing table by sending a .Em request or .Em poll -command. The routing information in any routing +command. +The routing information in any routing .Em response packets returned is displayed numerically and symbolically. .Pp @@ -51,82 +53,71 @@ the command is preferred over the .Em request command because the response is not subject to Split Horizon and/or -Poisoned Reverse, and because some versions of -.Xr gated 8 -do not answer -the +Poisoned Reverse, and because some versions of gated do not answer the .Em request command. -.Nm Routed +.Xr Routed 8 does not answer the .Em poll -command, but -recognizes -.Em request -commands coming from +command, but recognizes +.Em requests +coming from .Nm and so answers completely. .Pp .Nm Rtquery is also used to turn tracing on or off in -.Nm routed . +.Xr routed 8 . .Pp The following options are available: .Bl -tag -width indent .It Fl n -Normally network and host numbers are displayed both symbolically -and numerically. -The -.Fl n -option displays only the numeric network and host numbers. +displays only the numeric network and host numbers instead of both +numeric and symbolic. .It Fl p -Use the -.Em Poll +uses the +.Em poll command to request full routing information from .Xr gated 8 . This is an undocumented extension RIP protocol supported only by .Xr gated 8 . .It Fl 1 -Query using RIP version 1 instead of RIP version 2. +queries using RIP version 1 instead of RIP version 2. .It Fl w Ar timeout -Change the delay for an answer from each host. +changes the delay for an answer from each host. By default, each host is given 15 seconds to respond. .It Fl r Ar addr -Ask about the route to destination +asks about the route to destination .Em addr . .It Fl a Ar passwd=XXX .It Fl a Ar md5_passwd=XXX|KeyID -Cause the query to be sent with the indicated cleartext or MD5 password. +causes the query to be sent with the indicated cleartext or MD5 password. .It Fl t Ar op -Change tracing, where +changes tracing, where .Em op is one of the following. Requests from processes not running with UID 0 or on distant networks are generally ignored by the daemon except for a message in the system log. -.Xr Gated 8 +.Xr Gated 8 is likely to ignore these debugging requests. .El .Bl -tag -width Ds -offset indent-two .It Em on=tracefile -Turn tracing on into the specified file. That file must usually -have been specified when the daemon was started or be the same -as a fixed name, often +turns tracing on into the specified file. +That file must usually have been specified when the daemon was +started or be the same as a fixed name, often .Pa /etc/routed.trace . .It Em more -Increase the debugging level. +increases the debugging level. .It Em off -Turn off tracing. +turns off tracing. .It Em dump -Dump the daemon's routing table to the current tracefile. +dumps the daemon's routing table to the current tracefile. .El .Sh SEE ALSO -.Xr gated 8 , -.Xr routed 8 -.Rs -.%T Routing Information Protocol, RIPV1 -.%O RFC1058 -.Re -.Rs -.%T Routing Information Protocol, RIPv2 -.%O RFC1723 -.Re +.Xr routed 8 , +.Xr gated 8 +.br +RFC\ 1058 - Routing Information Protocol, RIPv1 +.br +RFC\ 1723 - Routing Information Protocol, RIPv2 diff --git a/sbin/routed/rtquery/rtquery.c b/sbin/routed/rtquery/rtquery.c index 071b8e9..25d9e82 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 @@ -29,50 +29,62 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $Id$ */ -#ifndef lint -static const char copyright[] = +char copyright[] = "@(#) Copyright (c) 1982, 1986, 1993\n\ The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)query.c 8.1 (Berkeley) 6/5/93"; -#endif -static const char rcsid[] = - "$Id: rtquery.c,v 1.8 1998/07/22 05:49:36 phk Exp $"; -#endif /* not lint */ +#include <sys/cdefs.h> #include <sys/param.h> +#include <sys/protosw.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> #define RIPVERSION RIPv2 #include <protocols/routed.h> #include <arpa/inet.h> -#include <err.h> -#include <errno.h> #include <netdb.h> +#include <errno.h> +#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #ifdef sgi #include <strings.h> #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 -#include <md5.h> +#define MD5_DIGEST_LEN 16 +typedef struct { + u_int32_t state[4]; /* state (ABCD) */ + u_int32_t count[2]; /* # of bits, modulo 2^64 (LSB 1st) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; +extern void MD5Init(MD5_CTX*); +extern void MD5Update(MD5_CTX*, u_char*, u_int); +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; + +const char *pgmname; union { struct rip rip; @@ -99,26 +111,32 @@ 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); + 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:")) != -1) switch (ch) { case 'n': @@ -150,11 +168,14 @@ main(int argc, rflag = getnet(optarg, &OMSG.rip_nets[0]); if (!rflag) { struct hostent *hp = gethostbyname(optarg); - if (hp == 0) - errx(1, "%s: %s", - optarg, hstrerror(h_errno)); - bcopy(hp->h_addr, &OMSG.rip_nets[0].n_dst, - sizeof(OMSG.rip_nets[0].n_dst)); + if (hp == 0) { + fprintf(stderr, "%s: %s:", + pgmname, optarg); + herror(0); + exit(1); + } + 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; @@ -165,47 +186,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) - usage(); + usage(); + result = value; break; case TRACE_MORE: if (value) - usage(); + usage(); OMSG.rip_cmd = RIPCMD_TRACEON; - value = ""; break; case TRACE_OFF: if (value) - usage(); + usage(); OMSG.rip_cmd = RIPCMD_TRACEOFF; - value = ""; break; case TRACE_DUMP: if (value) - usage(); + usage(); OMSG.rip_cmd = RIPCMD_TRACEON; - value = "dump/../table"; + result = "dump/../table"; break; default: 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; @@ -222,7 +248,7 @@ main(int argc, else usage(); if (0 > parse_quote(&p,"|",&delim, - passwd,sizeof(passwd))) + passwd, sizeof(passwd))) usage(); if (auth_type == RIP_AUTH_MD5 && delim == '|') { @@ -239,20 +265,26 @@ main(int argc, } argv += optind; argc -= optind; - if ((not_trace && trace) || argc == 0) + if (not_trace && trace) usage(); + if (argc == 0) { + argc = 1; + argv = default_argv; + } - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) - err(2, "socket"); + 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) { - warn("setsockopt SO_RCVBUF"); + perror("setsockopt SO_RCVBUF"); break; } } @@ -261,19 +293,23 @@ main(int argc, trace_loop(argv); else query_loop(argv, argc); - return(0); /* NOTREACHED */ + return 0; } + static void -usage() +usage(void) { - fprintf(stderr, "%s\n%s\n", - "usage: rtquery [-np1v] [-r addr] [-w timeout] [-a secret] host ...", - " rtquery [-t op] host ..."); + 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); } + /* tell the target hosts about tracing */ static void @@ -282,8 +318,10 @@ trace_loop(char *argv[]) struct sockaddr_in myaddr; int res; - if (geteuid() != 0) - errx(1, "-t requires UID 0"); + if (geteuid() != 0) { + (void)fprintf(stderr, "-t requires UID 0\n"); + exit(1); + } if (ripv2) { OMSG.rip_vers = RIPv2; @@ -291,15 +329,18 @@ 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) { - if (errno != EADDRINUSE || myaddr.sin_port == 0) - err(2, "bind"); + while (bind(soc, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) { + if (errno != EADDRINUSE + || myaddr.sin_port == 0) { + perror("bind"); + exit(2); + } myaddr.sin_port = htons(ntohs(myaddr.sin_port)-1); } @@ -339,8 +380,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) { @@ -348,15 +388,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]); } @@ -370,23 +412,25 @@ query_loop(char *argv[], int argc) seen = 0; while (0 > out(*argv++)) { if (*argv == 0) - exit(1); + exit(-1); answered++; } 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) - err(1, "recvfrom"); + if (cc < 0) { + perror("recvfrom"); + exit(1); + } /* count the distinct responding hosts. * You cannot match responding hosts with * addresses to which queries were transmitted, @@ -399,6 +443,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; @@ -412,7 +461,8 @@ query_loop(char *argv[], int argc) if (cc < 0) { if (errno == EINTR) continue; - err(1, "select"); + perror("select"); + exit(1); } /* After a pause in responses, probe another host. @@ -429,8 +479,10 @@ query_loop(char *argv[], int argc) /* or until we have waited a long time */ - if (gettimeofday(&now, 0) < 0) - err(1, "gettimeofday(now)"); + if (gettimeofday(&now, 0) < 0) { + perror("gettimeofday(now)"); + exit(1); + } if (sent.tv_sec + wtime <= now.tv_sec) break; } @@ -443,17 +495,17 @@ 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; if (gettimeofday(&sent, 0) < 0) { - warn("gettimeofday(sent)"); + perror("gettimeofday(sent)"); 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); @@ -464,13 +516,13 @@ 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) { - warn("%s", host); + perror(host); return -1; } @@ -541,8 +593,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; @@ -572,10 +627,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); @@ -657,22 +712,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 { @@ -685,7 +756,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; @@ -740,11 +811,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; @@ -781,12 +852,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; |