diff options
author | Garrett Wollman <wollman@FreeBSD.org> | 1996-12-11 20:59:33 +0000 |
---|---|---|
committer | Garrett Wollman <wollman@FreeBSD.org> | 1996-12-11 20:59:33 +0000 |
commit | fda109d2ad660dbffe58bdd26c3dc69a35cfdd3d (patch) | |
tree | bc6bf18eb6754dc39af9394d2a09bf01e9912480 /sbin | |
parent | 0e27dc0563ee38af6ba28aa9a2e169b2fe965a57 (diff) | |
parent | 71965874ee69f5093d3dc664d26fa81eadf09523 (diff) | |
download | src-fda109d2ad660dbffe58bdd26c3dc69a35cfdd3d.tar.gz src-fda109d2ad660dbffe58bdd26c3dc69a35cfdd3d.zip |
This commit was generated by cvs2svn to compensate for changes in r20339,
which included commits to RCS files with non-trunk default branches.
Notes
Notes:
svn path=/head/; revision=20340
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/routed/if.c | 81 | ||||
-rw-r--r-- | sbin/routed/input.c | 102 | ||||
-rw-r--r-- | sbin/routed/output.c | 88 | ||||
-rw-r--r-- | sbin/routed/parms.c | 233 | ||||
-rw-r--r-- | sbin/routed/rdisc.c | 5 | ||||
-rw-r--r-- | sbin/routed/trace.c | 438 |
6 files changed, 530 insertions, 417 deletions
diff --git a/sbin/routed/if.c b/sbin/routed/if.c index 3eea2df322c6..8a42344bd8ae 100644 --- a/sbin/routed/if.c +++ b/sbin/routed/if.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93"; #elif defined(__NetBSD__) static char rcsid[] = "$NetBSD$"; #endif -#ident "$Revision: 1.18 $" +#ident "$Revision: 1.21 $" #include "defs.h" #include "pathnames.h" @@ -208,42 +208,54 @@ ifwithindex(u_short index) /* Find an interface from which the specified address * should have come from. Used for figuring out which - * interface a packet came in on -- for tracing. + * interface a packet came in on. */ struct interface * iflookup(naddr addr) { struct interface *ifp, *maybe; + static struct timeval retried; maybe = 0; - for (ifp = ifnet; ifp; ifp = ifp->int_next) { - if (ifp->int_if_flags & IFF_POINTOPOINT) { - /* finished with a match */ - if (ifp->int_dstaddr == addr) - return ifp; + for (;;) { + for (ifp = ifnet; ifp; ifp = ifp->int_next) { + if (ifp->int_if_flags & IFF_POINTOPOINT) { + /* finished with a match */ + if (ifp->int_dstaddr == addr) + return ifp; - } else { - /* finished with an exact match */ - if (ifp->int_addr == addr) - return ifp; + } else { + /* finished with an exact match */ + if (ifp->int_addr == addr) + return ifp; - /* Look for the longest approximate match. - */ - if (on_net(addr, ifp->int_net, ifp->int_mask) - && (maybe == 0 - || ifp->int_mask > maybe->int_mask)) - maybe = ifp; + /* Look for the longest approximate match. + */ + if (on_net(addr, ifp->int_net, ifp->int_mask) + && (maybe == 0 + || ifp->int_mask > maybe->int_mask)) + maybe = ifp; + } } - } - return maybe; + if (maybe != 0 + || (retried.tv_sec == now.tv_sec + && retried.tv_usec == now.tv_usec)) + return maybe; + + /* If there is no known interface, maybe there is a + * new interface. So just once look for new interfaces. + */ + ifinit(); + retried = now; + } } /* Return the classical netmask for an IP address. */ -naddr -std_mask(naddr addr) /* in network order */ +naddr /* host byte order */ +std_mask(naddr addr) /* network byte order */ { NTOHL(addr); /* was a host, not a network */ @@ -338,9 +350,9 @@ check_dst(naddr addr) /* See a new interface duplicates an existing interface. */ struct interface * -check_dup(naddr addr, - naddr dstaddr, - naddr mask, +check_dup(naddr addr, /* IP address, so network byte order */ + naddr dstaddr, /* ditto */ + naddr mask, /* mask, so host byte order */ int if_flags) { struct interface *ifp; @@ -691,6 +703,7 @@ ifinit(void) ifs0.int_index = ifm->ifm_index; ifs0.int_if_flags = ifm->ifm_flags; ifs0.int_state = IS_CHECKED; + ifs0.int_query_time = NEVER; ifs0.int_act_time = now.tv_sec; ifs0.int_data.ts = now.tv_sec; ifs0.int_data.ipackets = ifm->ifm_data.ifi_ipackets; @@ -1006,10 +1019,20 @@ ifinit(void) if (ifp != 0) { if (!(prev_complaints & COMP_DUP)) { complaints |= COMP_DUP; - msglog("%s is duplicated by %s at %s to %s", - ifs.int_name, ifp->int_name, - naddr_ntoa(ifp->int_addr), - naddr_ntoa(ifp->int_dstaddr)); + msglog("%s (%s%s%s) is duplicated by" + " %s (%s%s%s)", + ifs.int_name, + addrname(ifs.int_addr,ifs.int_mask,1), + ((ifs.int_if_flags & IFF_POINTOPOINT) + ? "-->" : ""), + ((ifs.int_if_flags & IFF_POINTOPOINT) + ? naddr_ntoa(ifs.int_dstaddr) : ""), + ifp->int_name, + addrname(ifp->int_addr,ifp->int_mask,1), + ((ifp->int_if_flags & IFF_POINTOPOINT) + ? "-->" : ""), + ((ifp->int_if_flags & IFF_POINTOPOINT) + ? naddr_ntoa(ifp->int_dstaddr) : "")); } ifp->int_state |= IS_DUP; continue; @@ -1263,7 +1286,7 @@ addrouteforif(struct interface *ifp) * it must be reachable using our physical interfaces */ if ((ifp->int_state & IS_REMOTE) - && !(ifp->int_state && IS_EXTERNAL) + && !(ifp->int_state & IS_EXTERNAL) && !check_remote(ifp)) return 0; diff --git a/sbin/routed/input.c b/sbin/routed/input.c index 24a02b9e79c4..fb5dbf57f231 100644 --- a/sbin/routed/input.c +++ b/sbin/routed/input.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93"; #elif defined(__NetBSD__) static char rcsid[] = "$NetBSD$"; #endif -#ident "$Revision: 1.17 $" +#ident "$Revision: 1.19 $" #include "defs.h" @@ -54,16 +54,20 @@ void read_rip(int sock, struct interface *sifp) { - static struct msg_limit bad_name; struct sockaddr_in from; struct interface *aifp; int fromlen, cc; - struct { #ifdef USE_PASSIFNAME + static struct msg_limit bad_name; + struct { char ifname[IFNAMSIZ]; -#endif union pkt_buf pbuf; } inbuf; +#else + struct { + union pkt_buf pbuf; + } inbuf; +#endif for (;;) { @@ -148,7 +152,7 @@ input(struct sockaddr_in *from, /* received from this IP address */ struct netinfo *n, *lim; struct interface *ifp1; naddr gate, mask, v1_mask, dst, ddst_h; - struct auth_key *ap; + struct auth *ap; int i; /* Notice when we hear from a remote gateway @@ -262,17 +266,16 @@ input(struct sockaddr_in *from, /* received from this IP address */ * do not disclose our secret unless the other guy * already knows it. */ - if (aifp != 0 - && aifp->int_auth.type == RIP_AUTH_PW + ap = find_auth(aifp); + if (aifp == 0 && ap->type == RIP_AUTH_PW + && n->n_family == RIP_AF_AUTH && !ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth)) ap = 0; - else - ap = find_auth(aifp); } else { v12buf.buf->rip_vers = RIPv1; ap = 0; } - clr_ws_buf(&v12buf, ap, aifp); + clr_ws_buf(&v12buf, ap); do { NTOHL(n->n_metric); @@ -397,7 +400,7 @@ input(struct sockaddr_in *from, /* received from this IP address */ /* Send the answer about specific routes. */ - if (ap != 0 && aifp->int_auth.type == RIP_AUTH_MD5) + if (ap != 0 && ap->type == RIP_AUTH_MD5) end_md5_auth(&v12buf, ap); if (from->sin_port != htons(RIP_PORT)) { @@ -433,7 +436,8 @@ input(struct sockaddr_in *from, /* received from this IP address */ } if (rip->rip_cmd == RIPCMD_TRACEON) { rip->rip_tracefile[cc-4] = '\0'; - trace_on((char*)rip->rip_tracefile, 0); + set_tracefile((char*)rip->rip_tracefile, + "trace command: %s\n", 0); } else { trace_off("tracing turned off by %s\n", naddr_ntoa(FROM_NADDR)); @@ -519,8 +523,8 @@ input(struct sockaddr_in *from, /* received from this IP address */ } /* If the interface cares, ignore bad routers. - * Trace but do not log this problem because when it - * happens it happens a lot. + * Trace but do not log this problem, because where it + * happens, it happens frequently. */ if (aifp->int_state & IS_DISTRUST) { struct tgate *tg = tgates; @@ -536,14 +540,13 @@ input(struct sockaddr_in *from, /* received from this IP address */ } /* Authenticate the packet if we have a secret. - * If we do not, ignore the silliness in RFC 1723 - * and accept it regardless. + * If we do not have any secrets, ignore the error in + * RFC 1723 and accept it regardless. */ - if (aifp->int_auth.type != RIP_AUTH_NONE - && rip->rip_vers != RIPv1) { - if (!ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth)) - return; - } + if (aifp->int_auth[0].type != RIP_AUTH_NONE + && rip->rip_vers != RIPv1 + && !ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth)) + return; do { if (n->n_family == RIP_AF_AUTH) @@ -860,9 +863,8 @@ ck_passwd(struct interface *aifp, struct msg_limit *use_authp) { # define NA (rip->rip_auths) -# define DAY (24*60*60) struct netauth *na2; - struct auth_key *akp = aifp->int_auth.keys; + struct auth *ap; MD5_CTX md5_ctx; u_char hash[RIP_AUTH_PW_LEN]; int i; @@ -874,35 +876,24 @@ ck_passwd(struct interface *aifp, return 0; } - if (NA->a_type != aifp->int_auth.type) { - msglim(use_authp, from, "wrong type of password from %s", - naddr_ntoa(from)); - return 0; - } - - if (NA->a_type == RIP_AUTH_PW) { - /* accept any current cleartext password - */ - for (i = 0; i < MAX_AUTH_KEYS; i++, akp++) { - if ((u_long)akp->start-DAY > (u_long)clk.tv_sec - || (u_long)akp->end+DAY < (u_long)clk.tv_sec) - continue; - - if (!bcmp(NA->au.au_pw, akp->key, RIP_AUTH_PW_LEN)) + /* accept any current (+/- 24 hours) password + */ + for (ap = aifp->int_auth, i = 0; i < MAX_AUTH_KEYS; i++, ap++) { + if (ap->type != NA->a_type + || (u_long)ap->start > (u_long)clk.tv_sec+DAY + || (u_long)ap->end+DAY < (u_long)clk.tv_sec) + continue; + + if (NA->a_type == RIP_AUTH_PW) { + if (!bcmp(NA->au.au_pw, ap->key, RIP_AUTH_PW_LEN)) return 1; - } - } else { - /* accept any current MD5 secret with the right key ID - */ - for (i = 0; i < MAX_AUTH_KEYS; i++, akp++) { - if (NA->au.a_md5.md5_keyid == akp->keyid - && (u_long)akp->start-DAY <= (u_long)clk.tv_sec - && (u_long)akp->end+DAY >= (u_long)clk.tv_sec) - break; - } + } else { + /* accept MD5 secret with the right key ID + */ + if (NA->au.a_md5.md5_keyid != ap->keyid) + continue; - if (i < MAX_AUTH_KEYS) { na2 = (struct netauth *)((char *)(NA+1) + NA->au.a_md5.md5_pkt_len); if (NA->au.a_md5.md5_pkt_len % sizeof(*NA) != 0 @@ -917,13 +908,14 @@ ck_passwd(struct interface *aifp, MD5Update(&md5_ctx, (u_char *)NA, (char *)na2->au.au_pw - (char *)NA); MD5Update(&md5_ctx, - (u_char *)akp->key, sizeof(akp->key)); + (u_char *)ap->key, sizeof(ap->key)); MD5Final(hash, &md5_ctx); - if (na2->a_family == RIP_AF_AUTH - && na2->a_type == 1 - && NA->au.a_md5.md5_auth_len == RIP_AUTH_PW_LEN - && !bcmp(hash, na2->au.au_pw, sizeof(hash))) - return 1; + if (na2->a_family != RIP_AF_AUTH + || na2->a_type != 1 + || NA->au.a_md5.md5_auth_len != RIP_AUTH_PW_LEN + || bcmp(hash, na2->au.au_pw, sizeof(hash))) + return 0; + return 1; } } diff --git a/sbin/routed/output.c b/sbin/routed/output.c index 69f7da9fa78d..de8f97dd6329 100644 --- a/sbin/routed/output.c +++ b/sbin/routed/output.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/5/93"; #elif defined(__NetBSD__) static char rcsid[] = "$NetBSD$"; #endif -#ident "$Revision: 1.18 $" +#ident "$Revision: 1.21 $" #include "defs.h" @@ -53,7 +53,7 @@ struct { naddr to_std_mask; naddr to_std_net; struct interface *ifp; /* usually output interface */ - struct auth_key *a; + struct auth *a; char metric; /* adjust metrics by interface */ int npackets; int gen_limit; @@ -180,10 +180,15 @@ output(enum output_type type, } sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP); } + break; case NO_OUT_MULTICAST: case NO_OUT_RIPV2: - break; + default: +#ifdef DEBUG + abort(); +#endif + return -1; } trace_rip(msg, "to", &sin, ifp, buf, size); @@ -206,28 +211,42 @@ output(enum output_type type, } -/* Find the first key that has not expired, but settle for +/* Find the first key for a packet to send. + * Try for a key that is eligable and has not expired, but settle for * the last key if they have all expired. * If no key is ready yet, give up. */ -struct auth_key * +struct auth * find_auth(struct interface *ifp) { - struct auth_key *ap, *res; + struct auth *ap, *res; int i; - if (ifp == 0 || ifp->int_auth.type == RIP_AUTH_NONE) + if (ifp == 0) return 0; - + res = 0; - ap = ifp->int_auth.keys; + ap = ifp->int_auth; for (i = 0; i < MAX_AUTH_KEYS; i++, ap++) { - if ((u_long)ap->start <= (u_long)clk.tv_sec) { - if ((u_long)ap->end >= (u_long)clk.tv_sec) - return ap; - res = ap; + /* stop looking after the last key */ + if (ap->type == RIP_AUTH_NONE) + break; + + /* ignore keys that are not ready yet */ + if ((u_long)ap->start > (u_long)clk.tv_sec) + continue; + + if ((u_long)ap->end < (u_long)clk.tv_sec) { + /* note best expired password as a fall-back */ + if (res == 0 || (u_long)ap->end > (u_long)res->end) + res = ap; + continue; } + + /* note key with the best future */ + if (res == 0 || (u_long)res->end < (u_long)ap->end) + res = ap; } return res; } @@ -235,8 +254,7 @@ find_auth(struct interface *ifp) void clr_ws_buf(struct ws_buf *wb, - struct auth_key *ap, - struct interface *ifp) + struct auth *ap) { struct netauth *na; @@ -249,13 +267,13 @@ clr_ws_buf(struct ws_buf *wb, if (ap == 0) return; na = (struct netauth*)wb->n; - if (ifp->int_auth.type == RIP_AUTH_PW) { + if (ap->type == RIP_AUTH_PW) { na->a_family = RIP_AF_AUTH; na->a_type = RIP_AUTH_PW; bcopy(ap->key, na->au.au_pw, sizeof(na->au.au_pw)); wb->n++; - } else if (ifp->int_auth.type == RIP_AUTH_MD5) { + } else if (ap->type == RIP_AUTH_MD5) { na->a_family = RIP_AF_AUTH; na->a_type = RIP_AUTH_MD5; na->au.a_md5.md5_keyid = ap->keyid; @@ -269,7 +287,7 @@ clr_ws_buf(struct ws_buf *wb, void end_md5_auth(struct ws_buf *wb, - struct auth_key *ap) + struct auth *ap) { struct netauth *na, *na2; MD5_CTX md5_ctx; @@ -306,7 +324,7 @@ supply_write(struct ws_buf *wb) case NO_OUT_RIPV2: break; default: - if (ws.ifp->int_auth.type == RIP_AUTH_MD5) + if (ws.a != 0 && ws.a->type == RIP_AUTH_MD5) end_md5_auth(wb,ws.a); if (output(wb->type, &ws.to, ws.ifp, wb->buf, ((char *)wb->n - (char*)wb->buf)) < 0 @@ -316,7 +334,7 @@ supply_write(struct ws_buf *wb) break; } - clr_ws_buf(wb,ws.a,ws.ifp); + clr_ws_buf(wb,ws.a); } @@ -326,7 +344,7 @@ static void supply_out(struct ag_info *ag) { int i; - naddr mask, v1_mask, dst_h, ddst_h; + naddr mask, v1_mask, dst_h, ddst_h = 0; struct ws_buf *wb; @@ -563,25 +581,33 @@ walk_supply(struct radix_node *rn, * forgotten. * * Include the routes for both ends of point-to-point interfaces - * since the other side presumably knows them as well as we do. + * among those suppressed by split-horizon, since the other side + * should knows them as well as we do. */ if (RT->rt_ifp == ws.ifp && ws.ifp != 0 && !(ws.state & WS_ST_QUERY) && (ws.state & WS_ST_TO_ON_NET) && (!(RT->rt_state & RS_IF) || ws.ifp->int_if_flags & IFF_POINTOPOINT)) { - /* Poison-reverse the route instead of only not advertising it - * it is recently changed from some other route. + /* If we do not mark the route with AGS_SPLIT_HZ here, + * it will be poisoned-reverse, or advertised back toward + * its source with an infinite metric. If we have recently + * advertised the route with a better metric than we now + * have, then we should poison-reverse the route before + * suppressing it for split-horizon. + * * In almost all cases, if there is no spare for the route - * then it is either old or a brand new route, and if it - * is brand new, there is no need for poison-reverse. + * then it is either old and dead or a brand new route. + * If it is brand new, there is no need for poison-reverse. + * If it is old and dead, it is already poisoned. */ - metric = HOPCNT_INFINITY; if (RT->rt_poison_time < now_expire - || RT->rt_spares[1].rts_gate ==0) { + || RT->rt_poison_metric >= metric + || RT->rt_spares[1].rts_gate == 0) { ags |= AGS_SPLIT_HZ; ags &= ~(AGS_PROMOTE | AGS_SUPPRESS); } + metric = HOPCNT_INFINITY; } /* Adjust the outgoing metric by the cost of the link. @@ -716,10 +742,10 @@ supply(struct sockaddr_in *dst, } ws.a = (vers == RIPv2) ? find_auth(ifp) : 0; - if (ws.a != 0 && !passwd_ok && ifp->int_auth.type == RIP_AUTH_PW) + if (!passwd_ok && ws.a != 0 && ws.a->type == RIP_AUTH_PW) ws.a = 0; - clr_ws_buf(&v12buf,ws.a,ifp); - clr_ws_buf(&v2buf,ws.a,ifp); + clr_ws_buf(&v12buf,ws.a); + clr_ws_buf(&v2buf,ws.a); /* Fake a default route if asked and if there is not already * a better, real default route. diff --git a/sbin/routed/parms.c b/sbin/routed/parms.c index ab5c75e65c35..87ca4a810e26 100644 --- a/sbin/routed/parms.c +++ b/sbin/routed/parms.c @@ -36,10 +36,11 @@ static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93"; #elif defined(__NetBSD__) static char rcsid[] = "$NetBSD$"; #endif -#ident "$Revision: 1.10 $" +#ident "$Revision: 1.12 $" #include "defs.h" #include "pathnames.h" +#include <sys/stat.h> struct parm *parms; @@ -54,6 +55,7 @@ get_parms(struct interface *ifp) { static warned_auth_in, warned_auth_out; struct parm *parmp; + int i, num_passwds = 0; /* get all relevant parameters */ @@ -68,9 +70,14 @@ get_parms(struct interface *ifp) * so get its settings */ ifp->int_state |= parmp->parm_int_state; - if (parmp->parm_auth.type != RIP_AUTH_NONE) - bcopy(&parmp->parm_auth, &ifp->int_auth, - sizeof(ifp->int_auth)); + for (i = 0; i < MAX_AUTH_KEYS; i++) { + if (parmp->parm_auth[0].type == RIP_AUTH_NONE + || num_passwds >= MAX_AUTH_KEYS) + break; + bcopy(&parmp->parm_auth[i], + &ifp->int_auth[num_passwds++], + sizeof(ifp->int_auth[0])); + } if (parmp->parm_rdisc_pref != 0) ifp->int_rdisc_pref = parmp->parm_rdisc_pref; if (parmp->parm_rdisc_int != 0) @@ -114,7 +121,7 @@ get_parms(struct interface *ifp) ifp->int_state |= IS_NO_RIP; if (!IS_RIP_IN_OFF(ifp->int_state) - && ifp->int_auth.type != RIP_AUTH_NONE + && ifp->int_auth[0].type != RIP_AUTH_NONE && !(ifp->int_state & IS_NO_RIPV1_IN) && !warned_auth_in) { msglog("Warning: RIPv1 input via %s" @@ -123,14 +130,14 @@ get_parms(struct interface *ifp) warned_auth_in = 1; } if (!IS_RIP_OUT_OFF(ifp->int_state) - && ifp->int_auth.type != RIP_AUTH_NONE - && !(ifp->int_state & IS_NO_RIPV1_OUT) - && !warned_auth_out) { - msglog("Warning: RIPv1 output via %s" - " will be sent without authentication", - ifp->int_name); - warned_auth_out = 1; - ifp->int_auth.type = RIP_AUTH_NONE; + && ifp->int_auth[0].type != RIP_AUTH_NONE + && !(ifp->int_state & IS_NO_RIPV1_OUT)) { + if (!warned_auth_out) { + msglog("Warning: RIPv1 output via %s" + " will be sent without authentication", + ifp->int_name); + warned_auth_out = 1; + } } } @@ -160,6 +167,7 @@ gwkludge(void) struct interface *ifp; naddr dst, netmask, gate; int metric, n; + struct stat sb; u_int state; char *type; @@ -168,6 +176,12 @@ gwkludge(void) if (fp == 0) return; + if (0 > fstat(fileno(fp), &sb)) { + msglog("could not stat() "_PATH_GATEWAYS); + (void)fclose(fp); + return; + } + for (;;) { if (0 == fgets(lbuf, sizeof(lbuf)-1, fp)) break; @@ -185,10 +199,12 @@ gwkludge(void) */ if (strncasecmp("net", lptr, 3) && strncasecmp("host", lptr, 4)) { - p = parse_parms(lptr); + p = parse_parms(lptr, + (sb.st_uid == 0 + && !(sb.st_mode&(S_IRWXG|S_IRWXO)))); if (p != 0) { if (strcasecmp(p,lptr)) - msglog("bad %s in "_PATH_GATEWAYS + msglog("%s in "_PATH_GATEWAYS " entry \"%s\"", p, lptr); else msglog("bad \"%s\" in "_PATH_GATEWAYS, @@ -225,6 +241,7 @@ gwkludge(void) " entry \"%s\"", dname, lptr); continue; } + HTONL(dst); /* make network # into IP address */ } else { msglog("bad \"%s\" in "_PATH_GATEWAYS " entry \"%s\"", lptr); @@ -333,12 +350,14 @@ gwkludge(void) trace_if("Add", ifp); } + + (void)fclose(fp); } /* strtok(), but honoring backslash */ -static int /* -1=bad */ +static int /* 0=ok, -1=bad */ parse_quote(char **linep, char *delims, char *delimp, @@ -352,9 +371,7 @@ parse_quote(char **linep, if (*pc == '\0') return -1; - for (;;) { - if (lim == 0) - return -1; + while (lim != 0) { c = *pc++; if (c == '\0') break; @@ -388,11 +405,13 @@ parse_quote(char **linep, --lim; } exit: + if (lim == 0) + return -1; + + *buf = '\0'; if (delimp != 0) *delimp = c; *linep = pc-1; - if (lim != 0) - *buf = '\0'; return 0; } @@ -413,7 +432,7 @@ parse_ts(time_t *tp, buf,bufsize) || buf[bufsize-1] != '\0' || buf[bufsize-2] != '\0') { - sprintf(buf,"timestamp %.25s", val0); + sprintf(buf,"bad timestamp %.25s", val0); return buf; } strcat(buf,"\n"); @@ -421,14 +440,14 @@ parse_ts(time_t *tp, if (5 != sscanf(buf, "%u/%u/%u@%u:%u\n", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min)) { - sprintf(buf,"timestamp %.25s", val0); + sprintf(buf,"bad timestamp %.25s", val0); return buf; } if (tm.tm_year <= 37) tm.tm_year += 100; if ((*tp = mktime(&tm)) == -1) { - sprintf(buf,"timestamp %.25s", val0); + sprintf(buf,"bad timestamp %.25s", val0); return buf; } @@ -436,92 +455,93 @@ parse_ts(time_t *tp, } -/* Get one or more password, key ID's, and expiration dates in - * the format - * passwd|keyID|year/mon/day@hour:min|year/mon/day@hour:min|passwd|... +/* Get a password, key ID, and expiration date in the format + * passwd|keyID|year/mon/day@hour:min|year/mon/day@hour:min */ static char * /* 0 or error message */ -get_passwds(char *tgt, - char *val, - struct parm *parmp, - u_char type) +get_passwd(char *tgt, + char *val, + struct parm *parmp, + u_char type, + int safe) /* 1=from secure file */ { static char buf[80]; char *val0, *p, delim; - struct auth_key *akp, *akp2; + struct auth k, *ap, *ap2; int i; u_long l; - if (parmp->parm_auth.type != RIP_AUTH_NONE) - return "duplicate authentication"; - parmp->parm_auth.type = type; + if (!safe) + return "unsafe password"; - bzero(buf, sizeof(buf)); + for (ap = parmp->parm_auth, i = 0; + ap->type != RIP_AUTH_NONE; i++, ap++) { + if (i >= MAX_AUTH_KEYS) + return "too many passwords"; + } - akp = parmp->parm_auth.keys; - for (i = 0; i < MAX_AUTH_KEYS; i++, val++, akp++) { - if ((delim = *val) == '\0') - break; - val0 = val; - if (0 > parse_quote(&val, "| ,\n\r", &delim, - (char *)akp->key, sizeof(akp->key))) - return tgt; + bzero(&k, sizeof(k)); + k.type = type; + k.end = -1-DAY; - akp->end = -1; + val0 = val; + if (0 > parse_quote(&val, "| ,\n\r", &delim, + (char *)k.key, sizeof(k.key))) + return tgt; - if (delim != '|') { - if (type == RIP_AUTH_MD5) - return "missing Keyid"; - break; - } + if (delim != '|') { + if (type == RIP_AUTH_MD5) + return "missing Keyid"; + } else { val0 = ++val; + buf[sizeof(buf)-1] = '\0'; if (0 > parse_quote(&val, "| ,\n\r", &delim, buf,sizeof(buf)) || buf[sizeof(buf)-1] != '\0' || (l = strtoul(buf,&p,0)) > 255 || *p != '\0') { - sprintf(buf,"KeyID \"%.20s\"", val0); + sprintf(buf,"bad KeyID \"%.20s\"", val0); return buf; } - for (akp2 = parmp->parm_auth.keys; akp2 < akp; akp2++) { - if (akp2->keyid == l) { - *val = '\0'; + for (ap2 = parmp->parm_auth; ap2 < ap; ap2++) { + if (ap2->keyid == l) { sprintf(buf,"duplicate KeyID \"%.20s\"", val0); return buf; } } - akp->keyid = (int)l; - - if (delim != '|') - break; - - val0 = ++val; - if (0 != (p = parse_ts(&akp->start,&val,val0,&delim, - buf,sizeof(buf)))) - return p; - if (delim != '|') - return "missing second timestamp"; - val0 = ++val; - if (0 != (p = parse_ts(&akp->end,&val,val0,&delim, - buf,sizeof(buf)))) - return p; - if ((u_long)akp->start > (u_long)akp->end) { - sprintf(buf,"out of order timestamp %.30s",val0); - return buf; + k.keyid = (int)l; + + if (delim == '|') { + val0 = ++val; + if (0 != (p = parse_ts(&k.start,&val,val0,&delim, + buf,sizeof(buf)))) + return p; + if (delim != '|') + return "missing second timestamp"; + val0 = ++val; + if (0 != (p = parse_ts(&k.end,&val,val0,&delim, + buf,sizeof(buf)))) + return p; + if ((u_long)k.start > (u_long)k.end) { + sprintf(buf,"out of order timestamp %.30s", + val0); + return buf; + } } - - if (delim != '|') - break; } + if (delim != '\0') + return tgt; - return (delim != '\0') ? tgt : 0; + bcopy(&k, ap, sizeof(*ap)); + return 0; } /* Parse a set of parameters for an interface. */ char * /* 0 or error message */ -parse_parms(char *line) +parse_parms(char *line, + int safe) /* 1=from secure file */ { #define PARS(str) (!strcasecmp(tgt, str)) #define PARSEQ(str) (!strncasecmp(tgt, str"=", sizeof(str))) @@ -554,6 +574,7 @@ parse_parms(char *line) free(intnetp); return line; } + HTONL(intnetp->intnet_addr); intnetp->intnet_next = intnets; intnets = intnetp; return 0; @@ -591,7 +612,7 @@ parse_parms(char *line) * The parm_net stuff is needed to allow several * -F settings. */ - if (!getnet(val, &addr, &mask) + if (!getnet(val0, &addr, &mask) || parm.parm_name[0] != '\0') return tgt; parm.parm_net = addr; @@ -599,14 +620,21 @@ parse_parms(char *line) parm.parm_name[0] = '\n'; } else if (PARSEQ("passwd")) { - tgt = get_passwds(tgt, val0, &parm, RIP_AUTH_PW); - if (tgt) + /* since cleartext passwords are so weak allow + * them anywhere + */ + tgt = get_passwd(tgt,val0,&parm,RIP_AUTH_PW,1); + if (tgt) { + *val0 = '\0'; return tgt; + } } else if (PARSEQ("md5_passwd")) { - tgt = get_passwds(tgt, val0, &parm, RIP_AUTH_MD5); - if (tgt) + tgt = get_passwd(tgt,val0,&parm,RIP_AUTH_MD5,safe); + if (tgt) { + *val0 = '\0'; return tgt; + } } else if (PARS("no_ag")) { parm.parm_int_state |= (IS_NO_AG | IS_NO_SUPER_AG); @@ -693,6 +721,9 @@ parse_parms(char *line) tgates = tg; parm.parm_int_state |= IS_DISTRUST; + } else if (PARS("redirect_ok")) { + parm.parm_int_state |= IS_REDIRECT_OK; + } else { return tgt; /* error */ } @@ -708,16 +739,24 @@ parse_parms(char *line) char * /* 0 or error message */ check_parms(struct parm *new) { - struct parm *parmp; + struct parm *parmp, **parmpp; + int i, num_passwds; /* set implicit values */ if (new->parm_int_state & IS_NO_ADV_IN) new->parm_int_state |= IS_NO_SOL_OUT; + for (i = num_passwds = 0; i < MAX_AUTH_KEYS; i++) { + if (new->parm_auth[i].type != RIP_AUTH_NONE) + num_passwds++; + } + /* compare with existing sets of parameters */ - for (parmp = parms; parmp != 0; parmp = parmp->parm_next) { + for (parmpp = &parms; + (parmp = *parmpp) != 0; + parmpp = &parmp->parm_next) { if (strcmp(new->parm_name, parmp->parm_name)) continue; if (!on_net(htonl(parmp->parm_net), @@ -726,12 +765,12 @@ check_parms(struct parm *new) parmp->parm_net, parmp->parm_mask)) continue; - if (parmp->parm_auth.type != RIP_AUTH_NONE - && new->parm_auth.type != RIP_AUTH_NONE - && bcmp(&parmp->parm_auth, &new->parm_auth, - sizeof(parmp->parm_auth))) { - return "conflicting, duplicate authentication"; + for (i = 0; i < MAX_AUTH_KEYS; i++) { + if (parmp->parm_auth[i].type != RIP_AUTH_NONE) + num_passwds++; } + if (num_passwds > MAX_AUTH_KEYS) + return "too many conflicting passwords"; if ((0 != (new->parm_int_state & GROUP_IS_SOL) && 0 != (parmp->parm_int_state & GROUP_IS_SOL) @@ -760,10 +799,12 @@ check_parms(struct parm *new) } } + /* link new entry on the so that when the entries are scanned, + * they affect the result in the order the operator specified. + */ parmp = (struct parm*)malloc(sizeof(*parmp)); bcopy(new, parmp, sizeof(*parmp)); - parmp->parm_next = parms; - parms = parmp; + *parmpp = parmp; return 0; } @@ -774,13 +815,13 @@ check_parms(struct parm *new) */ int /* 0=bad */ getnet(char *name, - naddr *netp, /* host byte order */ - naddr *maskp) + naddr *netp, /* a network so host byte order */ + naddr *maskp) /* masks are always in host order */ { int i; struct netent *np; - naddr mask; - struct in_addr in; + naddr mask; /* in host byte order */ + struct in_addr in; /* a network and so host byte order */ char hname[MAXHOSTNAMELEN+1]; char *mname, *p; @@ -812,7 +853,7 @@ getnet(char *name, /* we cannot use the interfaces here because we have not * looked at them yet. */ - mask = std_mask(in.s_addr); + mask = std_mask(htonl(in.s_addr)); if ((~mask & in.s_addr) != 0) mask = HOST_MASK; } else { diff --git a/sbin/routed/rdisc.c b/sbin/routed/rdisc.c index 7433b792e6fe..1e9f42d17b03 100644 --- a/sbin/routed/rdisc.c +++ b/sbin/routed/rdisc.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)rdisc.c 8.1 (Berkeley) x/y/95"; #elif defined(__NetBSD__) static char rcsid[] = "$NetBSD$"; #endif -#ident "$Revision: 1.17 $" +#ident "$Revision: 1.19 $" #include "defs.h" #include <netinet/in_systm.h> @@ -127,7 +127,7 @@ trace_rdisc(char *act, wp = &p->ad.icmp_ad_info[0].icmp_ad_addr; lim = &wp[(len - sizeof(p->ad)) / sizeof(*wp)]; for (i = 0; i < p->ad.icmp_ad_num && wp <= lim; i++) { - (void)fprintf(ftrace, "\t%s preference=%#x", + (void)fprintf(ftrace, "\t%s preference=%d", naddr_ntoa(wp[0]), (int)ntohl(wp[1])); wp += p->ad.icmp_ad_asize; } @@ -689,6 +689,7 @@ send_rdisc(union ad_u *p, switch (type) { case 0: /* unicast */ + default: msg = "Send"; break; diff --git a/sbin/routed/trace.c b/sbin/routed/trace.c index dabf4d146768..a171ce86dad9 100644 --- a/sbin/routed/trace.c +++ b/sbin/routed/trace.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93"; #elif defined(__NetBSD__) static char rcsid[] = "$NetBSD$"; #endif -#ident "$Revision: 1.14 $" +#ident "$Revision: 1.16 $" #define RIPCMDS #include "defs.h" @@ -53,11 +53,12 @@ static char rcsid[] = "$NetBSD$"; #define NRECORDS 50 /* size of circular trace buffer */ -u_int tracelevel, new_tracelevel; +int tracelevel, new_tracelevel; FILE *ftrace = stdout; /* output trace file */ -static char *tracelevel_pat = "%s\n"; - -char savetracename[MAXPATHLEN+1]; +static char *sigtrace_pat = "%s\n"; +static char savetracename[MAXPATHLEN+1]; +char inittracename[MAXPATHLEN+1]; +int file_trace; /* 1=tracing to file, not stdout */ static void trace_dump(void); @@ -162,15 +163,15 @@ ts(time_t secs) { * This assumes that 'now' is update once for each event, and * that at least now.tv_usec changes. */ +static struct timeval lastlog_time; + void lastlog(void) { - static struct timeval last; - - if (last.tv_sec != now.tv_sec - || last.tv_usec != now.tv_usec) { + if (lastlog_time.tv_sec != now.tv_sec + || lastlog_time.tv_usec != now.tv_usec) { (void)fprintf(ftrace, "-- %s --\n", ts(now.tv_sec)); - last = now; + lastlog_time = now; } } @@ -198,15 +199,17 @@ trace_close(void) fflush(stdout); fflush(stderr); - if (ftrace != 0 - && savetracename[0] != '\0') { + if (ftrace != 0 && file_trace) { + if (ftrace != stdout) + fclose(ftrace); + ftrace = 0; fd = open(_PATH_DEVNULL, O_RDWR); + (void)dup2(fd, STDIN_FILENO); (void)dup2(fd, STDOUT_FILENO); (void)dup2(fd, STDERR_FILENO); (void)close(fd); - fclose(ftrace); - ftrace = 0; } + lastlog_time.tv_sec = 0; } @@ -231,7 +234,6 @@ trace_off(char *p, ...) lastlog(); va_start(args, p); vfprintf(ftrace, p, args); - fflush(ftrace); } trace_close(); @@ -239,33 +241,101 @@ trace_off(char *p, ...) } +/* log a change in tracing + */ void -trace_on(char *filename, - int initial) /* 1=setting from command line */ +tracelevel_msg(char *pat, + int dump) /* -1=no dump, 0=default, 1=force */ +{ + static char *off_msgs[MAX_TRACELEVEL] = { + "Tracing actions stopped", + "Tracing packets stopped", + "Tracing packet contents stopped", + "Tracing kernel changes stopped", + }; + static char *on_msgs[MAX_TRACELEVEL] = { + "Tracing actions started", + "Tracing packets started", + "Tracing packet contents started", + "Tracing kernel changes started", + }; + u_int old_tracelevel = tracelevel; + + + if (new_tracelevel < 0) + new_tracelevel = 0; + else if (new_tracelevel > MAX_TRACELEVEL) + new_tracelevel = MAX_TRACELEVEL; + + if (new_tracelevel < tracelevel) { + if (new_tracelevel <= 0) { + trace_off(pat, off_msgs[0]); + } else do { + tmsg(pat, off_msgs[tracelevel]); + } + while (--tracelevel != new_tracelevel); + + } else if (new_tracelevel > tracelevel) { + do { + tmsg(pat, on_msgs[tracelevel++]); + } while (tracelevel != new_tracelevel); + } + + if (dump > 0 + || (dump == 0 && old_tracelevel == 0 && tracelevel != 0)) + trace_dump(); +} + + +void +set_tracefile(char *filename, + char *pat, + int dump) /* -1=no dump, 0=default, 1=force */ { struct stat stbuf; FILE *n_ftrace; - u_int old_tracelevel; + char *fn; - /* Given a null filename when tracing is already on, increase the - * debugging level and re-open the file in case it has been unlinked. + /* Allow a null filename to increase the level if the trace file + * is already open or if coming from a trusted source, such as + * a signal or the command line. */ - if (filename[0] == '\0') { - if (tracelevel != 0) { - new_tracelevel++; - tracelevel_pat = "trace command: %s\n"; - } else if (savetracename[0] == '\0') { - msglog("missing trace file name"); - return; + if (filename == 0 || filename[0] == '\0') { + filename = 0; + if (ftrace == 0) { + if (inittracename[0] == '\0') { + msglog("missing trace file name"); + return; + } + fn = inittracename; + } else { + fn = 0; } - filename = savetracename; } else if (!strcmp(filename,"dump/../table")) { trace_dump(); return; } else { + /* Allow the file specified with "-T file" to be reopened, + * but require all other names specified over the net to + * match the official path. The path can specify a directory + * in which the file is to be created. + */ + if (strcmp(filename, inittracename) +#ifdef _PATH_TRACE + && (strncmp(filename, _PATH_TRACE, sizeof(_PATH_TRACE)-1) + || strstr(filename,"../") + || 0 > stat(_PATH_TRACE, &stbuf)) +#endif + ) { + msglog("wrong trace file \"%s\"", filename); + return; + } + + /* If the new tracefile exists, it must be a regular file. + */ if (stat(filename, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) != S_IFREG) { msglog("wrong type (%#x) of trace file \"%s\"", @@ -273,44 +343,37 @@ trace_on(char *filename, return; } - if (!initial -#ifdef _PATH_TRACE - && (strncmp(filename, _PATH_TRACE, sizeof(_PATH_TRACE)-1) - || strstr(filename,"../") - || 0 > stat(_PATH_TRACE, &stbuf)) -#endif - && strcmp(filename, savetracename)) { - msglog("wrong directory for trace file \"%s\"", - filename); + fn = filename; + } + + if (fn != 0) { + n_ftrace = fopen(fn, "a"); + if (n_ftrace == 0) { + msglog("failed to open trace file \"%s\" %s", + fn, strerror(errno)); + if (fn == inittracename) + inittracename[0] = '\0'; return; } - } - n_ftrace = fopen(filename, "a"); - if (n_ftrace == 0) { - msglog("failed to open trace file \"%s\" %s", - filename, strerror(errno)); - return; - } + tmsg("switch to trace file %s\n", fn); - tmsg("switch to trace file %s\n", filename); - trace_close(); - if (filename != savetracename) - strncpy(savetracename, filename, sizeof(savetracename)-1); - ftrace = n_ftrace; + file_trace = 1; + trace_close(); - fflush(stdout); - fflush(stderr); - dup2(fileno(ftrace), STDOUT_FILENO); - dup2(fileno(ftrace), STDERR_FILENO); + if (fn != savetracename) + strncpy(savetracename, fn, sizeof(savetracename)-1); + ftrace = n_ftrace; - if (new_tracelevel == 0) - new_tracelevel = 1; - old_tracelevel = tracelevel; - set_tracelevel(initial); + fflush(stdout); + fflush(stderr); + dup2(fileno(ftrace), STDOUT_FILENO); + dup2(fileno(ftrace), STDERR_FILENO); + } - if (!initial && old_tracelevel == 0) - trace_dump(); + if (new_tracelevel == 0 || filename == 0) + new_tracelevel++; + tracelevel_msg(pat, dump != 0 ? dump : (filename != 0)); } @@ -319,7 +382,7 @@ void sigtrace_on(int s) { new_tracelevel++; - tracelevel_pat = "SIGUSR1: %s\n"; + sigtrace_pat = "SIGUSR1: %s\n"; } @@ -328,59 +391,33 @@ void sigtrace_off(int s) { new_tracelevel--; - tracelevel_pat = "SIGUSR2: %s\n"; + sigtrace_pat = "SIGUSR2: %s\n"; } -/* Move to next higher level of tracing when -t option processed or - * SIGUSR1 is received. Successive levels are: - * actions - * actions + packets - * actions + packets + contents +/* Set tracing after a signal. */ void -set_tracelevel(int initial) +set_tracelevel(void) { - static char *off_msgs[MAX_TRACELEVEL] = { - "Tracing actions stopped", - "Tracing packets stopped", - "Tracing packet contents stopped", - "Tracing kernel changes stopped", - }; - static char *on_msgs[MAX_TRACELEVEL] = { - "Tracing actions started", - "Tracing packets started", - "Tracing packet contents started", - "Tracing kernel changes started", - }; - - - if (new_tracelevel > MAX_TRACELEVEL) { - new_tracelevel = MAX_TRACELEVEL; - if (new_tracelevel == tracelevel) { - tmsg(tracelevel_pat, on_msgs[tracelevel-1]); - return; - } - } + if (new_tracelevel == tracelevel) + return; - for (; new_tracelevel != tracelevel; tracelevel++) { - if (new_tracelevel < tracelevel) { - if (--tracelevel == 0) - trace_off(tracelevel_pat, off_msgs[0]); - else - tmsg(tracelevel_pat, off_msgs[tracelevel]); + /* If tracing entirely off, and there was no tracefile specified + * on the command line, then leave it off. + */ + if (new_tracelevel > tracelevel && ftrace == 0) { + if (savetracename[0] != '\0') { + set_tracefile(savetracename,sigtrace_pat,0); + } else if (inittracename[0] != '\0') { + set_tracefile(inittracename,sigtrace_pat,0); } else { - if (ftrace == 0) { - if (savetracename[0] != '\0') - trace_on(savetracename, 1); - else - ftrace = stdout; - } - if (!initial || tracelevel+1 == new_tracelevel) - tmsg(tracelevel_pat, on_msgs[tracelevel]); + new_tracelevel = 0; + return; } + } else { + tracelevel_msg(sigtrace_pat, 0); } - tracelevel_pat = "%s\n"; } @@ -454,6 +491,7 @@ static struct bits is_bits[] = { { IS_BROKE, IS_SICK, "BROKEN" }, { IS_SICK, 0, "SICK" }, { IS_DUP, 0, "DUPLICATE" }, + { IS_REDIRECT_OK, 0, "REDIRECT_OK" }, { IS_NEED_NET_SYN, 0, "" }, { IS_NO_AG, IS_NO_SUPER_AG, "NO_AG" }, { IS_NO_SUPER_AG, 0, "NO_SUPER_AG" }, @@ -548,6 +586,32 @@ trace_pair(naddr dst, } +static void +print_rts(struct rt_spare *rts, + int force_metric, /* -1=suppress, 0=default */ + int force_ifp, /* -1=suppress, 0=default */ + int force_router, /* -1=suppress, 0=default, 1=display */ + int force_tag, /* -1=suppress, 0=default, 1=display */ + int force_time) /* 0=suppress, 1=display */ +{ + if (force_metric >= 0) + (void)fprintf(ftrace, "metric=%-2d ", rts->rts_metric); + if (force_ifp >= 0) + (void)fprintf(ftrace, "%s ", (rts->rts_ifp == 0 ? + "if?" : rts->rts_ifp->int_name)); + if (force_router > 0 + || (force_router == 0 && rts->rts_router != rts->rts_gate)) + (void)fprintf(ftrace, "router=%s ", + naddr_ntoa(rts->rts_router)); + if (force_time > 0) + (void)fprintf(ftrace, "%s ", ts(rts->rts_time)); + if (force_tag > 0 + || (force_tag == 0 && rts->rts_tag != 0)) + (void)fprintf(ftrace, "tag=%#x ", + ntohs(rts->rts_tag)); +} + + void trace_if(char *act, struct interface *ifp) @@ -584,13 +648,22 @@ trace_upslot(struct rt_entry *rt, u_short tag, time_t new_time) { + struct rt_spare new; + if (!TRACEACTIONS || ftrace == 0) return; + if (rts->rts_gate == gate && rts->rts_router == router && rts->rts_metric == metric && rts->rts_tag == tag) return; + new.rts_ifp = ifp; + new.rts_gate = gate; + new.rts_router = router; + new.rts_metric = metric; + new.rts_time = new_time; + new.rts_tag = tag; lastlog(); if (rts->rts_gate != RIP_DEFAULT) { @@ -598,45 +671,32 @@ trace_upslot(struct rt_entry *rt, rts - rt->rt_spares, trace_pair(rt->rt_dst, rt->rt_mask, naddr_ntoa(rts->rts_gate))); - if (rts->rts_gate != rts->rts_gate) - (void)fprintf(ftrace, "router=%s ", - naddr_ntoa(rts->rts_gate)); - if (rts->rts_tag != 0) - (void)fprintf(ftrace, "tag=%#x ", ntohs(rts->rts_tag)); - (void)fprintf(ftrace, "metric=%-2d ", rts->rts_metric); - if (rts->rts_ifp != 0) - (void)fprintf(ftrace, "%s ", - rts->rts_ifp->int_name); - (void)fprintf(ftrace, "%s\n", ts(rts->rts_time)); + print_rts(rts, 0,0, + rts->rts_gate != gate, + rts->rts_tag != tag, + rts != rt->rt_spares || AGE_RT(rt->rt_state, + rt->rt_ifp)); - (void)fprintf(ftrace, " %19s%-16s ", - "", + (void)fprintf(ftrace, "\n %19s%-16s ", "", gate != rts->rts_gate ? naddr_ntoa(gate) : ""); - if (gate != router) - (void)fprintf(ftrace,"router=%s ",naddr_ntoa(router)); - if (tag != rts->rts_tag) - (void)fprintf(ftrace, "tag=%#x ", ntohs(tag)); - if (metric != rts->rts_metric) - (void)fprintf(ftrace, "metric=%-2d ", metric); - if (ifp != rts->rts_ifp && ifp != 0 ) - (void)fprintf(ftrace, "%s ", ifp->int_name); - (void)fprintf(ftrace, "%s\n", - new_time != rts->rts_time ? ts(new_time) : ""); + print_rts(&new, + -(metric == rts->rts_metric), + -(ifp == rts->rts_ifp), + 0, + rts->rts_tag != tag, + new_time != rts->rts_time && (rts != rt->rt_spares + || AGE_RT(rt->rt_state, + ifp))); } else { (void)fprintf(ftrace, "Add #%d %-35s ", rts - rt->rt_spares, trace_pair(rt->rt_dst, rt->rt_mask, naddr_ntoa(gate))); - if (gate != router) - (void)fprintf(ftrace, "router=%s ", naddr_ntoa(gate)); - if (tag != 0) - (void)fprintf(ftrace, "tag=%#x ", ntohs(tag)); - (void)fprintf(ftrace, "metric=%-2d ", metric); - if (ifp != 0) - (void)fprintf(ftrace, "%s ", ifp->int_name); - (void)fprintf(ftrace, "%s\n", ts(new_time)); + print_rts(&new, 0,0,0,0, + rts != rt->rt_spares || AGE_RT(rt->rt_state,ifp)); } + (void)fputc('\n',ftrace); } @@ -701,6 +761,8 @@ trace_change(struct rt_entry *rt, time_t new_time, char *label) { + struct rt_spare new; + if (ftrace == 0) return; @@ -710,67 +772,51 @@ trace_change(struct rt_entry *rt, && rt->rt_state == state && rt->rt_tag == tag) return; + new.rts_ifp = ifp; + new.rts_gate = gate; + new.rts_router = router; + new.rts_metric = metric; + new.rts_time = new_time; + new.rts_tag = tag; lastlog(); - (void)fprintf(ftrace, "%s %-35s metric=%-2d ", + (void)fprintf(ftrace, "%s %-35s ", label, trace_pair(rt->rt_dst, rt->rt_mask, - naddr_ntoa(rt->rt_gate)), - rt->rt_metric); - if (rt->rt_router != rt->rt_gate) - (void)fprintf(ftrace, "router=%s ", - naddr_ntoa(rt->rt_router)); - if (rt->rt_tag != 0) - (void)fprintf(ftrace, "tag=%#x ", ntohs(rt->rt_tag)); + naddr_ntoa(rt->rt_gate))); + print_rts(rt->rt_spares, + 0,0,0,0, AGE_RT(rt->rt_state, rt->rt_ifp)); trace_bits(rs_bits, rt->rt_state, rt->rt_state != state); - (void)fprintf(ftrace, "%s ", - rt->rt_ifp == 0 ? "?" : rt->rt_ifp->int_name); - (void)fprintf(ftrace, "%s\n", - AGE_RT(rt->rt_state, rt->rt_ifp) ? ts(rt->rt_time) : ""); - (void)fprintf(ftrace, "%*s %19s%-16s ", + (void)fprintf(ftrace, "\n%*s %19s%-16s ", strlen(label), "", "", rt->rt_gate != gate ? naddr_ntoa(gate) : ""); - if (rt->rt_metric != metric) - (void)fprintf(ftrace, "metric=%-2d ", metric); - if (router != gate) - (void)fprintf(ftrace, "router=%s ", naddr_ntoa(router)); - if (rt->rt_tag != tag) - (void)fprintf(ftrace, "tag=%#x ", ntohs(tag)); + print_rts(&new, + -(metric == rt->rt_metric), + -(ifp == rt->rt_ifp), + 0, + rt->rt_tag != tag, + rt->rt_time != new_time && AGE_RT(rt->rt_state,ifp)); if (rt->rt_state != state) trace_bits(rs_bits, state, 1); - if (rt->rt_ifp != ifp) - (void)fprintf(ftrace, "%s ", - ifp != 0 ? ifp->int_name : "?"); - (void)fprintf(ftrace, "%s\n", - ((rt->rt_time == new_time || !AGE_RT(rt->rt_state, ifp)) - ? "" : ts(new_time))); + (void)fputc('\n',ftrace); } void trace_add_del(char * action, struct rt_entry *rt) { - u_int state = rt->rt_state; - if (ftrace == 0) return; lastlog(); - (void)fprintf(ftrace, "%s %-35s metric=%-2d ", + (void)fprintf(ftrace, "%s %-35s ", action, trace_pair(rt->rt_dst, rt->rt_mask, - naddr_ntoa(rt->rt_gate)), - rt->rt_metric); - if (rt->rt_router != rt->rt_gate) - (void)fprintf(ftrace, "router=%s ", - naddr_ntoa(rt->rt_router)); - if (rt->rt_tag != 0) - (void)fprintf(ftrace, "tag=%#x ", ntohs(rt->rt_tag)); - trace_bits(rs_bits, state, 0); - (void)fprintf(ftrace, "%s ", - rt->rt_ifp != 0 ? rt->rt_ifp->int_name : "?"); - (void)fprintf(ftrace, "%s\n", ts(rt->rt_time)); + naddr_ntoa(rt->rt_gate))); + print_rts(rt->rt_spares, 0,0,0,0,AGE_RT(rt->rt_state,rt->rt_ifp)); + trace_bits(rs_bits, rt->rt_state, 0); + (void)fputc('\n',ftrace); } @@ -781,42 +827,24 @@ walk_trace(struct radix_node *rn, { #define RT ((struct rt_entry *)rn) struct rt_spare *rts; - int i, age; + int i, age = AGE_RT(RT->rt_state, RT->rt_ifp); - (void)fprintf(ftrace, " %-35s metric=%-2d ", - trace_pair(RT->rt_dst, RT->rt_mask, - naddr_ntoa(RT->rt_gate)), - RT->rt_metric); - if (RT->rt_router != RT->rt_gate) - (void)fprintf(ftrace, "router=%s ", - naddr_ntoa(RT->rt_router)); - if (RT->rt_tag != 0) - (void)fprintf(ftrace, "tag=%#x ", - ntohs(RT->rt_tag)); + (void)fprintf(ftrace, " %-35s ", trace_pair(RT->rt_dst, RT->rt_mask, + naddr_ntoa(RT->rt_gate))); + print_rts(&RT->rt_spares[0], 0,0,0,0,age); trace_bits(rs_bits, RT->rt_state, 0); - (void)fprintf(ftrace, "%s ", - RT->rt_ifp == 0 ? "?" : RT->rt_ifp->int_name); - age = AGE_RT(RT->rt_state, RT->rt_ifp); - if (age) - (void)fprintf(ftrace, "%s", ts(RT->rt_time)); + if (RT->rt_poison_time >= now_garbage + && RT->rt_poison_metric < RT->rt_metric) + (void)fprintf(ftrace, "pm=%d@%s", + RT->rt_poison_metric, + ts(RT->rt_poison_time)); rts = &RT->rt_spares[1]; for (i = 1; i < NUM_SPARES; i++, rts++) { - if (rts->rts_metric != HOPCNT_INFINITY) { - (void)fprintf(ftrace,"\n #%d%15s%-16s metric=%-2d ", - i, "", naddr_ntoa(rts->rts_gate), - rts->rts_metric); - if (rts->rts_router != rts->rts_gate) - (void)fprintf(ftrace, "router=%s ", - naddr_ntoa(rts->rts_router)); - if (rts->rts_tag != 0) - (void)fprintf(ftrace, "tag=%#x ", - ntohs(rts->rts_tag)); - (void)fprintf(ftrace, "%s ", - (rts->rts_ifp == 0 - ? "?" : rts->rts_ifp->int_name)); - if (age) - (void)fprintf(ftrace, "%s", ts(rts->rts_time)); + if (rts->rts_gate != RIP_DEFAULT) { + (void)fprintf(ftrace,"\n #%d%15s%-16s ", + i, "", naddr_ntoa(rts->rts_gate)); + print_rts(rts, 0,0,0,0,1); } } (void)fputc('\n',ftrace); @@ -834,6 +862,7 @@ trace_dump(void) return; lastlog(); + (void)fputs("current daemon state:\n", ftrace); for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) trace_if("", ifp); (void)rn_walktree(rhead, walk_trace, 0); @@ -976,7 +1005,8 @@ trace_rip(char *dir1, char *dir2, break; case RIPCMD_TRACEON: - fprintf(ftrace, "\tfile=%*s\n", size-4, msg->rip_tracefile); + fprintf(ftrace, "\tfile=\"%.*s\"\n", size-4, + msg->rip_tracefile); break; case RIPCMD_TRACEOFF: |