Fix markup. Fix backslashes to surive roff.
[netbsd-mini2440.git] / dist / tcpdump / print-aodv.c
blob08b9dec026f223615c1bd23ece3448390157616d
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org>
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Bruce M. Simpson.
18 * 4. Neither the name of Bruce M. Simpson nor the names of co-
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bruce M. Simpson OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/cdefs.h>
36 #ifndef lint
37 #if 0
38 static const char rcsid[] _U_ =
39 "@(#) Header: /tcpdump/master/tcpdump/print-aodv.c,v 1.11 2004/03/24 00:30:19 guy Exp (LBL)";
40 #else
41 __RCSID("$NetBSD: tcpdump2rcsid.ex,v 1.1 2001/06/25 20:09:58 itojun Exp $");
42 #endif
43 #endif
45 #ifdef HAVE_CONFIG_H
46 #include "config.h"
47 #endif
49 #include <tcpdump-stdinc.h>
51 #include <stddef.h>
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <string.h>
56 #include "interface.h"
57 #include "addrtoname.h"
58 #include "extract.h" /* must come after interface.h */
60 #include "aodv.h"
62 static void
63 aodv_extension(const struct aodv_ext *ep, u_int length)
65 u_int i;
66 const struct aodv_hello *ah;
68 switch (ep->type) {
69 case AODV_EXT_HELLO:
70 if (snapend < (u_char *) ep) {
71 printf(" [|hello]");
72 return;
74 i = min(length, (u_int)(snapend - (u_char *)ep));
75 if (i < sizeof(struct aodv_hello)) {
76 printf(" [|hello]");
77 return;
79 i -= sizeof(struct aodv_hello);
80 ah = (void *)ep;
81 printf("\n\text HELLO %ld ms",
82 (unsigned long)EXTRACT_32BITS(&ah->interval));
83 break;
85 default:
86 printf("\n\text %u %u", ep->type, ep->length);
87 break;
91 static void
92 aodv_rreq(const union aodv *ap, const u_char *dat, u_int length)
94 u_int i;
96 if (snapend < dat) {
97 printf(" [|aodv]");
98 return;
100 i = min(length, (u_int)(snapend - dat));
101 if (i < sizeof(ap->rreq)) {
102 printf(" [|rreq]");
103 return;
105 i -= sizeof(ap->rreq);
106 printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
107 "\tdst %s seq %lu src %s seq %lu", length,
108 ap->rreq.rreq_type & RREQ_JOIN ? "[J]" : "",
109 ap->rreq.rreq_type & RREQ_REPAIR ? "[R]" : "",
110 ap->rreq.rreq_type & RREQ_GRAT ? "[G]" : "",
111 ap->rreq.rreq_type & RREQ_DEST ? "[D]" : "",
112 ap->rreq.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
113 ap->rreq.rreq_hops,
114 (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_id),
115 ipaddr_string(&ap->rreq.rreq_da),
116 (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_ds),
117 ipaddr_string(&ap->rreq.rreq_oa),
118 (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_os));
119 if (i >= sizeof(struct aodv_ext))
120 aodv_extension((void *)(&ap->rreq + 1), i);
123 static void
124 aodv_rrep(const union aodv *ap, const u_char *dat, u_int length)
126 u_int i;
128 if (snapend < dat) {
129 printf(" [|aodv]");
130 return;
132 i = min(length, (u_int)(snapend - dat));
133 if (i < sizeof(ap->rrep)) {
134 printf(" [|rrep]");
135 return;
137 i -= sizeof(ap->rrep);
138 printf(" rrep %u %s%sprefix %u hops %u\n"
139 "\tdst %s dseq %lu src %s %lu ms", length,
140 ap->rrep.rrep_type & RREP_REPAIR ? "[R]" : "",
141 ap->rrep.rrep_type & RREP_ACK ? "[A] " : " ",
142 ap->rrep.rrep_ps & RREP_PREFIX_MASK,
143 ap->rrep.rrep_hops,
144 ipaddr_string(&ap->rrep.rrep_da),
145 (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_ds),
146 ipaddr_string(&ap->rrep.rrep_oa),
147 (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_life));
148 if (i >= sizeof(struct aodv_ext))
149 aodv_extension((void *)(&ap->rrep + 1), i);
152 static void
153 aodv_rerr(const union aodv *ap, const u_char *dat, u_int length)
155 u_int i;
156 const struct rerr_unreach *dp = NULL;
157 int n, trunc;
159 if (snapend < dat) {
160 printf(" [|aodv]");
161 return;
163 i = min(length, (u_int)(snapend - dat));
164 if (i < offsetof(struct aodv_rerr, r)) {
165 printf(" [|rerr]");
166 return;
168 i -= offsetof(struct aodv_rerr, r);
169 dp = &ap->rerr.r.dest[0];
170 n = ap->rerr.rerr_dc * sizeof(ap->rerr.r.dest[0]);
171 printf(" rerr %s [items %u] [%u]:",
172 ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
173 ap->rerr.rerr_dc, length);
174 trunc = n - (i/sizeof(ap->rerr.r.dest[0]));
175 for (; i >= sizeof(ap->rerr.r.dest[0]);
176 ++dp, i -= sizeof(ap->rerr.r.dest[0])) {
177 printf(" {%s}(%ld)", ipaddr_string(&dp->u_da),
178 (unsigned long)EXTRACT_32BITS(&dp->u_ds));
180 if (trunc)
181 printf("[|rerr]");
184 static void
185 #ifdef INET6
186 aodv_v6_rreq(const union aodv *ap, const u_char *dat, u_int length)
187 #else
188 aodv_v6_rreq(const union aodv *ap _U_, const u_char *dat _U_, u_int length)
189 #endif
191 #ifdef INET6
192 u_int i;
194 if (snapend < dat) {
195 printf(" [|aodv]");
196 return;
198 i = min(length, (u_int)(snapend - dat));
199 if (i < sizeof(ap->rreq6)) {
200 printf(" [|rreq6]");
201 return;
203 i -= sizeof(ap->rreq6);
204 printf(" v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
205 "\tdst %s seq %lu src %s seq %lu", length,
206 ap->rreq6.rreq_type & RREQ_JOIN ? "[J]" : "",
207 ap->rreq6.rreq_type & RREQ_REPAIR ? "[R]" : "",
208 ap->rreq6.rreq_type & RREQ_GRAT ? "[G]" : "",
209 ap->rreq6.rreq_type & RREQ_DEST ? "[D]" : "",
210 ap->rreq6.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
211 ap->rreq6.rreq_hops,
212 (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_id),
213 ip6addr_string(&ap->rreq6.rreq_da),
214 (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_ds),
215 ip6addr_string(&ap->rreq6.rreq_oa),
216 (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_os));
217 if (i >= sizeof(struct aodv_ext))
218 aodv_extension((void *)(&ap->rreq6 + 1), i);
219 #else
220 printf(" v6 rreq %u", length);
221 #endif
224 static void
225 #ifdef INET6
226 aodv_v6_rrep(const union aodv *ap, const u_char *dat, u_int length)
227 #else
228 aodv_v6_rrep(const union aodv *ap _U_, const u_char *dat _U_, u_int length)
229 #endif
231 #ifdef INET6
232 u_int i;
234 if (snapend < dat) {
235 printf(" [|aodv]");
236 return;
238 i = min(length, (u_int)(snapend - dat));
239 if (i < sizeof(ap->rrep6)) {
240 printf(" [|rrep6]");
241 return;
243 i -= sizeof(ap->rrep6);
244 printf(" rrep %u %s%sprefix %u hops %u\n"
245 "\tdst %s dseq %lu src %s %lu ms", length,
246 ap->rrep6.rrep_type & RREP_REPAIR ? "[R]" : "",
247 ap->rrep6.rrep_type & RREP_ACK ? "[A] " : " ",
248 ap->rrep6.rrep_ps & RREP_PREFIX_MASK,
249 ap->rrep6.rrep_hops,
250 ip6addr_string(&ap->rrep6.rrep_da),
251 (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_ds),
252 ip6addr_string(&ap->rrep6.rrep_oa),
253 (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_life));
254 if (i >= sizeof(struct aodv_ext))
255 aodv_extension((void *)(&ap->rrep6 + 1), i);
256 #else
257 printf(" rrep %u", length);
258 #endif
261 static void
262 #ifdef INET6
263 aodv_v6_rerr(const union aodv *ap, u_int length)
264 #else
265 aodv_v6_rerr(const union aodv *ap _U_, u_int length)
266 #endif
268 #ifdef INET6
269 const struct rerr_unreach6 *dp6 = NULL;
270 int i, j, n, trunc;
272 i = length - offsetof(struct aodv_rerr, r);
273 j = sizeof(ap->rerr.r.dest6[0]);
274 dp6 = &ap->rerr.r.dest6[0];
275 n = ap->rerr.rerr_dc * j;
276 printf(" rerr %s [items %u] [%u]:",
277 ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
278 ap->rerr.rerr_dc, length);
279 trunc = n - (i/j);
280 for (; i -= j >= 0; ++dp6) {
281 printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da),
282 (unsigned long)EXTRACT_32BITS(&dp6->u_ds));
284 if (trunc)
285 printf("[|rerr]");
286 #else
287 printf(" rerr %u", length);
288 #endif
291 static void
292 #ifdef INET6
293 aodv_v6_draft_01_rreq(const union aodv *ap, const u_char *dat, u_int length)
294 #else
295 aodv_v6_draft_01_rreq(const union aodv *ap _U_, const u_char *dat _U_,
296 u_int length)
297 #endif
299 #ifdef INET6
300 u_int i;
302 if (snapend < dat) {
303 printf(" [|aodv]");
304 return;
306 i = min(length, (u_int)(snapend - dat));
307 if (i < sizeof(ap->rreq6_draft_01)) {
308 printf(" [|rreq6]");
309 return;
311 i -= sizeof(ap->rreq6_draft_01);
312 printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
313 "\tdst %s seq %lu src %s seq %lu", length,
314 ap->rreq6_draft_01.rreq_type & RREQ_JOIN ? "[J]" : "",
315 ap->rreq6_draft_01.rreq_type & RREQ_REPAIR ? "[R]" : "",
316 ap->rreq6_draft_01.rreq_type & RREQ_GRAT ? "[G]" : "",
317 ap->rreq6_draft_01.rreq_type & RREQ_DEST ? "[D]" : "",
318 ap->rreq6_draft_01.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
319 ap->rreq6_draft_01.rreq_hops,
320 (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_id),
321 ip6addr_string(&ap->rreq6_draft_01.rreq_da),
322 (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_ds),
323 ip6addr_string(&ap->rreq6_draft_01.rreq_oa),
324 (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_os));
325 if (i >= sizeof(struct aodv_ext))
326 aodv_extension((void *)(&ap->rreq6_draft_01 + 1), i);
327 #else
328 printf(" rreq %u", length);
329 #endif
332 static void
333 #ifdef INET6
334 aodv_v6_draft_01_rrep(const union aodv *ap, const u_char *dat, u_int length)
335 #else
336 aodv_v6_draft_01_rrep(const union aodv *ap _U_, const u_char *dat _U_,
337 u_int length)
338 #endif
340 #ifdef INET6
341 u_int i;
343 if (snapend < dat) {
344 printf(" [|aodv]");
345 return;
347 i = min(length, (u_int)(snapend - dat));
348 if (i < sizeof(ap->rrep6_draft_01)) {
349 printf(" [|rrep6]");
350 return;
352 i -= sizeof(ap->rrep6_draft_01);
353 printf(" rrep %u %s%sprefix %u hops %u\n"
354 "\tdst %s dseq %lu src %s %lu ms", length,
355 ap->rrep6_draft_01.rrep_type & RREP_REPAIR ? "[R]" : "",
356 ap->rrep6_draft_01.rrep_type & RREP_ACK ? "[A] " : " ",
357 ap->rrep6_draft_01.rrep_ps & RREP_PREFIX_MASK,
358 ap->rrep6_draft_01.rrep_hops,
359 ip6addr_string(&ap->rrep6_draft_01.rrep_da),
360 (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_ds),
361 ip6addr_string(&ap->rrep6_draft_01.rrep_oa),
362 (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_life));
363 if (i >= sizeof(struct aodv_ext))
364 aodv_extension((void *)(&ap->rrep6_draft_01 + 1), i);
365 #else
366 printf(" rrep %u", length);
367 #endif
370 static void
371 #ifdef INET6
372 aodv_v6_draft_01_rerr(const union aodv *ap, u_int length)
373 #else
374 aodv_v6_draft_01_rerr(const union aodv *ap _U_, u_int length)
375 #endif
377 #ifdef INET6
378 const struct rerr_unreach6_draft_01 *dp6 = NULL;
379 int i, j, n, trunc;
381 i = length - offsetof(struct aodv_rerr, r);
382 j = sizeof(ap->rerr.r.dest6_draft_01[0]);
383 dp6 = &ap->rerr.r.dest6_draft_01[0];
384 n = ap->rerr.rerr_dc * j;
385 printf(" rerr %s [items %u] [%u]:",
386 ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
387 ap->rerr.rerr_dc, length);
388 trunc = n - (i/j);
389 for (; i -= j >= 0; ++dp6) {
390 printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da),
391 (unsigned long)EXTRACT_32BITS(&dp6->u_ds));
393 if (trunc)
394 printf("[|rerr]");
395 #else
396 printf(" rerr %u", length);
397 #endif
400 void
401 aodv_print(const u_char *dat, u_int length, int is_ip6)
403 const union aodv *ap;
405 ap = (union aodv *)dat;
406 if (snapend < dat) {
407 printf(" [|aodv]");
408 return;
410 if (min(length, (u_int)(snapend - dat)) < sizeof(ap->rrep_ack)) {
411 printf(" [|aodv]");
412 return;
414 printf(" aodv");
416 switch (ap->rerr.rerr_type) {
418 case AODV_RREQ:
419 if (is_ip6)
420 aodv_v6_rreq(ap, dat, length);
421 else
422 aodv_rreq(ap, dat, length);
423 break;
425 case AODV_RREP:
426 if (is_ip6)
427 aodv_v6_rrep(ap, dat, length);
428 else
429 aodv_rrep(ap, dat, length);
430 break;
432 case AODV_RERR:
433 if (is_ip6)
434 aodv_v6_rerr(ap, length);
435 else
436 aodv_rerr(ap, dat, length);
437 break;
439 case AODV_RREP_ACK:
440 printf(" rrep-ack %u", length);
441 break;
443 case AODV_V6_DRAFT_01_RREQ:
444 aodv_v6_draft_01_rreq(ap, dat, length);
445 break;
447 case AODV_V6_DRAFT_01_RREP:
448 aodv_v6_draft_01_rrep(ap, dat, length);
449 break;
451 case AODV_V6_DRAFT_01_RERR:
452 aodv_v6_draft_01_rerr(ap, length);
453 break;
455 case AODV_V6_DRAFT_01_RREP_ACK:
456 printf(" rrep-ack %u", length);
457 break;
459 default:
460 printf(" %u %u", ap->rreq.rreq_type, length);