2 * Routines for Babel dissection (RFC 6126)
3 * Copyright 2011 by Juliusz Chroboczek <jch@pps.jussieu.fr>
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 void proto_register_babel(void);
17 void proto_reg_handoff_babel(void);
19 static dissector_handle_t babel_handle
;
21 static int proto_babel
;
24 static int hf_babel_magic
;
25 static int hf_babel_version
;
26 static int hf_babel_bodylen
;
28 static int hf_babel_message
;
29 static int ett_message
;
30 static int hf_babel_message_type
;
31 static int hf_babel_message_length
;
32 static int hf_babel_message_nonce
;
33 static int hf_babel_message_interval
;
34 static int hf_babel_message_seqno
;
35 static int hf_babel_message_ae
;
36 static int hf_babel_message_prefix
;
37 static int hf_babel_message_rxcost
;
38 static int hf_babel_message_routerid
;
39 static int hf_babel_message_flags
;
40 static int hf_babel_message_plen
;
41 static int hf_babel_message_omitted
;
42 static int hf_babel_message_metric
;
43 static int hf_babel_message_hopcount
;
44 static int hf_babel_message_index
;
45 static int hf_babel_subtlv
;
46 static int hf_babel_subtlv_type
;
47 static int hf_babel_subtlv_len
;
48 static int hf_babel_subtlv_diversity
;
50 static int ett_subtree
;
51 static int ett_packet_trailer
;
52 static int ett_unicast
;
53 static int ett_subtlv
;
54 static int ett_timestamp
;
55 static int ett_mandatory
;
57 #define UDP_PORT_RANGE_BABEL "6696"
59 #define MESSAGE_PAD1 0
60 #define MESSAGE_PADN 1
61 #define MESSAGE_ACK_REQ 2
63 #define MESSAGE_HELLO 4
65 #define MESSAGE_ROUTER_ID 6
67 #define MESSAGE_UPDATE 8
68 #define MESSAGE_REQUEST 9
69 #define MESSAGE_MH_REQUEST 10
70 #define MESSAGE_TS_PC 11
71 #define MESSAGE_HMAC_OLD 12
72 #define MESSAGE_SRC_UPDATE 13
73 #define MESSAGE_SRC_REQUEST 14
74 #define MESSAGE_SRC_SEQNO 15
75 #define MESSAGE_HMAC 16
77 #define MESSAGE_CHALLENGE_REQUEST 18
78 #define MESSAGE_CHALLENGE_REPLY 19
81 #define MESSAGE_SUB_PAD1 0
82 #define MESSAGE_SUB_PADN 1
83 #define MESSAGE_SUB_DIVERSITY 2
84 #define MESSAGE_SUB_TIMESTAMP 3
87 #define UNICAST_FLAG 0x80
88 #define MANDATORY_FLAG 128
90 /** message string values listed in rfc7557 */
91 static const value_string messages
[] = {
92 { MESSAGE_PAD1
, "pad1"},
93 { MESSAGE_PADN
, "padn"},
94 { MESSAGE_ACK_REQ
, "ack-req"},
95 { MESSAGE_ACK
, "ack"},
96 { MESSAGE_HELLO
, "hello"},
97 { MESSAGE_IHU
, "ihu"},
98 { MESSAGE_ROUTER_ID
, "router-id"},
100 { MESSAGE_UPDATE
, "update"},
101 { MESSAGE_REQUEST
, "request"},
102 { MESSAGE_MH_REQUEST
, "mh-request"},
103 { MESSAGE_TS_PC
, "ts/pc (obsolete)"},
104 { MESSAGE_HMAC_OLD
, "hmac" },
105 { MESSAGE_SRC_UPDATE
, "source-specific-update"},
106 { MESSAGE_SRC_REQUEST
, "source-specific-req"},
107 { MESSAGE_SRC_SEQNO
, "source-specific-seqno"},
108 { MESSAGE_HMAC
, "hmac"},
110 { MESSAGE_CHALLENGE_REQUEST
, "challenge-request"},
111 { MESSAGE_CHALLENGE_REPLY
, "challenge-reply"},
115 static const value_string subtlvs
[] = {
116 { MESSAGE_SUB_PAD1
, "sub-pad1"},
117 { MESSAGE_SUB_PADN
, "sub-padn"},
118 { MESSAGE_SUB_DIVERSITY
, "diversity"},
119 { MESSAGE_SUB_TIMESTAMP
, "timestamp"},
123 static const value_string aes
[] = {
127 { 3, "Link-Local IPv6"},
131 /* The prefix for v6-mapped IPv4 addresses. Format_address below
132 returns IPv4 addresses in that format. */
134 static const unsigned char v4prefix
[16] =
135 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
137 /* The following two functions return ephemeral or constant strings, no
138 need to call free. */
141 format_address(wmem_allocator_t
*scope
, const unsigned char *prefix
)
147 else if (memcmp(prefix
, v4prefix
, 12) == 0)
151 addr
.data
= prefix
+ 12;
153 return address_to_str(scope
, &addr
);
161 return address_to_str(scope
, &addr
);
166 format_prefix(wmem_allocator_t
*scope
, const unsigned char *prefix
, unsigned char plen
)
168 return wmem_strdup_printf(scope
, "%s/%u", format_address(scope
, prefix
), plen
);
172 network_prefix(int ae
, int plen
, unsigned int omitted
,
173 tvbuff_t
*tvb
, int offset
, const unsigned char *dp
,
174 unsigned int len
, unsigned char *p_r
)
177 unsigned char prefix
[16];
190 memset(prefix
, 0, 16);
195 if (omitted
> 4 || pb
> 4 || (pb
> omitted
&& len
< pb
- omitted
))
197 memcpy(prefix
, v4prefix
, 12);
199 if (dp
== NULL
) return -1;
200 memcpy(prefix
, dp
, 12 + omitted
);
203 tvb_memcpy(tvb
, prefix
+ 12 + omitted
, offset
, pb
- omitted
);
204 consumed
= pb
- omitted
;
208 if (omitted
> 16 || (pb
> omitted
&& len
< pb
- omitted
))
211 if (dp
== NULL
) return -1;
212 memcpy(prefix
, dp
, omitted
);
215 tvb_memcpy(tvb
, prefix
+ omitted
, offset
, pb
- omitted
);
216 consumed
= pb
- omitted
;
220 if (pb
> 8 && len
< pb
- 8) return -1;
224 tvb_memcpy(tvb
, prefix
+ 8, offset
, pb
- 8);
232 memcpy(p_r
, prefix
, 16);
237 network_address(int ae
, tvbuff_t
*tvb
, int offset
, unsigned int len
,
240 return network_prefix(ae
, -1, 0, tvb
, offset
, NULL
, len
, a_r
);
244 format_timestamp(const uint32_t i
)
246 static char buf
[sizeof("0000.000000s")];
247 snprintf(buf
, sizeof(buf
), "%u.%06us", i
/ 1000000, i
% 1000000);
252 dissect_babel_subtlvs(tvbuff_t
* tvb
, uint8_t type
, uint16_t beg
,
253 uint16_t end
, proto_tree
*message_tree
)
255 proto_tree
*channel_tree
= NULL
;
256 proto_item
*sub_item
;
257 uint8_t subtype
, sublen
;
261 proto_tree
*subtlv_tree
;
262 subtype
= tvb_get_uint8(tvb
, beg
);
263 if (subtype
!= MESSAGE_SUB_PAD1
) {
264 sublen
= tvb_get_uint8(tvb
, beg
+1);
270 proto_tree_add_uint_format(message_tree
, hf_babel_subtlv
,
271 tvb
, beg
, sublen
+ ((subtype
== MESSAGE_SUB_PAD1
) ? 1 : 2),
272 subtype
, "Sub TLV %s (%u)",
273 val_to_str_const(subtype
, subtlvs
, "unknown"),
275 subtlv_tree
= proto_item_add_subtree(sub_item
, ett_subtlv
);
277 proto_tree_add_item(subtlv_tree
, hf_babel_subtlv_type
,
278 tvb
, beg
, 1, ENC_BIG_ENDIAN
);
279 if(subtype
== MESSAGE_SUB_PAD1
){
283 proto_tree_add_item(subtlv_tree
, hf_babel_subtlv_len
,
284 tvb
, beg
+1, 1, ENC_BIG_ENDIAN
);
286 if ((MANDATORY_FLAG
& subtype
) != 0) {
287 proto_tree_add_subtree_format(subtlv_tree
, tvb
, beg
+2, sublen
,
288 ett_mandatory
, NULL
, "Mandatory");
292 case MESSAGE_SUB_PADN
:
294 case MESSAGE_SUB_DIVERSITY
: {
296 channel_tree
= proto_tree_add_subtree_format(subtlv_tree
, tvb
,
297 beg
+2, 0, ett_subtlv
,
300 proto_tree_add_item(channel_tree
, hf_babel_subtlv_diversity
,
301 tvb
, beg
+2+i
, 1, ENC_BIG_ENDIAN
);
306 case MESSAGE_SUB_TIMESTAMP
: {
307 if (type
== MESSAGE_HELLO
) {
308 uint32_t t1
= tvb_get_uint32(tvb
, beg
+2, ENC_BIG_ENDIAN
);
309 proto_tree_add_subtree_format(subtlv_tree
, tvb
, beg
+2,
310 sublen
, ett_timestamp
, NULL
,
312 format_timestamp(t1
));
313 } else if (type
== MESSAGE_IHU
) {
314 uint32_t t1
= tvb_get_uint32(tvb
, beg
+2, ENC_BIG_ENDIAN
);
315 uint32_t t2
= tvb_get_uint32(tvb
, beg
+6, ENC_BIG_ENDIAN
);
316 proto_tree_add_subtree_format(subtlv_tree
, tvb
, beg
+2,
317 sublen
, ett_timestamp
, NULL
,
318 "Timestamp origin : %s",
319 format_timestamp(t1
));
320 proto_tree_add_subtree_format(subtlv_tree
, tvb
, beg
+6,
321 sublen
, ett_timestamp
, NULL
,
322 "Timestamp receive: %s",
323 format_timestamp(t2
));
325 proto_tree_add_subtree_format(subtlv_tree
, tvb
, beg
+2, sublen
,
326 ett_timestamp
, NULL
, "Bogus");
337 /* The following function is used to read the packet body and
338 the packet trailer */
340 // NOLINTNEXTLINE(misc-no-recursion)
341 dissect_babel_body(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
342 int offset
, uint16_t bodylen
)
344 proto_item
*ti
= NULL
;
345 unsigned char v4_prefix
[16] = {0}, v6_prefix
[16] = {0};
350 while (i
-offset
< bodylen
) {
351 uint8_t type
, len
= 0;
352 uint16_t total_length
;
353 proto_tree
*message_tree
= NULL
;
356 type
= tvb_get_uint8(tvb
, message
);
357 if (type
== MESSAGE_PAD1
)
360 len
= tvb_get_uint8(tvb
, message
+ 1);
361 total_length
= len
+ 2;
364 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s",
365 val_to_str_const(type
, messages
, "unknown"));
367 ti
= proto_tree_add_uint_format(tree
, hf_babel_message
,
368 tvb
, message
, total_length
, type
,
370 val_to_str_const(type
, messages
, "unknown"),
374 message_tree
= proto_item_add_subtree(ti
, ett_message
);
375 proto_tree_add_item(message_tree
, hf_babel_message_type
,
376 tvb
, message
, 1, ENC_BIG_ENDIAN
);
379 if (type
== MESSAGE_PAD1
) {
385 proto_tree_add_item(message_tree
, hf_babel_message_length
,
386 tvb
, message
+ 1, 1, ENC_BIG_ENDIAN
);
387 if (type
== MESSAGE_PADN
) {
388 } else if (type
== MESSAGE_ACK_REQ
) {
389 proto_tree_add_item(message_tree
, hf_babel_message_nonce
,
390 tvb
, message
+ 4, 2, ENC_BIG_ENDIAN
);
391 proto_tree_add_item(message_tree
, hf_babel_message_interval
,
392 tvb
, message
+ 6, 2, ENC_BIG_ENDIAN
);
393 } else if (type
== MESSAGE_ACK
) {
394 proto_tree_add_item(message_tree
, hf_babel_message_nonce
,
395 tvb
, message
+ 2, 2, ENC_BIG_ENDIAN
);
396 } else if (type
== MESSAGE_HELLO
) {
397 uint8_t unicast
= tvb_get_uint8(tvb
, 2);
398 proto_tree_add_subtree_format(message_tree
,
403 proto_tree_add_item(message_tree
, hf_babel_message_seqno
,
404 tvb
, message
+ 4, 2, ENC_BIG_ENDIAN
);
405 proto_tree_add_item(message_tree
, hf_babel_message_interval
,
406 tvb
, message
+ 6, 2, ENC_BIG_ENDIAN
);
408 dissect_babel_subtlvs(tvb
, type
, message
+ 8,
409 message
+ 2 + len
, message_tree
);
410 } else if (type
== MESSAGE_IHU
) {
412 unsigned char addr_str
[16];
414 network_address(tvb_get_uint8(tvb
, message
+ 2),
415 tvb
, message
+ 8, len
- 6, addr_str
);
416 proto_tree_add_item(message_tree
, hf_babel_message_rxcost
,
417 tvb
, message
+ 4, 2, ENC_BIG_ENDIAN
);
418 proto_tree_add_item(message_tree
, hf_babel_message_interval
,
419 tvb
, message
+ 6, 2, ENC_BIG_ENDIAN
);
420 subtree
= proto_tree_add_subtree_format(message_tree
,
421 tvb
, message
+ 4, len
- 2,
422 ett_subtree
, NULL
, "Address: %s",
423 format_address(pinfo
->pool
,
424 rc
< 0 ? NULL
: addr_str
));
425 proto_tree_add_item(subtree
, hf_babel_message_ae
,
426 tvb
, message
+ 2, 1, ENC_BIG_ENDIAN
);
427 proto_tree_add_item(subtree
, hf_babel_message_prefix
,
428 tvb
, message
+ 4, len
- 2, ENC_NA
);
430 dissect_babel_subtlvs(tvb
, type
, message
+ 8 + rc
,
431 message
+ 2 + len
, message_tree
);
432 } else if (type
== MESSAGE_ROUTER_ID
) {
433 proto_tree_add_item(message_tree
, hf_babel_message_routerid
,
434 tvb
, message
+ 4, 8, ENC_NA
);
435 } else if (type
== MESSAGE_NH
) {
437 unsigned char nh
[16];
439 network_address(tvb_get_uint8(tvb
, message
+ 2),
440 tvb
, message
+ 4, len
- 2, nh
);
441 subtree
= proto_tree_add_subtree_format(message_tree
,
442 tvb
, message
+ 4, len
- 2,
445 format_address(pinfo
->pool
,
446 rc
< 0 ? NULL
: nh
));
447 proto_tree_add_item(subtree
, hf_babel_message_ae
,
448 tvb
, message
+ 2, 1, ENC_BIG_ENDIAN
);
449 proto_tree_add_item(subtree
, hf_babel_message_prefix
,
450 tvb
, message
+ 4, len
- 2, ENC_NA
);
451 } else if (type
== MESSAGE_UPDATE
) {
454 uint8_t ae
= tvb_get_uint8(tvb
, message
+ 2);
455 uint8_t flags
= tvb_get_uint8(tvb
, message
+ 3);
456 uint8_t plen
= tvb_get_uint8(tvb
, message
+ 4);
458 network_prefix(ae
, plen
,
459 tvb_get_uint8(tvb
, message
+ 5),
461 ae
== 1 ? v4_prefix
: v6_prefix
,
463 if (rc
>= 0 && (flags
& 0x80)) {
465 memcpy(v4_prefix
, p
, 16);
467 memcpy(v6_prefix
, p
, 16);
470 proto_tree_add_item(message_tree
, hf_babel_message_flags
,
471 tvb
, message
+ 3, 1, ENC_BIG_ENDIAN
);
472 proto_tree_add_item(message_tree
, hf_babel_message_interval
,
473 tvb
, message
+ 6, 2, ENC_BIG_ENDIAN
);
474 proto_tree_add_item(message_tree
, hf_babel_message_seqno
,
475 tvb
, message
+ 8, 2, ENC_BIG_ENDIAN
);
476 proto_tree_add_item(message_tree
, hf_babel_message_metric
,
477 tvb
, message
+ 10, 2, ENC_BIG_ENDIAN
);
478 subtree
= proto_tree_add_subtree_format(message_tree
,
479 tvb
, message
+ 12, len
- 10,
482 format_prefix(pinfo
->pool
,
485 proto_tree_add_item(subtree
, hf_babel_message_ae
,
486 tvb
, message
+ 2, 1, ENC_BIG_ENDIAN
);
487 proto_tree_add_item(subtree
, hf_babel_message_plen
,
488 tvb
, message
+ 4, 1, ENC_BIG_ENDIAN
);
489 proto_tree_add_item(subtree
, hf_babel_message_omitted
,
490 tvb
, message
+ 5, 1, ENC_BIG_ENDIAN
);
491 proto_tree_add_item(subtree
, hf_babel_message_prefix
,
492 tvb
, message
+ 12, len
- 10, ENC_NA
);
493 if (((uint8_t)rc
) < len
- 10)
494 dissect_babel_subtlvs(tvb
, type
, message
+ 12 + rc
,
495 message
+ 2 + len
, message_tree
);
496 } else if (type
== MESSAGE_REQUEST
) {
499 uint8_t plen
= tvb_get_uint8(tvb
, message
+ 3);
501 network_prefix(tvb_get_uint8(tvb
, message
+ 2), plen
,
502 0, tvb
, message
+ 4, NULL
,
504 subtree
= proto_tree_add_subtree_format(message_tree
,
505 tvb
, message
+ 4, len
- 2,
508 format_prefix(pinfo
->pool
,
511 proto_tree_add_item(subtree
, hf_babel_message_ae
,
512 tvb
, message
+ 2, 1, ENC_BIG_ENDIAN
);
513 proto_tree_add_item(subtree
, hf_babel_message_plen
,
514 tvb
, message
+ 3, 1, ENC_BIG_ENDIAN
);
515 proto_tree_add_item(subtree
, hf_babel_message_prefix
,
516 tvb
, message
+ 4, len
- 2, ENC_NA
);
517 } else if (type
== MESSAGE_MH_REQUEST
) {
520 uint8_t plen
= tvb_get_uint8(tvb
, message
+ 3);
522 network_prefix(tvb_get_uint8(tvb
, message
+ 2), plen
,
523 0, tvb
, message
+ 16, NULL
,
525 proto_tree_add_item(message_tree
, hf_babel_message_seqno
,
526 tvb
, message
+ 4, 2, ENC_BIG_ENDIAN
);
527 proto_tree_add_item(message_tree
, hf_babel_message_hopcount
,
528 tvb
, message
+ 6, 1, ENC_BIG_ENDIAN
);
529 proto_tree_add_item(message_tree
, hf_babel_message_routerid
,
530 tvb
, message
+ 8, 8, ENC_NA
);
531 subtree
= proto_tree_add_subtree_format(message_tree
,
532 tvb
, message
+ 16, len
- 14,
535 format_prefix(pinfo
->pool
,
538 proto_tree_add_item(subtree
, hf_babel_message_ae
,
539 tvb
, message
+ 2, 1, ENC_BIG_ENDIAN
);
540 proto_tree_add_item(subtree
, hf_babel_message_plen
,
541 tvb
, message
+ 3, 1, ENC_BIG_ENDIAN
);
542 proto_tree_add_item(subtree
, hf_babel_message_prefix
,
543 tvb
, message
+ 16, len
- 14, ENC_NA
);
544 } else if (type
== MESSAGE_PC
){
545 proto_tree_add_item(message_tree
, hf_babel_message_index
,
546 tvb
, message
+ 2, 4, ENC_NA
);
551 uint8_t packet_len
= tvb_reported_length(tvb
) - bodylen
- 4;
552 if ((offset
== 0) && (packet_len
!= 0)) {
553 proto_tree
* subtree
;
554 subtree
= proto_tree_add_subtree_format(tree
, tvb
, 4+bodylen
, packet_len
,
555 ett_packet_trailer
, NULL
,
556 "Packet Trailer (%u)", packet_len
);
557 increment_dissection_depth(pinfo
);
558 dissect_babel_body(tvb
, pinfo
, subtree
, bodylen
, packet_len
);
559 decrement_dissection_depth(pinfo
);
565 dissect_babel(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
568 proto_tree
*babel_tree
= NULL
;
572 if (tvb_captured_length(tvb
) < 4)
575 if (tvb_get_uint8(tvb
, 0) != 42)
577 version
= tvb_get_uint8(tvb
, 1);
579 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Babel");
580 col_set_str(pinfo
->cinfo
, COL_INFO
, "Babel");
583 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Version %u", version
);
588 ti
= proto_tree_add_item(tree
, proto_babel
, tvb
, 0, -1, ENC_NA
);
589 babel_tree
= proto_item_add_subtree(ti
, ett_babel
);
591 proto_tree_add_item(babel_tree
, hf_babel_magic
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
592 proto_tree_add_item(babel_tree
, hf_babel_version
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
593 proto_tree_add_item(babel_tree
, hf_babel_bodylen
,
594 tvb
, 2, 2, ENC_BIG_ENDIAN
);
596 bodylen
= tvb_get_ntohs(tvb
, 2);
597 return dissect_babel_body(tvb
, pinfo
, babel_tree
, 0, bodylen
);
602 proto_register_babel(void)
604 static hf_register_info hf
[] = {
606 { "Magic", "babel.magic", FT_UINT8
, BASE_DEC
,
607 NULL
, 0, "Magic value 42", HFILL
}
610 { "Version", "babel.version", FT_UINT8
, BASE_DEC
,
611 NULL
, 0, "Version of the Babel protocol", HFILL
}
614 { "Body Length", "babel.bodylen", FT_UINT16
, BASE_DEC
,
615 NULL
, 0, NULL
, HFILL
}
618 { "Message", "babel.message", FT_UINT8
, BASE_DEC
,
619 NULL
, 0, "Babel Message", HFILL
}
621 { &hf_babel_message_type
,
622 { "Message Type", "babel.message.type", FT_UINT8
, BASE_DEC
,
623 VALS(messages
), 0, NULL
, HFILL
}
625 { &hf_babel_message_length
,
626 { "Message Length", "babel.message.length", FT_UINT8
, BASE_DEC
,
627 NULL
, 0, NULL
, HFILL
}
629 { &hf_babel_message_nonce
,
630 { "Nonce", "babel.message.nonce", FT_UINT16
, BASE_HEX
,
631 NULL
, 0, NULL
, HFILL
}
633 { &hf_babel_message_interval
,
634 { "Interval", "babel.message.interval", FT_UINT16
, BASE_DEC
,
635 NULL
, 0, "Interval (in centiseconds)", HFILL
}
637 { &hf_babel_message_seqno
,
638 { "Seqno", "babel.message.seqno", FT_UINT16
, BASE_HEX
,
639 NULL
, 0, NULL
, HFILL
}
641 { &hf_babel_message_ae
,
642 { "Address Encoding", "babel.message.ae", FT_UINT8
, BASE_DEC
,
643 VALS(aes
), 0, NULL
, HFILL
}
645 { &hf_babel_message_prefix
,
646 { "Raw Prefix", "babel.message.prefix", FT_BYTES
, BASE_NONE
,
647 NULL
, 0, NULL
, HFILL
}
649 { &hf_babel_message_rxcost
,
650 { "Rxcost", "babel.message.rxcost", FT_UINT16
, BASE_HEX
,
651 NULL
, 0, "Rxcost (from the point of vue of the sender)", HFILL
}
653 { &hf_babel_message_routerid
,
654 { "Router ID", "babel.message.routerid", FT_BYTES
, BASE_NONE
,
655 NULL
, 0, NULL
, HFILL
}
657 { &hf_babel_message_flags
,
658 { "Flags", "babel.message.flags", FT_UINT8
, BASE_HEX
,
659 NULL
, 0, NULL
, HFILL
}
661 { &hf_babel_message_plen
,
662 { "Prefix Length", "babel.message.plen", FT_UINT8
, BASE_DEC
,
663 NULL
, 0, NULL
, HFILL
}
665 { &hf_babel_message_omitted
,
666 { "Omitted Bytes", "babel.message.omitted", FT_UINT8
, BASE_DEC
,
667 NULL
, 0, "Number of bytes omitted from the prefix", HFILL
}
669 { &hf_babel_message_metric
,
670 { "Metric", "babel.message.metric", FT_UINT16
, BASE_DEC
,
671 NULL
, 0, NULL
, HFILL
}
673 { &hf_babel_message_hopcount
,
674 { "Hop Count", "babel.message.hopcount", FT_UINT8
, BASE_DEC
,
675 NULL
, 0, NULL
, HFILL
}
677 { &hf_babel_message_index
,
678 { "Index", "babel.message.index", FT_UINT32
, BASE_DEC
,
679 NULL
, 0, NULL
, HFILL
}
682 { "Sub-TLV", "babel.subtlv", FT_UINT8
, BASE_DEC
,
683 NULL
, 0, "Babel Sub-TLV", HFILL
}
685 { &hf_babel_subtlv_type
,
686 { "Sub-TLV Type", "babel.subtlv.type", FT_UINT8
, BASE_DEC
,
687 VALS(subtlvs
), 0, NULL
, HFILL
}
689 { &hf_babel_subtlv_len
,
690 { "Sub-TLV Length", "babel.subtlv.length", FT_UINT8
, BASE_DEC
,
691 VALS(subtlvs
), 0, NULL
, HFILL
}
693 { &hf_babel_subtlv_diversity
,
694 { "Channel", "babel.subtlv.diversity.channel", FT_UINT8
, BASE_DEC
,
695 NULL
, 0, NULL
, HFILL
}
699 static int *ett
[] = {
711 proto_register_protocol("Babel Routing Protocol", "Babel", "babel");
713 proto_register_field_array(proto_babel
, hf
, array_length(hf
));
714 proto_register_subtree_array(ett
, array_length(ett
));
716 babel_handle
= register_dissector("babel", dissect_babel
, proto_babel
);
720 proto_reg_handoff_babel(void)
722 dissector_add_uint_range_with_preference("udp.port", UDP_PORT_RANGE_BABEL
, babel_handle
);
726 * Editor modelines - https://www.wireshark.org/tools/modelines.html
731 * indent-tabs-mode: nil
734 * vi: set shiftwidth=4 tabstop=8 expandtab:
735 * :indentSize=4:tabSize=8:noTabs=true: