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
22313537Sglebius/* \summary: IPv6 Routing Information Protocol (RIPng) printer */
23313537Sglebius
2456893Sfenner#ifdef HAVE_CONFIG_H
2556893Sfenner#include "config.h"
2656893Sfenner#endif
2756893Sfenner
28313537Sglebius#include <netdissect-stdinc.h>
2956893Sfenner
30313537Sglebius#include "netdissect.h"
3156893Sfenner#include "addrtoname.h"
32127668Sbms#include "extract.h"
3356893Sfenner
34276788Sdelphij/*
35276788Sdelphij * Copyright (C) 1995, 1996, 1997 and 1998 WIDE Project.
36276788Sdelphij * All rights reserved.
37276788Sdelphij *
38276788Sdelphij * Redistribution and use in source and binary forms, with or without
39276788Sdelphij * modification, are permitted provided that the following conditions
40276788Sdelphij * are met:
41276788Sdelphij * 1. Redistributions of source code must retain the above copyright
42276788Sdelphij *    notice, this list of conditions and the following disclaimer.
43276788Sdelphij * 2. Redistributions in binary form must reproduce the above copyright
44276788Sdelphij *    notice, this list of conditions and the following disclaimer in the
45276788Sdelphij *    documentation and/or other materials provided with the distribution.
46276788Sdelphij * 3. Neither the name of the project nor the names of its contributors
47276788Sdelphij *    may be used to endorse or promote products derived from this software
48276788Sdelphij *    without specific prior written permission.
49276788Sdelphij *
50276788Sdelphij * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
51276788Sdelphij * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52276788Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53276788Sdelphij * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
54276788Sdelphij * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55276788Sdelphij * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56276788Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57276788Sdelphij * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58276788Sdelphij * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59276788Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60276788Sdelphij * SUCH DAMAGE.
61276788Sdelphij */
62276788Sdelphij#define	RIP6_VERSION	1
63276788Sdelphij
64276788Sdelphij#define	RIP6_REQUEST	1
65276788Sdelphij#define	RIP6_RESPONSE	2
66276788Sdelphij
67276788Sdelphijstruct netinfo6 {
68276788Sdelphij	struct in6_addr	rip6_dest;
69276788Sdelphij	uint16_t	rip6_tag;
70276788Sdelphij	uint8_t		rip6_plen;
71276788Sdelphij	uint8_t		rip6_metric;
72276788Sdelphij};
73276788Sdelphij
74276788Sdelphijstruct	rip6 {
75276788Sdelphij	uint8_t		rip6_cmd;
76276788Sdelphij	uint8_t		rip6_vers;
77276788Sdelphij	uint8_t		rip6_res1[2];
78276788Sdelphij	union {
79276788Sdelphij		struct	netinfo6	ru6_nets[1];
80276788Sdelphij		char	ru6_tracefile[1];
81276788Sdelphij	} rip6un;
82276788Sdelphij#define	rip6_nets	rip6un.ru6_nets
83276788Sdelphij#define	rip6_tracefile	rip6un.ru6_tracefile
84276788Sdelphij};
85276788Sdelphij
86276788Sdelphij#define	HOPCNT_INFINITY6	16
87276788Sdelphij
88146773Ssam#if !defined(IN6_IS_ADDR_UNSPECIFIED) && !defined(_MSC_VER) /* MSVC inline */
89146773Ssamstatic int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *addr)
90146773Ssam{
91146773Ssam    static const struct in6_addr in6addr_any;        /* :: */
92146773Ssam    return (memcmp(addr, &in6addr_any, sizeof(*addr)) == 0);
93146773Ssam}
94146773Ssam#endif
95146773Ssam
9656893Sfennerstatic int
97276788Sdelphijrip6_entry_print(netdissect_options *ndo, register const struct netinfo6 *ni, int metric)
9856893Sfenner{
9956893Sfenner	int l;
100276788Sdelphij	l = ND_PRINT((ndo, "%s/%d", ip6addr_string(ndo, &ni->rip6_dest), ni->rip6_plen));
10156893Sfenner	if (ni->rip6_tag)
102276788Sdelphij		l += ND_PRINT((ndo, " [%d]", EXTRACT_16BITS(&ni->rip6_tag)));
10356893Sfenner	if (metric)
104276788Sdelphij		l += ND_PRINT((ndo, " (%d)", ni->rip6_metric));
10556893Sfenner	return l;
10656893Sfenner}
10756893Sfenner
10856893Sfennervoid
109276788Sdelphijripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length)
11056893Sfenner{
111313537Sglebius	register const struct rip6 *rp = (const struct rip6 *)dat;
11256893Sfenner	register const struct netinfo6 *ni;
113327234Semaste	unsigned int length_left;
114327234Semaste	u_int j;
11556893Sfenner
116327234Semaste	ND_TCHECK(rp->rip6_cmd);
11756893Sfenner	switch (rp->rip6_cmd) {
11856893Sfenner
11956893Sfenner	case RIP6_REQUEST:
120327234Semaste		length_left = length;
121327234Semaste		if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6)))
122327234Semaste			goto trunc;
123327234Semaste		length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6));
124327234Semaste 		j = length_left / sizeof(*ni);
125327234Semaste		if (j == 1) {
126327234Semaste			ND_TCHECK(rp->rip6_nets);
127327234Semaste			if (rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
128327234Semaste			    &&  IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
129327234Semaste				ND_PRINT((ndo, " ripng-req dump"));
130327234Semaste				break;
131327234Semaste			}
13256893Sfenner		}
133327234Semaste		if (j * sizeof(*ni) != length_left)
134327234Semaste			ND_PRINT((ndo, " ripng-req %u[%u]:", j, length));
13556893Sfenner		else
136327234Semaste			ND_PRINT((ndo, " ripng-req %u:", j));
137327234Semaste		for (ni = rp->rip6_nets; length_left >= sizeof(*ni);
138327234Semaste		    length_left -= sizeof(*ni), ++ni) {
139327234Semaste			ND_TCHECK(*ni);
140276788Sdelphij			if (ndo->ndo_vflag > 1)
141276788Sdelphij				ND_PRINT((ndo, "\n\t"));
14256893Sfenner			else
143276788Sdelphij				ND_PRINT((ndo, " "));
144276788Sdelphij			rip6_entry_print(ndo, ni, 0);
14556893Sfenner		}
146327234Semaste		if (length_left != 0)
147327234Semaste			goto trunc;
14856893Sfenner		break;
14956893Sfenner	case RIP6_RESPONSE:
150327234Semaste		length_left = length;
151327234Semaste		if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6)))
152327234Semaste			goto trunc;
153327234Semaste		length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6));
154327234Semaste		j = length_left / sizeof(*ni);
155327234Semaste		if (j * sizeof(*ni) != length_left)
156276788Sdelphij			ND_PRINT((ndo, " ripng-resp %d[%u]:", j, length));
15756893Sfenner		else
158276788Sdelphij			ND_PRINT((ndo, " ripng-resp %d:", j));
159327234Semaste		for (ni = rp->rip6_nets; length_left >= sizeof(*ni);
160327234Semaste		    length_left -= sizeof(*ni), ++ni) {
161327234Semaste			ND_TCHECK(*ni);
162276788Sdelphij			if (ndo->ndo_vflag > 1)
163276788Sdelphij				ND_PRINT((ndo, "\n\t"));
16456893Sfenner			else
165276788Sdelphij				ND_PRINT((ndo, " "));
166276788Sdelphij			rip6_entry_print(ndo, ni, ni->rip6_metric);
16756893Sfenner		}
168327234Semaste		if (length_left != 0)
169327234Semaste			goto trunc;
17056893Sfenner		break;
17156893Sfenner	default:
172276788Sdelphij		ND_PRINT((ndo, " ripng-%d ?? %u", rp->rip6_cmd, length));
17356893Sfenner		break;
17456893Sfenner	}
175327234Semaste	ND_TCHECK(rp->rip6_vers);
17656893Sfenner	if (rp->rip6_vers != RIP6_VERSION)
177276788Sdelphij		ND_PRINT((ndo, " [vers %d]", rp->rip6_vers));
178327234Semaste	return;
179327234Semaste
180327234Semastetrunc:
181327234Semaste	ND_PRINT((ndo, "[|ripng]"));
182327234Semaste	return;
18356893Sfenner}
184