2 * Routines for AODV dissection
3 * Copyright 2000, Erik Nordstrom <erik.nordstrom@it.uu.se>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/to_str.h>
16 #include <epan/expert.h>
18 #include <epan/unit_strings.h>
23 * RFC 3561 (which indicates that, for IPv6, the only change is that
24 * the address fields are enlarged)
26 * http://www.cs.ucsb.edu/~ebelding/txt/aodv6.txt
28 * http://www.tcs.hut.fi/~anttit/manet/drafts/draft-perkins-aodv6-01.txt
30 * (both of the above two are draft-perkins-manet-aodv6-01.txt, which
31 * is from November 2000)
33 void proto_register_aodv(void);
34 void proto_reg_handoff_aodv(void);
35 static dissector_handle_t aodv_handle
;
37 #define INET6_ADDRLEN 16
38 #define UDP_PORT_AODV 654
45 #define DRAFT_01_V6_RREQ 16
46 #define DRAFT_01_V6_RREP 17
47 #define DRAFT_01_V6_RERR 18
48 #define DRAFT_01_V6_RREP_ACK 19
52 #define AODV_EXT_INT 2
53 #define AODV_EXT_NTP 3
56 #define RREQ_UNKNSEQ 0x0800
57 #define RREQ_DESTONLY 0x1000
58 #define RREQ_GRATRREP 0x2000
59 #define RREQ_REP 0x4000
60 #define RREQ_JOIN 0x8000
62 #define RREP_ACK_REQ 0x4000
63 #define RREP_REP 0x8000
65 #define RERR_NODEL 0x8000
67 static const value_string type_vals
[] = {
68 { RREQ
, "Route Request" },
69 { RREP
, "Route Reply" },
70 { RERR
, "Route Error" },
71 { RREP_ACK
, "Route Reply Acknowledgment"},
72 { DRAFT_01_V6_RREQ
, "draft-perkins-manet-aodv6-01 IPv6 Route Request"},
73 { DRAFT_01_V6_RREP
, "draft-perkins-manet-aodv6-01 IPv6 Route Reply"},
74 { DRAFT_01_V6_RERR
, "draft-perkins-manet-aodv6-01 IPv6 Route Error"},
75 { DRAFT_01_V6_RREP_ACK
, "draft-perkins-manet-aodv6-01 IPv6 Route Reply Acknowledgment"},
79 static const value_string exttype_vals
[] = {
81 { AODV_EXT_INT
, "Hello Interval"},
82 { AODV_EXT_NTP
, "Timestamp"},
86 typedef struct v6_ext
{
91 /* Initialize the protocol and registered fields */
92 static int proto_aodv
;
93 static int hf_aodv_type
;
94 static int hf_aodv_flags
;
95 static int hf_aodv_prefix_sz
;
96 static int hf_aodv_hopcount
;
97 static int hf_aodv_rreq_id
;
98 static int hf_aodv_dest_ip
;
99 static int hf_aodv_dest_ipv6
;
100 static int hf_aodv_dest_seqno
;
101 static int hf_aodv_orig_ip
;
102 static int hf_aodv_orig_ipv6
;
103 static int hf_aodv_orig_seqno
;
104 static int hf_aodv_lifetime
;
105 static int hf_aodv_destcount
;
106 static int hf_aodv_unreach_dest_ip
;
107 static int hf_aodv_unreach_dest_ipv6
;
108 /* static int hf_aodv_unreach_dest_seqno; */
109 static int hf_aodv_flags_rreq_join
;
110 static int hf_aodv_flags_rreq_repair
;
111 static int hf_aodv_flags_rreq_gratuitous
;
112 static int hf_aodv_flags_rreq_destinationonly
;
113 static int hf_aodv_flags_rreq_unknown
;
114 static int hf_aodv_flags_rrep_repair
;
115 static int hf_aodv_flags_rrep_ack
;
116 static int hf_aodv_flags_rerr_nodelete
;
117 static int hf_aodv_ext_type
;
118 static int hf_aodv_ext_length
;
119 static int hf_aodv_ext_interval
;
120 static int hf_aodv_ext_timestamp
;
122 /* Initialize the subtree pointers */
124 static int ett_aodv_flags
;
125 static int ett_aodv_unreach_dest
;
126 static int ett_aodv_extensions
;
128 static expert_field ei_aodv_ext_length
;
129 static expert_field ei_aodv_type
;
131 /* Code to actually dissect the packets */
134 dissect_aodv_ext(tvbuff_t
* tvb
, packet_info
*pinfo
, int offset
, proto_tree
* tree
)
136 proto_tree
*ext_tree
;
137 proto_item
*len_item
;
141 if ((int) tvb_reported_length(tvb
) <= offset
)
142 return; /* No more options left */
144 type
= tvb_get_uint8(tvb
, offset
);
145 len
= tvb_get_uint8(tvb
, offset
+ 1);
147 ext_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 2 + len
, ett_aodv_extensions
, NULL
, "Extensions");
149 proto_tree_add_item(ext_tree
, hf_aodv_ext_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
151 len_item
= proto_tree_add_uint(ext_tree
, hf_aodv_ext_length
, tvb
, offset
+ 1, 1, len
);
153 expert_add_info(pinfo
, len_item
, &ei_aodv_ext_length
);
154 return; /* we must not try to decode this */
161 proto_tree_add_item(ext_tree
, hf_aodv_ext_interval
,
162 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
165 proto_tree_add_item(ext_tree
, hf_aodv_ext_timestamp
,
166 tvb
, offset
, 8, ENC_BIG_ENDIAN
);
171 /* If multifield extensions appear, we need more
172 * sophisticated handler. For now, this is okay. */
179 dissect_aodv_rreq(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*aodv_tree
,
180 proto_item
*ti
, bool is_ipv6
)
185 const char *dest_addr_v4
;
186 const char *dest_addr_v6
;
188 const char *orig_addr_v4
;
189 const char *orig_addr_v6
;
192 static int * const aodv_flags
[] = {
193 &hf_aodv_flags_rreq_join
,
194 &hf_aodv_flags_rreq_repair
,
195 &hf_aodv_flags_rreq_gratuitous
,
196 &hf_aodv_flags_rreq_destinationonly
,
197 &hf_aodv_flags_rreq_unknown
,
201 proto_tree_add_bitmask_with_flags(aodv_tree
, tvb
, offset
, hf_aodv_flags
,
202 ett_aodv_flags
, aodv_flags
, ENC_BIG_ENDIAN
, BMT_NO_FALSE
| BMT_NO_TFS
| BMT_NO_INT
);
203 offset
+= 2; /* skip reserved byte */
205 hop_count
= tvb_get_uint8(tvb
, offset
);
206 proto_tree_add_uint(aodv_tree
, hf_aodv_hopcount
, tvb
, offset
, 1,
210 rreq_id
= tvb_get_ntohl(tvb
, offset
);
211 proto_tree_add_uint(aodv_tree
, hf_aodv_rreq_id
, tvb
, offset
, 4,
216 dest_addr_v6
= tvb_ip6_to_str(pinfo
->pool
, tvb
, offset
);
218 proto_tree_add_item(aodv_tree
, hf_aodv_dest_ipv6
, tvb
, offset
,
219 INET6_ADDRLEN
, ENC_NA
);
220 proto_item_append_text(ti
, ", Dest IP: %s", dest_addr_v6
);
222 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", D: %s", dest_addr_v6
);
223 offset
+= INET6_ADDRLEN
;
225 dest_addr_v4
= tvb_ip_to_str(pinfo
->pool
, tvb
, offset
);
227 proto_tree_add_item(aodv_tree
, hf_aodv_dest_ip
, tvb
, offset
, 4,
229 proto_item_append_text(ti
, ", Dest IP: %s", dest_addr_v4
);
231 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", D: %s", dest_addr_v4
);
235 dest_seqno
= tvb_get_ntohl(tvb
, offset
);
236 proto_tree_add_uint(aodv_tree
, hf_aodv_dest_seqno
, tvb
, offset
, 4,
241 orig_addr_v6
= tvb_ip6_to_str(pinfo
->pool
, tvb
, offset
);
243 proto_tree_add_item(aodv_tree
, hf_aodv_orig_ipv6
, tvb
, offset
,
244 INET6_ADDRLEN
, ENC_NA
);
245 proto_item_append_text(ti
, ", Orig IP: %s", orig_addr_v6
);
247 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", O: %s", orig_addr_v6
);
248 offset
+= INET6_ADDRLEN
;
250 orig_addr_v4
= tvb_ip_to_str(pinfo
->pool
, tvb
, offset
);
252 proto_tree_add_item(aodv_tree
, hf_aodv_orig_ip
, tvb
, offset
, 4,
254 proto_item_append_text(ti
, ", Orig IP: %s", orig_addr_v4
);
256 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", O: %s", orig_addr_v4
);
260 orig_seqno
= tvb_get_ntohl(tvb
, offset
);
261 proto_tree_add_uint(aodv_tree
, hf_aodv_orig_seqno
, tvb
, offset
, 4,
263 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Id=%u Hcnt=%u DSN=%u OSN=%u",
270 extlen
= tvb_reported_length_remaining(tvb
, offset
);
272 dissect_aodv_ext(tvb
, pinfo
, offset
, aodv_tree
);
276 dissect_aodv_rrep(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*aodv_tree
,
277 proto_item
*ti
, bool is_ipv6
)
283 const char *dest_addr_v4
;
284 const char *dest_addr_v6
;
286 const char *orig_addr_v4
;
287 const char *orig_addr_v6
;
290 static int * const aodv_flags
[] = {
291 &hf_aodv_flags_rrep_repair
,
292 &hf_aodv_flags_rrep_ack
,
296 flags
= tvb_get_ntohs(tvb
, offset
);
297 proto_tree_add_bitmask_with_flags(aodv_tree
, tvb
, offset
, hf_aodv_flags
,
298 ett_aodv_flags
, aodv_flags
, ENC_BIG_ENDIAN
, BMT_NO_FALSE
| BMT_NO_TFS
| BMT_NO_INT
);
301 prefix_sz
= flags
& 0x1F;
303 proto_tree_add_uint(aodv_tree
, hf_aodv_prefix_sz
, tvb
, offset
, 1,
307 hop_count
= tvb_get_uint8(tvb
, offset
);
309 proto_tree_add_uint(aodv_tree
, hf_aodv_hopcount
, tvb
, offset
, 1,
314 dest_addr_v6
= tvb_ip6_to_str(pinfo
->pool
, tvb
, offset
);
316 proto_tree_add_item(aodv_tree
, hf_aodv_dest_ipv6
, tvb
, offset
,
317 INET6_ADDRLEN
, ENC_NA
);
318 proto_item_append_text(ti
, ", Dest IP: %s", dest_addr_v6
);
321 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", D: %s", dest_addr_v6
);
322 offset
+= INET6_ADDRLEN
;
324 dest_addr_v4
= tvb_ip_to_str(pinfo
->pool
, tvb
, offset
);
326 proto_tree_add_item(aodv_tree
, hf_aodv_dest_ip
, tvb
, offset
, 4,
328 proto_item_append_text(ti
, ", Dest IP: %s", dest_addr_v4
);
330 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", D: %s", dest_addr_v4
);
334 dest_seqno
= tvb_get_ntohl(tvb
, offset
);
336 proto_tree_add_uint(aodv_tree
, hf_aodv_dest_seqno
, tvb
, offset
, 4,
341 orig_addr_v6
= tvb_ip6_to_str(pinfo
->pool
, tvb
, offset
);
343 proto_tree_add_item(aodv_tree
, hf_aodv_orig_ipv6
, tvb
, offset
,
344 INET6_ADDRLEN
, ENC_NA
);
345 proto_item_append_text(ti
, ", Orig IP: %s", orig_addr_v6
);
347 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", O: %s", orig_addr_v6
);
348 offset
+= INET6_ADDRLEN
;
350 orig_addr_v4
= tvb_ip_to_str(pinfo
->pool
, tvb
, offset
);
352 proto_tree_add_item(aodv_tree
, hf_aodv_orig_ip
, tvb
, offset
, 4,
354 proto_item_append_text(ti
, ", Orig IP: %s", orig_addr_v4
);
356 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", O: %s", orig_addr_v4
);
360 lifetime
= tvb_get_ntohl(tvb
, offset
);
362 proto_tree_add_uint(aodv_tree
, hf_aodv_lifetime
, tvb
, offset
, 4,
364 proto_item_append_text(ti
, ", Lifetime=%u", lifetime
);
367 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Hcnt=%u DSN=%u Lifetime=%u",
373 extlen
= tvb_reported_length_remaining(tvb
, offset
);
375 dissect_aodv_ext(tvb
, pinfo
, offset
, aodv_tree
);
379 dissect_aodv_rerr(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*aodv_tree
,
383 proto_tree
*aodv_unreach_dest_tree
;
386 static int * const aodv_flags
[] = {
387 &hf_aodv_flags_rerr_nodelete
,
391 proto_tree_add_bitmask_with_flags(aodv_tree
, tvb
, offset
, hf_aodv_flags
,
392 ett_aodv_flags
, aodv_flags
, ENC_BIG_ENDIAN
, BMT_NO_FALSE
| BMT_NO_TFS
| BMT_NO_INT
);
393 offset
+= 2; /* skip reserved byte */
395 dest_count
= tvb_get_uint8(tvb
, offset
);
397 proto_tree_add_uint(aodv_tree
, hf_aodv_destcount
, tvb
, offset
, 1,
399 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Dest Count=%u",
404 aodv_unreach_dest_tree
= proto_tree_add_subtree(aodv_tree
, tvb
, offset
,
405 (INET6_ADDRLEN
+ 4)*dest_count
, ett_aodv_unreach_dest
, NULL
,
406 "Unreachable Destinations");
407 for (i
= 0; i
< dest_count
; i
++) {
408 proto_tree_add_item(aodv_unreach_dest_tree
,
409 hf_aodv_unreach_dest_ipv6
,
410 tvb
, offset
, INET6_ADDRLEN
, ENC_NA
);
411 offset
+= INET6_ADDRLEN
;
412 proto_tree_add_item(aodv_unreach_dest_tree
, hf_aodv_dest_seqno
,
413 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
417 aodv_unreach_dest_tree
= proto_tree_add_subtree(aodv_tree
, tvb
, offset
, (4 + 4)*dest_count
,
418 ett_aodv_unreach_dest
, NULL
, "Unreachable Destinations");
419 for (i
= 0; i
< dest_count
; i
++) {
420 proto_tree_add_item(aodv_unreach_dest_tree
, hf_aodv_unreach_dest_ip
,
421 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
423 proto_tree_add_item(aodv_unreach_dest_tree
, hf_aodv_dest_seqno
,
424 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
431 dissect_aodv_draft_01_v6_rreq(tvbuff_t
*tvb
, packet_info
*pinfo
,
432 proto_tree
*aodv_tree
, proto_item
*ti
)
439 const char *dest_addr_v6
;
440 const char *orig_addr_v6
;
442 static int * const aodv_flags
[] = {
443 &hf_aodv_flags_rreq_join
,
444 &hf_aodv_flags_rreq_repair
,
445 &hf_aodv_flags_rreq_gratuitous
,
446 &hf_aodv_flags_rreq_destinationonly
,
447 &hf_aodv_flags_rreq_unknown
,
451 proto_tree_add_bitmask_with_flags(aodv_tree
, tvb
, offset
, hf_aodv_flags
,
452 ett_aodv_flags
, aodv_flags
, ENC_BIG_ENDIAN
, BMT_NO_FALSE
| BMT_NO_TFS
| BMT_NO_INT
);
453 offset
+= 2; /* skip reserved byte */
455 hop_count
= tvb_get_uint8(tvb
, offset
);
456 proto_tree_add_uint(aodv_tree
, hf_aodv_hopcount
, tvb
, offset
, 1,
460 rreq_id
= tvb_get_ntohl(tvb
, offset
);
461 proto_tree_add_uint(aodv_tree
, hf_aodv_rreq_id
, tvb
, offset
, 4,
465 dest_seqno
= tvb_get_ntohl(tvb
, offset
);
466 proto_tree_add_uint(aodv_tree
, hf_aodv_dest_seqno
, tvb
, offset
, 4,
470 orig_seqno
= tvb_get_ntohl(tvb
, offset
);
471 proto_tree_add_uint(aodv_tree
, hf_aodv_orig_seqno
, tvb
, offset
, 4,
475 dest_addr_v6
= tvb_ip6_to_str(pinfo
->pool
, tvb
, offset
);
477 proto_tree_add_item(aodv_tree
, hf_aodv_dest_ipv6
, tvb
, offset
,
478 INET6_ADDRLEN
, ENC_NA
);
479 proto_item_append_text(ti
, ", Dest IP: %s", dest_addr_v6
);
482 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", D: %s", dest_addr_v6
);
483 offset
+= INET6_ADDRLEN
;
485 orig_addr_v6
= tvb_ip6_to_str(pinfo
->pool
, tvb
, offset
);
487 proto_tree_add_item(aodv_tree
, hf_aodv_orig_ipv6
, tvb
, offset
,
488 INET6_ADDRLEN
, ENC_NA
);
489 proto_item_append_text(ti
, ", Orig IP: %s", orig_addr_v6
);
492 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
493 ", O: %s Id=%u Hcnt=%u DSN=%u OSN=%u",
499 offset
+= INET6_ADDRLEN
;
501 extlen
= tvb_reported_length_remaining(tvb
, offset
);
503 dissect_aodv_ext(tvb
, pinfo
, offset
, aodv_tree
);
507 dissect_aodv_draft_01_v6_rrep(tvbuff_t
*tvb
, packet_info
*pinfo
,
508 proto_tree
*aodv_tree
, proto_item
*ti
)
515 const char *dest_addr_v6
;
516 const char *orig_addr_v6
;
519 static int * const aodv_flags
[] = {
520 &hf_aodv_flags_rrep_repair
,
521 &hf_aodv_flags_rrep_ack
,
525 flags
= tvb_get_ntohs(tvb
, offset
);
526 proto_tree_add_bitmask_with_flags(aodv_tree
, tvb
, offset
, hf_aodv_flags
,
527 ett_aodv_flags
, aodv_flags
, ENC_BIG_ENDIAN
, BMT_NO_FALSE
| BMT_NO_TFS
| BMT_NO_INT
);
530 prefix_sz
= flags
& 0x7F;
531 proto_tree_add_uint(aodv_tree
, hf_aodv_prefix_sz
, tvb
, offset
, 1,
535 hop_count
= tvb_get_uint8(tvb
, offset
);
536 proto_tree_add_uint(aodv_tree
, hf_aodv_hopcount
, tvb
, offset
, 1,
540 dest_seqno
= tvb_get_ntohl(tvb
, offset
);
541 proto_tree_add_uint(aodv_tree
, hf_aodv_dest_seqno
, tvb
, offset
, 4,
545 dest_addr_v6
= tvb_ip6_to_str(pinfo
->pool
, tvb
, offset
);
547 proto_tree_add_item(aodv_tree
, hf_aodv_dest_ipv6
, tvb
, offset
,
548 INET6_ADDRLEN
, ENC_NA
);
549 proto_item_append_text(ti
, ", Dest IP: %s", dest_addr_v6
);
552 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", D: %s", dest_addr_v6
);
553 offset
+= INET6_ADDRLEN
;
555 orig_addr_v6
= tvb_ip6_to_str(pinfo
->pool
, tvb
, offset
);
557 proto_tree_add_item(aodv_tree
, hf_aodv_orig_ipv6
, tvb
, offset
,
558 INET6_ADDRLEN
, ENC_NA
);
559 proto_item_append_text(ti
, ", Orig IP: %s", orig_addr_v6
);
562 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", O: %s", orig_addr_v6
);
563 offset
+= INET6_ADDRLEN
;
565 lifetime
= tvb_get_ntohl(tvb
, offset
);
567 proto_tree_add_uint(aodv_tree
, hf_aodv_lifetime
, tvb
, offset
, 4,
569 proto_item_append_text(ti
, ", Lifetime=%u", lifetime
);
572 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Hcnt=%u DSN=%u Lifetime=%u",
578 extlen
= tvb_reported_length_remaining(tvb
, offset
);
580 dissect_aodv_ext(tvb
, pinfo
, offset
, aodv_tree
);
584 dissect_aodv_draft_01_v6_rerr(tvbuff_t
*tvb
, packet_info
*pinfo
,
585 proto_tree
*aodv_tree
)
588 proto_tree
*aodv_unreach_dest_tree
;
591 static int * const aodv_flags
[] = {
592 &hf_aodv_flags_rerr_nodelete
,
596 proto_tree_add_bitmask_with_flags(aodv_tree
, tvb
, offset
, hf_aodv_flags
,
597 ett_aodv_flags
, aodv_flags
, ENC_BIG_ENDIAN
, BMT_NO_FALSE
| BMT_NO_TFS
| BMT_NO_INT
);
598 offset
+= 2; /* skip reserved byte */
600 dest_count
= tvb_get_uint8(tvb
, offset
);
601 proto_tree_add_uint(aodv_tree
, hf_aodv_destcount
, tvb
, offset
, 1,
604 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Dest Count=%u",
608 aodv_unreach_dest_tree
= proto_tree_add_subtree(aodv_tree
, tvb
, offset
,
609 (4 + INET6_ADDRLEN
)*dest_count
,
610 ett_aodv_unreach_dest
, NULL
,
611 "Unreachable Destinations");
612 for (i
= 0; i
< dest_count
; i
++) {
613 proto_tree_add_item(aodv_unreach_dest_tree
, hf_aodv_dest_seqno
,
614 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
616 proto_tree_add_item(aodv_unreach_dest_tree
,
617 hf_aodv_unreach_dest_ipv6
,
618 tvb
, offset
, INET6_ADDRLEN
, ENC_NA
);
619 offset
+= INET6_ADDRLEN
;
624 dissect_aodv(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
626 proto_item
*ti
, *type_item
;
627 proto_tree
*aodv_tree
;
631 /* Make entries in Protocol column and Info column on summary display */
632 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "AODV");
634 col_clear(pinfo
->cinfo
, COL_INFO
);
636 /* Is this running over IPv6? */
637 is_ipv6
= (pinfo
->src
.type
== AT_IPv6
);
639 /* Check the type of AODV packet. */
640 type
= tvb_get_uint8(tvb
, 0);
641 if (try_val_to_str(type
, type_vals
) == NULL
) {
643 * We assume this is not an AODV packet.
649 col_add_str(pinfo
->cinfo
, COL_INFO
,
650 val_to_str(type
, type_vals
,
651 "Unknown AODV Packet Type (%u)"));
652 ti
= proto_tree_add_protocol_format(tree
, proto_aodv
, tvb
, 0, -1,
653 "Ad hoc On-demand Distance Vector Routing Protocol, %s",
654 val_to_str(type
, type_vals
, "Unknown AODV Packet Type (%u)"));
655 aodv_tree
= proto_item_add_subtree(ti
, ett_aodv
);
657 type_item
= proto_tree_add_uint(aodv_tree
, hf_aodv_type
, tvb
, 0, 1, type
);
661 dissect_aodv_rreq(tvb
, pinfo
, aodv_tree
, ti
, is_ipv6
);
664 dissect_aodv_rrep(tvb
, pinfo
, aodv_tree
, ti
, is_ipv6
);
667 dissect_aodv_rerr(tvb
, pinfo
, aodv_tree
, is_ipv6
);
671 case DRAFT_01_V6_RREQ
:
672 dissect_aodv_draft_01_v6_rreq(tvb
, pinfo
, aodv_tree
, ti
);
674 case DRAFT_01_V6_RREP
:
675 dissect_aodv_draft_01_v6_rrep(tvb
, pinfo
, aodv_tree
, ti
);
677 case DRAFT_01_V6_RERR
:
678 dissect_aodv_draft_01_v6_rerr(tvb
, pinfo
, aodv_tree
);
680 case DRAFT_01_V6_RREP_ACK
:
683 expert_add_info(pinfo
, type_item
, &ei_aodv_type
);
686 return tvb_reported_length(tvb
);
690 /* Register the protocol with Wireshark */
692 proto_register_aodv(void)
694 static hf_register_info hf
[] = {
696 { "Type", "aodv.type",
697 FT_UINT8
, BASE_DEC
, VALS(type_vals
), 0x0,
698 "AODV packet type", HFILL
}
701 { "Flags", "aodv.flags",
702 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
705 { &hf_aodv_flags_rreq_join
,
706 { "RREQ Join", "aodv.flags.rreq_join",
707 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), RREQ_JOIN
,
710 { &hf_aodv_flags_rreq_repair
,
711 { "RREQ Repair", "aodv.flags.rreq_repair",
712 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), RREQ_REP
,
715 { &hf_aodv_flags_rreq_gratuitous
,
716 { "RREQ Gratuitous RREP", "aodv.flags.rreq_gratuitous",
717 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), RREQ_GRATRREP
,
720 { &hf_aodv_flags_rreq_destinationonly
,
721 { "RREQ Destination only", "aodv.flags.rreq_destinationonly",
722 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), RREQ_DESTONLY
,
725 { &hf_aodv_flags_rreq_unknown
,
726 { "RREQ Unknown Sequence Number", "aodv.flags.rreq_unknown",
727 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), RREQ_UNKNSEQ
,
730 { &hf_aodv_flags_rrep_repair
,
731 { "RREP Repair", "aodv.flags.rrep_repair",
732 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), RREP_REP
,
735 { &hf_aodv_flags_rrep_ack
,
736 { "RREP Acknowledgement", "aodv.flags.rrep_ack",
737 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), RREP_ACK_REQ
,
740 { &hf_aodv_flags_rerr_nodelete
,
741 { "RERR No Delete", "aodv.flags.rerr_nodelete",
742 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), RERR_NODEL
,
745 { &hf_aodv_prefix_sz
,
746 { "Prefix Size", "aodv.prefix_sz",
747 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
751 { "Hop Count", "aodv.hopcount",
752 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
756 { "RREQ Id", "aodv.rreq_id",
757 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
761 { "Destination IP", "aodv.dest_ip",
762 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
763 "Destination IP Address", HFILL
}
765 { &hf_aodv_dest_ipv6
,
766 { "Destination IPv6", "aodv.dest_ipv6",
767 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
768 "Destination IPv6 Address", HFILL
}
770 { &hf_aodv_dest_seqno
,
771 { "Destination Sequence Number", "aodv.dest_seqno",
772 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
776 { "Originator IP", "aodv.orig_ip",
777 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
778 "Originator IP Address", HFILL
}
780 { &hf_aodv_orig_ipv6
,
781 { "Originator IPv6", "aodv.orig_ipv6",
782 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
783 "Originator IPv6 Address", HFILL
}
785 { &hf_aodv_orig_seqno
,
786 { "Originator Sequence Number", "aodv.orig_seqno",
787 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
791 { "Lifetime", "aodv.lifetime",
792 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
795 { &hf_aodv_destcount
,
796 { "Destination Count", "aodv.destcount",
797 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
798 "Unreachable Destinations Count", HFILL
}
800 { &hf_aodv_unreach_dest_ip
,
801 { "Unreachable Destination IP", "aodv.unreach_dest_ip",
802 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
803 "Unreachable Destination IP Address", HFILL
}
805 { &hf_aodv_unreach_dest_ipv6
,
806 { "Unreachable Destination IPv6", "aodv.unreach_dest_ipv6",
807 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
808 "Unreachable Destination IPv6 Address", HFILL
}
811 { &hf_aodv_unreach_dest_seqno
,
812 { "Unreachable Destination Sequence Number", "aodv.unreach_dest_seqno",
813 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
818 { "Extension Type", "aodv.ext_type",
819 FT_UINT8
, BASE_DEC
, VALS(exttype_vals
), 0x0,
820 "Extension Format Type", HFILL
}
822 { &hf_aodv_ext_length
,
823 { "Extension Length", "aodv.ext_length",
824 FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_byte_bytes
), 0x0,
825 "Extension Data Length", HFILL
}
827 { &hf_aodv_ext_interval
,
828 { "Hello Interval", "aodv.hello_interval",
829 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
830 "Hello Interval Extension", HFILL
}
832 { &hf_aodv_ext_timestamp
,
833 { "Timestamp", "aodv.timestamp",
834 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
835 "Timestamp Extension", HFILL
}
839 /* Setup protocol subtree array */
840 static int *ett
[] = {
843 &ett_aodv_unreach_dest
,
844 &ett_aodv_extensions
,
847 static ei_register_info ei
[] = {
848 { &ei_aodv_ext_length
, { "aodv.ext_length.invalid", PI_MALFORMED
, PI_ERROR
, "Invalid option length", EXPFILL
}},
849 { &ei_aodv_type
, { "aodv.ext_type.unknown", PI_PROTOCOL
, PI_WARN
, "Unknown AODV Packet Type", EXPFILL
}},
852 expert_module_t
* expert_aodv
;
854 /* Register the protocol name and description */
855 proto_aodv
= proto_register_protocol("Ad hoc On-demand Distance Vector Routing Protocol", "AODV", "aodv");
856 aodv_handle
= register_dissector("aodv", dissect_aodv
, proto_aodv
);
858 /* Required function calls to register the header fields and subtrees used */
859 proto_register_field_array(proto_aodv
, hf
, array_length(hf
));
860 proto_register_subtree_array(ett
, array_length(ett
));
861 expert_aodv
= expert_register_protocol(proto_aodv
);
862 expert_register_field_array(expert_aodv
, ei
, array_length(ei
));
867 proto_reg_handoff_aodv(void)
869 dissector_add_uint_with_preference("udp.port", UDP_PORT_AODV
, aodv_handle
);
873 * Editor modelines - https://www.wireshark.org/tools/modelines.html
878 * indent-tabs-mode: nil
881 * vi: set shiftwidth=4 tabstop=8 expandtab:
882 * :indentSize=4:tabSize=8:noTabs=true: