/*
 * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1996
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef lint
static const char rcsid[] =
    "@(#) $Header: /tcpdump/master/tcpdump/print-rip.c,v 1.51 2002-09-05 00:00:18 guy Exp $ (LBL)";
#endif

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <tcpdump-stdinc.h>

#include <stdio.h>
#include <string.h>

#include "interface.h"
#include "addrtoname.h"
#include "extract.h"			/* must come after interface.h */

struct rip {
	u_char rip_cmd;			/* request/response */
	u_char rip_vers;		/* protocol version # */
	u_short rip_zero2;		/* unused */
};
#define	RIPCMD_REQUEST		1	/* want info */
#define	RIPCMD_RESPONSE		2	/* responding to request */
#define	RIPCMD_TRACEON		3	/* turn tracing on */
#define	RIPCMD_TRACEOFF		4	/* turn it off */
#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;
	u_int32_t rip_dest;
	u_int32_t rip_dest_mask;
	u_int32_t rip_router;
	u_int32_t rip_metric;		/* cost of route */
};

static void
rip_printblk(const u_char *cp, const u_char *ep)
{
	for (; cp < ep; cp += 2)
		printf(" %04x", EXTRACT_16BITS(cp));
	return;
}

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));
}

static void
rip_entry_print_v2(register int vers, register const struct rip_netinfo *ni)
{
	register u_char *p;
	register u_short family;
	u_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("]");
		return;
	} else { /* AF_INET */
		printf(" {%s", ipaddr_string(&ni->rip_dest));
		if (ni->rip_dest_mask)
			printf("/%s", ipaddr_string(&ni->rip_dest_mask));
		if (ni->rip_router)
			printf("->%s", ipaddr_string(&ni->rip_router));
		if (ni->rip_tag)
			printf(" tag %04x", EXTRACT_16BITS(&ni->rip_tag));
		printf("}(%d)", EXTRACT_32BITS(&ni->rip_metric));
	}
}

void
rip_print(const u_char *dat, u_int length)
{
	register const struct rip *rp;
	register const struct rip_netinfo *ni;
	register u_int i, j;
	register int trunc;

	if (snapend < dat) {
		printf(" [|rip]");
		return;
	}
	i = snapend - dat;
	if (i > length)
		i = length;
	if (i < sizeof(*rp)) {
		printf(" [|rip]");
		return;
	}
	i -= sizeof(*rp);

	rp = (struct rip *)dat;
	switch (rp->rip_vers) {
	case 0:
		/*
		 * RFC 1058.
		 *
		 * XXX - RFC 1058 says
		 *
		 * 0  Datagrams whose version number is zero are to be ignored.
		 *    These are from a previous version of the protocol, whose
		 *    packet format was machine-specific.
		 *
		 * so perhaps we should just dump the first few words of
		 * the packet, in hex.
		 */
		printf(" RIPv0: ");
		ni = (struct rip_netinfo *)(rp + 1);
		rip_printblk((u_char *)&ni->rip_family,
			     (u_char *)&ni->rip_metric +
			     sizeof(ni->rip_metric));
		break;
	default:
		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) + 4 != length)
				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); ++ni) {
				if (rp->rip_vers == 1)
					rip_entry_print_v1(rp->rip_vers, ni);
				else
					rip_entry_print_v2(rp->rip_vers, ni);
				i -= sizeof(*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("\"", 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;
		}
	}
}
