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