Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-babel.c
blob84b9b0a9f8c204b0c377421bb9c9c6e47b891b12
1 /* packet-babel.c
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
12 #include "config.h"
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;
23 static int ett_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
62 #define MESSAGE_ACK 3
63 #define MESSAGE_HELLO 4
64 #define MESSAGE_IHU 5
65 #define MESSAGE_ROUTER_ID 6
66 #define MESSAGE_NH 7
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
76 #define MESSAGE_PC 17
77 #define MESSAGE_CHALLENGE_REQUEST 18
78 #define MESSAGE_CHALLENGE_REPLY 19
80 /** sub-TLVs */
81 #define MESSAGE_SUB_PAD1 0
82 #define MESSAGE_SUB_PADN 1
83 #define MESSAGE_SUB_DIVERSITY 2
84 #define MESSAGE_SUB_TIMESTAMP 3
86 /** mask for bits */
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"},
99 { MESSAGE_NH, "nh"},
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"},
109 { MESSAGE_PC, "pc"},
110 { MESSAGE_CHALLENGE_REQUEST, "challenge-request"},
111 { MESSAGE_CHALLENGE_REPLY, "challenge-reply"},
112 { 0, NULL}
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"},
120 { 0, NULL}
123 static const value_string aes[] = {
124 { 0, "Wildcard" },
125 { 1, "IPv4" },
126 { 2, "IPv6" },
127 { 3, "Link-Local IPv6"},
128 { 0, NULL }
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. */
140 static const char *
141 format_address(wmem_allocator_t *scope, const unsigned char *prefix)
143 address addr;
145 if (prefix == NULL)
146 return "corrupt";
147 else if (memcmp(prefix, v4prefix, 12) == 0)
149 addr.type = AT_IPv4;
150 addr.len = 4;
151 addr.data = prefix + 12;
153 return address_to_str(scope, &addr);
155 else
157 addr.type = AT_IPv6;
158 addr.len = 16;
159 addr.data = prefix;
161 return address_to_str(scope, &addr);
165 static const char *
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);
171 static int
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)
176 unsigned pb;
177 unsigned char prefix[16];
178 int consumed = 0;
180 if (plen >= 0)
181 pb = (plen + 7) / 8;
182 else if (ae == 1)
183 pb = 4;
184 else
185 pb = 16;
187 if (pb > 16)
188 return -1;
190 memset(prefix, 0, 16);
192 switch(ae) {
193 case 0: break;
194 case 1:
195 if (omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
196 return -1;
197 memcpy(prefix, v4prefix, 12);
198 if (omitted) {
199 if (dp == NULL) return -1;
200 memcpy(prefix, dp, 12 + omitted);
202 if (pb > omitted) {
203 tvb_memcpy(tvb, prefix + 12 + omitted, offset, pb - omitted);
204 consumed = pb - omitted;
206 break;
207 case 2:
208 if (omitted > 16 || (pb > omitted && len < pb - omitted))
209 return -1;
210 if (omitted) {
211 if (dp == NULL) return -1;
212 memcpy(prefix, dp, omitted);
214 if (pb > omitted) {
215 tvb_memcpy(tvb, prefix + omitted, offset, pb - omitted);
216 consumed = pb - omitted;
218 break;
219 case 3:
220 if (pb > 8 && len < pb - 8) return -1;
221 prefix[0] = 0xfe;
222 prefix[1] = 0x80;
223 if (pb > 8) {
224 tvb_memcpy(tvb, prefix + 8, offset, pb - 8);
225 consumed = pb - 8;
227 break;
228 default:
229 return -1;
232 memcpy(p_r, prefix, 16);
233 return consumed;
236 static int
237 network_address(int ae, tvbuff_t *tvb, int offset, unsigned int len,
238 unsigned char *a_r)
240 return network_prefix(ae, -1, 0, tvb, offset, NULL, len, a_r);
243 static const char *
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);
248 return buf;
251 static int
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;
258 int i = 0;
260 while(beg < end) {
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);
265 } else {
266 sublen = 0;
269 sub_item =
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"),
274 subtype);
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){
280 beg += 1;
281 continue;
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");
291 switch(subtype) {
292 case MESSAGE_SUB_PADN:
293 break;
294 case MESSAGE_SUB_DIVERSITY: {
295 i = 0;
296 channel_tree = proto_tree_add_subtree_format(subtlv_tree, tvb,
297 beg+2, 0, ett_subtlv,
298 NULL, "Channel");
299 while(i < sublen) {
300 proto_tree_add_item(channel_tree, hf_babel_subtlv_diversity,
301 tvb, beg+2+i, 1, ENC_BIG_ENDIAN);
302 i++;
305 break;
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,
311 "Timestamp : %s",
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));
324 } else {
325 proto_tree_add_subtree_format(subtlv_tree, tvb, beg+2, sublen,
326 ett_timestamp, NULL, "Bogus");
329 break;
331 beg += (sublen+2);
333 return end-beg;
337 /* The following function is used to read the packet body and
338 the packet trailer */
339 static int
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};
346 int i;
349 i = offset;
350 while (i-offset < bodylen) {
351 uint8_t type, len = 0;
352 uint16_t total_length;
353 proto_tree *message_tree = NULL;
354 int message = 4 + i;
356 type = tvb_get_uint8(tvb, message);
357 if (type == MESSAGE_PAD1)
358 total_length = 1;
359 else {
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,
369 "Message %s (%u)",
370 val_to_str_const(type, messages, "unknown"),
371 type);
373 if (tree) {
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) {
380 i++;
381 continue;
384 if (tree) {
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,
399 tvb, message + 2, 2,
400 ett_unicast, NULL,
401 "Unicast : %u",
402 unicast);
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);
407 if(len > 6)
408 dissect_babel_subtlvs(tvb, type, message + 8,
409 message + 2 + len, message_tree);
410 } else if (type == MESSAGE_IHU) {
411 proto_tree *subtree;
412 unsigned char addr_str[16];
413 int rc =
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);
429 if (rc < len - 6)
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) {
436 proto_tree *subtree;
437 unsigned char nh[16];
438 int rc =
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,
443 ett_subtree, NULL,
444 "NH: %s",
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) {
452 proto_tree *subtree;
453 unsigned char p[16];
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);
457 int rc =
458 network_prefix(ae, plen,
459 tvb_get_uint8(tvb, message + 5),
460 tvb, message + 12,
461 ae == 1 ? v4_prefix : v6_prefix,
462 len - 10, p);
463 if (rc >= 0 && (flags & 0x80)) {
464 if (ae == 1)
465 memcpy(v4_prefix, p, 16);
466 else
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,
480 ett_subtree, NULL,
481 "Prefix: %s",
482 format_prefix(pinfo->pool,
483 rc < 0 ? NULL : p,
484 plen));
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) {
497 proto_tree *subtree;
498 unsigned char p[16];
499 uint8_t plen = tvb_get_uint8(tvb, message + 3);
500 int rc =
501 network_prefix(tvb_get_uint8(tvb, message + 2), plen,
502 0, tvb, message + 4, NULL,
503 len - 2, p);
504 subtree = proto_tree_add_subtree_format(message_tree,
505 tvb, message + 4, len - 2,
506 ett_subtree, NULL,
507 "Prefix: %s",
508 format_prefix(pinfo->pool,
509 rc < 0 ? NULL : p,
510 plen));
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) {
518 proto_tree *subtree;
519 unsigned char p[16];
520 uint8_t plen = tvb_get_uint8(tvb, message + 3);
521 int rc =
522 network_prefix(tvb_get_uint8(tvb, message + 2), plen,
523 0, tvb, message + 16, NULL,
524 len - 14, p);
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,
533 ett_subtree, NULL,
534 "Prefix: %s",
535 format_prefix(pinfo->pool,
536 rc < 0 ? NULL : p,
537 plen));
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);
549 i += len + 2;
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);
561 return i;
564 static int
565 dissect_babel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
567 proto_item *ti;
568 proto_tree *babel_tree = NULL;
569 uint8_t version;
570 uint16_t bodylen;
572 if (tvb_captured_length(tvb) < 4)
573 return 0;
575 if (tvb_get_uint8(tvb, 0) != 42)
576 return 0;
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");
582 if (version != 2) {
583 col_add_fstr(pinfo->cinfo, COL_INFO, "Version %u", version);
584 return 2;
587 if (tree) {
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);
601 void
602 proto_register_babel(void)
604 static hf_register_info hf[] = {
605 { &hf_babel_magic,
606 { "Magic", "babel.magic", FT_UINT8, BASE_DEC,
607 NULL, 0, "Magic value 42", HFILL }
609 { &hf_babel_version,
610 { "Version", "babel.version", FT_UINT8, BASE_DEC,
611 NULL, 0, "Version of the Babel protocol", HFILL }
613 { &hf_babel_bodylen,
614 { "Body Length", "babel.bodylen", FT_UINT16, BASE_DEC,
615 NULL, 0, NULL, HFILL }
617 { &hf_babel_message,
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 }
681 { &hf_babel_subtlv,
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[] = {
700 &ett_babel,
701 &ett_message,
702 &ett_subtree,
703 &ett_packet_trailer,
704 &ett_unicast,
705 &ett_subtlv,
706 &ett_timestamp,
707 &ett_mandatory
710 proto_babel =
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);
719 void
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
728 * Local variables:
729 * c-basic-offset: 4
730 * tab-width: 8
731 * indent-tabs-mode: nil
732 * End:
734 * vi: set shiftwidth=4 tabstop=8 expandtab:
735 * :indentSize=4:tabSize=8:noTabs=true: