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 365b0fe478SBruce M Simpson #include "config.h" 375b0fe478SBruce M Simpson #endif 385b0fe478SBruce M Simpson 393340d773SGleb Smirnoff #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 45*0bff6a5aSEd Maste /* 46*0bff6a5aSEd Maste * RFC 3561 47*0bff6a5aSEd Maste */ 483c602fabSXin LI struct aodv_rreq { 493c602fabSXin LI uint8_t rreq_type; /* AODV message type (1) */ 503c602fabSXin LI uint8_t rreq_flags; /* various flags */ 513c602fabSXin LI uint8_t rreq_zero0; /* reserved, set to zero */ 523c602fabSXin LI uint8_t rreq_hops; /* number of hops from originator */ 533c602fabSXin LI uint32_t rreq_id; /* request ID */ 543c602fabSXin LI uint32_t rreq_da; /* destination IPv4 address */ 553c602fabSXin LI uint32_t rreq_ds; /* destination sequence number */ 563c602fabSXin LI uint32_t rreq_oa; /* originator IPv4 address */ 573c602fabSXin LI uint32_t rreq_os; /* originator sequence number */ 583c602fabSXin LI }; 593c602fabSXin LI struct aodv_rreq6 { 603c602fabSXin LI uint8_t rreq_type; /* AODV message type (1) */ 613c602fabSXin LI uint8_t rreq_flags; /* various flags */ 623c602fabSXin LI uint8_t rreq_zero0; /* reserved, set to zero */ 633c602fabSXin LI uint8_t rreq_hops; /* number of hops from originator */ 643c602fabSXin LI uint32_t rreq_id; /* request ID */ 653c602fabSXin LI struct in6_addr rreq_da; /* destination IPv6 address */ 663c602fabSXin LI uint32_t rreq_ds; /* destination sequence number */ 673c602fabSXin LI struct in6_addr rreq_oa; /* originator IPv6 address */ 683c602fabSXin LI uint32_t rreq_os; /* originator sequence number */ 693c602fabSXin LI }; 703c602fabSXin LI struct aodv_rreq6_draft_01 { 713c602fabSXin LI uint8_t rreq_type; /* AODV message type (16) */ 723c602fabSXin LI uint8_t rreq_flags; /* various flags */ 733c602fabSXin LI uint8_t rreq_zero0; /* reserved, set to zero */ 743c602fabSXin LI uint8_t rreq_hops; /* number of hops from originator */ 753c602fabSXin LI uint32_t rreq_id; /* request ID */ 763c602fabSXin LI uint32_t rreq_ds; /* destination sequence number */ 773c602fabSXin LI uint32_t rreq_os; /* originator sequence number */ 783c602fabSXin LI struct in6_addr rreq_da; /* destination IPv6 address */ 793c602fabSXin LI struct in6_addr 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 { 903c602fabSXin LI uint8_t rrep_type; /* AODV message type (2) */ 913c602fabSXin LI uint8_t rrep_flags; /* various flags */ 923c602fabSXin LI uint8_t rrep_ps; /* prefix size */ 933c602fabSXin LI uint8_t rrep_hops; /* number of hops from o to d */ 943c602fabSXin LI uint32_t rrep_da; /* destination IPv4 address */ 953c602fabSXin LI uint32_t rrep_ds; /* destination sequence number */ 963c602fabSXin LI uint32_t rrep_oa; /* originator IPv4 address */ 973c602fabSXin LI uint32_t rrep_life; /* lifetime of this route */ 983c602fabSXin LI }; 993c602fabSXin LI struct aodv_rrep6 { 1003c602fabSXin LI uint8_t rrep_type; /* AODV message type (2) */ 1013c602fabSXin LI uint8_t rrep_flags; /* various flags */ 1023c602fabSXin LI uint8_t rrep_ps; /* prefix size */ 1033c602fabSXin LI uint8_t rrep_hops; /* number of hops from o to d */ 1043c602fabSXin LI struct in6_addr rrep_da; /* destination IPv6 address */ 1053c602fabSXin LI uint32_t rrep_ds; /* destination sequence number */ 1063c602fabSXin LI struct in6_addr rrep_oa; /* originator IPv6 address */ 1073c602fabSXin LI uint32_t rrep_life; /* lifetime of this route */ 1083c602fabSXin LI }; 1093c602fabSXin LI struct aodv_rrep6_draft_01 { 1103c602fabSXin LI uint8_t rrep_type; /* AODV message type (17) */ 1113c602fabSXin LI uint8_t rrep_flags; /* various flags */ 1123c602fabSXin LI uint8_t rrep_ps; /* prefix size */ 1133c602fabSXin LI uint8_t rrep_hops; /* number of hops from o to d */ 1143c602fabSXin LI uint32_t rrep_ds; /* destination sequence number */ 1153c602fabSXin LI struct in6_addr rrep_da; /* destination IPv6 address */ 1163c602fabSXin LI struct in6_addr rrep_oa; /* originator IPv6 address */ 1173c602fabSXin LI 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 { 1263c602fabSXin LI uint32_t u_da; /* IPv4 address */ 1273c602fabSXin LI uint32_t u_ds; /* sequence number */ 1283c602fabSXin LI }; 1293c602fabSXin LI struct rerr_unreach6 { 1303c602fabSXin LI struct in6_addr u_da; /* IPv6 address */ 1313c602fabSXin LI uint32_t u_ds; /* sequence number */ 1323c602fabSXin LI }; 1333c602fabSXin LI struct rerr_unreach6_draft_01 { 1343c602fabSXin LI struct in6_addr u_da; /* IPv6 address */ 1353c602fabSXin LI uint32_t u_ds; /* sequence number */ 1363c602fabSXin LI }; 1373c602fabSXin LI 1383c602fabSXin LI struct aodv_rerr { 1393c602fabSXin LI uint8_t rerr_type; /* AODV message type (3 or 18) */ 1403c602fabSXin LI uint8_t rerr_flags; /* various flags */ 1413c602fabSXin LI uint8_t rerr_zero0; /* reserved, set to zero */ 1423c602fabSXin LI 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 { 1493c602fabSXin LI uint8_t ra_type; 1503c602fabSXin LI 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 { 1643c602fabSXin LI uint8_t type; /* extension type */ 1653c602fabSXin LI uint8_t length; /* extension length */ 1663c602fabSXin LI }; 1673c602fabSXin LI 1683c602fabSXin LI struct aodv_hello { 1693c602fabSXin LI struct aodv_ext eh; /* extension header */ 1703c602fabSXin LI uint8_t interval[4]; /* 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*0bff6a5aSEd Maste ND_TCHECK(*ep); 1845b0fe478SBruce M Simpson switch (ep->type) { 1855b0fe478SBruce M Simpson case AODV_EXT_HELLO: 1868bdc5a62SPatrick Kelsey ah = (const struct aodv_hello *)(const void *)ep; 1878bdc5a62SPatrick Kelsey ND_TCHECK(*ah); 1888bdc5a62SPatrick Kelsey if (length < sizeof(struct aodv_hello)) 1898bdc5a62SPatrick Kelsey goto trunc; 190*0bff6a5aSEd Maste if (ep->length < 4) { 191*0bff6a5aSEd Maste ND_PRINT((ndo, "\n\text HELLO - bad length %u", ep->length)); 192*0bff6a5aSEd Maste break; 193*0bff6a5aSEd Maste } 1943c602fabSXin LI ND_PRINT((ndo, "\n\text HELLO %ld ms", 1953c602fabSXin LI (unsigned long)EXTRACT_32BITS(&ah->interval))); 1965b0fe478SBruce M Simpson break; 1975b0fe478SBruce M Simpson 1985b0fe478SBruce M Simpson default: 1993c602fabSXin LI ND_PRINT((ndo, "\n\text %u %u", ep->type, ep->length)); 2005b0fe478SBruce M Simpson break; 2015b0fe478SBruce M Simpson } 2028bdc5a62SPatrick Kelsey return; 2038bdc5a62SPatrick Kelsey 2048bdc5a62SPatrick Kelsey trunc: 2058bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|hello]")); 2065b0fe478SBruce M Simpson } 2075b0fe478SBruce M Simpson 2085b0fe478SBruce M Simpson static void 2098bdc5a62SPatrick Kelsey aodv_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 2105b0fe478SBruce M Simpson { 2115b0fe478SBruce M Simpson u_int i; 2128bdc5a62SPatrick Kelsey const struct aodv_rreq *ap = (const struct aodv_rreq *)dat; 2135b0fe478SBruce M Simpson 2148bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 2158bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 2168bdc5a62SPatrick Kelsey goto trunc; 2173c602fabSXin LI ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 2185b0fe478SBruce M Simpson "\tdst %s seq %lu src %s seq %lu", length, 2198bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_JOIN ? "[J]" : "", 2208bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_REPAIR ? "[R]" : "", 2218bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_GRAT ? "[G]" : "", 2228bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_DEST ? "[D]" : "", 2238bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 2248bdc5a62SPatrick Kelsey ap->rreq_hops, 2258bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_id), 2268bdc5a62SPatrick Kelsey ipaddr_string(ndo, &ap->rreq_da), 2278bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), 2288bdc5a62SPatrick Kelsey ipaddr_string(ndo, &ap->rreq_oa), 2298bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); 2308bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 2315b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 2328bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 2338bdc5a62SPatrick Kelsey return; 2348bdc5a62SPatrick Kelsey 2358bdc5a62SPatrick Kelsey trunc: 2368bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 2375b0fe478SBruce M Simpson } 2385b0fe478SBruce M Simpson 2395b0fe478SBruce M Simpson static void 2408bdc5a62SPatrick Kelsey aodv_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 2415b0fe478SBruce M Simpson { 2425b0fe478SBruce M Simpson u_int i; 2438bdc5a62SPatrick Kelsey const struct aodv_rrep *ap = (const struct aodv_rrep *)dat; 2445b0fe478SBruce M Simpson 2458bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 2468bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 2478bdc5a62SPatrick Kelsey goto trunc; 2483c602fabSXin LI ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" 2495b0fe478SBruce M Simpson "\tdst %s dseq %lu src %s %lu ms", length, 2508bdc5a62SPatrick Kelsey ap->rrep_type & RREP_REPAIR ? "[R]" : "", 2518bdc5a62SPatrick Kelsey ap->rrep_type & RREP_ACK ? "[A] " : " ", 2528bdc5a62SPatrick Kelsey ap->rrep_ps & RREP_PREFIX_MASK, 2538bdc5a62SPatrick Kelsey ap->rrep_hops, 2548bdc5a62SPatrick Kelsey ipaddr_string(ndo, &ap->rrep_da), 2558bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), 2568bdc5a62SPatrick Kelsey ipaddr_string(ndo, &ap->rrep_oa), 2578bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); 2588bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 2595b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 2608bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 2618bdc5a62SPatrick Kelsey return; 2628bdc5a62SPatrick Kelsey 2638bdc5a62SPatrick Kelsey trunc: 2648bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 2655b0fe478SBruce M Simpson } 2665b0fe478SBruce M Simpson 2675b0fe478SBruce M Simpson static void 2688bdc5a62SPatrick Kelsey aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 2695b0fe478SBruce M Simpson { 2708bdc5a62SPatrick Kelsey u_int i, dc; 2718bdc5a62SPatrick Kelsey const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 2728bdc5a62SPatrick Kelsey const struct rerr_unreach *dp; 2735b0fe478SBruce M Simpson 2748bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 2758bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 2768bdc5a62SPatrick Kelsey goto trunc; 2773c602fabSXin LI ND_PRINT((ndo, " rerr %s [items %u] [%u]:", 2788bdc5a62SPatrick Kelsey ap->rerr_flags & RERR_NODELETE ? "[D]" : "", 2798bdc5a62SPatrick Kelsey ap->rerr_dc, length)); 2803340d773SGleb Smirnoff dp = (const struct rerr_unreach *)(dat + sizeof(*ap)); 2818bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 2828bdc5a62SPatrick Kelsey for (dc = ap->rerr_dc; dc != 0; dc--) { 2838bdc5a62SPatrick Kelsey ND_TCHECK(*dp); 2848bdc5a62SPatrick Kelsey if (i < sizeof(*dp)) 2858bdc5a62SPatrick Kelsey goto trunc; 2863c602fabSXin LI ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da), 2873c602fabSXin LI (unsigned long)EXTRACT_32BITS(&dp->u_ds))); 2888bdc5a62SPatrick Kelsey dp++; 2898bdc5a62SPatrick Kelsey i -= sizeof(*dp); 2905b0fe478SBruce M Simpson } 2918bdc5a62SPatrick Kelsey return; 2928bdc5a62SPatrick Kelsey 2938bdc5a62SPatrick Kelsey trunc: 2943c602fabSXin LI ND_PRINT((ndo, "[|rerr]")); 2955b0fe478SBruce M Simpson } 2965b0fe478SBruce M Simpson 2975b0fe478SBruce M Simpson static void 2988bdc5a62SPatrick Kelsey aodv_v6_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 2995b0fe478SBruce M Simpson { 3005b0fe478SBruce M Simpson u_int i; 3018bdc5a62SPatrick Kelsey const struct aodv_rreq6 *ap = (const struct aodv_rreq6 *)dat; 3025b0fe478SBruce M Simpson 3038bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 3048bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3058bdc5a62SPatrick Kelsey goto trunc; 3063c602fabSXin LI ND_PRINT((ndo, " v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 3075b0fe478SBruce M Simpson "\tdst %s seq %lu src %s seq %lu", length, 3088bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_JOIN ? "[J]" : "", 3098bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_REPAIR ? "[R]" : "", 3108bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_GRAT ? "[G]" : "", 3118bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_DEST ? "[D]" : "", 3128bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 3138bdc5a62SPatrick Kelsey ap->rreq_hops, 3148bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_id), 3158bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rreq_da), 3168bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), 3178bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rreq_oa), 3188bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); 3198bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 3205b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 3218bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 3228bdc5a62SPatrick Kelsey return; 3238bdc5a62SPatrick Kelsey 3248bdc5a62SPatrick Kelsey trunc: 3258bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 3265b0fe478SBruce M Simpson } 3275b0fe478SBruce M Simpson 3285b0fe478SBruce M Simpson static void 3298bdc5a62SPatrick Kelsey aodv_v6_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 3305b0fe478SBruce M Simpson { 3315b0fe478SBruce M Simpson u_int i; 3328bdc5a62SPatrick Kelsey const struct aodv_rrep6 *ap = (const struct aodv_rrep6 *)dat; 3335b0fe478SBruce M Simpson 3348bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 3358bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3368bdc5a62SPatrick Kelsey goto trunc; 3373c602fabSXin LI ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" 3385b0fe478SBruce M Simpson "\tdst %s dseq %lu src %s %lu ms", length, 3398bdc5a62SPatrick Kelsey ap->rrep_type & RREP_REPAIR ? "[R]" : "", 3408bdc5a62SPatrick Kelsey ap->rrep_type & RREP_ACK ? "[A] " : " ", 3418bdc5a62SPatrick Kelsey ap->rrep_ps & RREP_PREFIX_MASK, 3428bdc5a62SPatrick Kelsey ap->rrep_hops, 3438bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rrep_da), 3448bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), 3458bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rrep_oa), 3468bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); 3478bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 3485b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 3498bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 3508bdc5a62SPatrick Kelsey return; 3518bdc5a62SPatrick Kelsey 3528bdc5a62SPatrick Kelsey trunc: 3538bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 3545b0fe478SBruce M Simpson } 3555b0fe478SBruce M Simpson 3565b0fe478SBruce M Simpson static void 3578bdc5a62SPatrick Kelsey aodv_v6_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 3585b0fe478SBruce M Simpson { 3598bdc5a62SPatrick Kelsey u_int i, dc; 3608bdc5a62SPatrick Kelsey const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 3618bdc5a62SPatrick Kelsey const struct rerr_unreach6 *dp6; 3625b0fe478SBruce M Simpson 3638bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 3648bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3658bdc5a62SPatrick Kelsey goto trunc; 3663c602fabSXin LI ND_PRINT((ndo, " rerr %s [items %u] [%u]:", 3678bdc5a62SPatrick Kelsey ap->rerr_flags & RERR_NODELETE ? "[D]" : "", 3688bdc5a62SPatrick Kelsey ap->rerr_dc, length)); 3693340d773SGleb Smirnoff dp6 = (const struct rerr_unreach6 *)(const void *)(ap + 1); 3708bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 3718bdc5a62SPatrick Kelsey for (dc = ap->rerr_dc; dc != 0; dc--) { 3728bdc5a62SPatrick Kelsey ND_TCHECK(*dp6); 3738bdc5a62SPatrick Kelsey if (i < sizeof(*dp6)) 3748bdc5a62SPatrick Kelsey goto trunc; 3753c602fabSXin LI ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), 3763c602fabSXin LI (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); 3778bdc5a62SPatrick Kelsey dp6++; 3788bdc5a62SPatrick Kelsey i -= sizeof(*dp6); 3795b0fe478SBruce M Simpson } 3808bdc5a62SPatrick Kelsey return; 3818bdc5a62SPatrick Kelsey 3828bdc5a62SPatrick Kelsey trunc: 3833c602fabSXin LI ND_PRINT((ndo, "[|rerr]")); 3845b0fe478SBruce M Simpson } 3855b0fe478SBruce M Simpson 3865b0fe478SBruce M Simpson static void 3878bdc5a62SPatrick Kelsey aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 3885b0fe478SBruce M Simpson { 3895b0fe478SBruce M Simpson u_int i; 3908bdc5a62SPatrick Kelsey const struct aodv_rreq6_draft_01 *ap = (const struct aodv_rreq6_draft_01 *)dat; 3915b0fe478SBruce M Simpson 3928bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 3938bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3948bdc5a62SPatrick Kelsey goto trunc; 3953c602fabSXin LI ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 3965b0fe478SBruce M Simpson "\tdst %s seq %lu src %s seq %lu", length, 3978bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_JOIN ? "[J]" : "", 3988bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_REPAIR ? "[R]" : "", 3998bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_GRAT ? "[G]" : "", 4008bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_DEST ? "[D]" : "", 4018bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 4028bdc5a62SPatrick Kelsey ap->rreq_hops, 4038bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_id), 4048bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rreq_da), 4058bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), 4068bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rreq_oa), 4078bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); 4088bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 4095b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 4108bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 4118bdc5a62SPatrick Kelsey return; 4128bdc5a62SPatrick Kelsey 4138bdc5a62SPatrick Kelsey trunc: 4148bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 4155b0fe478SBruce M Simpson } 4165b0fe478SBruce M Simpson 4175b0fe478SBruce M Simpson static void 4188bdc5a62SPatrick Kelsey aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 4195b0fe478SBruce M Simpson { 4205b0fe478SBruce M Simpson u_int i; 4218bdc5a62SPatrick Kelsey const struct aodv_rrep6_draft_01 *ap = (const struct aodv_rrep6_draft_01 *)dat; 4225b0fe478SBruce M Simpson 4238bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 4248bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 4258bdc5a62SPatrick Kelsey goto trunc; 4263c602fabSXin LI ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" 4275b0fe478SBruce M Simpson "\tdst %s dseq %lu src %s %lu ms", length, 4288bdc5a62SPatrick Kelsey ap->rrep_type & RREP_REPAIR ? "[R]" : "", 4298bdc5a62SPatrick Kelsey ap->rrep_type & RREP_ACK ? "[A] " : " ", 4308bdc5a62SPatrick Kelsey ap->rrep_ps & RREP_PREFIX_MASK, 4318bdc5a62SPatrick Kelsey ap->rrep_hops, 4328bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rrep_da), 4338bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), 4348bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rrep_oa), 4358bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); 4368bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 4375b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 4388bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 4398bdc5a62SPatrick Kelsey return; 4408bdc5a62SPatrick Kelsey 4418bdc5a62SPatrick Kelsey trunc: 4428bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 4435b0fe478SBruce M Simpson } 4445b0fe478SBruce M Simpson 4455b0fe478SBruce M Simpson static void 4468bdc5a62SPatrick Kelsey aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 4475b0fe478SBruce M Simpson { 4488bdc5a62SPatrick Kelsey u_int i, dc; 4498bdc5a62SPatrick Kelsey const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 4508bdc5a62SPatrick Kelsey const struct rerr_unreach6_draft_01 *dp6; 4515b0fe478SBruce M Simpson 4528bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 4538bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 4548bdc5a62SPatrick Kelsey goto trunc; 4553c602fabSXin LI ND_PRINT((ndo, " rerr %s [items %u] [%u]:", 4568bdc5a62SPatrick Kelsey ap->rerr_flags & RERR_NODELETE ? "[D]" : "", 4578bdc5a62SPatrick Kelsey ap->rerr_dc, length)); 4583340d773SGleb Smirnoff dp6 = (const struct rerr_unreach6_draft_01 *)(const void *)(ap + 1); 4598bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 4608bdc5a62SPatrick Kelsey for (dc = ap->rerr_dc; dc != 0; dc--) { 4618bdc5a62SPatrick Kelsey ND_TCHECK(*dp6); 4628bdc5a62SPatrick Kelsey if (i < sizeof(*dp6)) 4638bdc5a62SPatrick Kelsey goto trunc; 4643c602fabSXin LI ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), 4653c602fabSXin LI (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); 4668bdc5a62SPatrick Kelsey dp6++; 4678bdc5a62SPatrick Kelsey i -= sizeof(*dp6); 4685b0fe478SBruce M Simpson } 4698bdc5a62SPatrick Kelsey return; 4708bdc5a62SPatrick Kelsey 4718bdc5a62SPatrick Kelsey trunc: 4723c602fabSXin LI ND_PRINT((ndo, "[|rerr]")); 4735b0fe478SBruce M Simpson } 4745b0fe478SBruce M Simpson 4755b0fe478SBruce M Simpson void 4763c602fabSXin LI aodv_print(netdissect_options *ndo, 4773c602fabSXin LI const u_char *dat, u_int length, int is_ip6) 4785b0fe478SBruce M Simpson { 4798bdc5a62SPatrick Kelsey uint8_t msg_type; 4805b0fe478SBruce M Simpson 4818bdc5a62SPatrick Kelsey /* 4828bdc5a62SPatrick Kelsey * The message type is the first byte; make sure we have it 4838bdc5a62SPatrick Kelsey * and then fetch it. 4848bdc5a62SPatrick Kelsey */ 4858bdc5a62SPatrick Kelsey ND_TCHECK(*dat); 4868bdc5a62SPatrick Kelsey msg_type = *dat; 4873c602fabSXin LI ND_PRINT((ndo, " aodv")); 4885b0fe478SBruce M Simpson 4898bdc5a62SPatrick Kelsey switch (msg_type) { 4905b0fe478SBruce M Simpson 4915b0fe478SBruce M Simpson case AODV_RREQ: 4925b0fe478SBruce M Simpson if (is_ip6) 4938bdc5a62SPatrick Kelsey aodv_v6_rreq(ndo, dat, length); 4945b0fe478SBruce M Simpson else 4958bdc5a62SPatrick Kelsey aodv_rreq(ndo, dat, length); 4965b0fe478SBruce M Simpson break; 4975b0fe478SBruce M Simpson 4985b0fe478SBruce M Simpson case AODV_RREP: 4995b0fe478SBruce M Simpson if (is_ip6) 5008bdc5a62SPatrick Kelsey aodv_v6_rrep(ndo, dat, length); 5015b0fe478SBruce M Simpson else 5028bdc5a62SPatrick Kelsey aodv_rrep(ndo, dat, length); 5035b0fe478SBruce M Simpson break; 5045b0fe478SBruce M Simpson 5055b0fe478SBruce M Simpson case AODV_RERR: 5065b0fe478SBruce M Simpson if (is_ip6) 5078bdc5a62SPatrick Kelsey aodv_v6_rerr(ndo, dat, length); 5085b0fe478SBruce M Simpson else 5098bdc5a62SPatrick Kelsey aodv_rerr(ndo, dat, length); 5105b0fe478SBruce M Simpson break; 5115b0fe478SBruce M Simpson 5125b0fe478SBruce M Simpson case AODV_RREP_ACK: 5133c602fabSXin LI ND_PRINT((ndo, " rrep-ack %u", length)); 5145b0fe478SBruce M Simpson break; 5155b0fe478SBruce M Simpson 5165b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RREQ: 5178bdc5a62SPatrick Kelsey aodv_v6_draft_01_rreq(ndo, dat, length); 5185b0fe478SBruce M Simpson break; 5195b0fe478SBruce M Simpson 5205b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RREP: 5218bdc5a62SPatrick Kelsey aodv_v6_draft_01_rrep(ndo, dat, length); 5225b0fe478SBruce M Simpson break; 5235b0fe478SBruce M Simpson 5245b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RERR: 5258bdc5a62SPatrick Kelsey aodv_v6_draft_01_rerr(ndo, dat, length); 5265b0fe478SBruce M Simpson break; 5275b0fe478SBruce M Simpson 5285b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RREP_ACK: 5293c602fabSXin LI ND_PRINT((ndo, " rrep-ack %u", length)); 5305b0fe478SBruce M Simpson break; 5315b0fe478SBruce M Simpson 5325b0fe478SBruce M Simpson default: 5338bdc5a62SPatrick Kelsey ND_PRINT((ndo, " type %u %u", msg_type, length)); 5345b0fe478SBruce M Simpson } 5358bdc5a62SPatrick Kelsey return; 5368bdc5a62SPatrick Kelsey 5378bdc5a62SPatrick Kelsey trunc: 5388bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|aodv]")); 5395b0fe478SBruce M Simpson } 540