Home | History | Annotate | Line # | Download | only in dist
print-ripng.c revision 1.3.10.1
      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 #include <sys/cdefs.h>
     23 #ifndef lint
     24 __RCSID("$NetBSD: print-ripng.c,v 1.3.10.1 2017/03/13 07:41:15 skrll Exp $");
     25 #endif
     26 
     27 /* \summary: IPv6 Routing Information Protocol (RIPng) printer */
     28 
     29 #ifdef HAVE_CONFIG_H
     30 #include "config.h"
     31 #endif
     32 
     33 #include <netdissect-stdinc.h>
     34 
     35 #include "netdissect.h"
     36 #include "addrtoname.h"
     37 #include "extract.h"
     38 
     39 /*
     40  * Copyright (C) 1995, 1996, 1997 and 1998 WIDE Project.
     41  * All rights reserved.
     42  *
     43  * Redistribution and use in source and binary forms, with or without
     44  * modification, are permitted provided that the following conditions
     45  * are met:
     46  * 1. Redistributions of source code must retain the above copyright
     47  *    notice, this list of conditions and the following disclaimer.
     48  * 2. Redistributions in binary form must reproduce the above copyright
     49  *    notice, this list of conditions and the following disclaimer in the
     50  *    documentation and/or other materials provided with the distribution.
     51  * 3. Neither the name of the project nor the names of its contributors
     52  *    may be used to endorse or promote products derived from this software
     53  *    without specific prior written permission.
     54  *
     55  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     56  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     57  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     58  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     59  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     60  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     61  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     62  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     63  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     65  * SUCH DAMAGE.
     66  */
     67 #define	RIP6_VERSION	1
     68 
     69 #define	RIP6_REQUEST	1
     70 #define	RIP6_RESPONSE	2
     71 
     72 struct netinfo6 {
     73 	struct in6_addr	rip6_dest;
     74 	uint16_t	rip6_tag;
     75 	uint8_t		rip6_plen;
     76 	uint8_t		rip6_metric;
     77 };
     78 
     79 struct	rip6 {
     80 	uint8_t		rip6_cmd;
     81 	uint8_t		rip6_vers;
     82 	uint8_t		rip6_res1[2];
     83 	union {
     84 		struct	netinfo6	ru6_nets[1];
     85 		char	ru6_tracefile[1];
     86 	} rip6un;
     87 #define	rip6_nets	rip6un.ru6_nets
     88 #define	rip6_tracefile	rip6un.ru6_tracefile
     89 };
     90 
     91 #define	HOPCNT_INFINITY6	16
     92 
     93 #if !defined(IN6_IS_ADDR_UNSPECIFIED) && !defined(_MSC_VER) /* MSVC inline */
     94 static int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *addr)
     95 {
     96     static const struct in6_addr in6addr_any;        /* :: */
     97     return (memcmp(addr, &in6addr_any, sizeof(*addr)) == 0);
     98 }
     99 #endif
    100 
    101 static int
    102 rip6_entry_print(netdissect_options *ndo, register const struct netinfo6 *ni, int metric)
    103 {
    104 	int l;
    105 	l = ND_PRINT((ndo, "%s/%d", ip6addr_string(ndo, &ni->rip6_dest), ni->rip6_plen));
    106 	if (ni->rip6_tag)
    107 		l += ND_PRINT((ndo, " [%d]", EXTRACT_16BITS(&ni->rip6_tag)));
    108 	if (metric)
    109 		l += ND_PRINT((ndo, " (%d)", ni->rip6_metric));
    110 	return l;
    111 }
    112 
    113 void
    114 ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length)
    115 {
    116 	register const struct rip6 *rp = (const struct rip6 *)dat;
    117 	register const struct netinfo6 *ni;
    118 	register u_int amt;
    119 	register u_int i;
    120 	int j;
    121 	int trunc;
    122 
    123 	if (ndo->ndo_snapend < dat)
    124 		return;
    125 	amt = ndo->ndo_snapend - dat;
    126 	i = min(length, amt);
    127 	if (i < (sizeof(struct rip6) - sizeof(struct netinfo6)))
    128 		return;
    129 	i -= (sizeof(struct rip6) - sizeof(struct netinfo6));
    130 
    131 	switch (rp->rip6_cmd) {
    132 
    133 	case RIP6_REQUEST:
    134 		j = length / sizeof(*ni);
    135 		if (j == 1
    136 		    &&  rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
    137 		    &&  IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
    138 			ND_PRINT((ndo, " ripng-req dump"));
    139 			break;
    140 		}
    141 		if (j * sizeof(*ni) != length - 4)
    142 			ND_PRINT((ndo, " ripng-req %d[%u]:", j, length));
    143 		else
    144 			ND_PRINT((ndo, " ripng-req %d:", j));
    145 		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
    146 		for (ni = rp->rip6_nets; i >= sizeof(*ni);
    147 		    i -= sizeof(*ni), ++ni) {
    148 			if (ndo->ndo_vflag > 1)
    149 				ND_PRINT((ndo, "\n\t"));
    150 			else
    151 				ND_PRINT((ndo, " "));
    152 			rip6_entry_print(ndo, ni, 0);
    153 		}
    154 		break;
    155 	case RIP6_RESPONSE:
    156 		j = length / sizeof(*ni);
    157 		if (j * sizeof(*ni) != length - 4)
    158 			ND_PRINT((ndo, " ripng-resp %d[%u]:", j, length));
    159 		else
    160 			ND_PRINT((ndo, " ripng-resp %d:", j));
    161 		trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
    162 		for (ni = rp->rip6_nets; i >= sizeof(*ni);
    163 		    i -= sizeof(*ni), ++ni) {
    164 			if (ndo->ndo_vflag > 1)
    165 				ND_PRINT((ndo, "\n\t"));
    166 			else
    167 				ND_PRINT((ndo, " "));
    168 			rip6_entry_print(ndo, ni, ni->rip6_metric);
    169 		}
    170 		if (trunc)
    171 			ND_PRINT((ndo, "[|ripng]"));
    172 		break;
    173 	default:
    174 		ND_PRINT((ndo, " ripng-%d ?? %u", rp->rip6_cmd, length));
    175 		break;
    176 	}
    177 	if (rp->rip6_vers != RIP6_VERSION)
    178 		ND_PRINT((ndo, " [vers %d]", rp->rip6_vers));
    179 }
    180