xref: /netbsd-src/external/bsd/tcpdump/dist/print-rip.c (revision 26ba0b503b498a5194a71ac319838b7f5497f3fe)
10f74e101Schristos /*
20f74e101Schristos  * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1996
30f74e101Schristos  *	The Regents of the University of California.  All rights reserved.
40f74e101Schristos  *
50f74e101Schristos  * Redistribution and use in source and binary forms, with or without
60f74e101Schristos  * modification, are permitted provided that: (1) source code distributions
70f74e101Schristos  * retain the above copyright notice and this paragraph in its entirety, (2)
80f74e101Schristos  * distributions including binary code include the above copyright notice and
90f74e101Schristos  * this paragraph in its entirety in the documentation or other materials
100f74e101Schristos  * provided with the distribution, and (3) all advertising materials mentioning
110f74e101Schristos  * features or use of this software display the following acknowledgement:
120f74e101Schristos  * ``This product includes software developed by the University of California,
130f74e101Schristos  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
140f74e101Schristos  * the University nor the names of its contributors may be used to endorse
150f74e101Schristos  * or promote products derived from this software without specific prior
160f74e101Schristos  * written permission.
170f74e101Schristos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
180f74e101Schristos  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
190f74e101Schristos  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
200f74e101Schristos  */
210f74e101Schristos 
2211b3aaa1Schristos #include <sys/cdefs.h>
230f74e101Schristos #ifndef lint
24*26ba0b50Schristos __RCSID("$NetBSD: print-rip.c,v 1.10 2024/09/02 16:15:32 christos Exp $");
250f74e101Schristos #endif
260f74e101Schristos 
27dc860a36Sspz /* \summary: Routing Information Protocol (RIP) printer */
28dc860a36Sspz 
29c74ad251Schristos /* specification: RFC 1058, RFC 2453, RFC 4822 */
30c74ad251Schristos 
31c74ad251Schristos #include <config.h>
320f74e101Schristos 
33c74ad251Schristos #include "netdissect-stdinc.h"
340f74e101Schristos 
35fdccd7e4Schristos #include "netdissect.h"
360f74e101Schristos #include "addrtoname.h"
37fdccd7e4Schristos #include "extract.h"
380f74e101Schristos 
390f74e101Schristos #include "af.h"
400f74e101Schristos 
41b3a00663Schristos 
42c74ad251Schristos /*
43c74ad251Schristos  * RFC 1058 and RFC 2453 header of packet.
44c74ad251Schristos  *
45c74ad251Schristos  *  0                   1                   2                   3 3
46c74ad251Schristos  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
47c74ad251Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48c74ad251Schristos  * | Command (1)   | Version (1)   |           unused              |
49c74ad251Schristos  * +---------------+---------------+-------------------------------+
50c74ad251Schristos  */
510f74e101Schristos struct rip {
52c74ad251Schristos 	nd_uint8_t rip_cmd;		/* request/response */
53c74ad251Schristos 	nd_uint8_t rip_vers;		/* protocol version # */
54c74ad251Schristos 	nd_byte    unused[2];		/* unused */
550f74e101Schristos };
560f74e101Schristos 
570f74e101Schristos #define	RIPCMD_REQUEST		1	/* want info */
580f74e101Schristos #define	RIPCMD_RESPONSE		2	/* responding to request */
590f74e101Schristos #define	RIPCMD_TRACEON		3	/* turn tracing on */
600f74e101Schristos #define	RIPCMD_TRACEOFF		4	/* turn it off */
61*26ba0b50Schristos /* 5 is reserved */
62*26ba0b50Schristos #define RIPCMD_TRIGREQ		6
63*26ba0b50Schristos #define RIPCMD_TRIGRESP		7
64*26ba0b50Schristos #define RIPCMD_TRIGACK		8
65*26ba0b50Schristos #define RIPCMD_UPDREQ		9
66*26ba0b50Schristos #define RIPCMD_UPDRESP		10
67*26ba0b50Schristos #define RIPCMD_UPDACK		11
680f74e101Schristos 
690f74e101Schristos static const struct tok rip_cmd_values[] = {
700f74e101Schristos     { RIPCMD_REQUEST,	        "Request" },
710f74e101Schristos     { RIPCMD_RESPONSE,	        "Response" },
720f74e101Schristos     { RIPCMD_TRACEON,	        "Trace on" },
730f74e101Schristos     { RIPCMD_TRACEOFF,	        "Trace off" },
74*26ba0b50Schristos     { RIPCMD_TRIGREQ,	        "Triggered Request" },
75*26ba0b50Schristos     { RIPCMD_TRIGRESP,	        "Triggered Response" },
76*26ba0b50Schristos     { RIPCMD_TRIGACK,	        "Triggered Acknowledgement" },
77*26ba0b50Schristos     { RIPCMD_UPDREQ,	        "Update Request" },
78*26ba0b50Schristos     { RIPCMD_UPDRESP,	        "Update Response" },
79*26ba0b50Schristos     { RIPCMD_UPDACK,	        "Update Acknowledge" },
800f74e101Schristos     { 0, NULL}
810f74e101Schristos };
820f74e101Schristos 
830f74e101Schristos #define RIP_AUTHLEN  16
840f74e101Schristos #define RIP_ROUTELEN 20
850f74e101Schristos 
860f74e101Schristos /*
87c74ad251Schristos  * First 4 bytes of all RIPv1/RIPv2 entries.
88c74ad251Schristos  */
89c74ad251Schristos struct rip_entry_header {
90c74ad251Schristos 	nd_uint16_t rip_family;
91c74ad251Schristos 	nd_uint16_t rip_tag;
92c74ad251Schristos };
93c74ad251Schristos 
94c74ad251Schristos /*
95c74ad251Schristos  * RFC 1058 entry.
960f74e101Schristos  *
970f74e101Schristos  *  0                   1                   2                   3 3
980f74e101Schristos  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
990f74e101Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
100c74ad251Schristos  * | Address Family Identifier (2) |       must be zero (2)        |
101c74ad251Schristos  * +-------------------------------+-------------------------------+
102c74ad251Schristos  * |                         IP Address (4)                        |
103c74ad251Schristos  * +---------------------------------------------------------------+
104c74ad251Schristos  * |                        must be zero (4)                       |
105c74ad251Schristos  * +---------------------------------------------------------------+
106c74ad251Schristos  * |                        must be zero (4)                       |
107c74ad251Schristos  * +---------------------------------------------------------------+
108c74ad251Schristos  * |                         Metric (4)                            |
109c74ad251Schristos  * +---------------------------------------------------------------+
110c74ad251Schristos  */
111c74ad251Schristos struct rip_netinfo_v1 {
112c74ad251Schristos 	nd_uint16_t rip_family;
113c74ad251Schristos 	nd_byte     rip_mbz1[2];
114c74ad251Schristos 	nd_ipv4     rip_dest;
115c74ad251Schristos 	nd_byte     rip_mbz2[4];
116c74ad251Schristos 	nd_byte     rip_mbz3[4];
117c74ad251Schristos 	nd_uint32_t rip_metric;		/* cost of route */
118c74ad251Schristos };
119c74ad251Schristos 
120c74ad251Schristos 
121c74ad251Schristos /*
122c74ad251Schristos  * RFC 2453 route entry
123c74ad251Schristos  *
124c74ad251Schristos  *  0                   1                   2                   3 3
125c74ad251Schristos  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
126c74ad251Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1270f74e101Schristos  * | Address Family Identifier (2) |        Route Tag (2)          |
1280f74e101Schristos  * +-------------------------------+-------------------------------+
1290f74e101Schristos  * |                         IP Address (4)                        |
1300f74e101Schristos  * +---------------------------------------------------------------+
1310f74e101Schristos  * |                         Subnet Mask (4)                       |
1320f74e101Schristos  * +---------------------------------------------------------------+
1330f74e101Schristos  * |                         Next Hop (4)                          |
1340f74e101Schristos  * +---------------------------------------------------------------+
1350f74e101Schristos  * |                         Metric (4)                            |
1360f74e101Schristos  * +---------------------------------------------------------------+
1370f74e101Schristos  *
1380f74e101Schristos  */
1390f74e101Schristos 
140c74ad251Schristos struct rip_netinfo_v2 {
141c74ad251Schristos 	nd_uint16_t rip_family;
142c74ad251Schristos 	nd_uint16_t rip_tag;
143c74ad251Schristos 	nd_ipv4     rip_dest;
144c74ad251Schristos 	nd_uint32_t rip_dest_mask;
145c74ad251Schristos 	nd_ipv4     rip_router;
146c74ad251Schristos 	nd_uint32_t rip_metric;		/* cost of route */
1470f74e101Schristos };
1480f74e101Schristos 
149c74ad251Schristos /*
150c74ad251Schristos  * RFC 2453 authentication entry
151c74ad251Schristos  *
152c74ad251Schristos  *  0                   1                   2                   3 3
153c74ad251Schristos  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
154c74ad251Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
155c74ad251Schristos  * |            0xFFFF             |    Authentication Type (2)    |
156c74ad251Schristos  * +-------------------------------+-------------------------------+
157c74ad251Schristos  * -                      Authentication (16)                      -
158c74ad251Schristos  * +---------------------------------------------------------------+
159c74ad251Schristos  */
160c74ad251Schristos 
161c74ad251Schristos struct rip_auth_v2 {
162c74ad251Schristos 	nd_uint16_t rip_family;
163c74ad251Schristos 	nd_uint16_t rip_tag;
164c74ad251Schristos 	nd_byte     rip_auth[16];
165c74ad251Schristos };
166c74ad251Schristos 
167c74ad251Schristos /*
168c74ad251Schristos  * RFC 4822 Cryptographic Authentication entry.
169c74ad251Schristos  *
170c74ad251Schristos  *  0                   1                   2                   3 3
171c74ad251Schristos  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
172c74ad251Schristos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
173c74ad251Schristos  * |     RIPv2 Packet Length       |   Key ID      | Auth Data Len |
174c74ad251Schristos  * +---------------+---------------+---------------+---------------+
175c74ad251Schristos  * |               Sequence Number (non-decreasing)                |
176c74ad251Schristos  * +---------------+---------------+---------------+---------------+
177c74ad251Schristos  * |                      reserved must be zero                    |
178c74ad251Schristos  * +---------------+---------------+---------------+---------------+
179c74ad251Schristos  * |                      reserved must be zero                    |
180c74ad251Schristos  * +---------------+---------------+---------------+---------------+
181c74ad251Schristos  */
182c74ad251Schristos struct rip_auth_crypto_v2 {
183c74ad251Schristos 	nd_uint16_t rip_packet_len;
184c74ad251Schristos 	nd_uint8_t  rip_key_id;
185c74ad251Schristos 	nd_uint8_t  rip_auth_data_len;
186c74ad251Schristos 	nd_uint32_t rip_seq_num;
187c74ad251Schristos 	nd_byte     rip_mbz1[4];
188c74ad251Schristos 	nd_byte     rip_mbz2[4];
189c74ad251Schristos };
190c74ad251Schristos 
191c74ad251Schristos static unsigned
192c74ad251Schristos rip_entry_print_v1(netdissect_options *ndo, const u_char *p,
193c74ad251Schristos 		   unsigned remaining)
1940f74e101Schristos {
195c74ad251Schristos 	const struct rip_entry_header *eh = (const struct rip_entry_header *)p;
196c74ad251Schristos 	u_short family;
197c74ad251Schristos 	const struct rip_netinfo_v1 *ni = (const struct rip_netinfo_v1 *)p;
1980f74e101Schristos 
1990f74e101Schristos 	/* RFC 1058 */
200c74ad251Schristos 	if (remaining < RIP_ROUTELEN)
201c74ad251Schristos 		return (0);
202c74ad251Schristos 	ND_TCHECK_SIZE(ni);
203c74ad251Schristos 	family = GET_BE_U_2(ni->rip_family);
204870189d2Schristos 	if (family != BSD_AFNUM_INET && family != 0) {
205c74ad251Schristos 		ND_PRINT("\n\t AFI %s, ", tok2str(bsd_af_values, "Unknown (%u)", family));
206c74ad251Schristos 		print_unknown_data(ndo, p + sizeof(*eh), "\n\t  ", RIP_ROUTELEN - sizeof(*eh));
207c74ad251Schristos 		return (RIP_ROUTELEN);
2080f74e101Schristos 	}
209c74ad251Schristos 	if (GET_BE_U_2(ni->rip_mbz1) ||
210c74ad251Schristos 	    GET_BE_U_4(ni->rip_mbz2) ||
211c74ad251Schristos 	    GET_BE_U_4(ni->rip_mbz3)) {
2120f74e101Schristos 		/* MBZ fields not zero */
213c74ad251Schristos 		print_unknown_data(ndo, p, "\n\t  ", RIP_ROUTELEN);
214c74ad251Schristos 		return (RIP_ROUTELEN);
215870189d2Schristos 	}
216870189d2Schristos 	if (family == 0) {
217c74ad251Schristos 		ND_PRINT("\n\t  AFI 0, %s, metric: %u",
218c74ad251Schristos 			 GET_IPADDR_STRING(ni->rip_dest),
219c74ad251Schristos 			 GET_BE_U_4(ni->rip_metric));
220c74ad251Schristos 		return (RIP_ROUTELEN);
2210f74e101Schristos 	} /* BSD_AFNUM_INET */
222c74ad251Schristos 	ND_PRINT("\n\t  %s, metric: %u",
223c74ad251Schristos 		 GET_IPADDR_STRING(ni->rip_dest),
224c74ad251Schristos 		 GET_BE_U_4(ni->rip_metric));
225c74ad251Schristos 	return (RIP_ROUTELEN);
226c74ad251Schristos trunc:
227c74ad251Schristos 	return 0;
2280f74e101Schristos }
2290f74e101Schristos 
230a8e08e94Skamil UNALIGNED_OK
231870189d2Schristos static unsigned
232c74ad251Schristos rip_entry_print_v2(netdissect_options *ndo, const u_char *p,
233c74ad251Schristos 		   unsigned remaining)
2340f74e101Schristos {
235c74ad251Schristos 	const struct rip_entry_header *eh = (const struct rip_entry_header *)p;
236c74ad251Schristos 	u_short family;
237c74ad251Schristos 	const struct rip_netinfo_v2 *ni;
2380f74e101Schristos 
239c74ad251Schristos 	if (remaining < sizeof(*eh))
240c74ad251Schristos 		return (0);
241c74ad251Schristos 	ND_TCHECK_SIZE(eh);
242c74ad251Schristos 	family = GET_BE_U_2(eh->rip_family);
243870189d2Schristos 	if (family == 0xFFFF) { /* variable-sized authentication structures */
244c74ad251Schristos 		uint16_t auth_type = GET_BE_U_2(eh->rip_tag);
245c74ad251Schristos 
246c74ad251Schristos 		p += sizeof(*eh);
247c74ad251Schristos 		remaining -= sizeof(*eh);
248870189d2Schristos 		if (auth_type == 2) {
249c74ad251Schristos 			ND_PRINT("\n\t  Simple Text Authentication data: ");
250c74ad251Schristos 			nd_printjnp(ndo, p, RIP_AUTHLEN);
251870189d2Schristos 		} else if (auth_type == 3) {
252c74ad251Schristos 			const struct rip_auth_crypto_v2 *ch;
253c74ad251Schristos 
254c74ad251Schristos 			ch = (const struct rip_auth_crypto_v2 *)p;
255c74ad251Schristos 			ND_TCHECK_SIZE(ch);
256c74ad251Schristos 			if (remaining < sizeof(*ch))
257c74ad251Schristos 				return (0);
258c74ad251Schristos 			ND_PRINT("\n\t  Auth header:");
259c74ad251Schristos 			ND_PRINT(" Packet Len %u,",
260c74ad251Schristos 				 GET_BE_U_2(ch->rip_packet_len));
261c74ad251Schristos 			ND_PRINT(" Key-ID %u,", GET_U_1(ch->rip_key_id));
262c74ad251Schristos 			ND_PRINT(" Auth Data Len %u,",
263c74ad251Schristos 				 GET_U_1(ch->rip_auth_data_len));
264c74ad251Schristos 			ND_PRINT(" SeqNo %u,", GET_BE_U_4(ch->rip_seq_num));
265c74ad251Schristos 			ND_PRINT(" MBZ %u,", GET_BE_U_4(ch->rip_mbz1));
266c74ad251Schristos 			ND_PRINT(" MBZ %u", GET_BE_U_4(ch->rip_mbz2));
267870189d2Schristos 		} else if (auth_type == 1) {
268c74ad251Schristos 			ND_PRINT("\n\t  Auth trailer:");
269c74ad251Schristos 			print_unknown_data(ndo, p, "\n\t  ", remaining);
270c74ad251Schristos 			return (sizeof(*eh) + remaining); /* AT spans till the packet end */
2710f74e101Schristos 		} else {
272c74ad251Schristos 			ND_PRINT("\n\t  Unknown (%u) Authentication data:",
273c74ad251Schristos 				 auth_type);
274c74ad251Schristos 			print_unknown_data(ndo, p, "\n\t  ", remaining);
275c74ad251Schristos 			return (sizeof(*eh) + remaining); /* we don't know how long this is, so we go to the packet end */
2760f74e101Schristos 		}
277870189d2Schristos 	} else if (family != BSD_AFNUM_INET && family != 0) {
278c74ad251Schristos 		ND_PRINT("\n\t  AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family));
279c74ad251Schristos 		print_unknown_data(ndo, p + sizeof(*eh), "\n\t  ", RIP_ROUTELEN - sizeof(*eh));
280870189d2Schristos 	} else { /* BSD_AFNUM_INET or AFI 0 */
281c74ad251Schristos 		ni = (const struct rip_netinfo_v2 *)p;
282c74ad251Schristos 		ND_TCHECK_SIZE(ni);
283c74ad251Schristos 		if (remaining < sizeof(*ni))
284c74ad251Schristos 			return (0);
285c74ad251Schristos 		ND_PRINT("\n\t  AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ",
286870189d2Schristos 			 tok2str(bsd_af_values, "%u", family),
287c74ad251Schristos 			 GET_IPADDR_STRING(ni->rip_dest),
288c74ad251Schristos 			 mask2plen(GET_BE_U_4(ni->rip_dest_mask)),
289c74ad251Schristos 			 GET_BE_U_2(ni->rip_tag),
290c74ad251Schristos 			 GET_BE_U_4(ni->rip_metric));
291c74ad251Schristos 		if (GET_BE_U_4(ni->rip_router))
292c74ad251Schristos 			ND_PRINT("%s", GET_IPADDR_STRING(ni->rip_router));
2930f74e101Schristos 		else
294c74ad251Schristos 			ND_PRINT("self");
2950f74e101Schristos 	}
296c74ad251Schristos 	return (RIP_ROUTELEN);
297c74ad251Schristos trunc:
298c74ad251Schristos 	return 0;
2990f74e101Schristos }
3000f74e101Schristos 
3010f74e101Schristos void
302b3a00663Schristos rip_print(netdissect_options *ndo,
303b3a00663Schristos 	  const u_char *dat, u_int length)
3040f74e101Schristos {
305c74ad251Schristos 	const struct rip *rp;
306c74ad251Schristos 	uint8_t vers, cmd;
307c74ad251Schristos 	const u_char *p;
308c74ad251Schristos 	u_int len, routecount;
309c74ad251Schristos 	unsigned entry_size;
3100f74e101Schristos 
311c74ad251Schristos 	ndo->ndo_protocol = "rip";
312b3a00663Schristos 	if (ndo->ndo_snapend < dat) {
313c74ad251Schristos 		nd_print_trunc(ndo);
3140f74e101Schristos 		return;
3150f74e101Schristos 	}
316c74ad251Schristos 	len = ND_BYTES_AVAILABLE_AFTER(dat);
317c74ad251Schristos 	if (len > length)
318c74ad251Schristos 		len = length;
319c74ad251Schristos 	if (len < sizeof(*rp)) {
320c74ad251Schristos 		nd_print_trunc(ndo);
3210f74e101Schristos 		return;
3220f74e101Schristos 	}
323c74ad251Schristos 	len -= sizeof(*rp);
3240f74e101Schristos 
325fdccd7e4Schristos 	rp = (const struct rip *)dat;
3260f74e101Schristos 
327c74ad251Schristos 	ND_TCHECK_SIZE(rp);
328c74ad251Schristos 	vers = GET_U_1(rp->rip_vers);
329c74ad251Schristos 	ND_PRINT("%sRIPv%u",
330b3a00663Schristos 		 (ndo->ndo_vflag >= 1) ? "\n\t" : "",
331c74ad251Schristos 		 vers);
3320f74e101Schristos 
3330f74e101Schristos 	/* dump version and lets see if we know the commands name*/
334c74ad251Schristos 	cmd = GET_U_1(rp->rip_cmd);
335c74ad251Schristos 	ND_PRINT(", %s, length: %u",
336c74ad251Schristos 		tok2str(rip_cmd_values, "unknown command (%u)", cmd),
337c74ad251Schristos 		length);
3380f74e101Schristos 
339b3a00663Schristos 	if (ndo->ndo_vflag < 1)
3400f74e101Schristos 		return;
3410f74e101Schristos 
342c74ad251Schristos 	switch (cmd) {
343c74ad251Schristos 
344870189d2Schristos 	case RIPCMD_REQUEST:
3450f74e101Schristos 	case RIPCMD_RESPONSE:
346c74ad251Schristos 		switch (vers) {
347c74ad251Schristos 
348c74ad251Schristos 		case 1:
349c74ad251Schristos 			routecount = length / RIP_ROUTELEN;
350c74ad251Schristos 			ND_PRINT(", routes: %u", routecount);
351c74ad251Schristos 			p = (const u_char *)(rp + 1);
352c74ad251Schristos 			while (len != 0) {
353c74ad251Schristos 				entry_size = rip_entry_print_v1(ndo, p, len);
354c74ad251Schristos 				if (entry_size == 0) {
355c74ad251Schristos 					/* Error */
356c74ad251Schristos 					nd_print_trunc(ndo);
357870189d2Schristos 					break;
358870189d2Schristos 				}
359c74ad251Schristos 				if (len < entry_size) {
360c74ad251Schristos 					ND_PRINT(" [remaining entries length %u < %u]",
361c74ad251Schristos 						 len, entry_size);
362c74ad251Schristos 					nd_print_invalid(ndo);
363c74ad251Schristos 					break;
364c74ad251Schristos 				}
365c74ad251Schristos 				p += entry_size;
366c74ad251Schristos 				len -= entry_size;
367c74ad251Schristos 			}
368c74ad251Schristos 			break;
369c74ad251Schristos 
370c74ad251Schristos 		case 2:
371c74ad251Schristos 			routecount = length / RIP_ROUTELEN;
372c74ad251Schristos 			ND_PRINT(", routes: %u or less", routecount);
373c74ad251Schristos 			p = (const u_char *)(rp + 1);
374c74ad251Schristos 			while (len != 0) {
375c74ad251Schristos 				entry_size = rip_entry_print_v2(ndo, p, len);
376c74ad251Schristos 				if (entry_size == 0) {
377c74ad251Schristos 					/* Error */
378c74ad251Schristos 					nd_print_trunc(ndo);
379c74ad251Schristos 					break;
380c74ad251Schristos 				}
381c74ad251Schristos 				if (len < entry_size) {
382c74ad251Schristos 					ND_PRINT(" [remaining entries length %u < %u]",
383c74ad251Schristos 						 len, entry_size);
384c74ad251Schristos 					nd_print_invalid(ndo);
385c74ad251Schristos 					break;
386c74ad251Schristos 				}
387c74ad251Schristos 				p += entry_size;
388c74ad251Schristos 				len -= entry_size;
389c74ad251Schristos 			}
390c74ad251Schristos 			break;
391c74ad251Schristos 
392c74ad251Schristos 		default:
393c74ad251Schristos 			ND_PRINT(", unknown version");
394c74ad251Schristos 			break;
395c74ad251Schristos 		}
3960f74e101Schristos 		break;
3970f74e101Schristos 
398*26ba0b50Schristos 	case RIPCMD_TRACEON:
3990f74e101Schristos 	case RIPCMD_TRACEOFF:
400*26ba0b50Schristos 	case RIPCMD_TRIGREQ:
401*26ba0b50Schristos 	case RIPCMD_TRIGRESP:
402*26ba0b50Schristos 	case RIPCMD_TRIGACK:
403*26ba0b50Schristos 	case RIPCMD_UPDREQ:
404*26ba0b50Schristos 	case RIPCMD_UPDRESP:
405*26ba0b50Schristos 	case RIPCMD_UPDACK:
4060f74e101Schristos 		break;
4070f74e101Schristos 
4080f74e101Schristos 	default:
409b3a00663Schristos 		if (ndo->ndo_vflag <= 1) {
410fdccd7e4Schristos 			if (!print_unknown_data(ndo, (const uint8_t *)rp, "\n\t", length))
4110f74e101Schristos 				return;
4120f74e101Schristos 		}
4130f74e101Schristos 		break;
4140f74e101Schristos 	}
4150f74e101Schristos 	/* do we want to see an additionally hexdump ? */
416b3a00663Schristos 	if (ndo->ndo_vflag> 1) {
417fdccd7e4Schristos 		if (!print_unknown_data(ndo, (const uint8_t *)rp, "\n\t", length))
4180f74e101Schristos 			return;
4190f74e101Schristos 	}
420c74ad251Schristos trunc:
421c74ad251Schristos 	return;
4220f74e101Schristos }
423