aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-bfd.c
diff options
context:
space:
mode:
authorstig <stig@f5534014-38df-0310-8fa8-9805f1628bb7>2007-09-07 19:05:55 +0000
committerstig <stig@f5534014-38df-0310-8fa8-9805f1628bb7>2007-09-07 19:05:55 +0000
commitdd034ae94ae0c7a1f2cd91a613fbcfcdb65599c7 (patch)
tree13e9db75f36ce4cc3d33e47e8aac28c9f5feb6c6 /epan/dissectors/packet-bfd.c
parent80bf7c5fb2fdb30d987f51dc17bda10759345c5c (diff)
From Todd J Martin:
The attached patch to packet-bfd.c adds the following enhancements to BFD decoding: - The Authentication Section is now decoded. All of the authentication methods are supported. Verification of checksums is not implemented. - BFD flags are now shown in a tree - Added support for the M flag - Added a display filter for the message length - For the Desired Min TX Interval, Required Min RX Interval, and Required Min Echo RX Interval fields, the time value is now printed in both milliseconds and microseconds. (Previously, only milliseconds was being shown.) The PDU represents the time in microseconds, but most implementations deal in milliseconds. - Added a warning to flag the packet if the Authentication bit is set, but the full Authentication Section is not present. - Added descriptions for most of the fields - Fix the name of the protocol. BFD stands for Bidirectional Forwarding Detection and not Bi-directional Fault Detection. - Register the protocol on the UDP multihop port (4784). - Change the filter name for the protocol from bfdcontrol to bfd since all of the other display filters started with bfd. Removed unused hf_bfd_auth_checksum. Modified printing of the ':' at the end of the Authentication tree. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@22825 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-bfd.c')
-rw-r--r--epan/dissectors/packet-bfd.c362
1 files changed, 315 insertions, 47 deletions
diff --git a/epan/dissectors/packet-bfd.c b/epan/dissectors/packet-bfd.c
index 7484b16e4e..530e92ea6c 100644
--- a/epan/dissectors/packet-bfd.c
+++ b/epan/dissectors/packet-bfd.c
@@ -1,8 +1,9 @@
/* packet-bfd.c
- * Routines for Bi-directional Fault Detection (BFD) message dissection
+ * Routines for Bidirectional Forwarding Detection (BFD) message dissection
*
* Copyright 2003, Hannes Gredler <hannes@juniper.net>
* Copyright 2006, Balint Reczey <Balint.Reczey@ericsson.com>
+ * Copyright 2007, Todd J Martin <todd.martin@acm.org>
*
* $Id$
*
@@ -36,8 +37,10 @@
#include <string.h>
#include <glib.h>
#include <epan/packet.h>
+#include <epan/expert.h>
-#define UDP_PORT_BFD_CONTROL 3784 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */
+#define UDP_PORT_BFD_1HOP_CONTROL 3784 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */
+#define UDP_PORT_BFD_MULTIHOP_CONTROL 4784 /* draft-ietf-bfd-multihop-05.txt */
static const value_string bfd_control_v0_diag_values[] = {
{ 0, "No Diagnostic" },
@@ -72,6 +75,41 @@ static const value_string bfd_control_sta_values[] = {
{ 0, NULL }
};
+#define BFD_AUTH_SIMPLE 1
+#define BFD_AUTH_MD5 2
+#define BFD_AUTH_MET_MD5 3
+#define BFD_AUTH_SHA1 4
+#define BFD_AUTH_MET_SHA1 5
+static const value_string bfd_control_auth_type_values[] = {
+ { BFD_AUTH_SIMPLE , "Simple Password" },
+ { BFD_AUTH_MD5 , "Keyed MD5" },
+ { BFD_AUTH_MET_MD5 , "Meticulous Keyed MD5" },
+ { BFD_AUTH_SHA1 , "Keyed SHA1" },
+ { BFD_AUTH_MET_SHA1 , "Meticulous Keyed SHA1" },
+ { 0, NULL }
+};
+/* Per the standard, the simple password must by 1-16 bytes in length */
+#define MAX_PASSWORD_LEN 16
+/* Per the standard, the length of the MD5 authentication packets must be 24
+ * bytes and the checksum is 16 bytes */
+#define MD5_AUTH_LEN 24
+#define MD5_CHECKSUM_LEN 16
+/* Per the standard, the length of the SHA1 authentication packets must be 28
+ * bytes and the checksum is 20 bytes */
+#define SHA1_AUTH_LEN 28
+#define SHA1_CHECKSUM_LEN 20
+
+#define APPEND_BOOLEAN_FLAG(flag, item, string) \
+ if(flag){ \
+ if(item) \
+ proto_item_append_text(item, string, sep); \
+ sep = cont_sep; \
+ }
+static const char initial_sep[] = " (";
+static const char cont_sep[] = ", ";
+
+
+
static gint proto_bfd = -1;
static gint hf_bfd_version = -1;
@@ -84,18 +122,27 @@ static gint hf_bfd_flags_f = -1;
static gint hf_bfd_flags_c = -1;
static gint hf_bfd_flags_a = -1;
static gint hf_bfd_flags_d = -1;
+static gint hf_bfd_flags_m = -1;
static gint hf_bfd_flags_d_v0 = -1;
static gint hf_bfd_flags_p_v0 = -1;
static gint hf_bfd_flags_f_v0 = -1;
static gint hf_bfd_detect_time_multiplier = -1;
+static gint hf_bfd_message_length = -1;
static gint hf_bfd_my_discriminator = -1;
static gint hf_bfd_your_discriminator = -1;
static gint hf_bfd_desired_min_tx_interval = -1;
static gint hf_bfd_required_min_rx_interval = -1;
static gint hf_bfd_required_min_echo_interval = -1;
+static gint hf_bfd_auth_type = -1;
+static gint hf_bfd_auth_len = -1;
+static gint hf_bfd_auth_key = -1;
+static gint hf_bfd_auth_password = -1;
+static gint hf_bfd_auth_seq_num = -1;
+
static gint ett_bfd = -1;
static gint ett_bfd_flags = -1;
+static gint ett_bfd_auth = -1;
/*
* Control packet version 0, draft-katz-ward-bfd-01.txt
@@ -137,17 +184,157 @@ static gint ett_bfd_flags = -1;
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* An optional Authentication Section may be present:
- * Dissection is not implemented yet.
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Auth Type | Auth Len | Authentication Data... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
+ * There are 5 types of authentication defined:
+ * 1 - Simple Password
+ * 2 - Keyed MD5
+ * 3 - Meticulous Keyed MD5
+ * 4 - Keyed SHA1
+ * 5 - Meticulous Keyed SHA1
+ *
+ * The format for Simple Password authentication is:
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Auth Type | Auth Len | Auth Key ID | Password... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * The format for Keyed MD5 and Meticulous Keyed MD5 authentication is:
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Auth Type | Auth Len | Auth Key ID | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Auth Key/Checksum... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * The format for Keyed SHA1 and Meticulous Keyed SHA1 authentication is:
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Auth Type | Auth Len | Auth Key ID | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Auth Key/Checksum... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*
*/
+
+/* Given the type of authentication being used, return the required length of
+ * the authentication header
+ */
+guint8 get_bfd_required_auth_len(guint8 auth_type)
+{
+ guint8 auth_len = 0;
+ switch (auth_type) {
+ case BFD_AUTH_MD5:
+ case BFD_AUTH_MET_MD5:
+ auth_len = MD5_AUTH_LEN;
+ break;
+ case BFD_AUTH_SHA1:
+ case BFD_AUTH_MET_SHA1:
+ auth_len = SHA1_AUTH_LEN;
+ break;
+ default:
+ break;
+ }
+ return auth_len;
+}
+
+/* Given the type of authentication being used, return the length of
+ * checksum field
+ */
+guint8 get_bfd_checksum_len(guint8 auth_type)
+{
+ guint8 checksum_len = 0;
+ switch (auth_type) {
+ case BFD_AUTH_MD5:
+ case BFD_AUTH_MET_MD5:
+ checksum_len = MD5_CHECKSUM_LEN;
+ break;
+ case BFD_AUTH_SHA1:
+ case BFD_AUTH_MET_SHA1:
+ checksum_len = SHA1_CHECKSUM_LEN;
+ break;
+ default:
+ break;
+ }
+ return checksum_len;
+}
+
+static void dissect_bfd_authentication(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ int offset = 24;
+ guint8 auth_type;
+ guint8 auth_len;
+ guint32 seq_num;
+ proto_item *ti;
+ proto_item *auth_item;
+ proto_tree *auth_tree;
+ char *password;
+
+ auth_type = tvb_get_guint8(tvb, offset);
+ auth_len = tvb_get_guint8(tvb, offset + 1);
+
+ auth_item = proto_tree_add_text(tree, tvb, offset, auth_len, "Authentication: %s",
+ val_to_str(auth_type, bfd_control_auth_type_values, "Unknown Authentication Type (%d)") );
+ auth_tree = proto_item_add_subtree(auth_item, ett_bfd_auth);
+
+ proto_tree_add_item(auth_tree, hf_bfd_auth_type, tvb, offset, 1, FALSE);
+
+ ti = proto_tree_add_item(auth_tree, hf_bfd_auth_len, tvb, offset + 1, 1, FALSE);
+ proto_item_append_text(ti, " bytes");
+
+ proto_tree_add_item(auth_tree, hf_bfd_auth_key, tvb, offset + 2, 1, FALSE);
+
+ switch (auth_type) {
+ case BFD_AUTH_SIMPLE:
+ password = tvb_get_ephemeral_string(tvb, offset+3, auth_len-3);
+ proto_tree_add_string(auth_tree, hf_bfd_auth_password, tvb, offset+3,
+ auth_len-3, password);
+ proto_item_append_text(auth_item, ": %s", password);
+ break;
+ case BFD_AUTH_MD5:
+ case BFD_AUTH_MET_MD5:
+ case BFD_AUTH_SHA1:
+ case BFD_AUTH_MET_SHA1:
+ if (auth_len != get_bfd_required_auth_len(auth_type)) {
+ ti = proto_tree_add_text(auth_tree, tvb, offset, auth_len,
+ "Length of authentication is invalid (%d)", auth_len);
+ proto_item_append_text(auth_item, ": Invalid Authentication Section");
+ expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_WARN,
+ "Length of authentication section is invalid for Authentication Type: %s",
+ val_to_str(auth_type, bfd_control_auth_type_values, "Unknown Authentication Type (%d)") );
+ }
+
+ seq_num = tvb_get_ntohl(tvb, offset+4);
+ proto_tree_add_item(auth_tree, hf_bfd_auth_seq_num, tvb, offset+4, 4, FALSE);
+
+ proto_tree_add_text(auth_tree, tvb, offset+8, get_bfd_checksum_len(auth_type), "Checksum: 0x%s",
+ tvb_bytes_to_str(tvb, offset+8, get_bfd_checksum_len(auth_type)) );
+ break;
+ default:
+ break;
+ }
+}
+
+
static void dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
gint bfd_version = -1;
@@ -160,6 +347,7 @@ static void dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
gint bfd_flags_c = -1;
gint bfd_flags_a = -1;
gint bfd_flags_d = -1;
+ gint bfd_flags_m = -1;
gint bfd_flags_d_v0 = -1;
gint bfd_flags_p_v0 = -1;
gint bfd_flags_f_v0 = -1;
@@ -174,6 +362,8 @@ static void dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
proto_item *ti;
proto_tree *bfd_tree;
proto_tree *bfd_flags_tree;
+
+ const char *sep;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "BFD Control");
@@ -199,6 +389,7 @@ static void dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
bfd_flags_c = (tvb_get_guint8(tvb, 1) & 0x08);
bfd_flags_a = (tvb_get_guint8(tvb, 1) & 0x04);
bfd_flags_d = (tvb_get_guint8(tvb, 1) & 0x02);
+ bfd_flags_m = (tvb_get_guint8(tvb, 1) & 0x01);
break;
}
bfd_detect_time_multiplier = tvb_get_guint8(tvb, 2);
@@ -233,10 +424,10 @@ static void dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
bfd_tree = proto_item_add_subtree(ti, ett_bfd);
- ti = proto_tree_add_uint(bfd_tree, hf_bfd_version, tvb, 0,
+ proto_tree_add_uint(bfd_tree, hf_bfd_version, tvb, 0,
1, bfd_version << 5);
- ti = proto_tree_add_uint(bfd_tree, hf_bfd_diag, tvb, 0,
+ proto_tree_add_uint(bfd_tree, hf_bfd_diag, tvb, 0,
1, bfd_diag);
switch (bfd_version) {
@@ -244,7 +435,7 @@ static void dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
break;
case 1:
default:
- ti = proto_tree_add_uint(bfd_tree, hf_bfd_sta, tvb, 1,
+ proto_tree_add_uint(bfd_tree, hf_bfd_sta, tvb, 1,
1, bfd_sta);
break;
@@ -253,54 +444,92 @@ static void dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
case 0:
ti = proto_tree_add_text ( bfd_tree, tvb, 1, 1, "Message Flags: 0x%02x",
bfd_flags);
- bfd_flags_tree = proto_item_add_subtree(bfd_tree, ett_bfd_flags);
- ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_h, tvb, 1, 1, bfd_flags_h);
- ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_d_v0, tvb, 1, 1, bfd_flags_d_v0);
- ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_p_v0, tvb, 1, 1, bfd_flags_p_v0);
- ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_f_v0, tvb, 1, 1, bfd_flags_f_v0);
+ bfd_flags_tree = proto_item_add_subtree(ti, ett_bfd_flags);
+ proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_h, tvb, 1, 1, bfd_flags_h);
+ proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_d_v0, tvb, 1, 1, bfd_flags_d_v0);
+ proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_p_v0, tvb, 1, 1, bfd_flags_p_v0);
+ proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_f_v0, tvb, 1, 1, bfd_flags_f_v0);
+
+ sep = initial_sep;
+ APPEND_BOOLEAN_FLAG(bfd_flags_h, ti, "%sH");
+ APPEND_BOOLEAN_FLAG(bfd_flags_d_v0, ti, "%sD");
+ APPEND_BOOLEAN_FLAG(bfd_flags_p_v0, ti, "%sP");
+ APPEND_BOOLEAN_FLAG(bfd_flags_f_v0, ti, "%sF");
+ if (sep != initial_sep) {
+ proto_item_append_text (ti, ")");
+ }
break;
case 1:
default:
ti = proto_tree_add_text ( bfd_tree, tvb, 1, 1, "Message Flags: 0x%02x",
bfd_flags);
- bfd_flags_tree = proto_item_add_subtree(bfd_tree, ett_bfd_flags);
- ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_p, tvb, 1, 1, bfd_flags_p);
- ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_f, tvb, 1, 1, bfd_flags_f);
- ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_c, tvb, 1, 1, bfd_flags_c);
- ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_a, tvb, 1, 1, bfd_flags_a);
- ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_d, tvb, 1, 1, bfd_flags_d);
+ bfd_flags_tree = proto_item_add_subtree(ti, ett_bfd_flags);
+ proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_p, tvb, 1, 1, bfd_flags_p);
+ proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_f, tvb, 1, 1, bfd_flags_f);
+ proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_c, tvb, 1, 1, bfd_flags_c);
+ proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_a, tvb, 1, 1, bfd_flags_a);
+ proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_d, tvb, 1, 1, bfd_flags_d);
+ proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_m, tvb, 1, 1, bfd_flags_m);
+
+ sep = initial_sep;
+ APPEND_BOOLEAN_FLAG(bfd_flags_p, ti, "%sP");
+ APPEND_BOOLEAN_FLAG(bfd_flags_f, ti, "%sF");
+ APPEND_BOOLEAN_FLAG(bfd_flags_c, ti, "%sC");
+ APPEND_BOOLEAN_FLAG(bfd_flags_a, ti, "%sA");
+ APPEND_BOOLEAN_FLAG(bfd_flags_d, ti, "%sD");
+ APPEND_BOOLEAN_FLAG(bfd_flags_m, ti, "%sM");
+ if (sep != initial_sep) {
+ proto_item_append_text (ti, ")");
+ }
break;
}
- ti = proto_tree_add_uint_format_value(bfd_tree, hf_bfd_detect_time_multiplier, tvb, 2,
+ proto_tree_add_uint_format_value(bfd_tree, hf_bfd_detect_time_multiplier, tvb, 2,
1, bfd_detect_time_multiplier,
"%u (= %u ms Detection time)",
bfd_detect_time_multiplier,
bfd_detect_time_multiplier * bfd_desired_min_tx_interval/1000);
- ti = proto_tree_add_text ( bfd_tree, tvb, 3, 1, "Message Length: %u Bytes", bfd_length );
+ proto_tree_add_uint_format_value(bfd_tree, hf_bfd_message_length, tvb, 3, 1, bfd_length,
+ "%u bytes", bfd_length);
- ti = proto_tree_add_uint(bfd_tree, hf_bfd_my_discriminator, tvb, 4,
+ proto_tree_add_uint(bfd_tree, hf_bfd_my_discriminator, tvb, 4,
4, bfd_my_discriminator);
- ti = proto_tree_add_uint(bfd_tree, hf_bfd_your_discriminator, tvb, 8,
+ proto_tree_add_uint(bfd_tree, hf_bfd_your_discriminator, tvb, 8,
4, bfd_your_discriminator);
- ti = proto_tree_add_uint_format_value(bfd_tree, hf_bfd_desired_min_tx_interval, tvb, 12,
+ proto_tree_add_uint_format_value(bfd_tree, hf_bfd_desired_min_tx_interval, tvb, 12,
4, bfd_desired_min_tx_interval,
- "%4u ms",
- bfd_desired_min_tx_interval/1000);
+ "%4u ms (%u us)",
+ bfd_desired_min_tx_interval/1000,
+ bfd_desired_min_tx_interval);
- ti = proto_tree_add_uint_format_value(bfd_tree, hf_bfd_required_min_rx_interval, tvb, 16,
+ proto_tree_add_uint_format_value(bfd_tree, hf_bfd_required_min_rx_interval, tvb, 16,
4, bfd_required_min_rx_interval,
- "%4u ms",
- bfd_required_min_rx_interval/1000);
+ "%4u ms (%u us)",
+ bfd_required_min_rx_interval/1000,
+ bfd_required_min_rx_interval);
- ti = proto_tree_add_uint_format_value(bfd_tree, hf_bfd_required_min_echo_interval, tvb, 20,
+ proto_tree_add_uint_format_value(bfd_tree, hf_bfd_required_min_echo_interval, tvb, 20,
4, bfd_required_min_echo_interval,
- "%4u ms",
- bfd_required_min_echo_interval/1000);
-
+ "%4u ms (%u us)",
+ bfd_required_min_echo_interval/1000,
+ bfd_required_min_echo_interval);
+
+ /* Dissect the authentication fields if the Authentication flag has
+ * been set
+ */
+ if (bfd_version && bfd_flags_a) {
+ if (bfd_length >= 28) {
+ dissect_bfd_authentication(tvb, pinfo, bfd_tree);
+ } else {
+ ti = proto_tree_add_text(bfd_tree, tvb, 24, bfd_length,
+ "Authentication: Length of the BFD frame is invalid (%d)", bfd_length);
+ expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_WARN,
+ "Authentication flag is set in a BFD packet, but no authentication data is present");
+ }
+ }
}
return;
}
@@ -314,17 +543,17 @@ void proto_register_bfd(void)
{ &hf_bfd_version,
{ "Protocol Version", "bfd.version",
FT_UINT8, BASE_DEC, NULL , 0xe0,
- "", HFILL }
+ "The version number of the BFD protocol", HFILL }
},
{ &hf_bfd_diag,
{ "Diagnostic Code", "bfd.diag",
FT_UINT8, BASE_HEX, VALS(bfd_control_v1_diag_values), 0x1f,
- "", HFILL }
+ "This field give the reason for a BFD session failure", HFILL }
},
{ &hf_bfd_sta,
{ "Session State", "bfd.sta",
FT_UINT8, BASE_HEX, VALS(bfd_control_sta_values), 0xc0,
- "", HFILL }
+ "The BFD state as seen by the transmitting system", HFILL }
},
{ &hf_bfd_flags,
{ "Message Flags", "bfd.flags",
@@ -354,32 +583,44 @@ void proto_register_bfd(void)
{ &hf_bfd_flags_p,
{ "Poll", "bfd.flags.p",
FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x20,
- "", HFILL }
+ "If set, the transmitting system is expecting a packet with the Final (F) bit in reply",
+ HFILL }
},
{ &hf_bfd_flags_f,
{ "Final", "bfd.flags.f",
FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x10,
- "", HFILL }
+ "If set, the transmitting system is replying to a packet with the Poll (P) bit set",
+ HFILL }
},
{ &hf_bfd_flags_c,
{ "Control Plane Independent", "bfd.flags.c",
FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x08,
- "", HFILL }
+ "If set, the BFD implementation is implemented in the forwarding plane", HFILL }
},
{ &hf_bfd_flags_a,
{ "Authentication Present", "bfd.flags.a",
FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x04,
- "", HFILL }
+ "The Authentication Section is present", HFILL }
},
{ &hf_bfd_flags_d,
{ "Demand", "bfd.flags.d",
FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x02,
- "", HFILL }
+ "If set, Demand mode is active in the transmitting system", HFILL }
+ },
+ { &hf_bfd_flags_m,
+ { "Multipoint", "bfd.flags.m",
+ FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x01,
+ "Reserved for future point-to-multipoint extensions", HFILL }
},
{ &hf_bfd_detect_time_multiplier,
{ "Detect Time Multiplier", "bfd.detect_time_multiplier",
FT_UINT8, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ "The transmit interval multiplied by this value is the failure detection time", HFILL }
+ },
+ { &hf_bfd_message_length,
+ { "Message Length", "bfd.message_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Length of the BFD Control packet, in bytes", HFILL }
},
{ &hf_bfd_my_discriminator,
{ "My Discriminator", "bfd.my_discriminator",
@@ -394,30 +635,56 @@ void proto_register_bfd(void)
{ &hf_bfd_desired_min_tx_interval,
{ "Desired Min TX Interval", "bfd.desired_min_tx_interval",
FT_UINT32, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ "The minimum interval to use when transmitting BFD Control packets", HFILL }
},
{ &hf_bfd_required_min_rx_interval,
{ "Required Min RX Interval", "bfd.required_min_rx_interval",
FT_UINT32, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ "The minimum interval between received BFD Control packets that this system can support", HFILL }
},
{ &hf_bfd_required_min_echo_interval,
{ "Required Min Echo Interval", "bfd.required_min_echo_interval",
FT_UINT32, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ "The minimum interval between received BFD Echo packets that this system can support", HFILL }
+ },
+ { &hf_bfd_auth_type,
+ { "Authentication Type", "bfd.auth.type",
+ FT_UINT8, BASE_DEC, VALS(bfd_control_auth_type_values), 0x0,
+ "The type of authentication in use on this session", HFILL }
},
+ { &hf_bfd_auth_len,
+ { "Authentication Length", "bfd.auth.len",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "The length, in bytes, of the authentication section", HFILL }
+ },
+ { &hf_bfd_auth_key,
+ { "Authentication Key ID", "bfd.auth.key",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "The Authentication Key ID, identifies which password is in use for this packet", HFILL }
+ },
+ { &hf_bfd_auth_password,
+ { "Password", "bfd.auth.password",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ "The simple password in use on this session", HFILL }
+ },
+ { &hf_bfd_auth_seq_num,
+ { "Sequence Number", "bfd.auth.seq_num",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "The Sequence Number is periodically incremented to prevent replay attacks", HFILL }
+ }
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_bfd,
- &ett_bfd_flags
+ &ett_bfd_flags,
+ &ett_bfd_auth
};
/* Register the protocol name and description */
- proto_bfd = proto_register_protocol("Bi-directional Fault Detection Control Message",
+ proto_bfd = proto_register_protocol("Bidirectional Forwarding Detection Control Message",
"BFD Control",
- "bfdcontrol");
+ "bfd");
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_bfd, hf, array_length(hf));
@@ -430,5 +697,6 @@ proto_reg_handoff_bfd(void)
dissector_handle_t bfd_control_handle;
bfd_control_handle = create_dissector_handle(dissect_bfd_control, proto_bfd);
- dissector_add("udp.port", UDP_PORT_BFD_CONTROL, bfd_control_handle);
+ dissector_add("udp.port", UDP_PORT_BFD_1HOP_CONTROL, bfd_control_handle);
+ dissector_add("udp.port", UDP_PORT_BFD_MULTIHOP_CONTROL, bfd_control_handle);
}