]> The Tcpdump Group git mirrors - tcpdump/commitdiff
improve RIPv0/v1/v2 handling. from openbsd-current
authoritojun <itojun>
Sun, 18 Jun 2000 17:41:35 +0000 (17:41 +0000)
committeritojun <itojun>
Sun, 18 Jun 2000 17:41:35 +0000 (17:41 +0000)
print-rip.c

index e66146bc5552cdc37ecebe74a485aa06f7e62b66..8d5363f030e12b5baf696a004f627dc3464a1b39 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-rip.c,v 1.40 1999-11-22 04:24:28 fenner Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-rip.c,v 1.41 2000-06-18 17:41:35 itojun Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -57,6 +57,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;
@@ -67,23 +69,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));
@@ -91,9 +153,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
@@ -110,56 +171,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;
+               }
         }
 }