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