summaryrefslogtreecommitdiffstats
path: root/usr.sbin/tcpdump/print-rip.c
diff options
context:
space:
mode:
authorjakob <jakob@openbsd.org>2000-06-18 09:39:28 +0000
committerjakob <jakob@openbsd.org>2000-06-18 09:39:28 +0000
commitc57674051a2fabbddb550e0d7eb7fcc70e309c3f (patch)
tree7cada495aa5166dca868590498a4b04e124827a0 /usr.sbin/tcpdump/print-rip.c
parentRegister software Rijndael. (diff)
downloadwireguard-openbsd-c57674051a2fabbddb550e0d7eb7fcc70e309c3f.tar.xz
wireguard-openbsd-c57674051a2fabbddb550e0d7eb7fcc70e309c3f.zip
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.c189
1 files changed, 125 insertions, 64 deletions
diff --git a/usr.sbin/tcpdump/print-rip.c b/usr.sbin/tcpdump/print-rip.c
index 818c13b3aa8..bb746dcdb38 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: /home/cvs/src/usr.sbin/tcpdump/print-rip.c,v 1.6 2000/04/26 21:35:42 jakob Exp $ (LBL)";
+ "@(#) $Header: /home/cvs/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;
+ }
}
}