print-ripng.c revision 127668
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_ =
24127668Sbms    "@(#) $Header: /tcpdump/master/tcpdump/print-ripng.c,v 1.15.2.2 2003/11/16 08:51:42 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
35127668Sbms#ifdef WIN32
36127668Sbmsconst struct in6_addr in6addr_any;        /* :: */
37127668Sbms#endif /* WIN32 */
3856893Sfenner
39127668Sbms#ifdef __MINGW32__
40127668Sbmsint
41127668SbmsIN6_ADDR_EQUAL(const struct in6_addr *a, const struct in6_addr *b)
42127668Sbms{
43127668Sbms    return (memcmp(a, b, sizeof(struct in6_addr)) == 0);
44127668Sbms}
45127668Sbms
46127668Sbms#define IN6_IS_ADDR_UNSPECIFIED(a) IN6_ADDR_EQUAL((a), &in6addr_any)
47127668Sbms
48127668Sbms#endif /* __MINGW32__ */
49127668Sbms
5056893Sfenner#include <stdio.h>
5156893Sfenner
5256893Sfenner#include "route6d.h"
5356893Sfenner#include "interface.h"
5456893Sfenner#include "addrtoname.h"
55127668Sbms#include "extract.h"
5656893Sfenner
5756893Sfennerstatic int
5856893Sfennerrip6_entry_print(register const struct netinfo6 *ni, int metric)
5956893Sfenner{
6056893Sfenner	int l;
6156893Sfenner	l = printf("%s/%d", ip6addr_string(&ni->rip6_dest), ni->rip6_plen);
6256893Sfenner	if (ni->rip6_tag)
63127668Sbms		l += printf(" [%d]", EXTRACT_16BITS(&ni->rip6_tag));
6456893Sfenner	if (metric)
6556893Sfenner		l += printf(" (%d)", ni->rip6_metric);
6656893Sfenner	return l;
6756893Sfenner}
6856893Sfenner
6956893Sfennervoid
7098524Sfennerripng_print(const u_char *dat, unsigned int length)
7156893Sfenner{
7256893Sfenner	register const struct rip6 *rp = (struct rip6 *)dat;
7356893Sfenner	register const struct netinfo6 *ni;
74127668Sbms	register u_int amt;
75127668Sbms	register u_int i;
7656893Sfenner	int j;
7756893Sfenner	int trunc;
7856893Sfenner
79127668Sbms	if (snapend < dat)
8056893Sfenner		return;
81127668Sbms	amt = snapend - dat;
82127668Sbms	i = min(length, amt);
83127668Sbms	if (i < (sizeof(struct rip6) - sizeof(struct netinfo6)))
84127668Sbms		return;
85127668Sbms	i -= (sizeof(struct rip6) - sizeof(struct netinfo6));
8656893Sfenner
8756893Sfenner	switch (rp->rip6_cmd) {
8856893Sfenner
8956893Sfenner	case RIP6_REQUEST:
9056893Sfenner		j = length / sizeof(*ni);
9156893Sfenner		if (j == 1
9256893Sfenner		    &&  rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
9356893Sfenner		    &&  IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
9456893Sfenner			printf(" ripng-req dump");
9556893Sfenner			break;
9656893Sfenner		}
9756893Sfenner		if (j * sizeof(*ni) != length - 4)
9898524Sfenner			printf(" ripng-req %d[%u]:", j, length);
9956893Sfenner		else
10056893Sfenner			printf(" ripng-req %d:", j);
10156893Sfenner		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
102127668Sbms		for (ni = rp->rip6_nets; i >= sizeof(*ni);
103127668Sbms		    i -= sizeof(*ni), ++ni) {
10498524Sfenner			if (vflag > 1)
10556893Sfenner				printf("\n\t");
10656893Sfenner			else
10756893Sfenner				printf(" ");
10856893Sfenner			rip6_entry_print(ni, 0);
10956893Sfenner		}
11056893Sfenner		break;
11156893Sfenner	case RIP6_RESPONSE:
11256893Sfenner		j = length / sizeof(*ni);
11356893Sfenner		if (j * sizeof(*ni) != length - 4)
11498524Sfenner			printf(" ripng-resp %d[%u]:", j, length);
11556893Sfenner		else
11656893Sfenner			printf(" ripng-resp %d:", j);
11756893Sfenner		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
118127668Sbms		for (ni = rp->rip6_nets; i >= sizeof(*ni);
119127668Sbms		    i -= sizeof(*ni), ++ni) {
12098524Sfenner			if (vflag > 1)
12156893Sfenner				printf("\n\t");
12256893Sfenner			else
12356893Sfenner				printf(" ");
12456893Sfenner			rip6_entry_print(ni, ni->rip6_metric);
12556893Sfenner		}
12656893Sfenner		if (trunc)
12798524Sfenner			printf("[|ripng]");
12856893Sfenner		break;
12956893Sfenner	default:
13098524Sfenner		printf(" ripng-%d ?? %u", rp->rip6_cmd, length);
13156893Sfenner		break;
13256893Sfenner	}
13356893Sfenner	if (rp->rip6_vers != RIP6_VERSION)
13456893Sfenner		printf(" [vers %d]", rp->rip6_vers);
13556893Sfenner}
13656893Sfenner#endif /* INET6 */
137