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>
48 #include "interface.h"
49 #include "addrtoname.h"
50 #include "extract.h" /* must come after interface.h */
55 aodv_extension(const struct aodv_ext
*ep
, u_int length
)
57 const struct aodv_hello
*ah
;
61 ah
= (const struct aodv_hello
*)(const void *)ep
;
63 if (length
< sizeof(struct aodv_hello
))
65 printf("\n\text HELLO %ld ms",
66 (unsigned long)EXTRACT_32BITS(&ah
->interval
));
70 printf("\n\text %u %u", ep
->type
, ep
->length
);
80 aodv_rreq(const u_char
*dat
, u_int length
)
83 const struct aodv_rreq
*ap
= (const struct aodv_rreq
*)dat
;
86 if (length
< sizeof(*ap
))
88 printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
89 "\tdst %s seq %lu src %s seq %lu", length
,
90 ap
->rreq_type
& RREQ_JOIN
? "[J]" : "",
91 ap
->rreq_type
& RREQ_REPAIR
? "[R]" : "",
92 ap
->rreq_type
& RREQ_GRAT
? "[G]" : "",
93 ap
->rreq_type
& RREQ_DEST
? "[D]" : "",
94 ap
->rreq_type
& RREQ_UNKNOWN
? "[U] " : " ",
96 (unsigned long)EXTRACT_32BITS(&ap
->rreq_id
),
97 ipaddr_string(&ap
->rreq_da
),
98 (unsigned long)EXTRACT_32BITS(&ap
->rreq_ds
),
99 ipaddr_string(&ap
->rreq_oa
),
100 (unsigned long)EXTRACT_32BITS(&ap
->rreq_os
));
101 i
= length
- sizeof(*ap
);
102 if (i
>= sizeof(struct aodv_ext
))
103 aodv_extension((const struct aodv_ext
*)(dat
+ sizeof(*ap
)), i
);
111 aodv_rrep(const u_char
*dat
, u_int length
)
114 const struct aodv_rrep
*ap
= (const struct aodv_rrep
*)dat
;
117 if (length
< sizeof(*ap
))
119 printf(" rrep %u %s%sprefix %u hops %u\n"
120 "\tdst %s dseq %lu src %s %lu ms", length
,
121 ap
->rrep_type
& RREP_REPAIR
? "[R]" : "",
122 ap
->rrep_type
& RREP_ACK
? "[A] " : " ",
123 ap
->rrep_ps
& RREP_PREFIX_MASK
,
125 ipaddr_string(&ap
->rrep_da
),
126 (unsigned long)EXTRACT_32BITS(&ap
->rrep_ds
),
127 ipaddr_string(&ap
->rrep_oa
),
128 (unsigned long)EXTRACT_32BITS(&ap
->rrep_life
));
129 i
= length
- sizeof(*ap
);
130 if (i
>= sizeof(struct aodv_ext
))
131 aodv_extension((const struct aodv_ext
*)(dat
+ sizeof(*ap
)), i
);
139 aodv_rerr(const u_char
*dat
, u_int length
)
142 const struct aodv_rerr
*ap
= (const struct aodv_rerr
*)dat
;
143 const struct rerr_unreach
*dp
;
146 if (length
< sizeof(*ap
))
148 printf(" rerr %s [items %u] [%u]:",
149 ap
->rerr_flags
& RERR_NODELETE
? "[D]" : "",
150 ap
->rerr_dc
, length
);
151 dp
= (struct rerr_unreach
*)(dat
+ sizeof(*ap
));
152 i
= length
- sizeof(*ap
);
153 for (dc
= ap
->rerr_dc
; dc
!= 0; dc
--) {
157 printf(" {%s}(%ld)", ipaddr_string(&dp
->u_da
),
158 (unsigned long)EXTRACT_32BITS(&dp
->u_ds
));
170 aodv_v6_rreq(const u_char
*dat
, u_int length
)
172 aodv_v6_rreq(const u_char
*dat _U_
, u_int length
)
177 const struct aodv_rreq6
*ap
= (const struct aodv_rreq6
*)dat
;
180 if (length
< sizeof(*ap
))
182 printf(" v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
183 "\tdst %s seq %lu src %s seq %lu", length
,
184 ap
->rreq_type
& RREQ_JOIN
? "[J]" : "",
185 ap
->rreq_type
& RREQ_REPAIR
? "[R]" : "",
186 ap
->rreq_type
& RREQ_GRAT
? "[G]" : "",
187 ap
->rreq_type
& RREQ_DEST
? "[D]" : "",
188 ap
->rreq_type
& RREQ_UNKNOWN
? "[U] " : " ",
190 (unsigned long)EXTRACT_32BITS(&ap
->rreq_id
),
191 ip6addr_string(&ap
->rreq_da
),
192 (unsigned long)EXTRACT_32BITS(&ap
->rreq_ds
),
193 ip6addr_string(&ap
->rreq_oa
),
194 (unsigned long)EXTRACT_32BITS(&ap
->rreq_os
));
195 i
= length
- sizeof(*ap
);
196 if (i
>= sizeof(struct aodv_ext
))
197 aodv_extension((const struct aodv_ext
*)(dat
+ sizeof(*ap
)), i
);
203 printf(" v6 rreq %u", length
);
209 aodv_v6_rrep(const u_char
*dat
, u_int length
)
211 aodv_v6_rrep(const u_char
*dat _U_
, u_int length
)
216 const struct aodv_rrep6
*ap
= (const struct aodv_rrep6
*)dat
;
219 if (length
< sizeof(*ap
))
221 printf(" rrep %u %s%sprefix %u hops %u\n"
222 "\tdst %s dseq %lu src %s %lu ms", length
,
223 ap
->rrep_type
& RREP_REPAIR
? "[R]" : "",
224 ap
->rrep_type
& RREP_ACK
? "[A] " : " ",
225 ap
->rrep_ps
& RREP_PREFIX_MASK
,
227 ip6addr_string(&ap
->rrep_da
),
228 (unsigned long)EXTRACT_32BITS(&ap
->rrep_ds
),
229 ip6addr_string(&ap
->rrep_oa
),
230 (unsigned long)EXTRACT_32BITS(&ap
->rrep_life
));
231 i
= length
- sizeof(*ap
);
232 if (i
>= sizeof(struct aodv_ext
))
233 aodv_extension((const struct aodv_ext
*)(dat
+ sizeof(*ap
)), i
);
239 printf(" rrep %u", length
);
245 aodv_v6_rerr(const u_char
*dat
, u_int length
)
247 aodv_v6_rerr(const u_char
*dat _U_
, u_int length
)
252 const struct aodv_rerr
*ap
= (const struct aodv_rerr
*)dat
;
253 const struct rerr_unreach6
*dp6
;
256 if (length
< sizeof(*ap
))
258 printf(" rerr %s [items %u] [%u]:",
259 ap
->rerr_flags
& RERR_NODELETE
? "[D]" : "",
260 ap
->rerr_dc
, length
);
261 dp6
= (struct rerr_unreach6
*)(void *)(ap
+ 1);
262 i
= length
- sizeof(*ap
);
263 for (dc
= ap
->rerr_dc
; dc
!= 0; dc
--) {
265 if (i
< sizeof(*dp6
))
267 printf(" {%s}(%ld)", ip6addr_string(&dp6
->u_da
),
268 (unsigned long)EXTRACT_32BITS(&dp6
->u_ds
));
277 printf(" rerr %u", length
);
283 aodv_v6_draft_01_rreq(const u_char
*dat
, u_int length
)
285 aodv_v6_draft_01_rreq(const u_char
*dat _U_
, u_int length
)
290 const struct aodv_rreq6_draft_01
*ap
= (const struct aodv_rreq6_draft_01
*)dat
;
293 if (length
< sizeof(*ap
))
295 printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
296 "\tdst %s seq %lu src %s seq %lu", length
,
297 ap
->rreq_type
& RREQ_JOIN
? "[J]" : "",
298 ap
->rreq_type
& RREQ_REPAIR
? "[R]" : "",
299 ap
->rreq_type
& RREQ_GRAT
? "[G]" : "",
300 ap
->rreq_type
& RREQ_DEST
? "[D]" : "",
301 ap
->rreq_type
& RREQ_UNKNOWN
? "[U] " : " ",
303 (unsigned long)EXTRACT_32BITS(&ap
->rreq_id
),
304 ip6addr_string(&ap
->rreq_da
),
305 (unsigned long)EXTRACT_32BITS(&ap
->rreq_ds
),
306 ip6addr_string(&ap
->rreq_oa
),
307 (unsigned long)EXTRACT_32BITS(&ap
->rreq_os
));
308 i
= length
- sizeof(*ap
);
309 if (i
>= sizeof(struct aodv_ext
))
310 aodv_extension((const struct aodv_ext
*)(dat
+ sizeof(*ap
)), i
);
316 printf(" rreq %u", length
);
322 aodv_v6_draft_01_rrep(const u_char
*dat
, u_int length
)
324 aodv_v6_draft_01_rrep(const u_char
*dat _U_
, u_int length
)
329 const struct aodv_rrep6_draft_01
*ap
= (const struct aodv_rrep6_draft_01
*)dat
;
332 if (length
< sizeof(*ap
))
334 printf(" rrep %u %s%sprefix %u hops %u\n"
335 "\tdst %s dseq %lu src %s %lu ms", length
,
336 ap
->rrep_type
& RREP_REPAIR
? "[R]" : "",
337 ap
->rrep_type
& RREP_ACK
? "[A] " : " ",
338 ap
->rrep_ps
& RREP_PREFIX_MASK
,
340 ip6addr_string(&ap
->rrep_da
),
341 (unsigned long)EXTRACT_32BITS(&ap
->rrep_ds
),
342 ip6addr_string(&ap
->rrep_oa
),
343 (unsigned long)EXTRACT_32BITS(&ap
->rrep_life
));
344 i
= length
- sizeof(*ap
);
345 if (i
>= sizeof(struct aodv_ext
))
346 aodv_extension((const struct aodv_ext
*)(dat
+ sizeof(*ap
)), i
);
352 printf(" rrep %u", length
);
358 aodv_v6_draft_01_rerr(const u_char
*dat
, u_int length
)
360 aodv_v6_draft_01_rerr(const u_char
*dat _U_
, u_int length
)
365 const struct aodv_rerr
*ap
= (const struct aodv_rerr
*)dat
;
366 const struct rerr_unreach6_draft_01
*dp6
;
369 if (length
< sizeof(*ap
))
371 printf(" rerr %s [items %u] [%u]:",
372 ap
->rerr_flags
& RERR_NODELETE
? "[D]" : "",
373 ap
->rerr_dc
, length
);
374 dp6
= (struct rerr_unreach6_draft_01
*)(void *)(ap
+ 1);
375 i
= length
- sizeof(*ap
);
376 for (dc
= ap
->rerr_dc
; dc
!= 0; dc
--) {
378 if (i
< sizeof(*dp6
))
380 printf(" {%s}(%ld)", ip6addr_string(&dp6
->u_da
),
381 (unsigned long)EXTRACT_32BITS(&dp6
->u_ds
));
390 printf(" rerr %u", length
);
395 aodv_print(const u_char
*dat
, u_int length
, int is_ip6
)
400 * The message type is the first byte; make sure we have it
411 aodv_v6_rreq(dat
, length
);
413 aodv_rreq(dat
, length
);
418 aodv_v6_rrep(dat
, length
);
420 aodv_rrep(dat
, length
);
425 aodv_v6_rerr(dat
, length
);
427 aodv_rerr(dat
, length
);
431 printf(" rrep-ack %u", length
);
434 case AODV_V6_DRAFT_01_RREQ
:
435 aodv_v6_draft_01_rreq(dat
, length
);
438 case AODV_V6_DRAFT_01_RREP
:
439 aodv_v6_draft_01_rrep(dat
, length
);
442 case AODV_V6_DRAFT_01_RERR
:
443 aodv_v6_draft_01_rerr(dat
, length
);
446 case AODV_V6_DRAFT_01_RREP_ACK
:
447 printf(" rrep-ack %u", length
);
451 printf(" type %u %u", msg_type
, length
);