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
22276788Sdelphij#define NETDISSECT_REWORKED
2356893Sfenner#ifdef HAVE_CONFIG_H
2456893Sfenner#include "config.h"
2556893Sfenner#endif
2656893Sfenner
2756893Sfenner#ifdef INET6
2856893Sfenner
29127668Sbms#include <tcpdump-stdinc.h>
3056893Sfenner
3156893Sfenner#include "interface.h"
3256893Sfenner#include "addrtoname.h"
33127668Sbms#include "extract.h"
3456893Sfenner
35276788Sdelphij/*
36276788Sdelphij * Copyright (C) 1995, 1996, 1997 and 1998 WIDE Project.
37276788Sdelphij * All rights reserved.
38276788Sdelphij *
39276788Sdelphij * Redistribution and use in source and binary forms, with or without
40276788Sdelphij * modification, are permitted provided that the following conditions
41276788Sdelphij * are met:
42276788Sdelphij * 1. Redistributions of source code must retain the above copyright
43276788Sdelphij *    notice, this list of conditions and the following disclaimer.
44276788Sdelphij * 2. Redistributions in binary form must reproduce the above copyright
45276788Sdelphij *    notice, this list of conditions and the following disclaimer in the
46276788Sdelphij *    documentation and/or other materials provided with the distribution.
47276788Sdelphij * 3. Neither the name of the project nor the names of its contributors
48276788Sdelphij *    may be used to endorse or promote products derived from this software
49276788Sdelphij *    without specific prior written permission.
50276788Sdelphij *
51276788Sdelphij * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
52276788Sdelphij * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53276788Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54276788Sdelphij * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
55276788Sdelphij * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56276788Sdelphij * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57276788Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58276788Sdelphij * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59276788Sdelphij * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60276788Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61276788Sdelphij * SUCH DAMAGE.
62276788Sdelphij */
63276788Sdelphij#define	RIP6_VERSION	1
64276788Sdelphij
65276788Sdelphij#define	RIP6_REQUEST	1
66276788Sdelphij#define	RIP6_RESPONSE	2
67276788Sdelphij
68276788Sdelphijstruct netinfo6 {
69276788Sdelphij	struct in6_addr	rip6_dest;
70276788Sdelphij	uint16_t	rip6_tag;
71276788Sdelphij	uint8_t		rip6_plen;
72276788Sdelphij	uint8_t		rip6_metric;
73276788Sdelphij};
74276788Sdelphij
75276788Sdelphijstruct	rip6 {
76276788Sdelphij	uint8_t		rip6_cmd;
77276788Sdelphij	uint8_t		rip6_vers;
78276788Sdelphij	uint8_t		rip6_res1[2];
79276788Sdelphij	union {
80276788Sdelphij		struct	netinfo6	ru6_nets[1];
81276788Sdelphij		char	ru6_tracefile[1];
82276788Sdelphij	} rip6un;
83276788Sdelphij#define	rip6_nets	rip6un.ru6_nets
84276788Sdelphij#define	rip6_tracefile	rip6un.ru6_tracefile
85276788Sdelphij};
86276788Sdelphij
87276788Sdelphij#define	HOPCNT_INFINITY6	16
88276788Sdelphij
89146773Ssam#if !defined(IN6_IS_ADDR_UNSPECIFIED) && !defined(_MSC_VER) /* MSVC inline */
90146773Ssamstatic int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *addr)
91146773Ssam{
92146773Ssam    static const struct in6_addr in6addr_any;        /* :: */
93146773Ssam    return (memcmp(addr, &in6addr_any, sizeof(*addr)) == 0);
94146773Ssam}
95146773Ssam#endif
96146773Ssam
9756893Sfennerstatic int
98276788Sdelphijrip6_entry_print(netdissect_options *ndo, register const struct netinfo6 *ni, int metric)
9956893Sfenner{
10056893Sfenner	int l;
101276788Sdelphij	l = ND_PRINT((ndo, "%s/%d", ip6addr_string(ndo, &ni->rip6_dest), ni->rip6_plen));
10256893Sfenner	if (ni->rip6_tag)
103276788Sdelphij		l += ND_PRINT((ndo, " [%d]", EXTRACT_16BITS(&ni->rip6_tag)));
10456893Sfenner	if (metric)
105276788Sdelphij		l += ND_PRINT((ndo, " (%d)", ni->rip6_metric));
10656893Sfenner	return l;
10756893Sfenner}
10856893Sfenner
10956893Sfennervoid
110276788Sdelphijripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length)
11156893Sfenner{
11256893Sfenner	register const struct rip6 *rp = (struct rip6 *)dat;
11356893Sfenner	register const struct netinfo6 *ni;
114127668Sbms	register u_int amt;
115127668Sbms	register u_int i;
11656893Sfenner	int j;
11756893Sfenner	int trunc;
11856893Sfenner
119276788Sdelphij	if (ndo->ndo_snapend < dat)
12056893Sfenner		return;
121276788Sdelphij	amt = ndo->ndo_snapend - dat;
122127668Sbms	i = min(length, amt);
123127668Sbms	if (i < (sizeof(struct rip6) - sizeof(struct netinfo6)))
124127668Sbms		return;
125127668Sbms	i -= (sizeof(struct rip6) - sizeof(struct netinfo6));
12656893Sfenner
12756893Sfenner	switch (rp->rip6_cmd) {
12856893Sfenner
12956893Sfenner	case RIP6_REQUEST:
13056893Sfenner		j = length / sizeof(*ni);
13156893Sfenner		if (j == 1
13256893Sfenner		    &&  rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
13356893Sfenner		    &&  IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
134276788Sdelphij			ND_PRINT((ndo, " ripng-req dump"));
13556893Sfenner			break;
13656893Sfenner		}
13756893Sfenner		if (j * sizeof(*ni) != length - 4)
138276788Sdelphij			ND_PRINT((ndo, " ripng-req %d[%u]:", j, length));
13956893Sfenner		else
140276788Sdelphij			ND_PRINT((ndo, " ripng-req %d:", j));
14156893Sfenner		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
142127668Sbms		for (ni = rp->rip6_nets; i >= sizeof(*ni);
143127668Sbms		    i -= sizeof(*ni), ++ni) {
144276788Sdelphij			if (ndo->ndo_vflag > 1)
145276788Sdelphij				ND_PRINT((ndo, "\n\t"));
14656893Sfenner			else
147276788Sdelphij				ND_PRINT((ndo, " "));
148276788Sdelphij			rip6_entry_print(ndo, ni, 0);
14956893Sfenner		}
15056893Sfenner		break;
15156893Sfenner	case RIP6_RESPONSE:
15256893Sfenner		j = length / sizeof(*ni);
15356893Sfenner		if (j * sizeof(*ni) != length - 4)
154276788Sdelphij			ND_PRINT((ndo, " ripng-resp %d[%u]:", j, length));
15556893Sfenner		else
156276788Sdelphij			ND_PRINT((ndo, " ripng-resp %d:", j));
15756893Sfenner		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
158127668Sbms		for (ni = rp->rip6_nets; i >= sizeof(*ni);
159127668Sbms		    i -= sizeof(*ni), ++ni) {
160276788Sdelphij			if (ndo->ndo_vflag > 1)
161276788Sdelphij				ND_PRINT((ndo, "\n\t"));
16256893Sfenner			else
163276788Sdelphij				ND_PRINT((ndo, " "));
164276788Sdelphij			rip6_entry_print(ndo, ni, ni->rip6_metric);
16556893Sfenner		}
16656893Sfenner		if (trunc)
167276788Sdelphij			ND_PRINT((ndo, "[|ripng]"));
16856893Sfenner		break;
16956893Sfenner	default:
170276788Sdelphij		ND_PRINT((ndo, " ripng-%d ?? %u", rp->rip6_cmd, length));
17156893Sfenner		break;
17256893Sfenner	}
17356893Sfenner	if (rp->rip6_vers != RIP6_VERSION)
174276788Sdelphij		ND_PRINT((ndo, " [vers %d]", rp->rip6_vers));
17556893Sfenner}
17656893Sfenner#endif /* INET6 */
177