print-aodv.c revision 127668
1139749Simp/* 2137821Smarius * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org> 3137821Smarius * All rights reserved. 4137821Smarius * 5137821Smarius * Redistribution and use in source and binary forms, with or without 6137821Smarius * modification, are permitted provided that the following conditions 7137821Smarius * are met: 8137821Smarius * 1. Redistributions of source code must retain the above copyright 9137821Smarius * notice, this list of conditions and the following disclaimer. 10137821Smarius * 2. Redistributions in binary form must reproduce the above copyright 11137821Smarius * notice, this list of conditions and the following disclaimer in the 12137821Smarius * documentation and/or other materials provided with the distribution. 13137821Smarius * 3. All advertising materials mentioning features or use of this software 14137821Smarius * must display the following acknowledgement: 15137821Smarius * This product includes software developed by Bruce M. Simpson. 16137821Smarius * 4. Neither the name of Bruce M. Simpson nor the names of co- 17137821Smarius * contributors may be used to endorse or promote products derived 18137821Smarius * from this software without specific prior written permission. 19137821Smarius * 20137821Smarius * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson AND CONTRIBUTORS 21137821Smarius * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22137821Smarius * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23137821Smarius * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bruce M. Simpson OR CONTRIBUTORS 24201009Smarius * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25137821Smarius * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26137821Smarius * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27137821Smarius * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28137821Smarius * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29137821Smarius * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30137821Smarius * POSSIBILITY OF SUCH DAMAGE. 31137821Smarius */ 32137821Smarius 33137821Smarius#ifndef lint 34137821Smariusstatic const char rcsid[] _U_ = 35137821Smarius "@(#) $Header: /tcpdump/master/tcpdump/print-aodv.c,v 1.8.2.3 2004/03/24 00:30:41 guy Exp $ (LBL)"; 36137821Smarius#endif 37137821Smarius 38146417Smarius#ifdef HAVE_CONFIG_H 39146417Smarius#include "config.h" 40137821Smarius#endif 41137821Smarius 42137821Smarius#include <tcpdump-stdinc.h> 43137821Smarius 44137821Smarius#include <stddef.h> 45137821Smarius#include <stdio.h> 46137821Smarius#include <ctype.h> 47137821Smarius#include <string.h> 48137821Smarius 49137821Smarius#include "interface.h" 50137821Smarius#include "addrtoname.h" 51137821Smarius#include "extract.h" /* must come after interface.h */ 52137821Smarius 53137821Smarius#include "aodv.h" 54137821Smarius 55137821Smariusstatic void 56137821Smariusaodv_extension(const struct aodv_ext *ep, u_int length) 57137821Smarius{ 58146417Smarius u_int i; 59146417Smarius const struct aodv_hello *ah; 60146417Smarius 61146417Smarius switch (ep->type) { 62146417Smarius case AODV_EXT_HELLO: 63137821Smarius if (snapend < (u_char *) ep) { 64137821Smarius printf(" [|hello]"); 65137821Smarius return; 66137821Smarius } 67137821Smarius i = min(length, (u_int)(snapend - (u_char *)ep)); 68137821Smarius if (i < sizeof(struct aodv_hello)) { 69137821Smarius printf(" [|hello]"); 70137821Smarius return; 71137821Smarius } 72137821Smarius i -= sizeof(struct aodv_hello); 73137821Smarius ah = (void *)ep; 74137821Smarius printf("\n\text HELLO %ld ms", 75137821Smarius (unsigned long)EXTRACT_32BITS(&ah->interval)); 76137821Smarius break; 77137821Smarius 78137821Smarius default: 79146982Smarius printf("\n\text %u %u", ep->type, ep->length); 80137821Smarius break; 81146982Smarius } 82146417Smarius} 83137821Smarius 84137821Smariusstatic void 85137821Smariusaodv_rreq(const union aodv *ap, const u_char *dat, u_int length) 86137821Smarius{ 87137821Smarius u_int i; 88137821Smarius 89137821Smarius if (snapend < dat) { 90137821Smarius printf(" [|aodv]"); 91137821Smarius return; 92137821Smarius } 93146982Smarius i = min(length, (u_int)(snapend - dat)); 94137821Smarius if (i < sizeof(ap->rreq)) { 95201008Smarius printf(" [|rreq]"); 96137821Smarius return; 97137821Smarius } 98137821Smarius i -= sizeof(ap->rreq); 99137821Smarius printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 100137821Smarius "\tdst %s seq %lu src %s seq %lu", length, 101137821Smarius ap->rreq.rreq_type & RREQ_JOIN ? "[J]" : "", 102137821Smarius ap->rreq.rreq_type & RREQ_REPAIR ? "[R]" : "", 103137821Smarius ap->rreq.rreq_type & RREQ_GRAT ? "[G]" : "", 104137821Smarius ap->rreq.rreq_type & RREQ_DEST ? "[D]" : "", 105137821Smarius ap->rreq.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 106137821Smarius ap->rreq.rreq_hops, 107137821Smarius (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_id), 108137821Smarius ipaddr_string(&ap->rreq.rreq_da), 109137821Smarius (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_ds), 110137821Smarius ipaddr_string(&ap->rreq.rreq_oa), 111137821Smarius (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_os)); 112137821Smarius if (i >= sizeof(struct aodv_ext)) 113137821Smarius aodv_extension((void *)(&ap->rreq + 1), i); 114137821Smarius} 115137821Smarius 116137821Smariusstatic void 117201008Smariusaodv_rrep(const union aodv *ap, const u_char *dat, u_int length) 118137821Smarius{ 119137821Smarius u_int i; 120146982Smarius 121137821Smarius if (snapend < dat) { 122137821Smarius printf(" [|aodv]"); 123146982Smarius return; 124137821Smarius } 125146417Smarius i = min(length, (u_int)(snapend - dat)); 126137821Smarius if (i < sizeof(ap->rrep)) { 127137821Smarius printf(" [|rrep]"); 128137821Smarius return; 129137821Smarius } 130137821Smarius i -= sizeof(ap->rrep); 131137821Smarius printf(" rrep %u %s%sprefix %u hops %u\n" 132137821Smarius "\tdst %s dseq %lu src %s %lu ms", length, 133137821Smarius ap->rrep.rrep_type & RREP_REPAIR ? "[R]" : "", 134137821Smarius ap->rrep.rrep_type & RREP_ACK ? "[A] " : " ", 135137821Smarius ap->rrep.rrep_ps & RREP_PREFIX_MASK, 136146417Smarius ap->rrep.rrep_hops, 137137821Smarius ipaddr_string(&ap->rrep.rrep_da), 138137821Smarius (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_ds), 139137821Smarius ipaddr_string(&ap->rrep.rrep_oa), 140137821Smarius (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_life)); 141146417Smarius if (i >= sizeof(struct aodv_ext)) 142146417Smarius aodv_extension((void *)(&ap->rrep + 1), i); 143137821Smarius} 144137821Smarius 145146417Smariusstatic void 146146417Smariusaodv_rerr(const union aodv *ap, const u_char *dat, u_int length) 147146982Smarius{ 148137821Smarius u_int i; 149137821Smarius const struct rerr_unreach *dp = NULL; 150137821Smarius int n, trunc; 151137821Smarius 152137821Smarius if (snapend < dat) { 153137821Smarius printf(" [|aodv]"); 154137821Smarius return; 155137821Smarius } 156137821Smarius i = min(length, (u_int)(snapend - dat)); 157137821Smarius if (i < offsetof(struct aodv_rerr, r)) { 158137821Smarius printf(" [|rerr]"); 159137821Smarius return; 160137821Smarius } 161137821Smarius i -= offsetof(struct aodv_rerr, r); 162137821Smarius dp = &ap->rerr.r.dest[0]; 163137821Smarius n = ap->rerr.rerr_dc * sizeof(ap->rerr.r.dest[0]); 164137821Smarius printf(" rerr %s [items %u] [%u]:", 165137821Smarius ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", 166146982Smarius ap->rerr.rerr_dc, length); 167137821Smarius trunc = n - (i/sizeof(ap->rerr.r.dest[0])); 168137821Smarius for (; i >= sizeof(ap->rerr.r.dest[0]); 169146982Smarius ++dp, i -= sizeof(ap->rerr.r.dest[0])) { 170137821Smarius printf(" {%s}(%ld)", ipaddr_string(&dp->u_da), 171137821Smarius (unsigned long)EXTRACT_32BITS(&dp->u_ds)); 172146982Smarius } 173137821Smarius if (trunc) 174146417Smarius printf("[|rerr]"); 175137821Smarius} 176137821Smarius 177137821Smariusstatic void 178137821Smarius#ifdef INET6 179137821Smariusaodv_v6_rreq(const union aodv *ap, const u_char *dat, u_int length) 180137821Smarius#else 181137821Smariusaodv_v6_rreq(const union aodv *ap _U_, const u_char *dat _U_, u_int length) 182137821Smarius#endif 183137821Smarius{ 184137821Smarius#ifdef INET6 185137821Smarius u_int i; 186137821Smarius 187137821Smarius if (snapend < dat) { 188137821Smarius printf(" [|aodv]"); 189137821Smarius return; 190137821Smarius } 191137821Smarius i = min(length, (u_int)(snapend - dat)); 192137821Smarius if (i < sizeof(ap->rreq6)) { 193137821Smarius printf(" [|rreq6]"); 194137821Smarius return; 195137821Smarius } 196137821Smarius i -= sizeof(ap->rreq6); 197137821Smarius printf(" v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 198137821Smarius "\tdst %s seq %lu src %s seq %lu", length, 199137821Smarius ap->rreq6.rreq_type & RREQ_JOIN ? "[J]" : "", 200137821Smarius ap->rreq6.rreq_type & RREQ_REPAIR ? "[R]" : "", 201137821Smarius ap->rreq6.rreq_type & RREQ_GRAT ? "[G]" : "", 202137821Smarius ap->rreq6.rreq_type & RREQ_DEST ? "[D]" : "", 203137821Smarius ap->rreq6.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 204137821Smarius ap->rreq6.rreq_hops, 205146982Smarius (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_id), 206137821Smarius ip6addr_string(&ap->rreq6.rreq_da), 207137821Smarius (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_ds), 208137821Smarius ip6addr_string(&ap->rreq6.rreq_oa), 209137821Smarius (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_os)); 210137821Smarius if (i >= sizeof(struct aodv_ext)) 211137821Smarius aodv_extension((void *)(&ap->rreq6 + 1), i); 212137821Smarius#else 213137821Smarius printf(" v6 rreq %u", length); 214137821Smarius#endif 215146417Smarius} 216137821Smarius 217137821Smariusstatic void 218137821Smarius#ifdef INET6 219137821Smariusaodv_v6_rrep(const union aodv *ap, const u_char *dat, u_int length) 220137821Smarius#else 221146417Smariusaodv_v6_rrep(const union aodv *ap _U_, const u_char *dat _U_, u_int length) 222137821Smarius#endif 223137821Smarius{ 224137821Smarius#ifdef INET6 225146417Smarius u_int i; 226137821Smarius 227137821Smarius if (snapend < dat) { 228137821Smarius printf(" [|aodv]"); 229137821Smarius return; 230137821Smarius } 231146982Smarius i = min(length, (u_int)(snapend - dat)); 232137821Smarius if (i < sizeof(ap->rrep6)) { 233137821Smarius printf(" [|rrep6]"); 234137821Smarius return; 235137821Smarius } 236137821Smarius i -= sizeof(ap->rrep6); 237137821Smarius printf(" rrep %u %s%sprefix %u hops %u\n" 238137821Smarius "\tdst %s dseq %lu src %s %lu ms", length, 239137821Smarius ap->rrep6.rrep_type & RREP_REPAIR ? "[R]" : "", 240137821Smarius ap->rrep6.rrep_type & RREP_ACK ? "[A] " : " ", 241170844Smarius ap->rrep6.rrep_ps & RREP_PREFIX_MASK, 242137821Smarius ap->rrep6.rrep_hops, 243137821Smarius ip6addr_string(&ap->rrep6.rrep_da), 244137821Smarius (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_ds), 245137821Smarius ip6addr_string(&ap->rrep6.rrep_oa), 246137821Smarius (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_life)); 247137821Smarius if (i >= sizeof(struct aodv_ext)) 248137821Smarius aodv_extension((void *)(&ap->rrep6 + 1), i); 249137821Smarius#else 250137821Smarius printf(" rrep %u", length); 251170844Smarius#endif 252137821Smarius} 253137821Smarius 254137821Smariusstatic void 255137821Smarius#ifdef INET6 256137821Smariusaodv_v6_rerr(const union aodv *ap, u_int length) 257137821Smarius#else 258137821Smariusaodv_v6_rerr(const union aodv *ap _U_, u_int length) 259137821Smarius#endif 260137821Smarius{ 261201008Smarius#ifdef INET6 262201008Smarius const struct rerr_unreach6 *dp6 = NULL; 263201008Smarius int i, j, n, trunc; 264137821Smarius 265137821Smarius i = length - offsetof(struct aodv_rerr, r); 266137821Smarius j = sizeof(ap->rerr.r.dest6[0]); 267137821Smarius dp6 = &ap->rerr.r.dest6[0]; 268137821Smarius n = ap->rerr.rerr_dc * j; 269137821Smarius printf(" rerr %s [items %u] [%u]:", 270137821Smarius ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", 271137821Smarius ap->rerr.rerr_dc, length); 272137821Smarius trunc = n - (i/j); 273137821Smarius for (; i -= j >= 0; ++dp6) { 274137821Smarius printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da), 275137821Smarius (unsigned long)EXTRACT_32BITS(&dp6->u_ds)); 276137821Smarius } 277137821Smarius if (trunc) 278137821Smarius printf("[|rerr]"); 279137821Smarius#else 280137821Smarius printf(" rerr %u", length); 281137821Smarius#endif 282137821Smarius} 283137821Smarius 284137821Smariusstatic void 285137821Smarius#ifdef INET6 286137821Smariusaodv_v6_draft_01_rreq(const union aodv *ap, const u_char *dat, u_int length) 287201008Smarius#else 288201008Smariusaodv_v6_draft_01_rreq(const union aodv *ap _U_, const u_char *dat _U_, 289 u_int length) 290#endif 291{ 292#ifdef INET6 293 u_int i; 294 295 if (snapend < dat) { 296 printf(" [|aodv]"); 297 return; 298 } 299 i = min(length, (u_int)(snapend - dat)); 300 if (i < sizeof(ap->rreq6_draft_01)) { 301 printf(" [|rreq6]"); 302 return; 303 } 304 i -= sizeof(ap->rreq6_draft_01); 305 printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n" 306 "\tdst %s seq %lu src %s seq %lu", length, 307 ap->rreq6_draft_01.rreq_type & RREQ_JOIN ? "[J]" : "", 308 ap->rreq6_draft_01.rreq_type & RREQ_REPAIR ? "[R]" : "", 309 ap->rreq6_draft_01.rreq_type & RREQ_GRAT ? "[G]" : "", 310 ap->rreq6_draft_01.rreq_type & RREQ_DEST ? "[D]" : "", 311 ap->rreq6_draft_01.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", 312 ap->rreq6_draft_01.rreq_hops, 313 (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_id), 314 ip6addr_string(&ap->rreq6_draft_01.rreq_da), 315 (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_ds), 316 ip6addr_string(&ap->rreq6_draft_01.rreq_oa), 317 (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_os)); 318 if (i >= sizeof(struct aodv_ext)) 319 aodv_extension((void *)(&ap->rreq6_draft_01 + 1), i); 320#else 321 printf(" rreq %u", length); 322#endif 323} 324 325static void 326#ifdef INET6 327aodv_v6_draft_01_rrep(const union aodv *ap, const u_char *dat, u_int length) 328#else 329aodv_v6_draft_01_rrep(const union aodv *ap _U_, const u_char *dat _U_, 330 u_int length) 331#endif 332{ 333#ifdef INET6 334 u_int i; 335 336 if (snapend < dat) { 337 printf(" [|aodv]"); 338 return; 339 } 340 i = min(length, (u_int)(snapend - dat)); 341 if (i < sizeof(ap->rrep6_draft_01)) { 342 printf(" [|rrep6]"); 343 return; 344 } 345 i -= sizeof(ap->rrep6_draft_01); 346 printf(" rrep %u %s%sprefix %u hops %u\n" 347 "\tdst %s dseq %lu src %s %lu ms", length, 348 ap->rrep6_draft_01.rrep_type & RREP_REPAIR ? "[R]" : "", 349 ap->rrep6_draft_01.rrep_type & RREP_ACK ? "[A] " : " ", 350 ap->rrep6_draft_01.rrep_ps & RREP_PREFIX_MASK, 351 ap->rrep6_draft_01.rrep_hops, 352 ip6addr_string(&ap->rrep6_draft_01.rrep_da), 353 (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_ds), 354 ip6addr_string(&ap->rrep6_draft_01.rrep_oa), 355 (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_life)); 356 if (i >= sizeof(struct aodv_ext)) 357 aodv_extension((void *)(&ap->rrep6_draft_01 + 1), i); 358#else 359 printf(" rrep %u", length); 360#endif 361} 362 363static void 364#ifdef INET6 365aodv_v6_draft_01_rerr(const union aodv *ap, u_int length) 366#else 367aodv_v6_draft_01_rerr(const union aodv *ap _U_, u_int length) 368#endif 369{ 370#ifdef INET6 371 const struct rerr_unreach6_draft_01 *dp6 = NULL; 372 int i, j, n, trunc; 373 374 i = length - offsetof(struct aodv_rerr, r); 375 j = sizeof(ap->rerr.r.dest6_draft_01[0]); 376 dp6 = &ap->rerr.r.dest6_draft_01[0]; 377 n = ap->rerr.rerr_dc * j; 378 printf(" rerr %s [items %u] [%u]:", 379 ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", 380 ap->rerr.rerr_dc, length); 381 trunc = n - (i/j); 382 for (; i -= j >= 0; ++dp6) { 383 printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da), 384 (unsigned long)EXTRACT_32BITS(&dp6->u_ds)); 385 } 386 if (trunc) 387 printf("[|rerr]"); 388#else 389 printf(" rerr %u", length); 390#endif 391} 392 393void 394aodv_print(const u_char *dat, u_int length, int is_ip6) 395{ 396 const union aodv *ap; 397 398 ap = (union aodv *)dat; 399 if (snapend < dat) { 400 printf(" [|aodv]"); 401 return; 402 } 403 if (min(length, (u_int)(snapend - dat)) < sizeof(ap->rrep_ack)) { 404 printf(" [|aodv]"); 405 return; 406 } 407 printf(" aodv"); 408 409 switch (ap->rerr.rerr_type) { 410 411 case AODV_RREQ: 412 if (is_ip6) 413 aodv_v6_rreq(ap, dat, length); 414 else 415 aodv_rreq(ap, dat, length); 416 break; 417 418 case AODV_RREP: 419 if (is_ip6) 420 aodv_v6_rrep(ap, dat, length); 421 else 422 aodv_rrep(ap, dat, length); 423 break; 424 425 case AODV_RERR: 426 if (is_ip6) 427 aodv_v6_rerr(ap, length); 428 else 429 aodv_rerr(ap, dat, length); 430 break; 431 432 case AODV_RREP_ACK: 433 printf(" rrep-ack %u", length); 434 break; 435 436 case AODV_V6_DRAFT_01_RREQ: 437 aodv_v6_draft_01_rreq(ap, dat, length); 438 break; 439 440 case AODV_V6_DRAFT_01_RREP: 441 aodv_v6_draft_01_rrep(ap, dat, length); 442 break; 443 444 case AODV_V6_DRAFT_01_RERR: 445 aodv_v6_draft_01_rerr(ap, length); 446 break; 447 448 case AODV_V6_DRAFT_01_RREP_ACK: 449 printf(" rrep-ack %u", length); 450 break; 451 452 default: 453 printf(" %u %u", ap->rreq.rreq_type, length); 454 } 455} 456