diff options
author | Jakob Schlyter <jakob@cvs.openbsd.org> | 2000-06-18 09:39:29 +0000 |
---|---|---|
committer | Jakob Schlyter <jakob@cvs.openbsd.org> | 2000-06-18 09:39:29 +0000 |
commit | 4854d0bfa04291b919d0a22504785b1b2c4b5af9 (patch) | |
tree | 8f83b84243ddfd416db57a54fd9c51db110585d8 /usr.sbin/tcpdump/print-rip.c | |
parent | 94417fc8651819ccdc854d34cd754e2cf05ccf28 (diff) |
Improve RIP support; PR#1266, James Ponder <james@oaktree.co.uk>
* Fixes the way version numbers are handled so that it is compliant
with RFC 1058 in the order that you should look at things.
* Adds support for the authentication attribute with cleartext passwords.
* Improves readability in output.
* Handles version 0 of RIP and unknown conditions a lot better
Diffstat (limited to 'usr.sbin/tcpdump/print-rip.c')
-rw-r--r-- | usr.sbin/tcpdump/print-rip.c | 189 |
1 files changed, 125 insertions, 64 deletions
diff --git a/usr.sbin/tcpdump/print-rip.c b/usr.sbin/tcpdump/print-rip.c index 283245f6d02..b25aaeb576c 100644 --- a/usr.sbin/tcpdump/print-rip.c +++ b/usr.sbin/tcpdump/print-rip.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/print-rip.c,v 1.6 2000/04/26 21:35:42 jakob Exp $ (LBL)"; + "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/print-rip.c,v 1.7 2000/06/18 09:39:28 jakob Exp $ (LBL)"; #endif #include <sys/param.h> @@ -53,6 +53,8 @@ struct rip { #define RIPCMD_POLL 5 /* want info from everybody */ #define RIPCMD_POLLENTRY 6 /* poll for entry */ +#define RIP_AUTHLEN 16 + struct rip_netinfo { u_short rip_family; u_short rip_tag; @@ -63,23 +65,83 @@ struct rip_netinfo { }; static void -rip_entry_print(register int vers, register const struct rip_netinfo *ni) +rip_printblk(const u_char *cp, const u_char *ep) { - register u_char *cp, *ep; + for (; cp < ep; cp += 2) + printf(" %04x", EXTRACT_16BITS(cp)); + return; +} - if (EXTRACT_16BITS(&ni->rip_family) != AF_INET) { +static void +rip_entry_print_v1(register int vers, register const struct rip_netinfo *ni) +{ + register u_short family; + + /* RFC 1058 */ + family = EXTRACT_16BITS(&ni->rip_family); + if (family != AF_INET) { + printf(" [family %d:", family); + rip_printblk((u_char *)&ni->rip_tag, + (u_char *)&ni->rip_metric + + sizeof(ni->rip_metric)); + printf("]"); + return; + } + if (ni->rip_tag || ni->rip_dest_mask || ni->rip_router) { + /* MBZ fields not zero */ + printf(" ["); + rip_printblk((u_char *)&ni->rip_family, + (u_char *)&ni->rip_metric + + sizeof(ni->rip_metric)); + printf("]"); + return; + } + printf(" {%s}(%d)", ipaddr_string(&ni->rip_dest), + EXTRACT_32BITS(&ni->rip_metric)); +} - printf(" [family %d:", EXTRACT_16BITS(&ni->rip_family)); - cp = (u_char *)&ni->rip_tag; - ep = (u_char *)&ni->rip_metric + sizeof(ni->rip_metric); - for (; cp < ep; cp += 2) - printf(" %04x", EXTRACT_16BITS(cp)); +static void +rip_entry_print_v2(register int vers, register const struct rip_netinfo *ni) +{ + register u_char *p; + register u_short family; + char buf[RIP_AUTHLEN]; + + /* RFC 1723 */ + family = EXTRACT_16BITS(&ni->rip_family); + if (family == 0xFFFF) { + if (EXTRACT_16BITS(&ni->rip_tag) == 2) { + memcpy(buf, &ni->rip_dest, sizeof(buf)); + buf[sizeof(buf)-1] = '\0'; + for (p = buf; *p; p++) { + if (!isprint(*p)) + break; + } + if (!*p) { + printf(" [password %s]", buf); + } else { + printf(" [password: "); + rip_printblk((u_char *)&ni->rip_dest, + (u_char *)&ni->rip_metric + + sizeof(ni->rip_metric)); + printf("]"); + } + } else { + printf(" [auth %d:", + EXTRACT_16BITS(&ni->rip_tag)); + rip_printblk((u_char *)&ni->rip_dest, + (u_char *)&ni->rip_metric + + sizeof(ni->rip_metric)); + printf("]"); + } + } else if (family != AF_INET) { + printf(" [family %d:", family); + rip_printblk((u_char *)&ni->rip_tag, + (u_char *)&ni->rip_metric + + sizeof(ni->rip_metric)); printf("]"); - } else if (vers < 2) { - /* RFC 1058 */ - printf(" %s", ipaddr_string(&ni->rip_dest)); - } else { - /* RFC 1723 */ + return; + } else { /* AF_INET */ printf(" {%s", ipaddr_string(&ni->rip_dest)); if (ni->rip_dest_mask) printf("/%s", ipaddr_string(&ni->rip_dest_mask)); @@ -87,9 +149,8 @@ rip_entry_print(register int vers, register const struct rip_netinfo *ni) printf("->%s", ipaddr_string(&ni->rip_router)); if (ni->rip_tag) printf(" tag %04x", EXTRACT_16BITS(&ni->rip_tag)); - printf("}"); + printf("}(%d)", EXTRACT_32BITS(&ni->rip_metric)); } - printf("(%d)", EXTRACT_32BITS(&ni->rip_metric)); } void @@ -106,56 +167,56 @@ rip_print(const u_char *dat, u_int length) } rp = (struct rip *)dat; - switch (rp->rip_cmd) { - - case RIPCMD_REQUEST: - printf(" rip-req %d", length); - break; - - case RIPCMD_RESPONSE: - j = length / sizeof(*ni); - if (j * sizeof(*ni) != length - 4) - printf(" rip-resp %d[%d]:", j, length); - else - printf(" rip-resp %d:", j); - trunc = (i / sizeof(*ni)) != j; - ni = (struct rip_netinfo *)(rp + 1); - for (; (i -= sizeof(*ni)) >= 0; ++ni) - rip_entry_print(rp->rip_vers, ni); - if (trunc) - printf("[|rip]"); - break; - - case RIPCMD_TRACEON: - printf(" rip-traceon %d: \"", length); - (void)fn_print((const u_char *)(rp + 1), snapend); - fputs("\"\n", stdout); - break; - - case RIPCMD_TRACEOFF: - printf(" rip-traceoff %d", length); - break; - - case RIPCMD_POLL: - printf(" rip-poll %d", length); - break; - - case RIPCMD_POLLENTRY: - printf(" rip-pollentry %d", length); - break; - - default: - printf(" rip-#%d %d", rp->rip_cmd, length); - break; - } switch (rp->rip_vers) { - - case 1: - case 2: + case 0: + /* RFC 1058 */ + printf(" RIPv0: "); + rip_printblk((u_char *)&ni->rip_family, + (u_char *)&ni->rip_metric + + sizeof(ni->rip_metric)); break; - default: - printf(" [vers %d]", rp->rip_vers); - break; + switch (rp->rip_cmd) { + case RIPCMD_REQUEST: + printf(" RIPv%d-req %d", rp->rip_vers, length); + break; + case RIPCMD_RESPONSE: + j = length / sizeof(*ni); + if (j * sizeof(*ni) != length - 4) + printf(" RIPv%d-resp [items %d] [%d]:", + rp->rip_vers, j, length); + else + printf(" RIPv%d-resp [items %d]:", + rp->rip_vers, j); + trunc = (i / sizeof(*ni)) != j; + ni = (struct rip_netinfo *)(rp + 1); + for (; (i -= sizeof(*ni)) >= 0; ++ni) { + if (rp->rip_vers == 1) + rip_entry_print_v1(rp->rip_vers, ni); + else + rip_entry_print_v2(rp->rip_vers, ni); + } + if (trunc) + printf("[|rip]"); + break; + case RIPCMD_TRACEON: + printf(" RIPv%d-traceon %d: \"", rp->rip_vers, length); + (void)fn_print((const u_char *)(rp + 1), snapend); + fputs("\"\n", stdout); + break; + case RIPCMD_TRACEOFF: + printf(" RIPv%d-traceoff %d", rp->rip_vers, length); + break; + case RIPCMD_POLL: + printf(" RIPv%d-poll %d", rp->rip_vers, length); + break; + case RIPCMD_POLLENTRY: + printf(" RIPv%d-pollentry %d", rp->rip_vers, length); + break; + default: + printf(" RIPv%d-#%d %d", rp->rip_vers, rp->rip_cmd, + length); + break; + } } } |