15b0fe478SBruce M Simpson /* 25b0fe478SBruce M Simpson * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org> 35b0fe478SBruce M Simpson * All rights reserved. 45b0fe478SBruce M Simpson * 55b0fe478SBruce M Simpson * Redistribution and use in source and binary forms, with or without 65b0fe478SBruce M Simpson * modification, are permitted provided that the following conditions 75b0fe478SBruce M Simpson * are met: 85b0fe478SBruce M Simpson * 1. Redistributions of source code must retain the above copyright 95b0fe478SBruce M Simpson * notice, this list of conditions and the following disclaimer. 105b0fe478SBruce M Simpson * 2. Redistributions in binary form must reproduce the above copyright 115b0fe478SBruce M Simpson * notice, this list of conditions and the following disclaimer in the 125b0fe478SBruce M Simpson * documentation and/or other materials provided with the distribution. 135b0fe478SBruce M Simpson * 3. All advertising materials mentioning features or use of this software 145b0fe478SBruce M Simpson * must display the following acknowledgement: 155b0fe478SBruce M Simpson * This product includes software developed by Bruce M. Simpson. 165b0fe478SBruce M Simpson * 4. Neither the name of Bruce M. Simpson nor the names of co- 175b0fe478SBruce M Simpson * contributors may be used to endorse or promote products derived 185b0fe478SBruce M Simpson * from this software without specific prior written permission. 195b0fe478SBruce M Simpson * 205b0fe478SBruce M Simpson * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson AND CONTRIBUTORS 215b0fe478SBruce M Simpson * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 225b0fe478SBruce M Simpson * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 235b0fe478SBruce M Simpson * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bruce M. Simpson OR CONTRIBUTORS 245b0fe478SBruce M Simpson * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 255b0fe478SBruce M Simpson * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 265b0fe478SBruce M Simpson * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 275b0fe478SBruce M Simpson * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 285b0fe478SBruce M Simpson * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 295b0fe478SBruce M Simpson * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 305b0fe478SBruce M Simpson * POSSIBILITY OF SUCH DAMAGE. 315b0fe478SBruce M Simpson */ 325b0fe478SBruce M Simpson 333340d773SGleb Smirnoff /* \summary: Ad hoc On-Demand Distance Vector (AODV) Routing printer */ 343340d773SGleb Smirnoff 355b0fe478SBruce M Simpson #ifdef HAVE_CONFIG_H 36*ee67461eSJoseph Mingrone #include <config.h> 375b0fe478SBruce M Simpson #endif 385b0fe478SBruce M Simpson 39*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 405b0fe478SBruce M Simpson 413340d773SGleb Smirnoff #include "netdissect.h" 425b0fe478SBruce M Simpson #include "addrtoname.h" 433340d773SGleb Smirnoff #include "extract.h" 445b0fe478SBruce M Simpson 450bff6a5aSEd Maste /* 460bff6a5aSEd Maste * RFC 3561 470bff6a5aSEd Maste */ 483c602fabSXin LI struct aodv_rreq { 49*ee67461eSJoseph Mingrone nd_uint8_t rreq_type; /* AODV message type (1) */ 50*ee67461eSJoseph Mingrone nd_uint8_t rreq_flags; /* various flags */ 51*ee67461eSJoseph Mingrone nd_uint8_t rreq_zero0; /* reserved, set to zero */ 52*ee67461eSJoseph Mingrone nd_uint8_t rreq_hops; /* number of hops from originator */ 53*ee67461eSJoseph Mingrone nd_uint32_t rreq_id; /* request ID */ 54*ee67461eSJoseph Mingrone nd_ipv4 rreq_da; /* destination IPv4 address */ 55*ee67461eSJoseph Mingrone nd_uint32_t rreq_ds; /* destination sequence number */ 56*ee67461eSJoseph Mingrone nd_ipv4 rreq_oa; /* originator IPv4 address */ 57*ee67461eSJoseph Mingrone nd_uint32_t rreq_os; /* originator sequence number */ 583c602fabSXin LI }; 593c602fabSXin LI struct aodv_rreq6 { 60*ee67461eSJoseph Mingrone nd_uint8_t rreq_type; /* AODV message type (1) */ 61*ee67461eSJoseph Mingrone nd_uint8_t rreq_flags; /* various flags */ 62*ee67461eSJoseph Mingrone nd_uint8_t rreq_zero0; /* reserved, set to zero */ 63*ee67461eSJoseph Mingrone nd_uint8_t rreq_hops; /* number of hops from originator */ 64*ee67461eSJoseph Mingrone nd_uint32_t rreq_id; /* request ID */ 65*ee67461eSJoseph Mingrone nd_ipv6 rreq_da; /* destination IPv6 address */ 66*ee67461eSJoseph Mingrone nd_uint32_t rreq_ds; /* destination sequence number */ 67*ee67461eSJoseph Mingrone nd_ipv6 rreq_oa; /* originator IPv6 address */ 68*ee67461eSJoseph Mingrone nd_uint32_t rreq_os; /* originator sequence number */ 693c602fabSXin LI }; 703c602fabSXin LI struct aodv_rreq6_draft_01 { 71*ee67461eSJoseph Mingrone nd_uint8_t rreq_type; /* AODV message type (16) */ 72*ee67461eSJoseph Mingrone nd_uint8_t rreq_flags; /* various flags */ 73*ee67461eSJoseph Mingrone nd_uint8_t rreq_zero0; /* reserved, set to zero */ 74*ee67461eSJoseph Mingrone nd_uint8_t rreq_hops; /* number of hops from originator */ 75*ee67461eSJoseph Mingrone nd_uint32_t rreq_id; /* request ID */ 76*ee67461eSJoseph Mingrone nd_uint32_t rreq_ds; /* destination sequence number */ 77*ee67461eSJoseph Mingrone nd_uint32_t rreq_os; /* originator sequence number */ 78*ee67461eSJoseph Mingrone nd_ipv6 rreq_da; /* destination IPv6 address */ 79*ee67461eSJoseph Mingrone nd_ipv6 rreq_oa; /* originator IPv6 address */ 803c602fabSXin LI }; 813c602fabSXin LI 823c602fabSXin LI #define RREQ_JOIN 0x80 /* join (reserved for multicast */ 833c602fabSXin LI #define RREQ_REPAIR 0x40 /* repair (reserved for multicast */ 843c602fabSXin LI #define RREQ_GRAT 0x20 /* gratuitous RREP */ 853c602fabSXin LI #define RREQ_DEST 0x10 /* destination only */ 863c602fabSXin LI #define RREQ_UNKNOWN 0x08 /* unknown destination sequence num */ 873c602fabSXin LI #define RREQ_FLAGS_MASK 0xF8 /* mask for rreq_flags */ 883c602fabSXin LI 893c602fabSXin LI struct aodv_rrep { 90*ee67461eSJoseph Mingrone nd_uint8_t rrep_type; /* AODV message type (2) */ 91*ee67461eSJoseph Mingrone nd_uint8_t rrep_flags; /* various flags */ 92*ee67461eSJoseph Mingrone nd_uint8_t rrep_ps; /* prefix size */ 93*ee67461eSJoseph Mingrone nd_uint8_t rrep_hops; /* number of hops from o to d */ 94*ee67461eSJoseph Mingrone nd_ipv4 rrep_da; /* destination IPv4 address */ 95*ee67461eSJoseph Mingrone nd_uint32_t rrep_ds; /* destination sequence number */ 96*ee67461eSJoseph Mingrone nd_ipv4 rrep_oa; /* originator IPv4 address */ 97*ee67461eSJoseph Mingrone nd_uint32_t rrep_life; /* lifetime of this route */ 983c602fabSXin LI }; 993c602fabSXin LI struct aodv_rrep6 { 100*ee67461eSJoseph Mingrone nd_uint8_t rrep_type; /* AODV message type (2) */ 101*ee67461eSJoseph Mingrone nd_uint8_t rrep_flags; /* various flags */ 102*ee67461eSJoseph Mingrone nd_uint8_t rrep_ps; /* prefix size */ 103*ee67461eSJoseph Mingrone nd_uint8_t rrep_hops; /* number of hops from o to d */ 104*ee67461eSJoseph Mingrone nd_ipv6 rrep_da; /* destination IPv6 address */ 105*ee67461eSJoseph Mingrone nd_uint32_t rrep_ds; /* destination sequence number */ 106*ee67461eSJoseph Mingrone nd_ipv6 rrep_oa; /* originator IPv6 address */ 107*ee67461eSJoseph Mingrone nd_uint32_t rrep_life; /* lifetime of this route */ 1083c602fabSXin LI }; 1093c602fabSXin LI struct aodv_rrep6_draft_01 { 110*ee67461eSJoseph Mingrone nd_uint8_t rrep_type; /* AODV message type (17) */ 111*ee67461eSJoseph Mingrone nd_uint8_t rrep_flags; /* various flags */ 112*ee67461eSJoseph Mingrone nd_uint8_t rrep_ps; /* prefix size */ 113*ee67461eSJoseph Mingrone nd_uint8_t rrep_hops; /* number of hops from o to d */ 114*ee67461eSJoseph Mingrone nd_uint32_t rrep_ds; /* destination sequence number */ 115*ee67461eSJoseph Mingrone nd_ipv6 rrep_da; /* destination IPv6 address */ 116*ee67461eSJoseph Mingrone nd_ipv6 rrep_oa; /* originator IPv6 address */ 117*ee67461eSJoseph Mingrone nd_uint32_t rrep_life; /* lifetime of this route */ 1183c602fabSXin LI }; 1193c602fabSXin LI 1203c602fabSXin LI #define RREP_REPAIR 0x80 /* repair (reserved for multicast */ 1213c602fabSXin LI #define RREP_ACK 0x40 /* acknowledgement required */ 1223c602fabSXin LI #define RREP_FLAGS_MASK 0xC0 /* mask for rrep_flags */ 1233c602fabSXin LI #define RREP_PREFIX_MASK 0x1F /* mask for prefix size */ 1243c602fabSXin LI 1253c602fabSXin LI struct rerr_unreach { 126*ee67461eSJoseph Mingrone nd_ipv4 u_da; /* IPv4 address */ 127*ee67461eSJoseph Mingrone nd_uint32_t u_ds; /* sequence number */ 1283c602fabSXin LI }; 1293c602fabSXin LI struct rerr_unreach6 { 130*ee67461eSJoseph Mingrone nd_ipv6 u_da; /* IPv6 address */ 131*ee67461eSJoseph Mingrone nd_uint32_t u_ds; /* sequence number */ 1323c602fabSXin LI }; 1333c602fabSXin LI struct rerr_unreach6_draft_01 { 134*ee67461eSJoseph Mingrone nd_ipv6 u_da; /* IPv6 address */ 135*ee67461eSJoseph Mingrone nd_uint32_t u_ds; /* sequence number */ 1363c602fabSXin LI }; 1373c602fabSXin LI 1383c602fabSXin LI struct aodv_rerr { 139*ee67461eSJoseph Mingrone nd_uint8_t rerr_type; /* AODV message type (3 or 18) */ 140*ee67461eSJoseph Mingrone nd_uint8_t rerr_flags; /* various flags */ 141*ee67461eSJoseph Mingrone nd_uint8_t rerr_zero0; /* reserved, set to zero */ 142*ee67461eSJoseph Mingrone nd_uint8_t rerr_dc; /* destination count */ 1433c602fabSXin LI }; 1443c602fabSXin LI 1453c602fabSXin LI #define RERR_NODELETE 0x80 /* don't delete the link */ 1463c602fabSXin LI #define RERR_FLAGS_MASK 0x80 /* mask for rerr_flags */ 1473c602fabSXin LI 1483c602fabSXin LI struct aodv_rrep_ack { 149*ee67461eSJoseph Mingrone nd_uint8_t ra_type; 150*ee67461eSJoseph Mingrone nd_uint8_t ra_zero0; 1513c602fabSXin LI }; 1523c602fabSXin LI 1533c602fabSXin LI #define AODV_RREQ 1 /* route request */ 1543c602fabSXin LI #define AODV_RREP 2 /* route response */ 1553c602fabSXin LI #define AODV_RERR 3 /* error report */ 1563c602fabSXin LI #define AODV_RREP_ACK 4 /* route response acknowledgement */ 1573c602fabSXin LI 1583c602fabSXin LI #define AODV_V6_DRAFT_01_RREQ 16 /* IPv6 route request */ 1593c602fabSXin LI #define AODV_V6_DRAFT_01_RREP 17 /* IPv6 route response */ 1603c602fabSXin LI #define AODV_V6_DRAFT_01_RERR 18 /* IPv6 error report */ 1613c602fabSXin LI #define AODV_V6_DRAFT_01_RREP_ACK 19 /* IPV6 route response acknowledgment */ 1623c602fabSXin LI 1633c602fabSXin LI struct aodv_ext { 164*ee67461eSJoseph Mingrone nd_uint8_t type; /* extension type */ 165*ee67461eSJoseph Mingrone nd_uint8_t length; /* extension length */ 1663c602fabSXin LI }; 1673c602fabSXin LI 1683c602fabSXin LI struct aodv_hello { 1693c602fabSXin LI struct aodv_ext eh; /* extension header */ 170*ee67461eSJoseph Mingrone nd_uint32_t interval; /* expect my next hello in 1713c602fabSXin LI * (n) ms 1723c602fabSXin LI * NOTE: this is not aligned */ 1733c602fabSXin LI }; 1743c602fabSXin LI 1753c602fabSXin LI #define AODV_EXT_HELLO 1 1765b0fe478SBruce M Simpson 1775b0fe478SBruce M Simpson static void 1783c602fabSXin LI aodv_extension(netdissect_options *ndo, 1793c602fabSXin LI const struct aodv_ext *ep, u_int length) 1805b0fe478SBruce M Simpson { 1815b0fe478SBruce M Simpson const struct aodv_hello *ah; 1825b0fe478SBruce M Simpson 183*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ep); 184*ee67461eSJoseph Mingrone switch (GET_U_1(ep->type)) { 1855b0fe478SBruce M Simpson case AODV_EXT_HELLO: 1868bdc5a62SPatrick Kelsey ah = (const struct aodv_hello *)(const void *)ep; 187*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ah); 1888bdc5a62SPatrick Kelsey if (length < sizeof(struct aodv_hello)) 1898bdc5a62SPatrick Kelsey goto trunc; 190*ee67461eSJoseph Mingrone if (GET_U_1(ep->length) < 4) { 191*ee67461eSJoseph Mingrone ND_PRINT("\n\text HELLO - bad length %u", 192*ee67461eSJoseph Mingrone GET_U_1(ep->length)); 1930bff6a5aSEd Maste break; 1940bff6a5aSEd Maste } 195*ee67461eSJoseph Mingrone ND_PRINT("\n\text HELLO %u ms", 196*ee67461eSJoseph Mingrone GET_BE_U_4(ah->interval)); 1975b0fe478SBruce M Simpson break; 1985b0fe478SBruce M Simpson 1995b0fe478SBruce M Simpson default: 200*ee67461eSJoseph Mingrone ND_PRINT("\n\text %u %u", GET_U_1(ep->type), 201*ee67461eSJoseph Mingrone GET_U_1(ep->length)); 2025b0fe478SBruce M Simpson break; 2035b0fe478SBruce M Simpson } 2048bdc5a62SPatrick Kelsey return; 2058bdc5a62SPatrick Kelsey 2068bdc5a62SPatrick Kelsey trunc: 207*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 2085b0fe478SBruce M Simpson } 2095b0fe478SBruce M Simpson 2105b0fe478SBruce M Simpson static void 2118bdc5a62SPatrick Kelsey aodv_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 2125b0fe478SBruce M Simpson { 2135b0fe478SBruce M Simpson u_int i; 2148bdc5a62SPatrick Kelsey const struct aodv_rreq *ap = (const struct aodv_rreq *)dat; 2155b0fe478SBruce M Simpson 216*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ap); 2178bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 2188bdc5a62SPatrick Kelsey goto trunc; 219*ee67461eSJoseph Mingrone ND_PRINT(" rreq %u %s%s%s%s%shops %u id 0x%08x\n" 220*ee67461eSJoseph Mingrone "\tdst %s seq %u src %s seq %u", length, 221*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_JOIN ? "[J]" : "", 222*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_REPAIR ? "[R]" : "", 223*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_GRAT ? "[G]" : "", 224*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_DEST ? "[D]" : "", 225*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_UNKNOWN ? "[U] " : " ", 226*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_hops), 227*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rreq_id), 228*ee67461eSJoseph Mingrone GET_IPADDR_STRING(ap->rreq_da), 229*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rreq_ds), 230*ee67461eSJoseph Mingrone GET_IPADDR_STRING(ap->rreq_oa), 231*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rreq_os)); 2328bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 2335b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 2348bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 2358bdc5a62SPatrick Kelsey return; 2368bdc5a62SPatrick Kelsey 2378bdc5a62SPatrick Kelsey trunc: 238*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 2395b0fe478SBruce M Simpson } 2405b0fe478SBruce M Simpson 2415b0fe478SBruce M Simpson static void 2428bdc5a62SPatrick Kelsey aodv_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 2435b0fe478SBruce M Simpson { 2445b0fe478SBruce M Simpson u_int i; 2458bdc5a62SPatrick Kelsey const struct aodv_rrep *ap = (const struct aodv_rrep *)dat; 2465b0fe478SBruce M Simpson 247*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ap); 2488bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 2498bdc5a62SPatrick Kelsey goto trunc; 250*ee67461eSJoseph Mingrone ND_PRINT(" rrep %u %s%sprefix %u hops %u\n" 251*ee67461eSJoseph Mingrone "\tdst %s dseq %u src %s %u ms", length, 252*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_type) & RREP_REPAIR ? "[R]" : "", 253*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_type) & RREP_ACK ? "[A] " : " ", 254*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_ps) & RREP_PREFIX_MASK, 255*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_hops), 256*ee67461eSJoseph Mingrone GET_IPADDR_STRING(ap->rrep_da), 257*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rrep_ds), 258*ee67461eSJoseph Mingrone GET_IPADDR_STRING(ap->rrep_oa), 259*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rrep_life)); 2608bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 2615b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 2628bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 2638bdc5a62SPatrick Kelsey return; 2648bdc5a62SPatrick Kelsey 2658bdc5a62SPatrick Kelsey trunc: 266*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 2675b0fe478SBruce M Simpson } 2685b0fe478SBruce M Simpson 2695b0fe478SBruce M Simpson static void 2708bdc5a62SPatrick Kelsey aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 2715b0fe478SBruce M Simpson { 2728bdc5a62SPatrick Kelsey u_int i, dc; 2738bdc5a62SPatrick Kelsey const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 2748bdc5a62SPatrick Kelsey const struct rerr_unreach *dp; 2755b0fe478SBruce M Simpson 276*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ap); 2778bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 2788bdc5a62SPatrick Kelsey goto trunc; 279*ee67461eSJoseph Mingrone ND_PRINT(" rerr %s [items %u] [%u]:", 280*ee67461eSJoseph Mingrone GET_U_1(ap->rerr_flags) & RERR_NODELETE ? "[D]" : "", 281*ee67461eSJoseph Mingrone GET_U_1(ap->rerr_dc), length); 2823340d773SGleb Smirnoff dp = (const struct rerr_unreach *)(dat + sizeof(*ap)); 2838bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 284*ee67461eSJoseph Mingrone for (dc = GET_U_1(ap->rerr_dc); dc != 0; dc--) { 285*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(dp); 2868bdc5a62SPatrick Kelsey if (i < sizeof(*dp)) 2878bdc5a62SPatrick Kelsey goto trunc; 288*ee67461eSJoseph Mingrone ND_PRINT(" {%s}(%u)", GET_IPADDR_STRING(dp->u_da), 289*ee67461eSJoseph Mingrone GET_BE_U_4(dp->u_ds)); 2908bdc5a62SPatrick Kelsey dp++; 2918bdc5a62SPatrick Kelsey i -= sizeof(*dp); 2925b0fe478SBruce M Simpson } 2938bdc5a62SPatrick Kelsey return; 2948bdc5a62SPatrick Kelsey 2958bdc5a62SPatrick Kelsey trunc: 296*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 2975b0fe478SBruce M Simpson } 2985b0fe478SBruce M Simpson 2995b0fe478SBruce M Simpson static void 3008bdc5a62SPatrick Kelsey aodv_v6_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 3015b0fe478SBruce M Simpson { 3025b0fe478SBruce M Simpson u_int i; 3038bdc5a62SPatrick Kelsey const struct aodv_rreq6 *ap = (const struct aodv_rreq6 *)dat; 3045b0fe478SBruce M Simpson 305*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ap); 3068bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3078bdc5a62SPatrick Kelsey goto trunc; 308*ee67461eSJoseph Mingrone ND_PRINT(" v6 rreq %u %s%s%s%s%shops %u id 0x%08x\n" 309*ee67461eSJoseph Mingrone "\tdst %s seq %u src %s seq %u", length, 310*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_JOIN ? "[J]" : "", 311*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_REPAIR ? "[R]" : "", 312*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_GRAT ? "[G]" : "", 313*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_DEST ? "[D]" : "", 314*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_UNKNOWN ? "[U] " : " ", 315*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_hops), 316*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rreq_id), 317*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(ap->rreq_da), 318*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rreq_ds), 319*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(ap->rreq_oa), 320*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rreq_os)); 3218bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 3225b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 3238bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 3248bdc5a62SPatrick Kelsey return; 3258bdc5a62SPatrick Kelsey 3268bdc5a62SPatrick Kelsey trunc: 327*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 3285b0fe478SBruce M Simpson } 3295b0fe478SBruce M Simpson 3305b0fe478SBruce M Simpson static void 3318bdc5a62SPatrick Kelsey aodv_v6_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 3325b0fe478SBruce M Simpson { 3335b0fe478SBruce M Simpson u_int i; 3348bdc5a62SPatrick Kelsey const struct aodv_rrep6 *ap = (const struct aodv_rrep6 *)dat; 3355b0fe478SBruce M Simpson 336*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ap); 3378bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3388bdc5a62SPatrick Kelsey goto trunc; 339*ee67461eSJoseph Mingrone ND_PRINT(" rrep %u %s%sprefix %u hops %u\n" 340*ee67461eSJoseph Mingrone "\tdst %s dseq %u src %s %u ms", length, 341*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_type) & RREP_REPAIR ? "[R]" : "", 342*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_type) & RREP_ACK ? "[A] " : " ", 343*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_ps) & RREP_PREFIX_MASK, 344*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_hops), 345*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(ap->rrep_da), 346*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rrep_ds), 347*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(ap->rrep_oa), 348*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rrep_life)); 3498bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 3505b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 3518bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 3528bdc5a62SPatrick Kelsey return; 3538bdc5a62SPatrick Kelsey 3548bdc5a62SPatrick Kelsey trunc: 355*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 3565b0fe478SBruce M Simpson } 3575b0fe478SBruce M Simpson 3585b0fe478SBruce M Simpson static void 3598bdc5a62SPatrick Kelsey aodv_v6_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 3605b0fe478SBruce M Simpson { 3618bdc5a62SPatrick Kelsey u_int i, dc; 3628bdc5a62SPatrick Kelsey const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 3638bdc5a62SPatrick Kelsey const struct rerr_unreach6 *dp6; 3645b0fe478SBruce M Simpson 365*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ap); 3668bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3678bdc5a62SPatrick Kelsey goto trunc; 368*ee67461eSJoseph Mingrone ND_PRINT(" rerr %s [items %u] [%u]:", 369*ee67461eSJoseph Mingrone GET_U_1(ap->rerr_flags) & RERR_NODELETE ? "[D]" : "", 370*ee67461eSJoseph Mingrone GET_U_1(ap->rerr_dc), length); 3713340d773SGleb Smirnoff dp6 = (const struct rerr_unreach6 *)(const void *)(ap + 1); 3728bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 373*ee67461eSJoseph Mingrone for (dc = GET_U_1(ap->rerr_dc); dc != 0; dc--) { 374*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(dp6); 3758bdc5a62SPatrick Kelsey if (i < sizeof(*dp6)) 3768bdc5a62SPatrick Kelsey goto trunc; 377*ee67461eSJoseph Mingrone ND_PRINT(" {%s}(%u)", GET_IP6ADDR_STRING(dp6->u_da), 378*ee67461eSJoseph Mingrone GET_BE_U_4(dp6->u_ds)); 3798bdc5a62SPatrick Kelsey dp6++; 3808bdc5a62SPatrick Kelsey i -= sizeof(*dp6); 3815b0fe478SBruce M Simpson } 3828bdc5a62SPatrick Kelsey return; 3838bdc5a62SPatrick Kelsey 3848bdc5a62SPatrick Kelsey trunc: 385*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 3865b0fe478SBruce M Simpson } 3875b0fe478SBruce M Simpson 3885b0fe478SBruce M Simpson static void 3898bdc5a62SPatrick Kelsey aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 3905b0fe478SBruce M Simpson { 3915b0fe478SBruce M Simpson u_int i; 3928bdc5a62SPatrick Kelsey const struct aodv_rreq6_draft_01 *ap = (const struct aodv_rreq6_draft_01 *)dat; 3935b0fe478SBruce M Simpson 394*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ap); 3958bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3968bdc5a62SPatrick Kelsey goto trunc; 397*ee67461eSJoseph Mingrone ND_PRINT(" rreq %u %s%s%s%s%shops %u id 0x%08x\n" 398*ee67461eSJoseph Mingrone "\tdst %s seq %u src %s seq %u", length, 399*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_JOIN ? "[J]" : "", 400*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_REPAIR ? "[R]" : "", 401*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_GRAT ? "[G]" : "", 402*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_DEST ? "[D]" : "", 403*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_type) & RREQ_UNKNOWN ? "[U] " : " ", 404*ee67461eSJoseph Mingrone GET_U_1(ap->rreq_hops), 405*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rreq_id), 406*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(ap->rreq_da), 407*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rreq_ds), 408*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(ap->rreq_oa), 409*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rreq_os)); 4108bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 4115b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 4128bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 4138bdc5a62SPatrick Kelsey return; 4148bdc5a62SPatrick Kelsey 4158bdc5a62SPatrick Kelsey trunc: 416*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 4175b0fe478SBruce M Simpson } 4185b0fe478SBruce M Simpson 4195b0fe478SBruce M Simpson static void 4208bdc5a62SPatrick Kelsey aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 4215b0fe478SBruce M Simpson { 4225b0fe478SBruce M Simpson u_int i; 4238bdc5a62SPatrick Kelsey const struct aodv_rrep6_draft_01 *ap = (const struct aodv_rrep6_draft_01 *)dat; 4245b0fe478SBruce M Simpson 425*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ap); 4268bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 4278bdc5a62SPatrick Kelsey goto trunc; 428*ee67461eSJoseph Mingrone ND_PRINT(" rrep %u %s%sprefix %u hops %u\n" 429*ee67461eSJoseph Mingrone "\tdst %s dseq %u src %s %u ms", length, 430*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_type) & RREP_REPAIR ? "[R]" : "", 431*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_type) & RREP_ACK ? "[A] " : " ", 432*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_ps) & RREP_PREFIX_MASK, 433*ee67461eSJoseph Mingrone GET_U_1(ap->rrep_hops), 434*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(ap->rrep_da), 435*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rrep_ds), 436*ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(ap->rrep_oa), 437*ee67461eSJoseph Mingrone GET_BE_U_4(ap->rrep_life)); 4388bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 4395b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 4408bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 4418bdc5a62SPatrick Kelsey return; 4428bdc5a62SPatrick Kelsey 4438bdc5a62SPatrick Kelsey trunc: 444*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 4455b0fe478SBruce M Simpson } 4465b0fe478SBruce M Simpson 4475b0fe478SBruce M Simpson static void 4488bdc5a62SPatrick Kelsey aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 4495b0fe478SBruce M Simpson { 4508bdc5a62SPatrick Kelsey u_int i, dc; 4518bdc5a62SPatrick Kelsey const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 4528bdc5a62SPatrick Kelsey const struct rerr_unreach6_draft_01 *dp6; 4535b0fe478SBruce M Simpson 454*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ap); 4558bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 4568bdc5a62SPatrick Kelsey goto trunc; 457*ee67461eSJoseph Mingrone ND_PRINT(" rerr %s [items %u] [%u]:", 458*ee67461eSJoseph Mingrone GET_U_1(ap->rerr_flags) & RERR_NODELETE ? "[D]" : "", 459*ee67461eSJoseph Mingrone GET_U_1(ap->rerr_dc), length); 4603340d773SGleb Smirnoff dp6 = (const struct rerr_unreach6_draft_01 *)(const void *)(ap + 1); 4618bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 462*ee67461eSJoseph Mingrone for (dc = GET_U_1(ap->rerr_dc); dc != 0; dc--) { 463*ee67461eSJoseph Mingrone ND_TCHECK_SIZE(dp6); 4648bdc5a62SPatrick Kelsey if (i < sizeof(*dp6)) 4658bdc5a62SPatrick Kelsey goto trunc; 466*ee67461eSJoseph Mingrone ND_PRINT(" {%s}(%u)", GET_IP6ADDR_STRING(dp6->u_da), 467*ee67461eSJoseph Mingrone GET_BE_U_4(dp6->u_ds)); 4688bdc5a62SPatrick Kelsey dp6++; 4698bdc5a62SPatrick Kelsey i -= sizeof(*dp6); 4705b0fe478SBruce M Simpson } 4718bdc5a62SPatrick Kelsey return; 4728bdc5a62SPatrick Kelsey 4738bdc5a62SPatrick Kelsey trunc: 474*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 4755b0fe478SBruce M Simpson } 4765b0fe478SBruce M Simpson 4775b0fe478SBruce M Simpson void 4783c602fabSXin LI aodv_print(netdissect_options *ndo, 4793c602fabSXin LI const u_char *dat, u_int length, int is_ip6) 4805b0fe478SBruce M Simpson { 4818bdc5a62SPatrick Kelsey uint8_t msg_type; 4825b0fe478SBruce M Simpson 483*ee67461eSJoseph Mingrone ndo->ndo_protocol = "aodv"; 4848bdc5a62SPatrick Kelsey /* 4858bdc5a62SPatrick Kelsey * The message type is the first byte; make sure we have it 4868bdc5a62SPatrick Kelsey * and then fetch it. 4878bdc5a62SPatrick Kelsey */ 488*ee67461eSJoseph Mingrone msg_type = GET_U_1(dat); 489*ee67461eSJoseph Mingrone ND_PRINT(" aodv"); 4905b0fe478SBruce M Simpson 4918bdc5a62SPatrick Kelsey switch (msg_type) { 4925b0fe478SBruce M Simpson 4935b0fe478SBruce M Simpson case AODV_RREQ: 4945b0fe478SBruce M Simpson if (is_ip6) 4958bdc5a62SPatrick Kelsey aodv_v6_rreq(ndo, dat, length); 4965b0fe478SBruce M Simpson else 4978bdc5a62SPatrick Kelsey aodv_rreq(ndo, dat, length); 4985b0fe478SBruce M Simpson break; 4995b0fe478SBruce M Simpson 5005b0fe478SBruce M Simpson case AODV_RREP: 5015b0fe478SBruce M Simpson if (is_ip6) 5028bdc5a62SPatrick Kelsey aodv_v6_rrep(ndo, dat, length); 5035b0fe478SBruce M Simpson else 5048bdc5a62SPatrick Kelsey aodv_rrep(ndo, dat, length); 5055b0fe478SBruce M Simpson break; 5065b0fe478SBruce M Simpson 5075b0fe478SBruce M Simpson case AODV_RERR: 5085b0fe478SBruce M Simpson if (is_ip6) 5098bdc5a62SPatrick Kelsey aodv_v6_rerr(ndo, dat, length); 5105b0fe478SBruce M Simpson else 5118bdc5a62SPatrick Kelsey aodv_rerr(ndo, dat, length); 5125b0fe478SBruce M Simpson break; 5135b0fe478SBruce M Simpson 5145b0fe478SBruce M Simpson case AODV_RREP_ACK: 515*ee67461eSJoseph Mingrone ND_PRINT(" rrep-ack %u", length); 5165b0fe478SBruce M Simpson break; 5175b0fe478SBruce M Simpson 5185b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RREQ: 5198bdc5a62SPatrick Kelsey aodv_v6_draft_01_rreq(ndo, dat, length); 5205b0fe478SBruce M Simpson break; 5215b0fe478SBruce M Simpson 5225b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RREP: 5238bdc5a62SPatrick Kelsey aodv_v6_draft_01_rrep(ndo, dat, length); 5245b0fe478SBruce M Simpson break; 5255b0fe478SBruce M Simpson 5265b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RERR: 5278bdc5a62SPatrick Kelsey aodv_v6_draft_01_rerr(ndo, dat, length); 5285b0fe478SBruce M Simpson break; 5295b0fe478SBruce M Simpson 5305b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RREP_ACK: 531*ee67461eSJoseph Mingrone ND_PRINT(" rrep-ack %u", length); 5325b0fe478SBruce M Simpson break; 5335b0fe478SBruce M Simpson 5345b0fe478SBruce M Simpson default: 535*ee67461eSJoseph Mingrone ND_PRINT(" type %u %u", msg_type, length); 5365b0fe478SBruce M Simpson } 5375b0fe478SBruce M Simpson } 538