2 * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
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)";
42 #include <tcpdump-stdinc.h>
49 #include "interface.h"
50 #include "addrtoname.h"
51 #include "extract.h" /* must come after interface.h */
56 aodv_extension(const struct aodv_ext *ep, u_int length)
59 const struct aodv_hello *ah;
63 if (snapend < (u_char *) ep) {
67 i = min(length, (u_int)(snapend - (u_char *)ep));
68 if (i < sizeof(struct aodv_hello)) {
72 i -= sizeof(struct aodv_hello);
74 printf("\n\text HELLO %ld ms",
75 (unsigned long)EXTRACT_32BITS(&ah->interval));
79 printf("\n\text %u %u", ep->type, ep->length);
85 aodv_rreq(const union aodv *ap, const u_char *dat, u_int length)
93 i = min(length, (u_int)(snapend - dat));
94 if (i < sizeof(ap->rreq)) {
98 i -= sizeof(ap->rreq);
99 printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
100 "\tdst %s seq %lu src %s seq %lu", length,
101 ap->rreq.rreq_type & RREQ_JOIN ? "[J]" : "",
102 ap->rreq.rreq_type & RREQ_REPAIR ? "[R]" : "",
103 ap->rreq.rreq_type & RREQ_GRAT ? "[G]" : "",
104 ap->rreq.rreq_type & RREQ_DEST ? "[D]" : "",
105 ap->rreq.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
107 (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_id),
108 ipaddr_string(&ap->rreq.rreq_da),
109 (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_ds),
110 ipaddr_string(&ap->rreq.rreq_oa),
111 (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_os));
112 if (i >= sizeof(struct aodv_ext))
113 aodv_extension((void *)(&ap->rreq + 1), i);
117 aodv_rrep(const union aodv *ap, const u_char *dat, u_int length)
125 i = min(length, (u_int)(snapend - dat));
126 if (i < sizeof(ap->rrep)) {
130 i -= sizeof(ap->rrep);
131 printf(" rrep %u %s%sprefix %u hops %u\n"
132 "\tdst %s dseq %lu src %s %lu ms", length,
133 ap->rrep.rrep_type & RREP_REPAIR ? "[R]" : "",
134 ap->rrep.rrep_type & RREP_ACK ? "[A] " : " ",
135 ap->rrep.rrep_ps & RREP_PREFIX_MASK,
137 ipaddr_string(&ap->rrep.rrep_da),
138 (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_ds),
139 ipaddr_string(&ap->rrep.rrep_oa),
140 (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_life));
141 if (i >= sizeof(struct aodv_ext))
142 aodv_extension((void *)(&ap->rrep + 1), i);
146 aodv_rerr(const union aodv *ap, const u_char *dat, u_int length)
149 const struct rerr_unreach *dp = NULL;
156 i = min(length, (u_int)(snapend - dat));
157 if (i < offsetof(struct aodv_rerr, r)) {
161 i -= offsetof(struct aodv_rerr, r);
162 dp = &ap->rerr.r.dest[0];
163 n = ap->rerr.rerr_dc * sizeof(ap->rerr.r.dest[0]);
164 printf(" rerr %s [items %u] [%u]:",
165 ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
166 ap->rerr.rerr_dc, length);
167 trunc = n - (i/sizeof(ap->rerr.r.dest[0]));
168 for (; i >= sizeof(ap->rerr.r.dest[0]);
169 ++dp, i -= sizeof(ap->rerr.r.dest[0])) {
170 printf(" {%s}(%ld)", ipaddr_string(&dp->u_da),
171 (unsigned long)EXTRACT_32BITS(&dp->u_ds));
179 aodv_v6_rreq(const union aodv *ap, const u_char *dat, u_int length)
181 aodv_v6_rreq(const union aodv *ap _U_, const u_char *dat _U_, u_int length)
191 i = min(length, (u_int)(snapend - dat));
192 if (i < sizeof(ap->rreq6)) {
196 i -= sizeof(ap->rreq6);
197 printf(" v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
198 "\tdst %s seq %lu src %s seq %lu", length,
199 ap->rreq6.rreq_type & RREQ_JOIN ? "[J]" : "",
200 ap->rreq6.rreq_type & RREQ_REPAIR ? "[R]" : "",
201 ap->rreq6.rreq_type & RREQ_GRAT ? "[G]" : "",
202 ap->rreq6.rreq_type & RREQ_DEST ? "[D]" : "",
203 ap->rreq6.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
205 (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_id),
206 ip6addr_string(&ap->rreq6.rreq_da),
207 (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_ds),
208 ip6addr_string(&ap->rreq6.rreq_oa),
209 (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_os));
210 if (i >= sizeof(struct aodv_ext))
211 aodv_extension((void *)(&ap->rreq6 + 1), i);
213 printf(" v6 rreq %u", length);
219 aodv_v6_rrep(const union aodv *ap, const u_char *dat, u_int length)
221 aodv_v6_rrep(const union aodv *ap _U_, const u_char *dat _U_, u_int length)
231 i = min(length, (u_int)(snapend - dat));
232 if (i < sizeof(ap->rrep6)) {
236 i -= sizeof(ap->rrep6);
237 printf(" rrep %u %s%sprefix %u hops %u\n"
238 "\tdst %s dseq %lu src %s %lu ms", length,
239 ap->rrep6.rrep_type & RREP_REPAIR ? "[R]" : "",
240 ap->rrep6.rrep_type & RREP_ACK ? "[A] " : " ",
241 ap->rrep6.rrep_ps & RREP_PREFIX_MASK,
243 ip6addr_string(&ap->rrep6.rrep_da),
244 (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_ds),
245 ip6addr_string(&ap->rrep6.rrep_oa),
246 (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_life));
247 if (i >= sizeof(struct aodv_ext))
248 aodv_extension((void *)(&ap->rrep6 + 1), i);
250 printf(" rrep %u", length);
256 aodv_v6_rerr(const union aodv *ap, u_int length)
258 aodv_v6_rerr(const union aodv *ap _U_, u_int length)
262 const struct rerr_unreach6 *dp6 = NULL;
265 i = length - offsetof(struct aodv_rerr, r);
266 j = sizeof(ap->rerr.r.dest6[0]);
267 dp6 = &ap->rerr.r.dest6[0];
268 n = ap->rerr.rerr_dc * j;
269 printf(" rerr %s [items %u] [%u]:",
270 ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
271 ap->rerr.rerr_dc, length);
273 for (; i -= j >= 0; ++dp6) {
274 printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da),
275 (unsigned long)EXTRACT_32BITS(&dp6->u_ds));
280 printf(" rerr %u", length);
286 aodv_v6_draft_01_rreq(const union aodv *ap, const u_char *dat, u_int length)
288 aodv_v6_draft_01_rreq(const union aodv *ap _U_, const u_char *dat _U_,
299 i = min(length, (u_int)(snapend - dat));
300 if (i < sizeof(ap->rreq6_draft_01)) {
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);
321 printf(" rreq %u", length);
327 aodv_v6_draft_01_rrep(const union aodv *ap, const u_char *dat, u_int length)
329 aodv_v6_draft_01_rrep(const union aodv *ap _U_, const u_char *dat _U_,
340 i = min(length, (u_int)(snapend - dat));
341 if (i < sizeof(ap->rrep6_draft_01)) {
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);
359 printf(" rrep %u", length);
365 aodv_v6_draft_01_rerr(const union aodv *ap, u_int length)
367 aodv_v6_draft_01_rerr(const union aodv *ap _U_, u_int length)
371 const struct rerr_unreach6_draft_01 *dp6 = NULL;
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);
382 for (; i -= j >= 0; ++dp6) {
383 printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da),
384 (unsigned long)EXTRACT_32BITS(&dp6->u_ds));
389 printf(" rerr %u", length);
394 aodv_print(const u_char *dat, u_int length, int is_ip6)
396 const union aodv *ap;
398 ap = (union aodv *)dat;
403 if (min(length, (u_int)(snapend - dat)) < sizeof(ap->rrep_ack)) {
409 switch (ap->rerr.rerr_type) {
413 aodv_v6_rreq(ap, dat, length);
415 aodv_rreq(ap, dat, length);
420 aodv_v6_rrep(ap, dat, length);
422 aodv_rrep(ap, dat, length);
427 aodv_v6_rerr(ap, length);
429 aodv_rerr(ap, dat, length);
433 printf(" rrep-ack %u", length);
436 case AODV_V6_DRAFT_01_RREQ:
437 aodv_v6_draft_01_rreq(ap, dat, length);
440 case AODV_V6_DRAFT_01_RREP:
441 aodv_v6_draft_01_rrep(ap, dat, length);
444 case AODV_V6_DRAFT_01_RERR:
445 aodv_v6_draft_01_rerr(ap, length);
448 case AODV_V6_DRAFT_01_RREP_ACK:
449 printf(" rrep-ack %u", length);
453 printf(" %u %u", ap->rreq.rreq_type, length);