From Balint Reczey (IJ/ETH)
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 20 Feb 2006 17:21:47 +0000 (17:21 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 20 Feb 2006 17:21:47 +0000 (17:21 +0000)
> 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.
>

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@17357 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-bfd.c

index da590e151bbc0c6eb34527c7104cea2886d5627f..17330da7214b524096bec0c1a44fb2b20741130d 100644 (file)
@@ -2,6 +2,7 @@
  * Routines for Bi-directional Fault Detection (BFD) message dissection
  *
  * Copyright 2003, Hannes Gredler <hannes@juniper.net>
+ * Copyright 2006, Balint Reczey <Balint.Reczey@ericsson.com>
  *
  * $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 */