1 /* 2 * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bruce M. Simpson. 16 * 4. Neither the name of Bruce M. Simpson nor the names of co- 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bruce M. Simpson OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 #ifndef lint 35 __RCSID("$NetBSD: print-aodv.c,v 1.5 2015/03/31 21:59:35 christos Exp $"); 36 #endif 37 38 #define NETDISSECT_REWORKED 39 #ifdef HAVE_CONFIG_H 40 #include "config.h" 41 #endif 42 43 #include <tcpdump-stdinc.h> 44 45 #include "interface.h" 46 #include "addrtoname.h" 47 #include "extract.h" /* must come after interface.h */ 48 49 50 struct aodv_rreq { 51 uint8_t rreq_type; /* AODV message type (1) */ 52 uint8_t rreq_flags; /* various flags */ 53 uint8_t rreq_zero0; /* reserved, set to zero */ 54 uint8_t rreq_hops; /* number of hops from originator */ 55 uint32_t rreq_id; /* request ID */ 56 uint32_t rreq_da; /* destination IPv4 address */ 57 uint32_t rreq_ds; /* destination sequence number */ 58 uint32_t rreq_oa; /* originator IPv4 address */ 59 uint32_t rreq_os; /* originator sequence number */ 60 }; 61 #ifdef INET6 62 struct aodv_rreq6 { 63 uint8_t rreq_type; /* AODV message type (1) */ 64 uint8_t rreq_flags; /* various flags */ 65 uint8_t rreq_zero0; /* reserved, set to zero */ 66 uint8_t rreq_hops; /* number of hops from originator */ 67 uint32_t rreq_id; /* request ID */ 68 struct in6_addr rreq_da; /* destination IPv6 address */ 69 uint32_t rreq_ds; /* destination sequence number */ 70 struct in6_addr rreq_oa; /* originator IPv6 address */ 71 uint32_t rreq_os; /* originator sequence number */ 72 }; 73 struct aodv_rreq6_draft_01 { 74 uint8_t rreq_type; /* AODV message type (16) */ 75 uint8_t rreq_flags; /* various flags */ 76 uint8_t rreq_zero0; /* reserved, set to zero */ 77 uint8_t rreq_hops; /* number of hops from originator */ 78 uint32_t rreq_id; /* request ID */ 79 uint32_t rreq_ds; /* destination sequence number */ 80 uint32_t rreq_os; /* originator sequence number */ 81 struct in6_addr rreq_da; /* destination IPv6 address */ 82 struct in6_addr rreq_oa; /* originator IPv6 address */ 83 }; 84 #endif 85 86 #define RREQ_JOIN 0x80 /* join (reserved for multicast */ 87 #define RREQ_REPAIR 0x40 /* repair (reserved for multicast */ 88 #define RREQ_GRAT 0x20 /* gratuitous RREP */ 89 #define RREQ_DEST 0x10 /* destination only */ 90 #define RREQ_UNKNOWN 0x08 /* unknown destination sequence num */ 91 #define RREQ_FLAGS_MASK 0xF8 /* mask for rreq_flags */ 92 93 struct aodv_rrep { 94 uint8_t rrep_type; /* AODV message type (2) */ 95 uint8_t rrep_flags; /* various flags */ 96 uint8_t rrep_ps; /* prefix size */ 97 uint8_t rrep_hops; /* number of hops from o to d */ 98 uint32_t rrep_da; /* destination IPv4 address */ 99 uint32_t rrep_ds; /* destination sequence number */ 100 uint32_t rrep_oa; /* originator IPv4 address */ 101 uint32_t rrep_life; /* lifetime of this route */ 102 }; 103 #ifdef INET6 104 struct aodv_rrep6 { 105 uint8_t rrep_type; /* AODV message type (2) */ 106 uint8_t rrep_flags; /* various flags */ 107 uint8_t rrep_ps; /* prefix size */ 108 uint8_t rrep_hops; /* number of hops from o to d */ 109 struct in6_addr rrep_da; /* destination IPv6 address */ 110 uint32_t rrep_ds; /* destination sequence number */ 111 struct in6_addr rrep_oa; /* originator IPv6 address */ 112 uint32_t rrep_life; /* lifetime of this route */ 113 }; 114 struct aodv_rrep6_draft_01 { 115 uint8_t rrep_type; /* AODV message type (17) */ 116 uint8_t rrep_flags; /* various flags */ 117 uint8_t rrep_ps; /* prefix size */ 118 uint8_t rrep_hops; /* number of hops from o to d */ 119 uint32_t rrep_ds; /* destination sequence number */ 120 struct in6_addr rrep_da; /* destination IPv6 address */ 121 struct in6_addr rrep_oa; /* originator IPv6 address */ 122 uint32_t rrep_life; /* lifetime of this route */ 123 }; 124 #endif 125 126 #define RREP_REPAIR 0x80 /* repair (reserved for multicast */ 127 #define RREP_ACK 0x40 /* acknowledgement required */ 128 #define RREP_FLAGS_MASK 0xC0 /* mask for rrep_flags */ 129 #define RREP_PREFIX_MASK 0x1F /* mask for prefix size */ 130 131 struct rerr_unreach { 132 uint32_t u_da; /* IPv4 address */ 133 uint32_t u_ds; /* sequence number */ 134 }; 135 #ifdef INET6 136 struct rerr_unreach6 { 137 struct in6_addr u_da; /* IPv6 address */ 138 uint32_t u_ds; /* sequence number */ 139 }; 140 struct rerr_unreach6_draft_01 { 141 struct in6_addr u_da; /* IPv6 address */ 142 uint32_t u_ds; /* sequence number */ 143 }; 144 #endif 145 146 struct aodv_rerr { 147 uint8_t rerr_type; /* AODV message type (3 or 18) */ 148 uint8_t rerr_flags; /* various flags */ 149 uint8_t rerr_zero0; /* reserved, set to zero */ 150 uint8_t rerr_dc; /* destination count */ 151 }; 152 153 #define RERR_NODELETE 0x80 /* don't delete the link */ 154 #define RERR_FLAGS_MASK 0x80 /* mask for rerr_flags */ 155 156 struct aodv_rrep_ack { 157 uint8_t ra_type; 158 uint8_t ra_zero0; 159 }; 160 161 #define AODV_RREQ 1 /* route request */ 162 #define AODV_RREP 2 /* route response */ 163 #define AODV_RERR 3 /* error report */ 164 #define AODV_RREP_ACK 4 /* route response acknowledgement */ 165 166 #define AODV_V6_DRAFT_01_RREQ 16 /* IPv6 route request */ 167 #define AODV_V6_DRAFT_01_RREP 17 /* IPv6 route response */ 168 #define AODV_V6_DRAFT_01_RERR 18 /* IPv6 error report */ 169 #define AODV_V6_DRAFT_01_RREP_ACK 19 /* IPV6 route response acknowledgment */ 170 171 struct aodv_ext { 172 uint8_t type; /* extension type */ 173 uint8_t length; /* extension length */ 174 }; 175 176 struct aodv_hello { 177 struct aodv_ext eh; /* extension header */ 178 uint8_t interval[4]; /* expect my next hello in 179 * (n) ms 180 * NOTE: this is not aligned */ 181 }; 182 183 #define AODV_EXT_HELLO 1 184 185 static void 186 aodv_extension(netdissect_options *ndo, 187 const struct aodv_ext *ep, u_int length) 188 { 189 const struct aodv_hello *ah; 190 191 switch (ep->type) { 192 case AODV_EXT_HELLO: 193 ah = (const struct aodv_hello *)(const void *)ep; 194 ND_TCHECK(*ah); 195 if (length < sizeof(struct aodv_hello)) 196 goto trunc; 197 ND_PRINT((ndo, "\n\text HELLO %ld ms", 198 (unsigned long)EXTRACT_32BITS(&ah->interval))); 199 break; 200 201 default: 202 ND_PRINT((ndo, "\n\text %u %u", ep->type, ep->length)); 203 break; 204 } 205 return; 206 207 trunc: 208 ND_PRINT((ndo, " [|hello]")); 209 } 210 211 static void 212 aodv_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 213 { 214 u_int i; 215 const struct aodv_rreq *ap = (const struct aodv_rreq *)dat; 216 217 ND_TCHECK(*ap); 218 if (length < sizeof(*ap)) 219 goto trunc; 220 ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 221 "\tdst %s seq %lu src %s seq %lu", length, 222 ap->rreq_type & RREQ_JOIN ? "[J]" : "", 223 ap->rreq_type & RREQ_REPAIR ? "[R]" : "", 224 ap->rreq_type & RREQ_GRAT ? "[G]" : "", 225 ap->rreq_type & RREQ_DEST ? "[D]" : "", 226 ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 227 ap->rreq_hops, 228 (unsigned long)EXTRACT_32BITS(&ap->rreq_id), 229 ipaddr_string(ndo, &ap->rreq_da), 230 (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), 231 ipaddr_string(ndo, &ap->rreq_oa), 232 (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); 233 i = length - sizeof(*ap); 234 if (i >= sizeof(struct aodv_ext)) 235 aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 236 return; 237 238 trunc: 239 ND_PRINT((ndo, " [|rreq")); 240 } 241 242 static void 243 aodv_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 244 { 245 u_int i; 246 const struct aodv_rrep *ap = (const struct aodv_rrep *)dat; 247 248 ND_TCHECK(*ap); 249 if (length < sizeof(*ap)) 250 goto trunc; 251 ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" 252 "\tdst %s dseq %lu src %s %lu ms", length, 253 ap->rrep_type & RREP_REPAIR ? "[R]" : "", 254 ap->rrep_type & RREP_ACK ? "[A] " : " ", 255 ap->rrep_ps & RREP_PREFIX_MASK, 256 ap->rrep_hops, 257 ipaddr_string(ndo, &ap->rrep_da), 258 (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), 259 ipaddr_string(ndo, &ap->rrep_oa), 260 (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); 261 i = length - sizeof(*ap); 262 if (i >= sizeof(struct aodv_ext)) 263 aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 264 return; 265 266 trunc: 267 ND_PRINT((ndo, " [|rreq")); 268 } 269 270 static void 271 aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 272 { 273 u_int i, dc; 274 const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 275 const struct rerr_unreach *dp; 276 277 ND_TCHECK(*ap); 278 if (length < sizeof(*ap)) 279 goto trunc; 280 ND_PRINT((ndo, " rerr %s [items %u] [%u]:", 281 ap->rerr_flags & RERR_NODELETE ? "[D]" : "", 282 ap->rerr_dc, length)); 283 dp = (struct rerr_unreach *)(dat + sizeof(*ap)); 284 i = length - sizeof(*ap); 285 for (dc = ap->rerr_dc; dc != 0; dc--) { 286 ND_TCHECK(*dp); 287 if (i < sizeof(*dp)) 288 goto trunc; 289 ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da), 290 (unsigned long)EXTRACT_32BITS(&dp->u_ds))); 291 dp++; 292 i -= sizeof(*dp); 293 } 294 return; 295 296 trunc: 297 ND_PRINT((ndo, "[|rerr]")); 298 } 299 300 static void 301 #ifdef INET6 302 aodv_v6_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 303 #else 304 aodv_v6_rreq(netdissect_options *ndo, const u_char *dat _U_, u_int length) 305 #endif 306 { 307 #ifdef INET6 308 u_int i; 309 const struct aodv_rreq6 *ap = (const struct aodv_rreq6 *)dat; 310 311 ND_TCHECK(*ap); 312 if (length < sizeof(*ap)) 313 goto trunc; 314 ND_PRINT((ndo, " v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 315 "\tdst %s seq %lu src %s seq %lu", length, 316 ap->rreq_type & RREQ_JOIN ? "[J]" : "", 317 ap->rreq_type & RREQ_REPAIR ? "[R]" : "", 318 ap->rreq_type & RREQ_GRAT ? "[G]" : "", 319 ap->rreq_type & RREQ_DEST ? "[D]" : "", 320 ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 321 ap->rreq_hops, 322 (unsigned long)EXTRACT_32BITS(&ap->rreq_id), 323 ip6addr_string(ndo, &ap->rreq_da), 324 (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), 325 ip6addr_string(ndo, &ap->rreq_oa), 326 (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); 327 i = length - sizeof(*ap); 328 if (i >= sizeof(struct aodv_ext)) 329 aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 330 return; 331 332 trunc: 333 ND_PRINT((ndo, " [|rreq")); 334 #else 335 ND_PRINT((ndo, " v6 rreq %u", length)); 336 #endif 337 } 338 339 static void 340 #ifdef INET6 341 aodv_v6_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 342 #else 343 aodv_v6_rrep(netdissect_options *ndo, const u_char *dat _U_, u_int length) 344 #endif 345 { 346 #ifdef INET6 347 u_int i; 348 const struct aodv_rrep6 *ap = (const struct aodv_rrep6 *)dat; 349 350 ND_TCHECK(*ap); 351 if (length < sizeof(*ap)) 352 goto trunc; 353 ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" 354 "\tdst %s dseq %lu src %s %lu ms", length, 355 ap->rrep_type & RREP_REPAIR ? "[R]" : "", 356 ap->rrep_type & RREP_ACK ? "[A] " : " ", 357 ap->rrep_ps & RREP_PREFIX_MASK, 358 ap->rrep_hops, 359 ip6addr_string(ndo, &ap->rrep_da), 360 (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), 361 ip6addr_string(ndo, &ap->rrep_oa), 362 (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); 363 i = length - sizeof(*ap); 364 if (i >= sizeof(struct aodv_ext)) 365 aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 366 return; 367 368 trunc: 369 ND_PRINT((ndo, " [|rreq")); 370 #else 371 ND_PRINT((ndo, " rrep %u", length)); 372 #endif 373 } 374 375 static void 376 #ifdef INET6 377 aodv_v6_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 378 #else 379 aodv_v6_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length) 380 #endif 381 { 382 #ifdef INET6 383 u_int i, dc; 384 const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 385 const struct rerr_unreach6 *dp6; 386 387 ND_TCHECK(*ap); 388 if (length < sizeof(*ap)) 389 goto trunc; 390 ND_PRINT((ndo, " rerr %s [items %u] [%u]:", 391 ap->rerr_flags & RERR_NODELETE ? "[D]" : "", 392 ap->rerr_dc, length)); 393 dp6 = (struct rerr_unreach6 *)(void *)(ap + 1); 394 i = length - sizeof(*ap); 395 for (dc = ap->rerr_dc; dc != 0; dc--) { 396 ND_TCHECK(*dp6); 397 if (i < sizeof(*dp6)) 398 goto trunc; 399 ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), 400 (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); 401 dp6++; 402 i -= sizeof(*dp6); 403 } 404 return; 405 406 trunc: 407 ND_PRINT((ndo, "[|rerr]")); 408 #else 409 ND_PRINT((ndo, " rerr %u", length)); 410 #endif 411 } 412 413 static void 414 #ifdef INET6 415 aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat, u_int length) 416 #else 417 aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat _U_, u_int length) 418 #endif 419 { 420 #ifdef INET6 421 u_int i; 422 const struct aodv_rreq6_draft_01 *ap = (const struct aodv_rreq6_draft_01 *)dat; 423 424 ND_TCHECK(*ap); 425 if (length < sizeof(*ap)) 426 goto trunc; 427 ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 428 "\tdst %s seq %lu src %s seq %lu", length, 429 ap->rreq_type & RREQ_JOIN ? "[J]" : "", 430 ap->rreq_type & RREQ_REPAIR ? "[R]" : "", 431 ap->rreq_type & RREQ_GRAT ? "[G]" : "", 432 ap->rreq_type & RREQ_DEST ? "[D]" : "", 433 ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 434 ap->rreq_hops, 435 (unsigned long)EXTRACT_32BITS(&ap->rreq_id), 436 ip6addr_string(ndo, &ap->rreq_da), 437 (unsigned long)EXTRACT_32BITS(&ap->rreq_ds), 438 ip6addr_string(ndo, &ap->rreq_oa), 439 (unsigned long)EXTRACT_32BITS(&ap->rreq_os))); 440 i = length - sizeof(*ap); 441 if (i >= sizeof(struct aodv_ext)) 442 aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 443 return; 444 445 trunc: 446 ND_PRINT((ndo, " [|rreq")); 447 #else 448 ND_PRINT((ndo, " rreq %u", length)); 449 #endif 450 } 451 452 static void 453 #ifdef INET6 454 aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat, u_int length) 455 #else 456 aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat _U_, u_int length) 457 #endif 458 { 459 #ifdef INET6 460 u_int i; 461 const struct aodv_rrep6_draft_01 *ap = (const struct aodv_rrep6_draft_01 *)dat; 462 463 ND_TCHECK(*ap); 464 if (length < sizeof(*ap)) 465 goto trunc; 466 ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n" 467 "\tdst %s dseq %lu src %s %lu ms", length, 468 ap->rrep_type & RREP_REPAIR ? "[R]" : "", 469 ap->rrep_type & RREP_ACK ? "[A] " : " ", 470 ap->rrep_ps & RREP_PREFIX_MASK, 471 ap->rrep_hops, 472 ip6addr_string(ndo, &ap->rrep_da), 473 (unsigned long)EXTRACT_32BITS(&ap->rrep_ds), 474 ip6addr_string(ndo, &ap->rrep_oa), 475 (unsigned long)EXTRACT_32BITS(&ap->rrep_life))); 476 i = length - sizeof(*ap); 477 if (i >= sizeof(struct aodv_ext)) 478 aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i); 479 return; 480 481 trunc: 482 ND_PRINT((ndo, " [|rreq")); 483 #else 484 ND_PRINT((ndo, " rrep %u", length)); 485 #endif 486 } 487 488 static void 489 #ifdef INET6 490 aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat, u_int length) 491 #else 492 aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length) 493 #endif 494 { 495 #ifdef INET6 496 u_int i, dc; 497 const struct aodv_rerr *ap = (const struct aodv_rerr *)dat; 498 const struct rerr_unreach6_draft_01 *dp6; 499 500 ND_TCHECK(*ap); 501 if (length < sizeof(*ap)) 502 goto trunc; 503 ND_PRINT((ndo, " rerr %s [items %u] [%u]:", 504 ap->rerr_flags & RERR_NODELETE ? "[D]" : "", 505 ap->rerr_dc, length)); 506 dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1); 507 i = length - sizeof(*ap); 508 for (dc = ap->rerr_dc; dc != 0; dc--) { 509 ND_TCHECK(*dp6); 510 if (i < sizeof(*dp6)) 511 goto trunc; 512 ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), 513 (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); 514 dp6++; 515 i -= sizeof(*dp6); 516 } 517 return; 518 519 trunc: 520 ND_PRINT((ndo, "[|rerr]")); 521 #else 522 ND_PRINT((ndo, " rerr %u", length)); 523 #endif 524 } 525 526 void 527 aodv_print(netdissect_options *ndo, 528 const u_char *dat, u_int length, int is_ip6) 529 { 530 uint8_t msg_type; 531 532 /* 533 * The message type is the first byte; make sure we have it 534 * and then fetch it. 535 */ 536 ND_TCHECK(*dat); 537 msg_type = *dat; 538 ND_PRINT((ndo, " aodv")); 539 540 switch (msg_type) { 541 542 case AODV_RREQ: 543 if (is_ip6) 544 aodv_v6_rreq(ndo, dat, length); 545 else 546 aodv_rreq(ndo, dat, length); 547 break; 548 549 case AODV_RREP: 550 if (is_ip6) 551 aodv_v6_rrep(ndo, dat, length); 552 else 553 aodv_rrep(ndo, dat, length); 554 break; 555 556 case AODV_RERR: 557 if (is_ip6) 558 aodv_v6_rerr(ndo, dat, length); 559 else 560 aodv_rerr(ndo, dat, length); 561 break; 562 563 case AODV_RREP_ACK: 564 ND_PRINT((ndo, " rrep-ack %u", length)); 565 break; 566 567 case AODV_V6_DRAFT_01_RREQ: 568 aodv_v6_draft_01_rreq(ndo, dat, length); 569 break; 570 571 case AODV_V6_DRAFT_01_RREP: 572 aodv_v6_draft_01_rrep(ndo, dat, length); 573 break; 574 575 case AODV_V6_DRAFT_01_RERR: 576 aodv_v6_draft_01_rerr(ndo, dat, length); 577 break; 578 579 case AODV_V6_DRAFT_01_RREP_ACK: 580 ND_PRINT((ndo, " rrep-ack %u", length)); 581 break; 582 583 default: 584 ND_PRINT((ndo, " type %u %u", msg_type, length)); 585 } 586 return; 587 588 trunc: 589 ND_PRINT((ndo, " [|aodv]")); 590 } 591