Merge remote-tracking branch 'goog/tcpdump'

* goog/tcpdump: (3066 commits)
  Remove old version. Getting ready for new tcpdump 4.5
  Support -Q for setting the capture direction.
  Clean up the TLV processing loop.
  With -A and -AA, don't send CRs to the standard output.
  Use the new libpcap <pcap/nflog.h> for NFLOG definitions and declarations.
  Do our own isascii(), isprint(), isgraph(), and toascii().
  Fix a compiler warning.
  Don't use the __attribute__((packed)) on most platforms.
  The interval in an AODV HELLO extension is not aligned on a 4-byte boundary.
  As with memcpy, so with memcmp.
  More UNALIGNED_MEM{CPY,CMP} on IP addresses.
  Another case where UNALIGNED_MEMCPY() is probably necessary.
  No need for casting back and forth.
  Only do the unaligned_mem{cpy,cmp} hack if necessary.
  No need to declare unaligned_mem{cpy,cmp} in netdissect.h *and* interface.h.
  More possibly-unaligned memcpy()s and assignments - use unaligned_memcpy().
  Check for compiling for IPv6; don't check whether we can create an IPv6 socket.
  Use unaligned_memcmp() to compare with IPv{4,6} addresses in a packet.
  Use EXTRACT_nBITS even when just testing against zero.
  Fix some more unaligned accesses.
  ...

Change-Id: I9e98707d30c989b9e32dcd5af798bd0746ab4434
diff --git a/print-rip.c b/print-rip.c
index 772a2e0..c753a92 100644
--- a/print-rip.c
+++ b/print-rip.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-rip.c,v 1.57 2003/11/16 09:36:34 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-rip.c,v 1.59 2006-03-23 14:58:44 hannes Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -37,6 +37,8 @@
 #include "addrtoname.h"
 #include "extract.h"			/* must come after interface.h */
 
+#include "af.h"
+
 struct rip {
 	u_int8_t rip_cmd;		/* request/response */
 	u_int8_t rip_vers;		/* protocol version # */
@@ -100,8 +102,8 @@
 
 	/* RFC 1058 */
 	family = EXTRACT_16BITS(&ni->rip_family);
-	if (family != AF_INET) {
-		printf("\n\t AFI: %u:", family);
+	if (family != BSD_AFNUM_INET && family != 0) {
+		printf("\n\t AFI %s, ", tok2str(bsd_af_values, "Unknown (%u)", family));
                 print_unknown_data((u_int8_t *)&ni->rip_family,"\n\t  ",RIP_ROUTELEN);
 		return;
 	}
@@ -111,40 +113,55 @@
 		/* MBZ fields not zero */
                 print_unknown_data((u_int8_t *)&ni->rip_family,"\n\t  ",RIP_ROUTELEN);
 		return;
-	} /* AF_INET */
+	}
+	if (family == 0) {
+		printf("\n\t  AFI 0, %s, metric: %u",
+			ipaddr_string(&ni->rip_dest),
+			EXTRACT_32BITS(&ni->rip_metric));
+		return;
+	} /* BSD_AFNUM_INET */
 	printf("\n\t  %s, metric: %u",
                ipaddr_string(&ni->rip_dest),
 	       EXTRACT_32BITS(&ni->rip_metric));
 }
 
-static void
-rip_entry_print_v2(register const struct rip_netinfo *ni)
+static unsigned
+rip_entry_print_v2(register const struct rip_netinfo *ni, const unsigned remaining)
 {
-	register u_char *p;
 	register u_short family;
-	u_char buf[RIP_AUTHLEN];
 
 	family = EXTRACT_16BITS(&ni->rip_family);
-	if (family == 0xFFFF) { /* 16 bytes authentication ? */
-                if (EXTRACT_16BITS(&ni->rip_tag) == 2) { /* simple text authentication ? */
-			memcpy(buf, &ni->rip_dest, sizeof(buf));
-			buf[sizeof(buf)-1] = '\0';
-			for (p = buf; *p; p++) {
-				if (!isprint(*p))
-					break;
-			}
-                        printf("\n\t  Simple Text Authentication data: %s", buf);
+	if (family == 0xFFFF) { /* variable-sized authentication structures */
+		u_int16_t auth_type = EXTRACT_16BITS(&ni->rip_tag);
+		if (auth_type == 2) {
+			register u_char *p = (u_char *)&ni->rip_dest;
+			u_int i = 0;
+			printf("\n\t  Simple Text Authentication data: ");
+			for (; i < RIP_AUTHLEN; p++, i++)
+				putchar (ND_ISPRINT(*p) ? *p : '.');
+		} else if (auth_type == 3) {
+			printf("\n\t  Auth header:");
+			printf(" Packet Len %u,", EXTRACT_16BITS((u_int8_t *)ni + 4));
+			printf(" Key-ID %u,", *((u_int8_t *)ni + 6));
+			printf(" Auth Data Len %u,", *((u_int8_t *)ni + 7));
+			printf(" SeqNo %u,", EXTRACT_32BITS(&ni->rip_dest_mask));
+			printf(" MBZ %u,", EXTRACT_32BITS(&ni->rip_router));
+			printf(" MBZ %u", EXTRACT_32BITS(&ni->rip_metric));
+		} else if (auth_type == 1) {
+			printf("\n\t  Auth trailer:");
+			print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t  ",remaining);
+			return remaining; /* AT spans till the packet end */
                 } else {
 			printf("\n\t  Unknown (%u) Authentication data:",
 			       EXTRACT_16BITS(&ni->rip_tag));
-                        print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t  ",RIP_AUTHLEN);
+			print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t  ",remaining);
 		}
-	} else if (family != AF_INET) {
-		printf("\n\t  AFI: %u", family);
+	} else if (family != BSD_AFNUM_INET && family != 0) {
+		printf("\n\t  AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family));
                 print_unknown_data((u_int8_t *)&ni->rip_tag,"\n\t  ",RIP_ROUTELEN-2);
-		return;
-	} else { /* AF_INET */
-		printf("\n\t  AFI: IPv4: %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ",
+	} else { /* BSD_AFNUM_INET or AFI 0 */
+		printf("\n\t  AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ",
+                       tok2str(bsd_af_values, "%u", family),
                        ipaddr_string(&ni->rip_dest),
 		       mask2plen(EXTRACT_32BITS(&ni->rip_dest_mask)),
                        EXTRACT_16BITS(&ni->rip_tag),
@@ -154,6 +171,7 @@
                 else
                     printf("self");
 	}
+	return sizeof (*ni);
 }
 
 void
@@ -162,7 +180,6 @@
 	register const struct rip *rp;
 	register const struct rip_netinfo *ni;
 	register u_int i, j;
-	register int trunc;
 
 	if (snapend < dat) {
 		printf(" [|rip]");
@@ -210,25 +227,26 @@
                     return;
 
 		switch (rp->rip_cmd) {
+		case RIPCMD_REQUEST:
 		case RIPCMD_RESPONSE:
 			j = length / sizeof(*ni);
-                        printf(", routes: %u",j);
-			trunc = (i / sizeof(*ni)) != j;
+                        printf(", routes: %u%s", j, rp->rip_vers == 2 ? " or less" : "");
 			ni = (struct rip_netinfo *)(rp + 1);
 			for (; i >= sizeof(*ni); ++ni) {
 				if (rp->rip_vers == 1)
+				{
 					rip_entry_print_v1(ni);
+					i -= sizeof(*ni);
+				}
 				else if (rp->rip_vers == 2)
-					rip_entry_print_v2(ni);
+					i -= rip_entry_print_v2(ni, i);
                                 else
                                     break;
-				i -= sizeof(*ni);
 			}
-			if (trunc)
+			if (i)
 				printf("[|rip]");
 			break;
 
-		case RIPCMD_REQUEST:
 		case RIPCMD_TRACEOFF:
 		case RIPCMD_POLL:
 		case RIPCMD_POLLENTRY: