From 8e03852501acbea883d3aae809a9215256e2406b Mon Sep 17 00:00:00 2001 From: Anders Broman Date: Mon, 20 Feb 2006 17:21:47 +0000 Subject: [PATCH] From Balint Reczey (IJ/ETH) > The included patch fixes BFD version detection in the BFD packet > dissector and extends it to correctly dissect version 1 packets. The > Authentication Section part of the packet is still not dissected. > svn path=/trunk/; revision=17357 --- epan/dissectors/packet-bfd.c | 200 ++++++++++++++++++++++++++++++----- 1 file changed, 173 insertions(+), 27 deletions(-) diff --git a/epan/dissectors/packet-bfd.c b/epan/dissectors/packet-bfd.c index da590e151b..17330da721 100644 --- a/epan/dissectors/packet-bfd.c +++ b/epan/dissectors/packet-bfd.c @@ -2,6 +2,7 @@ * Routines for Bi-directional Fault Detection (BFD) message dissection * * Copyright 2003, Hannes Gredler + * Copyright 2006, Balint Reczey * * $Id$ * @@ -38,7 +39,7 @@ #define UDP_PORT_BFD_CONTROL 3784 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */ -static const value_string bfd_control_diag_values[] = { +static const value_string bfd_control_v0_diag_values[] = { { 0, "No Diagnostic" }, { 1, "Control Detection Time Expired" }, { 2, "Echo Function Failed" }, @@ -50,23 +51,39 @@ static const value_string bfd_control_diag_values[] = { { 0, NULL } }; -static const value_string bfd_control_flag_values[] = { - { 0x80, "I Hear You" }, - { 0x40, "Demand" }, - { 0x20, "Poll" }, - { 0x10, "Final" }, - { 0x08, "Reserved" }, - { 0x04, "Reserved" }, - { 0x02, "Reserved" }, - { 0x01, "Reserved" }, +static const value_string bfd_control_v1_diag_values[] = { + { 0, "No Diagnostic" }, + { 1, "Control Detection Time Expired" }, + { 2, "Echo Function Failed" }, + { 3, "Neighbor Signaled Session Down" }, + { 4, "Forwarding Plane Reset" }, + { 5, "Path Down" }, + { 6, "Concatenated Path Down" }, + { 7, "Administratively Down" }, + { 8, "Reverse Concatenated Path Down" }, { 0, NULL } }; +static const value_string bfd_control_sta_values[] = { + { 0, "AdminDown" }, + { 1, "Down" }, + { 2, "Init" }, + { 3, "Up" } +}; + static gint proto_bfd = -1; static gint hf_bfd_version = -1; static gint hf_bfd_diag = -1; +static gint hf_bfd_sta = -1; static gint hf_bfd_flags = -1; +static gint hf_bfd_flags_h = -1; +static gint hf_bfd_flags_p = -1; +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_d_v0 = -1; static gint hf_bfd_detect_time_multiplier = -1; static gint hf_bfd_my_discriminator = -1; static gint hf_bfd_your_discriminator = -1; @@ -75,9 +92,10 @@ static gint hf_bfd_required_min_rx_interval = -1; static gint hf_bfd_required_min_echo_interval = -1; static gint ett_bfd = -1; +static gint ett_bfd_flags = -1; /* - * Control packet, draft-katz-ward-bfd-01.txt + * Control packet version 0, draft-katz-ward-bfd-01.txt * * 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 @@ -96,11 +114,50 @@ static gint ett_bfd = -1; * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* + * Control packet version 1, draft-ietf-bfd-base-04.txt + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Vers | Diag |Sta|P|F|C|A|D|R| Detect Mult | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | My Discriminator | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Your Discriminator | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Desired Min TX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Required Min RX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Required Min Echo RX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 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... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * + * + */ + static void dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint bfd_version = -1; gint bfd_diag = -1; + gint bfd_sta = -1; gint bfd_flags = -1; + gint bfd_flags_h = -1; + gint bfd_flags_p = -1; + gint bfd_flags_f = -1; + gint bfd_flags_c = -1; + gint bfd_flags_a = -1; + gint bfd_flags_d = -1; + gint bfd_flags_d_v0 = -1; gint bfd_detect_time_multiplier = -1; gint bfd_length = -1; gint bfd_my_discriminator = -1; @@ -111,6 +168,7 @@ 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; if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "BFD Control"); @@ -119,7 +177,23 @@ static void dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t bfd_version = ((tvb_get_guint8(tvb, 0) & 0xe0) >> 5); bfd_diag = (tvb_get_guint8(tvb, 0) & 0x1f); - bfd_flags = tvb_get_guint8(tvb, 1); + switch (bfd_version) { + case 0: + bfd_flags = tvb_get_guint8(tvb, 1 ); + bfd_flags_h = (tvb_get_guint8(tvb, 1) & 0x80); + bfd_flags_d_v0 = (tvb_get_guint8(tvb, 1) & 0x40); + break; + case 1: + default: + bfd_sta = (tvb_get_guint8(tvb, 1) & 0xc0); + bfd_flags = (tvb_get_guint8(tvb, 1) & 0x3e); + bfd_flags_p = (tvb_get_guint8(tvb, 1) & 0x20); + bfd_flags_f = (tvb_get_guint8(tvb, 1) & 0x10); + 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); + break; + } bfd_detect_time_multiplier = tvb_get_guint8(tvb, 2); bfd_length = tvb_get_guint8(tvb, 3); @@ -130,13 +204,20 @@ static void dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t bfd_required_min_echo_interval = tvb_get_ntohl(tvb, 20); if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Diag: %s, Flags: %s", - val_to_str(bfd_diag, bfd_control_diag_values, "UNKNOWN"), - decode_enumerated_bitfield(bfd_flags, - 0xf0, - 8, - bfd_control_flag_values, - "%s")); + switch (bfd_version) { + case 0: + col_add_fstr(pinfo->cinfo, COL_INFO, "Diag: %s, Flags: 0x%02x", + val_to_str(bfd_diag, bfd_control_v0_diag_values, "UNKNOWN"), + bfd_flags); + break; + case 1: + default: + col_add_fstr(pinfo->cinfo, COL_INFO, "Diag: %s, State: %s, Flags: 0x%02x", + val_to_str(bfd_diag, bfd_control_v1_diag_values, "UNKNOWN"), + val_to_str(bfd_sta >> 6 , bfd_control_sta_values, "UNKNOWN"), + bfd_flags); + break; + } } if (tree) { @@ -146,17 +227,41 @@ 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, - 1, bfd_version); + 1, bfd_version << 5); ti = proto_tree_add_uint(bfd_tree, hf_bfd_diag, tvb, 0, 1, bfd_diag); - ti = proto_tree_add_text ( bfd_tree, tvb, 1, 1, "Message Flags: %s", - decode_enumerated_bitfield(bfd_flags, - 0xf0, - 8, - bfd_control_flag_values, - "%s")); + switch (bfd_version) { + case 0: + break; + case 1: + default: + ti = proto_tree_add_uint(bfd_tree, hf_bfd_sta, tvb, 1, + 1, bfd_sta); + + break; + } + switch (bfd_version) { + 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, 8, 1, bfd_flags_h); + ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_d_v0, tvb, 8, 1, bfd_flags_d_v0); + 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, 6, 1, bfd_flags_p); + ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_f, tvb, 6, 1, bfd_flags_f); + ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_c, tvb, 6, 1, bfd_flags_c); + ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_a, tvb, 6, 1, bfd_flags_a); + ti = proto_tree_add_boolean(bfd_flags_tree, hf_bfd_flags_d, tvb, 6, 1, bfd_flags_d); + break; + } ti = proto_tree_add_uint_format_value(bfd_tree, hf_bfd_detect_time_multiplier, tvb, 2, 1, bfd_detect_time_multiplier, @@ -204,7 +309,12 @@ void proto_register_bfd(void) }, { &hf_bfd_diag, { "Diagnostic Code", "bfd.diag", - FT_UINT8, BASE_HEX, VALS(bfd_control_diag_values), 0x1f, + FT_UINT8, BASE_HEX, VALS(bfd_control_v1_diag_values), 0x1f, + "", HFILL } + }, + { &hf_bfd_sta, + { "Session State", "bfd.sta", + FT_UINT8, BASE_HEX, VALS(bfd_control_sta_values), 0xc0, "", HFILL } }, { &hf_bfd_flags, @@ -212,6 +322,41 @@ void proto_register_bfd(void) FT_UINT8, BASE_HEX, NULL, 0xf0, "", HFILL } }, + { &hf_bfd_flags_h, + { "I hear you", "bfd.flags.h", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x80, + "", HFILL } + }, + { &hf_bfd_flags_d_v0, + { "Demand", "bfd.flags.d", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x40, + "", HFILL } + }, + { &hf_bfd_flags_p, + { "Poll", "bfd.flags.p", + FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x20, + "", HFILL } + }, + { &hf_bfd_flags_f, + { "Final", "bfd.flags.f", + FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x10, + "", HFILL } + }, + { &hf_bfd_flags_c, + { "Control Plane Independent", "bfd.flags.c", + FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x08, + "", HFILL } + }, + { &hf_bfd_flags_a, + { "Authentication Present", "bfd.flags.a", + FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x04, + "", HFILL } + }, + { &hf_bfd_flags_d, + { "Demand", "bfd.flags.d", + FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x02, + "", HFILL } + }, { &hf_bfd_detect_time_multiplier, { "Detect Time Multiplier", "bfd.detect_time_multiplier", FT_UINT8, BASE_DEC, NULL, 0x0, @@ -247,6 +392,7 @@ void proto_register_bfd(void) /* Setup protocol subtree array */ static gint *ett[] = { &ett_bfd, + &ett_bfd_flags }; /* Register the protocol name and description */