print-ripng.c revision 127668
1/*
2 * Copyright (c) 1989, 1990, 1991, 1993, 1994
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22#ifndef lint
23static const char rcsid[] _U_ =
24    "@(#) $Header: /tcpdump/master/tcpdump/print-ripng.c,v 1.15.2.2 2003/11/16 08:51:42 guy Exp $";
25#endif
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#ifdef INET6
32
33#include <tcpdump-stdinc.h>
34
35#ifdef WIN32
36const struct in6_addr in6addr_any;        /* :: */
37#endif /* WIN32 */
38
39#ifdef __MINGW32__
40int
41IN6_ADDR_EQUAL(const struct in6_addr *a, const struct in6_addr *b)
42{
43    return (memcmp(a, b, sizeof(struct in6_addr)) == 0);
44}
45
46#define IN6_IS_ADDR_UNSPECIFIED(a) IN6_ADDR_EQUAL((a), &in6addr_any)
47
48#endif /* __MINGW32__ */
49
50#include <stdio.h>
51
52#include "route6d.h"
53#include "interface.h"
54#include "addrtoname.h"
55#include "extract.h"
56
57static int
58rip6_entry_print(register const struct netinfo6 *ni, int metric)
59{
60	int l;
61	l = printf("%s/%d", ip6addr_string(&ni->rip6_dest), ni->rip6_plen);
62	if (ni->rip6_tag)
63		l += printf(" [%d]", EXTRACT_16BITS(&ni->rip6_tag));
64	if (metric)
65		l += printf(" (%d)", ni->rip6_metric);
66	return l;
67}
68
69void
70ripng_print(const u_char *dat, unsigned int length)
71{
72	register const struct rip6 *rp = (struct rip6 *)dat;
73	register const struct netinfo6 *ni;
74	register u_int amt;
75	register u_int i;
76	int j;
77	int trunc;
78
79	if (snapend < dat)
80		return;
81	amt = snapend - dat;
82	i = min(length, amt);
83	if (i < (sizeof(struct rip6) - sizeof(struct netinfo6)))
84		return;
85	i -= (sizeof(struct rip6) - sizeof(struct netinfo6));
86
87	switch (rp->rip6_cmd) {
88
89	case RIP6_REQUEST:
90		j = length / sizeof(*ni);
91		if (j == 1
92		    &&  rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
93		    &&  IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
94			printf(" ripng-req dump");
95			break;
96		}
97		if (j * sizeof(*ni) != length - 4)
98			printf(" ripng-req %d[%u]:", j, length);
99		else
100			printf(" ripng-req %d:", j);
101		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
102		for (ni = rp->rip6_nets; i >= sizeof(*ni);
103		    i -= sizeof(*ni), ++ni) {
104			if (vflag > 1)
105				printf("\n\t");
106			else
107				printf(" ");
108			rip6_entry_print(ni, 0);
109		}
110		break;
111	case RIP6_RESPONSE:
112		j = length / sizeof(*ni);
113		if (j * sizeof(*ni) != length - 4)
114			printf(" ripng-resp %d[%u]:", j, length);
115		else
116			printf(" ripng-resp %d:", j);
117		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
118		for (ni = rp->rip6_nets; i >= sizeof(*ni);
119		    i -= sizeof(*ni), ++ni) {
120			if (vflag > 1)
121				printf("\n\t");
122			else
123				printf(" ");
124			rip6_entry_print(ni, ni->rip6_metric);
125		}
126		if (trunc)
127			printf("[|ripng]");
128		break;
129	default:
130		printf(" ripng-%d ?? %u", rp->rip6_cmd, length);
131		break;
132	}
133	if (rp->rip6_vers != RIP6_VERSION)
134		printf(" [vers %d]", rp->rip6_vers);
135}
136#endif /* INET6 */
137