156893Sfenner/*
256893Sfenner * Copyright (c) 1989, 1990, 1991, 1993, 1994
356893Sfenner *	The Regents of the University of California.  All rights reserved.
456893Sfenner *
556893Sfenner * Redistribution and use in source and binary forms, with or without
656893Sfenner * modification, are permitted provided that: (1) source code distributions
756893Sfenner * retain the above copyright notice and this paragraph in its entirety, (2)
856893Sfenner * distributions including binary code include the above copyright notice and
956893Sfenner * this paragraph in its entirety in the documentation or other materials
1056893Sfenner * provided with the distribution, and (3) all advertising materials mentioning
1156893Sfenner * features or use of this software display the following acknowledgement:
1256893Sfenner * ``This product includes software developed by the University of California,
1356893Sfenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1456893Sfenner * the University nor the names of its contributors may be used to endorse
1556893Sfenner * or promote products derived from this software without specific prior
1656893Sfenner * written permission.
1756893Sfenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1856893Sfenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1956893Sfenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2056893Sfenner */
2156893Sfenner
2256893Sfenner#ifndef lint
23127668Sbmsstatic const char rcsid[] _U_ =
24190207Srpaulo    "@(#) $Header: /tcpdump/master/tcpdump/print-ripng.c,v 1.18 2005-01-04 00:15:54 guy Exp $";
2556893Sfenner#endif
2656893Sfenner
2756893Sfenner#ifdef HAVE_CONFIG_H
2856893Sfenner#include "config.h"
2956893Sfenner#endif
3056893Sfenner
3156893Sfenner#ifdef INET6
3256893Sfenner
33127668Sbms#include <tcpdump-stdinc.h>
3456893Sfenner#include <stdio.h>
3556893Sfenner
3656893Sfenner#include "route6d.h"
3756893Sfenner#include "interface.h"
3856893Sfenner#include "addrtoname.h"
39127668Sbms#include "extract.h"
4056893Sfenner
41146773Ssam#if !defined(IN6_IS_ADDR_UNSPECIFIED) && !defined(_MSC_VER) /* MSVC inline */
42146773Ssamstatic int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *addr)
43146773Ssam{
44146773Ssam    static const struct in6_addr in6addr_any;        /* :: */
45146773Ssam    return (memcmp(addr, &in6addr_any, sizeof(*addr)) == 0);
46146773Ssam}
47146773Ssam#endif
48146773Ssam
4956893Sfennerstatic int
5056893Sfennerrip6_entry_print(register const struct netinfo6 *ni, int metric)
5156893Sfenner{
5256893Sfenner	int l;
5356893Sfenner	l = printf("%s/%d", ip6addr_string(&ni->rip6_dest), ni->rip6_plen);
5456893Sfenner	if (ni->rip6_tag)
55127668Sbms		l += printf(" [%d]", EXTRACT_16BITS(&ni->rip6_tag));
5656893Sfenner	if (metric)
5756893Sfenner		l += printf(" (%d)", ni->rip6_metric);
5856893Sfenner	return l;
5956893Sfenner}
6056893Sfenner
6156893Sfennervoid
6298524Sfennerripng_print(const u_char *dat, unsigned int length)
6356893Sfenner{
6456893Sfenner	register const struct rip6 *rp = (struct rip6 *)dat;
6556893Sfenner	register const struct netinfo6 *ni;
66127668Sbms	register u_int amt;
67127668Sbms	register u_int i;
6856893Sfenner	int j;
6956893Sfenner	int trunc;
7056893Sfenner
71127668Sbms	if (snapend < dat)
7256893Sfenner		return;
73127668Sbms	amt = snapend - dat;
74127668Sbms	i = min(length, amt);
75127668Sbms	if (i < (sizeof(struct rip6) - sizeof(struct netinfo6)))
76127668Sbms		return;
77127668Sbms	i -= (sizeof(struct rip6) - sizeof(struct netinfo6));
7856893Sfenner
7956893Sfenner	switch (rp->rip6_cmd) {
8056893Sfenner
8156893Sfenner	case RIP6_REQUEST:
8256893Sfenner		j = length / sizeof(*ni);
8356893Sfenner		if (j == 1
8456893Sfenner		    &&  rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
8556893Sfenner		    &&  IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
8656893Sfenner			printf(" ripng-req dump");
8756893Sfenner			break;
8856893Sfenner		}
8956893Sfenner		if (j * sizeof(*ni) != length - 4)
9098524Sfenner			printf(" ripng-req %d[%u]:", j, length);
9156893Sfenner		else
9256893Sfenner			printf(" ripng-req %d:", j);
9356893Sfenner		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
94127668Sbms		for (ni = rp->rip6_nets; i >= sizeof(*ni);
95127668Sbms		    i -= sizeof(*ni), ++ni) {
9698524Sfenner			if (vflag > 1)
9756893Sfenner				printf("\n\t");
9856893Sfenner			else
9956893Sfenner				printf(" ");
10056893Sfenner			rip6_entry_print(ni, 0);
10156893Sfenner		}
10256893Sfenner		break;
10356893Sfenner	case RIP6_RESPONSE:
10456893Sfenner		j = length / sizeof(*ni);
10556893Sfenner		if (j * sizeof(*ni) != length - 4)
10698524Sfenner			printf(" ripng-resp %d[%u]:", j, length);
10756893Sfenner		else
10856893Sfenner			printf(" ripng-resp %d:", j);
10956893Sfenner		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
110127668Sbms		for (ni = rp->rip6_nets; i >= sizeof(*ni);
111127668Sbms		    i -= sizeof(*ni), ++ni) {
11298524Sfenner			if (vflag > 1)
11356893Sfenner				printf("\n\t");
11456893Sfenner			else
11556893Sfenner				printf(" ");
11656893Sfenner			rip6_entry_print(ni, ni->rip6_metric);
11756893Sfenner		}
11856893Sfenner		if (trunc)
11998524Sfenner			printf("[|ripng]");
12056893Sfenner		break;
12156893Sfenner	default:
12298524Sfenner		printf(" ripng-%d ?? %u", rp->rip6_cmd, length);
12356893Sfenner		break;
12456893Sfenner	}
12556893Sfenner	if (rp->rip6_vers != RIP6_VERSION)
12656893Sfenner		printf(" [vers %d]", rp->rip6_vers);
12756893Sfenner}
12856893Sfenner#endif /* INET6 */
129