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