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