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 33*3340d773SGleb Smirnoff /* \summary: Ad hoc On-Demand Distance Vector (AODV) Routing printer */ 34*3340d773SGleb Smirnoff 355b0fe478SBruce M Simpson #ifdef HAVE_CONFIG_H 365b0fe478SBruce M Simpson #include "config.h" 375b0fe478SBruce M Simpson #endif 385b0fe478SBruce M Simpson 39*3340d773SGleb Smirnoff #include <netdissect-stdinc.h> 405b0fe478SBruce M Simpson 41*3340d773SGleb Smirnoff #include "netdissect.h" 425b0fe478SBruce M Simpson #include "addrtoname.h" 43*3340d773SGleb Smirnoff #include "extract.h" 445b0fe478SBruce M Simpson 453c602fabSXin LI 463c602fabSXin LI struct aodv_rreq { 473c602fabSXin LI uint8_t rreq_type; /* AODV message type (1) */ 483c602fabSXin LI uint8_t rreq_flags; /* various flags */ 493c602fabSXin LI uint8_t rreq_zero0; /* reserved, set to zero */ 503c602fabSXin LI uint8_t rreq_hops; /* number of hops from originator */ 513c602fabSXin LI uint32_t rreq_id; /* request ID */ 523c602fabSXin LI uint32_t rreq_da; /* destination IPv4 address */ 533c602fabSXin LI uint32_t rreq_ds; /* destination sequence number */ 543c602fabSXin LI uint32_t rreq_oa; /* originator IPv4 address */ 553c602fabSXin LI uint32_t rreq_os; /* originator sequence number */ 563c602fabSXin LI }; 573c602fabSXin LI struct aodv_rreq6 { 583c602fabSXin LI uint8_t rreq_type; /* AODV message type (1) */ 593c602fabSXin LI uint8_t rreq_flags; /* various flags */ 603c602fabSXin LI uint8_t rreq_zero0; /* reserved, set to zero */ 613c602fabSXin LI uint8_t rreq_hops; /* number of hops from originator */ 623c602fabSXin LI uint32_t rreq_id; /* request ID */ 633c602fabSXin LI struct in6_addr rreq_da; /* destination IPv6 address */ 643c602fabSXin LI uint32_t rreq_ds; /* destination sequence number */ 653c602fabSXin LI struct in6_addr rreq_oa; /* originator IPv6 address */ 663c602fabSXin LI uint32_t rreq_os; /* originator sequence number */ 673c602fabSXin LI }; 683c602fabSXin LI struct aodv_rreq6_draft_01 { 693c602fabSXin LI uint8_t rreq_type; /* AODV message type (16) */ 703c602fabSXin LI uint8_t rreq_flags; /* various flags */ 713c602fabSXin LI uint8_t rreq_zero0; /* reserved, set to zero */ 723c602fabSXin LI uint8_t rreq_hops; /* number of hops from originator */ 733c602fabSXin LI uint32_t rreq_id; /* request ID */ 743c602fabSXin LI uint32_t rreq_ds; /* destination sequence number */ 753c602fabSXin LI uint32_t rreq_os; /* originator sequence number */ 763c602fabSXin LI struct in6_addr rreq_da; /* destination IPv6 address */ 773c602fabSXin LI struct in6_addr rreq_oa; /* originator IPv6 address */ 783c602fabSXin LI }; 793c602fabSXin LI 803c602fabSXin LI #define RREQ_JOIN 0x80 /* join (reserved for multicast */ 813c602fabSXin LI #define RREQ_REPAIR 0x40 /* repair (reserved for multicast */ 823c602fabSXin LI #define RREQ_GRAT 0x20 /* gratuitous RREP */ 833c602fabSXin LI #define RREQ_DEST 0x10 /* destination only */ 843c602fabSXin LI #define RREQ_UNKNOWN 0x08 /* unknown destination sequence num */ 853c602fabSXin LI #define RREQ_FLAGS_MASK 0xF8 /* mask for rreq_flags */ 863c602fabSXin LI 873c602fabSXin LI struct aodv_rrep { 883c602fabSXin LI uint8_t rrep_type; /* AODV message type (2) */ 893c602fabSXin LI uint8_t rrep_flags; /* various flags */ 903c602fabSXin LI uint8_t rrep_ps; /* prefix size */ 913c602fabSXin LI uint8_t rrep_hops; /* number of hops from o to d */ 923c602fabSXin LI uint32_t rrep_da; /* destination IPv4 address */ 933c602fabSXin LI uint32_t rrep_ds; /* destination sequence number */ 943c602fabSXin LI uint32_t rrep_oa; /* originator IPv4 address */ 953c602fabSXin LI uint32_t rrep_life; /* lifetime of this route */ 963c602fabSXin LI }; 973c602fabSXin LI struct aodv_rrep6 { 983c602fabSXin LI uint8_t rrep_type; /* AODV message type (2) */ 993c602fabSXin LI uint8_t rrep_flags; /* various flags */ 1003c602fabSXin LI uint8_t rrep_ps; /* prefix size */ 1013c602fabSXin LI uint8_t rrep_hops; /* number of hops from o to d */ 1023c602fabSXin LI struct in6_addr rrep_da; /* destination IPv6 address */ 1033c602fabSXin LI uint32_t rrep_ds; /* destination sequence number */ 1043c602fabSXin LI struct in6_addr rrep_oa; /* originator IPv6 address */ 1053c602fabSXin LI uint32_t rrep_life; /* lifetime of this route */ 1063c602fabSXin LI }; 1073c602fabSXin LI struct aodv_rrep6_draft_01 { 1083c602fabSXin LI uint8_t rrep_type; /* AODV message type (17) */ 1093c602fabSXin LI uint8_t rrep_flags; /* various flags */ 1103c602fabSXin LI uint8_t rrep_ps; /* prefix size */ 1113c602fabSXin LI uint8_t rrep_hops; /* number of hops from o to d */ 1123c602fabSXin LI uint32_t rrep_ds; /* destination sequence number */ 1133c602fabSXin LI struct in6_addr rrep_da; /* destination IPv6 address */ 1143c602fabSXin LI struct in6_addr rrep_oa; /* originator IPv6 address */ 1153c602fabSXin LI uint32_t rrep_life; /* lifetime of this route */ 1163c602fabSXin LI }; 1173c602fabSXin LI 1183c602fabSXin LI #define RREP_REPAIR 0x80 /* repair (reserved for multicast */ 1193c602fabSXin LI #define RREP_ACK 0x40 /* acknowledgement required */ 1203c602fabSXin LI #define RREP_FLAGS_MASK 0xC0 /* mask for rrep_flags */ 1213c602fabSXin LI #define RREP_PREFIX_MASK 0x1F /* mask for prefix size */ 1223c602fabSXin LI 1233c602fabSXin LI struct rerr_unreach { 1243c602fabSXin LI uint32_t u_da; /* IPv4 address */ 1253c602fabSXin LI uint32_t u_ds; /* sequence number */ 1263c602fabSXin LI }; 1273c602fabSXin LI struct rerr_unreach6 { 1283c602fabSXin LI struct in6_addr u_da; /* IPv6 address */ 1293c602fabSXin LI uint32_t u_ds; /* sequence number */ 1303c602fabSXin LI }; 1313c602fabSXin LI struct rerr_unreach6_draft_01 { 1323c602fabSXin LI struct in6_addr u_da; /* IPv6 address */ 1333c602fabSXin LI uint32_t u_ds; /* sequence number */ 1343c602fabSXin LI }; 1353c602fabSXin LI 1363c602fabSXin LI struct aodv_rerr { 1373c602fabSXin LI uint8_t rerr_type; /* AODV message type (3 or 18) */ 1383c602fabSXin LI uint8_t rerr_flags; /* various flags */ 1393c602fabSXin LI uint8_t rerr_zero0; /* reserved, set to zero */ 1403c602fabSXin LI uint8_t rerr_dc; /* destination count */ 1413c602fabSXin LI }; 1423c602fabSXin LI 1433c602fabSXin LI #define RERR_NODELETE 0x80 /* don't delete the link */ 1443c602fabSXin LI #define RERR_FLAGS_MASK 0x80 /* mask for rerr_flags */ 1453c602fabSXin LI 1463c602fabSXin LI struct aodv_rrep_ack { 1473c602fabSXin LI uint8_t ra_type; 1483c602fabSXin LI uint8_t ra_zero0; 1493c602fabSXin LI }; 1503c602fabSXin LI 1513c602fabSXin LI #define AODV_RREQ 1 /* route request */ 1523c602fabSXin LI #define AODV_RREP 2 /* route response */ 1533c602fabSXin LI #define AODV_RERR 3 /* error report */ 1543c602fabSXin LI #define AODV_RREP_ACK 4 /* route response acknowledgement */ 1553c602fabSXin LI 1563c602fabSXin LI #define AODV_V6_DRAFT_01_RREQ 16 /* IPv6 route request */ 1573c602fabSXin LI #define AODV_V6_DRAFT_01_RREP 17 /* IPv6 route response */ 1583c602fabSXin LI #define AODV_V6_DRAFT_01_RERR 18 /* IPv6 error report */ 1593c602fabSXin LI #define AODV_V6_DRAFT_01_RREP_ACK 19 /* IPV6 route response acknowledgment */ 1603c602fabSXin LI 1613c602fabSXin LI struct aodv_ext { 1623c602fabSXin LI uint8_t type; /* extension type */ 1633c602fabSXin LI uint8_t length; /* extension length */ 1643c602fabSXin LI }; 1653c602fabSXin LI 1663c602fabSXin LI struct aodv_hello { 1673c602fabSXin LI struct aodv_ext eh; /* extension header */ 1683c602fabSXin LI uint8_t interval[4]; /* expect my next hello in 1693c602fabSXin LI * (n) ms 1703c602fabSXin LI * NOTE: this is not aligned */ 1713c602fabSXin LI }; 1723c602fabSXin LI 1733c602fabSXin LI #define AODV_EXT_HELLO 1 1745b0fe478SBruce M Simpson 1755b0fe478SBruce M Simpson static void 1763c602fabSXin LI aodv_extension(netdissect_options *ndo, 1773c602fabSXin LI const struct aodv_ext *ep, u_int length) 1785b0fe478SBruce M Simpson { 1795b0fe478SBruce M Simpson const struct aodv_hello *ah; 1805b0fe478SBruce M Simpson 1815b0fe478SBruce M Simpson switch (ep->type) { 1825b0fe478SBruce M Simpson case AODV_EXT_HELLO: 1838bdc5a62SPatrick Kelsey ah = (const struct aodv_hello *)(const void *)ep; 1848bdc5a62SPatrick Kelsey ND_TCHECK(*ah); 1858bdc5a62SPatrick Kelsey if (length < sizeof(struct aodv_hello)) 1868bdc5a62SPatrick Kelsey goto trunc; 1873c602fabSXin LI ND_PRINT((ndo, "\n\text HELLO %ld ms", 1883c602fabSXin LI (unsigned long)EXTRACT_32BITS(&ah->interval))); 1895b0fe478SBruce M Simpson break; 1905b0fe478SBruce M Simpson 1915b0fe478SBruce M Simpson default: 1923c602fabSXin LI ND_PRINT((ndo, "\n\text %u %u", ep->type, ep->length)); 1935b0fe478SBruce M Simpson break; 1945b0fe478SBruce M Simpson } 1958bdc5a62SPatrick Kelsey return; 1968bdc5a62SPatrick Kelsey 1978bdc5a62SPatrick Kelsey trunc: 1988bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|hello]")); 1995b0fe478SBruce M Simpson } 2005b0fe478SBruce M Simpson 2015b0fe478SBruce M Simpson static void 2028bdc5a62SPatrick Kelsey aodv_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 2035b0fe478SBruce M Simpson { 2045b0fe478SBruce M Simpson u_int i; 2058bdc5a62SPatrick Kelsey const struct aodv_rreq *ap = (const struct aodv_rreq *)dat; 2065b0fe478SBruce M Simpson 2078bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 2088bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 2098bdc5a62SPatrick Kelsey goto trunc; 2103c602fabSXin LI ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 2115b0fe478SBruce M Simpson "\tdst %s seq %lu src %s seq %lu", length, 2128bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_JOIN ? "[J]" : "", 2138bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_REPAIR ? "[R]" : "", 2148bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_GRAT ? "[G]" : "", 2158bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_DEST ? "[D]" : "", 2168bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 2178bdc5a62SPatrick Kelsey ap->rreq_hops, 2188bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_id), 2198bdc5a62SPatrick Kelsey ipaddr_string(ndo, &ap->rreq_da), 2208bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), 2218bdc5a62SPatrick Kelsey ipaddr_string(ndo, &ap->rreq_oa), 2228bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); 2238bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 2245b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 2258bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 2268bdc5a62SPatrick Kelsey return; 2278bdc5a62SPatrick Kelsey 2288bdc5a62SPatrick Kelsey trunc: 2298bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 2305b0fe478SBruce M Simpson } 2315b0fe478SBruce M Simpson 2325b0fe478SBruce M Simpson static void 2338bdc5a62SPatrick Kelsey aodv_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 2345b0fe478SBruce M Simpson { 2355b0fe478SBruce M Simpson u_int i; 2368bdc5a62SPatrick Kelsey const struct aodv_rrep *ap = (const struct aodv_rrep *)dat; 2375b0fe478SBruce M Simpson 2388bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 2398bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 2408bdc5a62SPatrick Kelsey goto trunc; 2413c602fabSXin LI ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" 2425b0fe478SBruce M Simpson "\tdst %s dseq %lu src %s %lu ms", length, 2438bdc5a62SPatrick Kelsey ap->rrep_type & RREP_REPAIR ? "[R]" : "", 2448bdc5a62SPatrick Kelsey ap->rrep_type & RREP_ACK ? "[A] " : " ", 2458bdc5a62SPatrick Kelsey ap->rrep_ps & RREP_PREFIX_MASK, 2468bdc5a62SPatrick Kelsey ap->rrep_hops, 2478bdc5a62SPatrick Kelsey ipaddr_string(ndo, &ap->rrep_da), 2488bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), 2498bdc5a62SPatrick Kelsey ipaddr_string(ndo, &ap->rrep_oa), 2508bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); 2518bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 2525b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 2538bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 2548bdc5a62SPatrick Kelsey return; 2558bdc5a62SPatrick Kelsey 2568bdc5a62SPatrick Kelsey trunc: 2578bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 2585b0fe478SBruce M Simpson } 2595b0fe478SBruce M Simpson 2605b0fe478SBruce M Simpson static void 2618bdc5a62SPatrick Kelsey aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 2625b0fe478SBruce M Simpson { 2638bdc5a62SPatrick Kelsey u_int i, dc; 2648bdc5a62SPatrick Kelsey const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 2658bdc5a62SPatrick Kelsey const struct rerr_unreach *dp; 2665b0fe478SBruce M Simpson 2678bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 2688bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 2698bdc5a62SPatrick Kelsey goto trunc; 2703c602fabSXin LI ND_PRINT((ndo, " rerr %s [items %u] [%u]:", 2718bdc5a62SPatrick Kelsey ap->rerr_flags & RERR_NODELETE ? "[D]" : "", 2728bdc5a62SPatrick Kelsey ap->rerr_dc, length)); 273*3340d773SGleb Smirnoff dp = (const struct rerr_unreach *)(dat + sizeof(*ap)); 2748bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 2758bdc5a62SPatrick Kelsey for (dc = ap->rerr_dc; dc != 0; dc--) { 2768bdc5a62SPatrick Kelsey ND_TCHECK(*dp); 2778bdc5a62SPatrick Kelsey if (i < sizeof(*dp)) 2788bdc5a62SPatrick Kelsey goto trunc; 2793c602fabSXin LI ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da), 2803c602fabSXin LI (unsigned long)EXTRACT_32BITS(&dp->u_ds))); 2818bdc5a62SPatrick Kelsey dp++; 2828bdc5a62SPatrick Kelsey i -= sizeof(*dp); 2835b0fe478SBruce M Simpson } 2848bdc5a62SPatrick Kelsey return; 2858bdc5a62SPatrick Kelsey 2868bdc5a62SPatrick Kelsey trunc: 2873c602fabSXin LI ND_PRINT((ndo, "[|rerr]")); 2885b0fe478SBruce M Simpson } 2895b0fe478SBruce M Simpson 2905b0fe478SBruce M Simpson static void 2918bdc5a62SPatrick Kelsey aodv_v6_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 2925b0fe478SBruce M Simpson { 2935b0fe478SBruce M Simpson u_int i; 2948bdc5a62SPatrick Kelsey const struct aodv_rreq6 *ap = (const struct aodv_rreq6 *)dat; 2955b0fe478SBruce M Simpson 2968bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 2978bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 2988bdc5a62SPatrick Kelsey goto trunc; 2993c602fabSXin LI ND_PRINT((ndo, " v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 3005b0fe478SBruce M Simpson "\tdst %s seq %lu src %s seq %lu", length, 3018bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_JOIN ? "[J]" : "", 3028bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_REPAIR ? "[R]" : "", 3038bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_GRAT ? "[G]" : "", 3048bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_DEST ? "[D]" : "", 3058bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 3068bdc5a62SPatrick Kelsey ap->rreq_hops, 3078bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_id), 3088bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rreq_da), 3098bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), 3108bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rreq_oa), 3118bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); 3128bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 3135b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 3148bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 3158bdc5a62SPatrick Kelsey return; 3168bdc5a62SPatrick Kelsey 3178bdc5a62SPatrick Kelsey trunc: 3188bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 3195b0fe478SBruce M Simpson } 3205b0fe478SBruce M Simpson 3215b0fe478SBruce M Simpson static void 3228bdc5a62SPatrick Kelsey aodv_v6_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 3235b0fe478SBruce M Simpson { 3245b0fe478SBruce M Simpson u_int i; 3258bdc5a62SPatrick Kelsey const struct aodv_rrep6 *ap = (const struct aodv_rrep6 *)dat; 3265b0fe478SBruce M Simpson 3278bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 3288bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3298bdc5a62SPatrick Kelsey goto trunc; 3303c602fabSXin LI ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" 3315b0fe478SBruce M Simpson "\tdst %s dseq %lu src %s %lu ms", length, 3328bdc5a62SPatrick Kelsey ap->rrep_type & RREP_REPAIR ? "[R]" : "", 3338bdc5a62SPatrick Kelsey ap->rrep_type & RREP_ACK ? "[A] " : " ", 3348bdc5a62SPatrick Kelsey ap->rrep_ps & RREP_PREFIX_MASK, 3358bdc5a62SPatrick Kelsey ap->rrep_hops, 3368bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rrep_da), 3378bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), 3388bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rrep_oa), 3398bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); 3408bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 3415b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 3428bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 3438bdc5a62SPatrick Kelsey return; 3448bdc5a62SPatrick Kelsey 3458bdc5a62SPatrick Kelsey trunc: 3468bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 3475b0fe478SBruce M Simpson } 3485b0fe478SBruce M Simpson 3495b0fe478SBruce M Simpson static void 3508bdc5a62SPatrick Kelsey aodv_v6_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 3515b0fe478SBruce M Simpson { 3528bdc5a62SPatrick Kelsey u_int i, dc; 3538bdc5a62SPatrick Kelsey const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 3548bdc5a62SPatrick Kelsey const struct rerr_unreach6 *dp6; 3555b0fe478SBruce M Simpson 3568bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 3578bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3588bdc5a62SPatrick Kelsey goto trunc; 3593c602fabSXin LI ND_PRINT((ndo, " rerr %s [items %u] [%u]:", 3608bdc5a62SPatrick Kelsey ap->rerr_flags & RERR_NODELETE ? "[D]" : "", 3618bdc5a62SPatrick Kelsey ap->rerr_dc, length)); 362*3340d773SGleb Smirnoff dp6 = (const struct rerr_unreach6 *)(const void *)(ap + 1); 3638bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 3648bdc5a62SPatrick Kelsey for (dc = ap->rerr_dc; dc != 0; dc--) { 3658bdc5a62SPatrick Kelsey ND_TCHECK(*dp6); 3668bdc5a62SPatrick Kelsey if (i < sizeof(*dp6)) 3678bdc5a62SPatrick Kelsey goto trunc; 3683c602fabSXin LI ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), 3693c602fabSXin LI (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); 3708bdc5a62SPatrick Kelsey dp6++; 3718bdc5a62SPatrick Kelsey i -= sizeof(*dp6); 3725b0fe478SBruce M Simpson } 3738bdc5a62SPatrick Kelsey return; 3748bdc5a62SPatrick Kelsey 3758bdc5a62SPatrick Kelsey trunc: 3763c602fabSXin LI ND_PRINT((ndo, "[|rerr]")); 3775b0fe478SBruce M Simpson } 3785b0fe478SBruce M Simpson 3795b0fe478SBruce M Simpson static void 3808bdc5a62SPatrick Kelsey aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 3815b0fe478SBruce M Simpson { 3825b0fe478SBruce M Simpson u_int i; 3838bdc5a62SPatrick Kelsey const struct aodv_rreq6_draft_01 *ap = (const struct aodv_rreq6_draft_01 *)dat; 3845b0fe478SBruce M Simpson 3858bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 3868bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 3878bdc5a62SPatrick Kelsey goto trunc; 3883c602fabSXin LI ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 3895b0fe478SBruce M Simpson "\tdst %s seq %lu src %s seq %lu", length, 3908bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_JOIN ? "[J]" : "", 3918bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_REPAIR ? "[R]" : "", 3928bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_GRAT ? "[G]" : "", 3938bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_DEST ? "[D]" : "", 3948bdc5a62SPatrick Kelsey ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 3958bdc5a62SPatrick Kelsey ap->rreq_hops, 3968bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_id), 3978bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rreq_da), 3988bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), 3998bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rreq_oa), 4008bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); 4018bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 4025b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 4038bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 4048bdc5a62SPatrick Kelsey return; 4058bdc5a62SPatrick Kelsey 4068bdc5a62SPatrick Kelsey trunc: 4078bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 4085b0fe478SBruce M Simpson } 4095b0fe478SBruce M Simpson 4105b0fe478SBruce M Simpson static void 4118bdc5a62SPatrick Kelsey aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 4125b0fe478SBruce M Simpson { 4135b0fe478SBruce M Simpson u_int i; 4148bdc5a62SPatrick Kelsey const struct aodv_rrep6_draft_01 *ap = (const struct aodv_rrep6_draft_01 *)dat; 4155b0fe478SBruce M Simpson 4168bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 4178bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 4188bdc5a62SPatrick Kelsey goto trunc; 4193c602fabSXin LI ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" 4205b0fe478SBruce M Simpson "\tdst %s dseq %lu src %s %lu ms", length, 4218bdc5a62SPatrick Kelsey ap->rrep_type & RREP_REPAIR ? "[R]" : "", 4228bdc5a62SPatrick Kelsey ap->rrep_type & RREP_ACK ? "[A] " : " ", 4238bdc5a62SPatrick Kelsey ap->rrep_ps & RREP_PREFIX_MASK, 4248bdc5a62SPatrick Kelsey ap->rrep_hops, 4258bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rrep_da), 4268bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), 4278bdc5a62SPatrick Kelsey ip6addr_string(ndo, &ap->rrep_oa), 4288bdc5a62SPatrick Kelsey (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); 4298bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 4305b0fe478SBruce M Simpson if (i >= sizeof(struct aodv_ext)) 4318bdc5a62SPatrick Kelsey aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 4328bdc5a62SPatrick Kelsey return; 4338bdc5a62SPatrick Kelsey 4348bdc5a62SPatrick Kelsey trunc: 4358bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|rreq")); 4365b0fe478SBruce M Simpson } 4375b0fe478SBruce M Simpson 4385b0fe478SBruce M Simpson static void 4398bdc5a62SPatrick Kelsey aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 4405b0fe478SBruce M Simpson { 4418bdc5a62SPatrick Kelsey u_int i, dc; 4428bdc5a62SPatrick Kelsey const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 4438bdc5a62SPatrick Kelsey const struct rerr_unreach6_draft_01 *dp6; 4445b0fe478SBruce M Simpson 4458bdc5a62SPatrick Kelsey ND_TCHECK(*ap); 4468bdc5a62SPatrick Kelsey if (length < sizeof(*ap)) 4478bdc5a62SPatrick Kelsey goto trunc; 4483c602fabSXin LI ND_PRINT((ndo, " rerr %s [items %u] [%u]:", 4498bdc5a62SPatrick Kelsey ap->rerr_flags & RERR_NODELETE ? "[D]" : "", 4508bdc5a62SPatrick Kelsey ap->rerr_dc, length)); 451*3340d773SGleb Smirnoff dp6 = (const struct rerr_unreach6_draft_01 *)(const void *)(ap + 1); 4528bdc5a62SPatrick Kelsey i = length - sizeof(*ap); 4538bdc5a62SPatrick Kelsey for (dc = ap->rerr_dc; dc != 0; dc--) { 4548bdc5a62SPatrick Kelsey ND_TCHECK(*dp6); 4558bdc5a62SPatrick Kelsey if (i < sizeof(*dp6)) 4568bdc5a62SPatrick Kelsey goto trunc; 4573c602fabSXin LI ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), 4583c602fabSXin LI (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); 4598bdc5a62SPatrick Kelsey dp6++; 4608bdc5a62SPatrick Kelsey i -= sizeof(*dp6); 4615b0fe478SBruce M Simpson } 4628bdc5a62SPatrick Kelsey return; 4638bdc5a62SPatrick Kelsey 4648bdc5a62SPatrick Kelsey trunc: 4653c602fabSXin LI ND_PRINT((ndo, "[|rerr]")); 4665b0fe478SBruce M Simpson } 4675b0fe478SBruce M Simpson 4685b0fe478SBruce M Simpson void 4693c602fabSXin LI aodv_print(netdissect_options *ndo, 4703c602fabSXin LI const u_char *dat, u_int length, int is_ip6) 4715b0fe478SBruce M Simpson { 4728bdc5a62SPatrick Kelsey uint8_t msg_type; 4735b0fe478SBruce M Simpson 4748bdc5a62SPatrick Kelsey /* 4758bdc5a62SPatrick Kelsey * The message type is the first byte; make sure we have it 4768bdc5a62SPatrick Kelsey * and then fetch it. 4778bdc5a62SPatrick Kelsey */ 4788bdc5a62SPatrick Kelsey ND_TCHECK(*dat); 4798bdc5a62SPatrick Kelsey msg_type = *dat; 4803c602fabSXin LI ND_PRINT((ndo, " aodv")); 4815b0fe478SBruce M Simpson 4828bdc5a62SPatrick Kelsey switch (msg_type) { 4835b0fe478SBruce M Simpson 4845b0fe478SBruce M Simpson case AODV_RREQ: 4855b0fe478SBruce M Simpson if (is_ip6) 4868bdc5a62SPatrick Kelsey aodv_v6_rreq(ndo, dat, length); 4875b0fe478SBruce M Simpson else 4888bdc5a62SPatrick Kelsey aodv_rreq(ndo, dat, length); 4895b0fe478SBruce M Simpson break; 4905b0fe478SBruce M Simpson 4915b0fe478SBruce M Simpson case AODV_RREP: 4925b0fe478SBruce M Simpson if (is_ip6) 4938bdc5a62SPatrick Kelsey aodv_v6_rrep(ndo, dat, length); 4945b0fe478SBruce M Simpson else 4958bdc5a62SPatrick Kelsey aodv_rrep(ndo, dat, length); 4965b0fe478SBruce M Simpson break; 4975b0fe478SBruce M Simpson 4985b0fe478SBruce M Simpson case AODV_RERR: 4995b0fe478SBruce M Simpson if (is_ip6) 5008bdc5a62SPatrick Kelsey aodv_v6_rerr(ndo, dat, length); 5015b0fe478SBruce M Simpson else 5028bdc5a62SPatrick Kelsey aodv_rerr(ndo, dat, length); 5035b0fe478SBruce M Simpson break; 5045b0fe478SBruce M Simpson 5055b0fe478SBruce M Simpson case AODV_RREP_ACK: 5063c602fabSXin LI ND_PRINT((ndo, " rrep-ack %u", length)); 5075b0fe478SBruce M Simpson break; 5085b0fe478SBruce M Simpson 5095b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RREQ: 5108bdc5a62SPatrick Kelsey aodv_v6_draft_01_rreq(ndo, dat, length); 5115b0fe478SBruce M Simpson break; 5125b0fe478SBruce M Simpson 5135b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RREP: 5148bdc5a62SPatrick Kelsey aodv_v6_draft_01_rrep(ndo, dat, length); 5155b0fe478SBruce M Simpson break; 5165b0fe478SBruce M Simpson 5175b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RERR: 5188bdc5a62SPatrick Kelsey aodv_v6_draft_01_rerr(ndo, dat, length); 5195b0fe478SBruce M Simpson break; 5205b0fe478SBruce M Simpson 5215b0fe478SBruce M Simpson case AODV_V6_DRAFT_01_RREP_ACK: 5223c602fabSXin LI ND_PRINT((ndo, " rrep-ack %u", length)); 5235b0fe478SBruce M Simpson break; 5245b0fe478SBruce M Simpson 5255b0fe478SBruce M Simpson default: 5268bdc5a62SPatrick Kelsey ND_PRINT((ndo, " type %u %u", msg_type, length)); 5275b0fe478SBruce M Simpson } 5288bdc5a62SPatrick Kelsey return; 5298bdc5a62SPatrick Kelsey 5308bdc5a62SPatrick Kelsey trunc: 5318bdc5a62SPatrick Kelsey ND_PRINT((ndo, " [|aodv]")); 5325b0fe478SBruce M Simpson } 533