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 22313537Sglebius/* \summary: IPv6 Routing Information Protocol (RIPng) printer */ 23313537Sglebius 2456893Sfenner#ifdef HAVE_CONFIG_H 2556893Sfenner#include "config.h" 2656893Sfenner#endif 2756893Sfenner 28313537Sglebius#include <netdissect-stdinc.h> 2956893Sfenner 30313537Sglebius#include "netdissect.h" 3156893Sfenner#include "addrtoname.h" 32127668Sbms#include "extract.h" 3356893Sfenner 34276788Sdelphij/* 35276788Sdelphij * Copyright (C) 1995, 1996, 1997 and 1998 WIDE Project. 36276788Sdelphij * All rights reserved. 37276788Sdelphij * 38276788Sdelphij * Redistribution and use in source and binary forms, with or without 39276788Sdelphij * modification, are permitted provided that the following conditions 40276788Sdelphij * are met: 41276788Sdelphij * 1. Redistributions of source code must retain the above copyright 42276788Sdelphij * notice, this list of conditions and the following disclaimer. 43276788Sdelphij * 2. Redistributions in binary form must reproduce the above copyright 44276788Sdelphij * notice, this list of conditions and the following disclaimer in the 45276788Sdelphij * documentation and/or other materials provided with the distribution. 46276788Sdelphij * 3. Neither the name of the project nor the names of its contributors 47276788Sdelphij * may be used to endorse or promote products derived from this software 48276788Sdelphij * without specific prior written permission. 49276788Sdelphij * 50276788Sdelphij * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 51276788Sdelphij * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52276788Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53276788Sdelphij * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 54276788Sdelphij * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55276788Sdelphij * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56276788Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57276788Sdelphij * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58276788Sdelphij * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59276788Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60276788Sdelphij * SUCH DAMAGE. 61276788Sdelphij */ 62276788Sdelphij#define RIP6_VERSION 1 63276788Sdelphij 64276788Sdelphij#define RIP6_REQUEST 1 65276788Sdelphij#define RIP6_RESPONSE 2 66276788Sdelphij 67276788Sdelphijstruct netinfo6 { 68276788Sdelphij struct in6_addr rip6_dest; 69276788Sdelphij uint16_t rip6_tag; 70276788Sdelphij uint8_t rip6_plen; 71276788Sdelphij uint8_t rip6_metric; 72276788Sdelphij}; 73276788Sdelphij 74276788Sdelphijstruct rip6 { 75276788Sdelphij uint8_t rip6_cmd; 76276788Sdelphij uint8_t rip6_vers; 77276788Sdelphij uint8_t rip6_res1[2]; 78276788Sdelphij union { 79276788Sdelphij struct netinfo6 ru6_nets[1]; 80276788Sdelphij char ru6_tracefile[1]; 81276788Sdelphij } rip6un; 82276788Sdelphij#define rip6_nets rip6un.ru6_nets 83276788Sdelphij#define rip6_tracefile rip6un.ru6_tracefile 84276788Sdelphij}; 85276788Sdelphij 86276788Sdelphij#define HOPCNT_INFINITY6 16 87276788Sdelphij 88146773Ssam#if !defined(IN6_IS_ADDR_UNSPECIFIED) && !defined(_MSC_VER) /* MSVC inline */ 89146773Ssamstatic int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *addr) 90146773Ssam{ 91146773Ssam static const struct in6_addr in6addr_any; /* :: */ 92146773Ssam return (memcmp(addr, &in6addr_any, sizeof(*addr)) == 0); 93146773Ssam} 94146773Ssam#endif 95146773Ssam 9656893Sfennerstatic int 97276788Sdelphijrip6_entry_print(netdissect_options *ndo, register const struct netinfo6 *ni, int metric) 9856893Sfenner{ 9956893Sfenner int l; 100276788Sdelphij l = ND_PRINT((ndo, "%s/%d", ip6addr_string(ndo, &ni->rip6_dest), ni->rip6_plen)); 10156893Sfenner if (ni->rip6_tag) 102276788Sdelphij l += ND_PRINT((ndo, " [%d]", EXTRACT_16BITS(&ni->rip6_tag))); 10356893Sfenner if (metric) 104276788Sdelphij l += ND_PRINT((ndo, " (%d)", ni->rip6_metric)); 10556893Sfenner return l; 10656893Sfenner} 10756893Sfenner 10856893Sfennervoid 109276788Sdelphijripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length) 11056893Sfenner{ 111313537Sglebius register const struct rip6 *rp = (const struct rip6 *)dat; 11256893Sfenner register const struct netinfo6 *ni; 113327234Semaste unsigned int length_left; 114327234Semaste u_int j; 11556893Sfenner 116327234Semaste ND_TCHECK(rp->rip6_cmd); 11756893Sfenner switch (rp->rip6_cmd) { 11856893Sfenner 11956893Sfenner case RIP6_REQUEST: 120327234Semaste length_left = length; 121327234Semaste if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6))) 122327234Semaste goto trunc; 123327234Semaste length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6)); 124327234Semaste j = length_left / sizeof(*ni); 125327234Semaste if (j == 1) { 126327234Semaste ND_TCHECK(rp->rip6_nets); 127327234Semaste if (rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6 128327234Semaste && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) { 129327234Semaste ND_PRINT((ndo, " ripng-req dump")); 130327234Semaste break; 131327234Semaste } 13256893Sfenner } 133327234Semaste if (j * sizeof(*ni) != length_left) 134327234Semaste ND_PRINT((ndo, " ripng-req %u[%u]:", j, length)); 13556893Sfenner else 136327234Semaste ND_PRINT((ndo, " ripng-req %u:", j)); 137327234Semaste for (ni = rp->rip6_nets; length_left >= sizeof(*ni); 138327234Semaste length_left -= sizeof(*ni), ++ni) { 139327234Semaste ND_TCHECK(*ni); 140276788Sdelphij if (ndo->ndo_vflag > 1) 141276788Sdelphij ND_PRINT((ndo, "\n\t")); 14256893Sfenner else 143276788Sdelphij ND_PRINT((ndo, " ")); 144276788Sdelphij rip6_entry_print(ndo, ni, 0); 14556893Sfenner } 146327234Semaste if (length_left != 0) 147327234Semaste goto trunc; 14856893Sfenner break; 14956893Sfenner case RIP6_RESPONSE: 150327234Semaste length_left = length; 151327234Semaste if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6))) 152327234Semaste goto trunc; 153327234Semaste length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6)); 154327234Semaste j = length_left / sizeof(*ni); 155327234Semaste if (j * sizeof(*ni) != length_left) 156276788Sdelphij ND_PRINT((ndo, " ripng-resp %d[%u]:", j, length)); 15756893Sfenner else 158276788Sdelphij ND_PRINT((ndo, " ripng-resp %d:", j)); 159327234Semaste for (ni = rp->rip6_nets; length_left >= sizeof(*ni); 160327234Semaste length_left -= sizeof(*ni), ++ni) { 161327234Semaste ND_TCHECK(*ni); 162276788Sdelphij if (ndo->ndo_vflag > 1) 163276788Sdelphij ND_PRINT((ndo, "\n\t")); 16456893Sfenner else 165276788Sdelphij ND_PRINT((ndo, " ")); 166276788Sdelphij rip6_entry_print(ndo, ni, ni->rip6_metric); 16756893Sfenner } 168327234Semaste if (length_left != 0) 169327234Semaste goto trunc; 17056893Sfenner break; 17156893Sfenner default: 172276788Sdelphij ND_PRINT((ndo, " ripng-%d ?? %u", rp->rip6_cmd, length)); 17356893Sfenner break; 17456893Sfenner } 175327234Semaste ND_TCHECK(rp->rip6_vers); 17656893Sfenner if (rp->rip6_vers != RIP6_VERSION) 177276788Sdelphij ND_PRINT((ndo, " [vers %d]", rp->rip6_vers)); 178327234Semaste return; 179327234Semaste 180327234Semastetrunc: 181327234Semaste ND_PRINT((ndo, "[|ripng]")); 182327234Semaste return; 18356893Sfenner} 184