Have "dissect_xdlc_control()" take a pointer to a structure containing
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 3 Jan 2004 03:51:27 +0000 (03:51 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 3 Jan 2004 03:51:27 +0000 (03:51 +0000)
pointers to hf_ values, so the subfields of the control field are put
into the protocol tree as filterable items.  Change the protocols that
use it appropriately.

Export "dissect_xdlc_control()" to plugins.

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

14 files changed:
packet-fr.c
packet-lapb.c
packet-lapd.c
packet-llc.c
packet-sdlc.c
packet-v120.c
plugins/Xass-list
plugins/Xplugin_api.c
plugins/Xplugin_api.h
plugins/Xplugin_api_decls.h
plugins/Xplugin_table.h
plugins/plugin_api_list.c
xdlc.c
xdlc.h

index ae599f445e121ca9a5a22c9564859e106aee09d7..91f6552fd65b0739ba0e6f82b940146c6e5954ae 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright 2001, Paul Ionescu        <paul@acorp.ro>
  *
- * $Id: packet-fr.c,v 1.45 2003/10/17 23:43:21 guy Exp $
+ * $Id: packet-fr.c,v 1.46 2004/01/03 03:49:22 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -91,6 +91,18 @@ static gint hf_fr_lower_dlci = -1;
 static gint hf_fr_dc    = -1;
 static gint hf_fr_dlci  = -1;
 static gint hf_fr_control = -1;
+static gint hf_fr_n_r = -1;
+static gint hf_fr_n_s = -1;
+static gint hf_fr_p = -1;
+static gint hf_fr_p_ext = -1;
+static gint hf_fr_f = -1;
+static gint hf_fr_f_ext = -1;
+static gint hf_fr_s_ftype = -1;
+static gint hf_fr_u_modifier_cmd = -1;
+static gint hf_fr_u_modifier_resp = -1;
+static gint hf_fr_ftype_i = -1;
+static gint hf_fr_ftype_s_u = -1;
+static gint hf_fr_ftype_s_u_ext = -1;
 static gint hf_fr_nlpid = -1;
 static gint hf_fr_oui   = -1;
 static gint hf_fr_pid   = -1;
@@ -162,6 +174,32 @@ static void dissect_fr_nlpid(tvbuff_t *tvb, int offset, packet_info *pinfo,
 static void dissect_lapf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 static void dissect_fr_xid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 
+/* Used only for U frames */
+static const xdlc_cf_items fr_cf_items = {
+       NULL,
+       NULL,
+       &hf_fr_p,
+       &hf_fr_f,
+       NULL,
+       &hf_fr_u_modifier_cmd,
+       &hf_fr_u_modifier_resp,
+       NULL,
+       &hf_fr_ftype_s_u
+};
+
+/* Used only for I and S frames */
+static const xdlc_cf_items fr_cf_items_ext = {
+       &hf_fr_n_r,
+       &hf_fr_n_s,
+       &hf_fr_p_ext,
+       &hf_fr_f_ext,
+       &hf_fr_s_ftype,
+       NULL,
+       NULL,
+       &hf_fr_ftype_i,
+       &hf_fr_ftype_s_u_ext
+};
+
 static void
 dissect_fr_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                  gboolean has_direction)
@@ -331,7 +369,8 @@ dissect_fr_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     fr_ctrl = tvb_get_guint8(tvb, offset);
     if (fr_ctrl == XDLC_U) {
       dissect_xdlc_control(tvb, offset, pinfo, fr_tree, hf_fr_control,
-                          ett_fr_control, is_response, TRUE, TRUE);
+                          ett_fr_control, &fr_cf_items, &fr_cf_items_ext,
+                          is_response, TRUE, TRUE);
       offset++;
 
       /*
@@ -355,6 +394,7 @@ dissect_fr_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                 */
                dissect_xdlc_control(tvb, offset, pinfo, fr_tree,
                                     hf_fr_control, ett_fr_control,
+                                    &fr_cf_items, &fr_cf_items_ext,
                                     is_response, TRUE, TRUE);
                dissect_lapf(tvb_new_subset(tvb,offset,-1,-1),pinfo,tree);
                return;
@@ -362,6 +402,7 @@ dissect_fr_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
       if (fr_ctrl == (XDLC_U|XDLC_XID)) {
                dissect_xdlc_control(tvb, offset, pinfo, fr_tree,
                                     hf_fr_control, ett_fr_control,
+                                    &fr_cf_items, &fr_cf_items_ext,
                                     is_response, TRUE, TRUE);
                dissect_fr_xid(tvb_new_subset(tvb,offset,-1,-1),pinfo,tree);
                return;
@@ -593,6 +634,42 @@ void proto_register_fr(void)
        { &hf_fr_control, {
           "Control Field", "fr.control", FT_UINT8, BASE_HEX,
           NULL, 0x0, "Control field", HFILL }},
+       { &hf_fr_n_r, {
+         "N(R)", "fr.control.n_r", FT_UINT16, BASE_DEC,
+         NULL, XDLC_N_R_EXT_MASK, "", HFILL }},
+       { &hf_fr_n_s, {
+         "N(S)", "fr.control.n_s", FT_UINT16, BASE_DEC,
+         NULL, XDLC_N_S_EXT_MASK, "", HFILL }},
+       { &hf_fr_p, {
+         "Poll", "fr.control.p", FT_BOOLEAN, 8,
+         TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+       { &hf_fr_p_ext, {
+         "Poll", "fr.control.p", FT_BOOLEAN, 16,
+         TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
+       { &hf_fr_f, {
+         "Final", "fr.control.f", FT_BOOLEAN, 8,
+         TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+       { &hf_fr_f_ext, {
+         "Final", "fr.control.f", FT_BOOLEAN, 16,
+         TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
+       { &hf_fr_s_ftype, {
+         "Supervisory frame type", "fr.control.s_ftype", FT_UINT16, BASE_HEX,
+         VALS(stype_vals), XDLC_S_FTYPE_MASK, "", HFILL }},
+       { &hf_fr_u_modifier_cmd, {
+         "Command", "lapd.control.u_modifier_cmd", FT_UINT8, BASE_HEX,
+         VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK, "", HFILL }},
+       { &hf_fr_u_modifier_resp, {
+         "Response", "lapd.control.u_modifier_resp", FT_UINT8, BASE_HEX,
+           VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK, "", HFILL }},
+       { &hf_fr_ftype_i, {
+         "Frame type", "fr.control.ftype", FT_UINT16, BASE_HEX,
+         VALS(ftype_vals), XDLC_I_MASK, "", HFILL }},
+       { &hf_fr_ftype_s_u, {
+         "Frame type", "fr.control.ftype", FT_UINT8, BASE_HEX,
+         VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
+       { &hf_fr_ftype_s_u_ext, {
+         "Frame type", "fr.control.ftype", FT_UINT16, BASE_HEX,
+         VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
         { &hf_fr_nlpid, {
            "NLPID", "fr.nlpid", FT_UINT8, BASE_HEX,
             VALS(fr_nlpid_vals), 0x0, "Frame Relay Encapsulated Protocol NLPID", HFILL }},
index 8b911dae6c1875d2c3ae257026da3f6ef8d4571e..9b1acfa879bb18a21d7129e298e96ad418323c99 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for lapb frame disassembly
  * Olivier Abad <oabad@noos.fr>
  *
- * $Id: packet-lapb.c,v 1.40 2003/09/26 08:19:55 guy Exp $
+ * $Id: packet-lapb.c,v 1.41 2004/01/03 03:49:22 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 static int proto_lapb = -1;
 static int hf_lapb_address = -1;
 static int hf_lapb_control = -1;
+static int hf_lapb_n_r = -1;
+static int hf_lapb_n_s = -1;
+static int hf_lapb_p = -1;
+static int hf_lapb_f = -1;
+static int hf_lapb_s_ftype = -1;
+static int hf_lapb_u_modifier_cmd = -1;
+static int hf_lapb_u_modifier_resp = -1;
+static int hf_lapb_ftype_i = -1;
+static int hf_lapb_ftype_s_u = -1;
 
 static gint ett_lapb = -1;
 static gint ett_lapb_control = -1;
@@ -43,6 +52,18 @@ static gint ett_lapb_control = -1;
 static dissector_handle_t x25_dir_handle;
 static dissector_handle_t x25_handle;
 
+static const xdlc_cf_items lapb_cf_items = {
+       &hf_lapb_n_r,
+       &hf_lapb_n_s,
+       &hf_lapb_p,
+       &hf_lapb_f,
+       &hf_lapb_s_ftype,
+       &hf_lapb_u_modifier_cmd,
+       &hf_lapb_u_modifier_resp,
+       &hf_lapb_ftype_i,
+       &hf_lapb_ftype_s_u
+};
+
 static void
 dissect_lapb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
@@ -130,7 +151,7 @@ dissect_lapb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         lapb_tree = NULL;
 
     dissect_xdlc_control(tvb, 1, pinfo, lapb_tree, hf_lapb_control,
-           ett_lapb_control, is_response, FALSE, FALSE);
+           ett_lapb_control, &lapb_cf_items, NULL, is_response, FALSE, FALSE);
 
     /* not end of frame ==> X.25 */
     if (tvb_reported_length(tvb) > 2) {
@@ -160,6 +181,42 @@ proto_register_lapb(void)
        { &hf_lapb_control,
          { "Control Field", "lapb.control", FT_UINT8, BASE_HEX, NULL, 0x0,
                "Control field", HFILL }},
+
+       { &hf_lapb_n_r,
+           { "N(R)", "lapb.control.n_r", FT_UINT8, BASE_DEC,
+             NULL, XDLC_N_R_MASK, "", HFILL }},
+
+       { &hf_lapb_n_s,
+           { "N(S)", "lapb.control.n_s", FT_UINT8, BASE_DEC,
+             NULL, XDLC_N_S_MASK, "", HFILL }},
+
+       { &hf_lapb_p,
+           { "Poll", "lapb.control.p", FT_BOOLEAN, 8,
+             TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+
+       { &hf_lapb_f,
+           { "Final", "lapb.control.f", FT_BOOLEAN, 8,
+             TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+
+       { &hf_lapb_s_ftype,
+           { "Supervisory frame type", "lapb.control.s_ftype", FT_UINT8, BASE_HEX,
+             VALS(stype_vals), XDLC_S_FTYPE_MASK, "", HFILL }},
+
+       { &hf_lapb_u_modifier_cmd,
+           { "Command", "lapb.control.u_modifier_cmd", FT_UINT8, BASE_HEX,
+             VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK, "", HFILL }},
+
+       { &hf_lapb_u_modifier_resp,
+           { "Response", "lapb.control.u_modifier_resp", FT_UINT8, BASE_HEX,
+             VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK, "", HFILL }},
+
+       { &hf_lapb_ftype_i,
+           { "Frame type", "lapb.control.ftype", FT_UINT8, BASE_HEX,
+             VALS(ftype_vals), XDLC_I_MASK, "", HFILL }},
+
+       { &hf_lapb_ftype_s_u,
+           { "Frame type", "lapb.control.ftype", FT_UINT8, BASE_HEX,
+             VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
     };
     static gint *ett[] = {
         &ett_lapb,
index f69b5cbce640a9d191b8fe2ddb2099b40086dcc2..03f76efcec7ae972e69626c15e39392fc950dba6 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for LAPD frame disassembly
  * Gilbert Ramirez <gram@alumni.rice.edu>
  *
- * $Id: packet-lapd.c,v 1.35 2003/09/02 19:18:52 guy Exp $
+ * $Id: packet-lapd.c,v 1.36 2004/01/03 03:49:22 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -48,6 +48,18 @@ static int hf_lapd_ea1 = -1;
 static int hf_lapd_tei = -1;
 static int hf_lapd_ea2 = -1;
 static int hf_lapd_control = -1;
+static int hf_lapd_n_r = -1;
+static int hf_lapd_n_s = -1;
+static int hf_lapd_p = -1;
+static int hf_lapd_p_ext = -1;
+static int hf_lapd_f = -1;
+static int hf_lapd_f_ext = -1;
+static int hf_lapd_s_ftype = -1;
+static int hf_lapd_u_modifier_cmd = -1;
+static int hf_lapd_u_modifier_resp = -1;
+static int hf_lapd_ftype_i = -1;
+static int hf_lapd_ftype_s_u = -1;
+static int hf_lapd_ftype_s_u_ext = -1;
 
 static gint ett_lapd = -1;
 static gint ett_lapd_address = -1;
@@ -79,6 +91,32 @@ static const value_string lapd_sapi_vals[] = {
        { 0,                    NULL }
 };
 
+/* Used only for U frames */
+static const xdlc_cf_items lapd_cf_items = {
+       NULL,
+       NULL,
+       &hf_lapd_p,
+       &hf_lapd_f,
+       NULL,
+       &hf_lapd_u_modifier_cmd,
+       &hf_lapd_u_modifier_resp,
+       NULL,
+       &hf_lapd_ftype_s_u
+};
+
+/* Used only for I and S frames */
+static const xdlc_cf_items lapd_cf_items_ext = {
+       &hf_lapd_n_r,
+       &hf_lapd_n_s,
+       &hf_lapd_p_ext,
+       &hf_lapd_f_ext,
+       &hf_lapd_s_ftype,
+       NULL,
+       NULL,
+       &hf_lapd_ftype_i,
+       &hf_lapd_ftype_s_u_ext
+};
+
 static void
 dissect_lapd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
@@ -137,7 +175,8 @@ dissect_lapd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        }
 
        control = dissect_xdlc_control(tvb, 2, pinfo, lapd_tree, hf_lapd_control,
-           ett_lapd_control, is_response, TRUE, FALSE);
+           ett_lapd_control, &lapd_cf_items, &lapd_cf_items_ext, is_response,
+           TRUE, FALSE);
        lapd_header_len += XDLC_CONTROL_LEN(control, TRUE);
 
        if (tree)
@@ -195,6 +234,54 @@ proto_register_lapd(void)
        { &hf_lapd_control,
          { "Control Field", "lapd.control", FT_UINT16, BASE_HEX, NULL, 0x0,
                "Control field", HFILL }},
+
+       { &hf_lapd_n_r,
+           { "N(R)", "lapd.control.n_r", FT_UINT16, BASE_DEC,
+               NULL, XDLC_N_R_EXT_MASK, "", HFILL }},
+
+       { &hf_lapd_n_s,
+           { "N(S)", "lapd.control.n_s", FT_UINT16, BASE_DEC,
+               NULL, XDLC_N_S_EXT_MASK, "", HFILL }},
+
+       { &hf_lapd_p,
+           { "Poll", "lapd.control.p", FT_BOOLEAN, 8,
+               TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+
+       { &hf_lapd_p_ext,
+           { "Poll", "lapd.control.p", FT_BOOLEAN, 16,
+               TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
+
+       { &hf_lapd_f,
+           { "Final", "lapd.control.f", FT_BOOLEAN, 8,
+               TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+
+       { &hf_lapd_f_ext,
+           { "Final", "lapd.control.f", FT_BOOLEAN, 16,
+               TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
+
+       { &hf_lapd_s_ftype,
+           { "Supervisory frame type", "lapd.control.s_ftype", FT_UINT16, BASE_HEX,
+               VALS(stype_vals), XDLC_S_FTYPE_MASK, "", HFILL }},
+
+       { &hf_lapd_u_modifier_cmd,
+           { "Command", "lapd.control.u_modifier_cmd", FT_UINT8, BASE_HEX,
+               VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK, "", HFILL }},
+
+       { &hf_lapd_u_modifier_resp,
+           { "Response", "lapd.control.u_modifier_resp", FT_UINT8, BASE_HEX,
+               VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK, "", HFILL }},
+
+       { &hf_lapd_ftype_i,
+           { "Frame type", "lapd.control.ftype", FT_UINT16, BASE_HEX,
+               VALS(ftype_vals), XDLC_I_MASK, "", HFILL }},
+
+       { &hf_lapd_ftype_s_u,
+           { "Frame type", "lapd.control.ftype", FT_UINT8, BASE_HEX,
+               VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
+
+       { &hf_lapd_ftype_s_u_ext,
+           { "Frame type", "lapd.control.ftype", FT_UINT16, BASE_HEX,
+               VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
     };
     static gint *ett[] = {
         &ett_lapd,
index 3bd505e93d2e5d27e2cf7a4f430e347f08859c5c..59e5c12470b3127c88d3137b2a633923393d2777 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for IEEE 802.2 LLC layer
  * Gilbert Ramirez <gram@alumni.rice.edu>
  *
- * $Id: packet-llc.c,v 1.116 2003/10/01 07:11:44 guy Exp $
+ * $Id: packet-llc.c,v 1.117 2004/01/03 03:49:22 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -57,6 +57,18 @@ static int hf_llc_ssap = -1;
 static int hf_llc_dsap_ig = -1;
 static int hf_llc_ssap_cr = -1;
 static int hf_llc_ctrl = -1;
+static int hf_llc_n_r = -1;
+static int hf_llc_n_s = -1;
+static int hf_llc_p = -1;
+static int hf_llc_p_ext = -1;
+static int hf_llc_f = -1;
+static int hf_llc_f_ext = -1;
+static int hf_llc_s_ftype = -1;
+static int hf_llc_u_modifier_cmd = -1;
+static int hf_llc_u_modifier_resp = -1;
+static int hf_llc_ftype_i = -1;
+static int hf_llc_ftype_s_u = -1;
+static int hf_llc_ftype_s_u_ext = -1;
 static int hf_llc_type = -1;
 static int hf_llc_oui = -1;
 static int hf_llc_pid = -1;
@@ -298,6 +310,32 @@ capture_llc(const guchar *pd, int offset, int len, packet_counts *ld) {
        }
 }
 
+/* Used only for U frames */
+static const xdlc_cf_items llc_cf_items = {
+       NULL,
+       NULL,
+       &hf_llc_p,
+       &hf_llc_f,
+       NULL,
+       &hf_llc_u_modifier_cmd,
+       &hf_llc_u_modifier_resp,
+       NULL,
+       &hf_llc_ftype_s_u
+};
+
+/* Used only for I and S frames */
+static const xdlc_cf_items llc_cf_items_ext = {
+       &hf_llc_n_r,
+       &hf_llc_n_s,
+       &hf_llc_p_ext,
+       &hf_llc_f_ext,
+       &hf_llc_s_ftype,
+       NULL,
+       NULL,
+       &hf_llc_ftype_i,
+       &hf_llc_ftype_s_u_ext
+};
+
 static void
 dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
@@ -347,6 +385,7 @@ dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         */
        control = dissect_xdlc_control(tvb, 2, pinfo, llc_tree,
                                hf_llc_ctrl, ett_llc_ctrl,
+                               &llc_cf_items, &llc_cf_items_ext,
                                ssap & SSAP_CR_BIT, TRUE, FALSE);
        llc_header_len += XDLC_CONTROL_LEN(control, TRUE);
        if (is_snap)
@@ -583,6 +622,54 @@ proto_register_llc(void)
                { "Control", "llc.control", FT_UINT16, BASE_HEX,
                        NULL, 0x0, "", HFILL }},
 
+               { &hf_llc_n_r,
+               { "N(R)", "llc.control.n_r", FT_UINT16, BASE_DEC,
+                       NULL, XDLC_N_R_EXT_MASK, "", HFILL }},
+
+               { &hf_llc_n_s,
+               { "N(S)", "llc.control.n_s", FT_UINT16, BASE_DEC,
+                       NULL, XDLC_N_S_EXT_MASK, "", HFILL }},
+
+               { &hf_llc_p,
+               { "Poll", "llc.control.p", FT_BOOLEAN, 8,
+                       TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+
+               { &hf_llc_p_ext,
+               { "Poll", "llc.control.p", FT_BOOLEAN, 16,
+                       TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
+
+               { &hf_llc_f,
+               { "Final", "llc.control.f", FT_BOOLEAN, 8,
+                       TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+
+               { &hf_llc_f_ext,
+               { "Final", "llc.control.f", FT_BOOLEAN, 16,
+                       TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
+
+               { &hf_llc_s_ftype,
+               { "Supervisory frame type", "llc.control.s_ftype", FT_UINT16, BASE_HEX,
+                       VALS(stype_vals), XDLC_S_FTYPE_MASK, "", HFILL }},
+
+               { &hf_llc_u_modifier_cmd,
+               { "Command", "llc.control.u_modifier_cmd", FT_UINT8, BASE_HEX,
+                       VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK, "", HFILL }},
+
+               { &hf_llc_u_modifier_resp,
+               { "Response", "llc.control.u_modifier_resp", FT_UINT8, BASE_HEX,
+                       VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK, "", HFILL }},
+
+               { &hf_llc_ftype_i,
+               { "Frame type", "llc.control.ftype", FT_UINT16, BASE_HEX,
+                       VALS(ftype_vals), XDLC_I_MASK, "", HFILL }},
+
+               { &hf_llc_ftype_s_u,
+               { "Frame type", "llc.control.ftype", FT_UINT8, BASE_HEX,
+                       VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
+
+               { &hf_llc_ftype_s_u_ext,
+               { "Frame type", "llc.control.ftype", FT_UINT16, BASE_HEX,
+                       VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
+
                /* registered here but handled in ethertype.c */
                { &hf_llc_type,
                { "Type", "llc.type", FT_UINT16, BASE_HEX,
index 8983090ee6f77d7cb961eb1f18200b6ca144d9ed..b777178f553cf64ec0ebb8b2dd6d11df3ade4540 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-sdlc.c
  * Routines for SDLC frame disassembly
  *
- * $Id: packet-sdlc.c,v 1.2 2003/09/02 19:18:52 guy Exp $
+ * $Id: packet-sdlc.c,v 1.3 2004/01/03 03:49:22 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 static int proto_sdlc = -1;
 static int hf_sdlc_address = -1;
 static int hf_sdlc_control = -1;
+static int hf_sdlc_n_r = -1;
+static int hf_sdlc_n_s = -1;
+static int hf_sdlc_p = -1;
+static int hf_sdlc_f = -1;
+static int hf_sdlc_s_ftype = -1;
+static int hf_sdlc_u_modifier_cmd = -1;
+static int hf_sdlc_u_modifier_resp = -1;
+static int hf_sdlc_ftype_i = -1;
+static int hf_sdlc_ftype_s_u = -1;
 
 static gint ett_sdlc = -1;
 static gint ett_sdlc_control = -1;
@@ -48,6 +57,18 @@ static gint ett_sdlc_control = -1;
 static dissector_handle_t sna_handle;
 static dissector_handle_t data_handle;
 
+static const xdlc_cf_items sdlc_cf_items = {
+       &hf_sdlc_n_r,
+       &hf_sdlc_n_s,
+       &hf_sdlc_p,
+       &hf_sdlc_f,
+       &hf_sdlc_s_ftype,
+       &hf_sdlc_u_modifier_cmd,
+       &hf_sdlc_u_modifier_resp,
+       &hf_sdlc_ftype_i,
+       &hf_sdlc_ftype_s_u
+};
+
 static void
 dissect_sdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
@@ -107,7 +128,7 @@ dissect_sdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         * to control what to use.
         */
        control = dissect_xdlc_control(tvb, 1, pinfo, sdlc_tree, hf_sdlc_control,
-           ett_sdlc_control, is_response, FALSE, FALSE);
+           ett_sdlc_control, &sdlc_cf_items, NULL, is_response, FALSE, FALSE);
        sdlc_header_len += XDLC_CONTROL_LEN(control, FALSE);
 
        if (tree)
@@ -136,6 +157,42 @@ proto_register_sdlc(void)
                { &hf_sdlc_control,
                  { "Control Field", "sdlc.control", FT_UINT16, BASE_HEX,
                    NULL, 0x0, "Control field", HFILL }},
+
+               { &hf_sdlc_n_r,
+                   { "N(R)", "sdlc.control.n_r", FT_UINT8, BASE_DEC,
+                     NULL, XDLC_N_R_MASK, "", HFILL }},
+
+               { &hf_sdlc_n_s,
+                   { "N(S)", "sdlc.control.n_s", FT_UINT8, BASE_DEC,
+                     NULL, XDLC_N_S_MASK, "", HFILL }},
+
+               { &hf_sdlc_p,
+                   { "Poll", "sdlc.control.p", FT_BOOLEAN, 8,
+                     TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+
+               { &hf_sdlc_f,
+                   { "Final", "sdlc.control.f", FT_BOOLEAN, 8,
+                     TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+
+               { &hf_sdlc_s_ftype,
+                   { "Supervisory frame type", "sdlc.control.s_ftype", FT_UINT8, BASE_HEX,
+                     VALS(stype_vals), XDLC_S_FTYPE_MASK, "", HFILL }},
+
+               { &hf_sdlc_u_modifier_cmd,
+                   { "Command", "sdlc.control.u_modifier_cmd", FT_UINT8, BASE_HEX,
+                     VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK, "", HFILL }},
+
+               { &hf_sdlc_u_modifier_resp,
+                   { "Response", "sdlc.control.u_modifier_resp", FT_UINT8, BASE_HEX,
+                     VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK, "", HFILL }},
+
+               { &hf_sdlc_ftype_i,
+                   { "Frame type", "sdlc.control.ftype", FT_UINT8, BASE_HEX,
+                     VALS(ftype_vals), XDLC_I_MASK, "", HFILL }},
+
+               { &hf_sdlc_ftype_s_u,
+                   { "Frame type", "sdlc.control.ftype", FT_UINT8, BASE_HEX,
+                     VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
        };
        static gint *ett[] = {
                &ett_sdlc,
index 25dc238d4e3ae3bd8cf872c04bf4ed901439d2e3..610ea7eab00760eda59057de79a034fb52355bfa 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for v120 frame disassembly
  * Bert Driehuis <driehuis@playbeing.org>
  *
- * $Id: packet-v120.c,v 1.31 2003/09/02 19:18:52 guy Exp $
+ * $Id: packet-v120.c,v 1.32 2004/01/03 03:49:22 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 static int proto_v120 = -1;
 static int hf_v120_address = -1;
 static int hf_v120_control = -1;
+static int hf_v120_n_r = -1;
+static int hf_v120_n_s = -1;
+static int hf_v120_p = -1;
+static int hf_v120_p_ext = -1;
+static int hf_v120_f = -1;
+static int hf_v120_f_ext = -1;
+static int hf_v120_s_ftype = -1;
+static int hf_v120_u_modifier_cmd = -1;
+static int hf_v120_u_modifier_resp = -1;
+static int hf_v120_ftype_i = -1;
+static int hf_v120_ftype_s_u = -1;
+static int hf_v120_ftype_s_u_ext = -1;
 static int hf_v120_header = -1;
 
 static gint ett_v120 = -1;
@@ -47,6 +59,32 @@ static dissector_handle_t data_handle;
 
 static int dissect_v120_header(tvbuff_t *tvb, int offset, proto_tree *tree);
 
+/* Used only for U frames */
+static const xdlc_cf_items v120_cf_items = {
+       NULL,
+       NULL,
+       &hf_v120_p,
+       &hf_v120_f,
+       NULL,
+       &hf_v120_u_modifier_cmd,
+       &hf_v120_u_modifier_resp,
+       NULL,
+       &hf_v120_ftype_s_u
+};
+
+/* Used only for I and S frames */
+static const xdlc_cf_items v120_cf_items_ext = {
+       &hf_v120_n_r,
+       &hf_v120_n_s,
+       &hf_v120_p_ext,
+       &hf_v120_f_ext,
+       &hf_v120_s_ftype,
+       NULL,
+       NULL,
+       &hf_v120_ftype_i,
+       &hf_v120_ftype_s_u_ext
+};
+
 static void
 dissect_v120(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
@@ -126,7 +164,8 @@ dissect_v120(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        ti = NULL;
     }
     control = dissect_xdlc_control(tvb, 2, pinfo, v120_tree, hf_v120_control,
-           ett_v120_control, is_response, TRUE, FALSE);
+           ett_v120_control, &v120_cf_items, &v120_cf_items_ext,
+           is_response, TRUE, FALSE);
     if (tree) {
        v120len = 2 + XDLC_CONTROL_LEN(control, TRUE);
        if (tvb_bytes_exist(tvb, v120len, 1))
@@ -204,6 +243,42 @@ proto_register_v120(void)
        { &hf_v120_control,
          { "Control Field", "v120.control", FT_UINT16, BASE_HEX, NULL, 0x0,
                "", HFILL }},
+       { &hf_v120_n_r,
+           { "N(R)", "v120.control.n_r", FT_UINT16, BASE_DEC,
+               NULL, XDLC_N_R_EXT_MASK, "", HFILL }},
+       { &hf_v120_n_s,
+           { "N(S)", "v120.control.n_s", FT_UINT16, BASE_DEC,
+               NULL, XDLC_N_S_EXT_MASK, "", HFILL }},
+       { &hf_v120_p,
+           { "Poll", "v120.control.p", FT_BOOLEAN, 8,
+               TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+       { &hf_v120_p_ext,
+           { "Poll", "v120.control.p", FT_BOOLEAN, 16,
+               TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
+       { &hf_v120_f,
+           { "Final", "v120.control.f", FT_BOOLEAN, 8,
+               TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
+       { &hf_v120_f_ext,
+           { "Final", "v120.control.f", FT_BOOLEAN, 16,
+               TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
+       { &hf_v120_s_ftype,
+           { "Supervisory frame type", "v120.control.s_ftype", FT_UINT16, BASE_HEX,
+               VALS(stype_vals), XDLC_S_FTYPE_MASK, "", HFILL }},
+       { &hf_v120_u_modifier_cmd,
+           { "Command", "v120.control.u_modifier_cmd", FT_UINT8, BASE_HEX,
+               VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK, "", HFILL }},
+       { &hf_v120_u_modifier_resp,
+           { "Response", "v120.control.u_modifier_resp", FT_UINT8, BASE_HEX,
+               VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK, "", HFILL }},
+       { &hf_v120_ftype_i,
+           { "Frame type", "v120.control.ftype", FT_UINT16, BASE_HEX,
+               VALS(ftype_vals), XDLC_I_MASK, "", HFILL }},
+       { &hf_v120_ftype_s_u,
+           { "Frame type", "v120.control.ftype", FT_UINT8, BASE_HEX,
+               VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
+       { &hf_v120_ftype_s_u_ext,
+           { "Frame type", "v120.control.ftype", FT_UINT16, BASE_HEX,
+               VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
        { &hf_v120_header,
          { "Header Field", "v120.header", FT_STRING, BASE_NONE, NULL, 0x0,
                "", HFILL }},
index a0052a3661141de492e04c70365d8e14e7c20533..eb8c51e5eb3db039d433344af64d0fa356dafcae 100644 (file)
@@ -72,4 +72,4 @@ dissector_add_string, dissector_delete_string, dissector_change_string,
 dissector_reset_string, dissector_try_string, dissector_get_string_handle,
 get_datafile_path, get_tempfile_path, register_heur_dissector_list,
 dissector_try_heuristic, asn1_id_decode1, col_get_writable, col_set_writable,
-decode_enumerated_bitfield_shifted, 
+decode_enumerated_bitfield_shifted, dissect_xdlc_control, 
index 1d14c7c2f0953e849a333acc2e5f13e9a69251f5..71d21da36be5d9666f044be00c0598ad547e4b3e 100644 (file)
@@ -247,3 +247,4 @@ p_asn1_id_decode1 = pat->p_asn1_id_decode1;
 p_col_get_writable = pat->p_col_get_writable;
 p_col_set_writable = pat->p_col_set_writable;
 p_decode_enumerated_bitfield_shifted = pat->p_decode_enumerated_bitfield_shifted;
+p_dissect_xdlc_control = pat->p_dissect_xdlc_control;
index 4b86e4911d6e31a2513a59ce354e5d963ee408dd..f2cf93926386f6ae2a759b5465f7905fae192da4 100644 (file)
 #define col_get_writable (*p_col_get_writable)
 #define col_set_writable (*p_col_set_writable)
 #define decode_enumerated_bitfield_shifted (*p_decode_enumerated_bitfield_shifted)
+#define dissect_xdlc_control (*p_dissect_xdlc_control)
index 2814307964d3dcadaad7f9adc2195fa6c8739707..c865f917cb5921edc0f967f9f11e7493be94670a 100644 (file)
@@ -247,3 +247,4 @@ addr_asn1_id_decode1 p_asn1_id_decode1;
 addr_col_get_writable p_col_get_writable;
 addr_col_set_writable p_col_set_writable;
 addr_decode_enumerated_bitfield_shifted p_decode_enumerated_bitfield_shifted;
+addr_dissect_xdlc_control p_dissect_xdlc_control;
index 9d0a8da59cfc0794847080fb8195e64c0eec8a3a..660808b3221c1756445e33660ac2f963e63e40d9 100644 (file)
@@ -247,3 +247,4 @@ typedef int (*addr_asn1_id_decode1) (ASN1_SCK *, guint *);
 typedef gboolean (*addr_col_get_writable) (column_info *);
 typedef void (*addr_col_set_writable) (column_info *, gboolean);
 typedef const char *(*addr_decode_enumerated_bitfield_shifted) (guint32, guint32, int, const value_string *, const char *);
+typedef int (*addr_dissect_xdlc_control) (tvbuff_t *, int, packet_info *, proto_tree *, int, gint, const xdlc_cf_items *, const xdlc_cf_items *, int, int, int);
index 07e326ea11f812b1bcede74c047de2a2683456d9..70b666efe502b9a755364cea60e7850524fc8946 100644 (file)
@@ -1,7 +1,7 @@
 /* plugin_api_list.c
  * Used to generate various included files for plugin API
  *
- * $Id: plugin_api_list.c,v 1.19 2003/12/01 23:41:45 guy Exp $
+ * $Id: plugin_api_list.c,v 1.20 2004/01/03 03:50:38 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -37,6 +37,7 @@
 #include "packet-tcp.h"
 #include "tap.h"
 #include "asn1.h"
+#include "xdlc.h"
 #include "epan/except.h"
 
 gint check_col(column_info*, gint);
@@ -393,3 +394,8 @@ void col_set_writable(column_info *, gboolean);
 
 const char *decode_enumerated_bitfield_shifted(guint32, guint32, int,
     const value_string *, const char *);
+
+int dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
+  proto_tree *xdlc_tree, int hf_xdlc_control, gint ett_xdlc_control,
+  const xdlc_cf_items *cf_items_nonext, const xdlc_cf_items *cf_items_ext,
+  int is_response, int extended, int append_info);
diff --git a/xdlc.c b/xdlc.c
index 85bd1df3162ba3399fa6ef93a6d1a7c1113a0b07..0f492458cc1d9c852e2b621a30b073489b00c519 100644 (file)
--- a/xdlc.c
+++ b/xdlc.c
@@ -2,7 +2,7 @@
  * Routines for use by various SDLC-derived protocols, such as HDLC
  * and its derivatives LAPB, IEEE 802.2 LLC, etc..
  *
- * $Id: xdlc.c,v 1.21 2003/09/02 19:18:52 guy Exp $
+ * $Id: xdlc.c,v 1.22 2004/01/03 03:49:23 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 #include <epan/packet.h>
 #include "xdlc.h"
 
-/*
- * N(S) and N(R) fields, in basic and extended operation.
- */
-#define XDLC_N_R_MASK          0xE0    /* basic */
-#define XDLC_N_R_SHIFT         5
-#define XDLC_N_R_EXT_MASK      0xFE00  /* extended */
-#define XDLC_N_R_EXT_SHIFT     9
-#define XDLC_N_S_MASK          0x0E    /* basic */
-#define XDLC_N_S_SHIFT         1
-#define XDLC_N_S_EXT_MASK      0x00FE  /* extended */
-#define XDLC_N_S_EXT_SHIFT     1
-
-/*
- * Poll/Final bit, in basic and extended operation.
- */
-#define XDLC_P_F       0x10    /* basic */
-#define XDLC_P_F_EXT   0x0100  /* extended */
-
-/*
- * S-format frame types.
- */
-#define XDLC_S_FTYPE_MASK      0x0C
-#define XDLC_RR                        0x00    /* Receiver ready */
-#define XDLC_RNR               0x04    /* Receiver not ready */
-#define XDLC_REJ               0x08    /* Reject */
-#define XDLC_SREJ              0x0C    /* Selective reject */
+const value_string ftype_vals[] = {
+    { XDLC_I, "Information frame" },
+    { XDLC_S, "Supervisory frame" },
+    { XDLC_U, "Unnumbered frame" },
+    { 0,      NULL }
+};
 
-static const value_string stype_vals[] = {
-    { XDLC_RR,   "Receiver ready" },
-    { XDLC_RNR,  "Receiver not ready" },
-    { XDLC_REJ,  "Reject" },
-    { XDLC_SREJ, "Selective reject" },
-    { 0,         NULL }
+const value_string stype_vals[] = {
+    { XDLC_RR>>2,   "Receiver ready" },
+    { XDLC_RNR>>2,  "Receiver not ready" },
+    { XDLC_REJ>>2,  "Reject" },
+    { XDLC_SREJ>>2, "Selective reject" },
+    { 0,            NULL }
 };
 
 static const value_string modifier_short_vals_cmd[] = {
@@ -91,25 +71,25 @@ static const value_string modifier_short_vals_cmd[] = {
     { 0,          NULL }
 };
 
-static const value_string modifier_vals_cmd[] = {
-    { XDLC_UI,    "Unnumbered Information" },
-    { XDLC_UP,    "Unnumbered Poll" },
-    { XDLC_DISC,  "Disconnect" },
-    { XDLC_UA,    "Unnumbered Acknowledge" },
-    { XDLC_SNRM,  "Set Normal Response Mode" },
-    { XDLC_TEST,  "Test" },
-    { XDLC_SIM,   "Set Initialization Mode" },
-    { XDLC_FRMR,  "Frame reject" },
-    { XDLC_CFGR,  "Configure" },
-    { XDLC_SARM,  "Set Asynchronous Response Mode" },
-    { XDLC_SABM,  "Set Asynchronous Balanced Mode" },
-    { XDLC_SARME, "Set Asynchronous Response Mode Extended" },
-    { XDLC_SABME, "Set Asynchronous Balanced Mode Extended" },
-    { XDLC_RESET, "Reset" },
-    { XDLC_XID,   "Exchange identification" },
-    { XDLC_SNRME, "Set Normal Response Mode Extended" },
-    { XDLC_BCN,   "Beacon" },
-    { 0,          NULL }
+const value_string modifier_vals_cmd[] = {
+    { XDLC_UI>>2,    "Unnumbered Information" },
+    { XDLC_UP>>2,    "Unnumbered Poll" },
+    { XDLC_DISC>>2,  "Disconnect" },
+    { XDLC_UA>>2,    "Unnumbered Acknowledge" },
+    { XDLC_SNRM>>2,  "Set Normal Response Mode" },
+    { XDLC_TEST>>2,  "Test" },
+    { XDLC_SIM>>2,   "Set Initialization Mode" },
+    { XDLC_FRMR>>2,  "Frame reject" },
+    { XDLC_CFGR>>2,  "Configure" },
+    { XDLC_SARM>>2,  "Set Asynchronous Response Mode" },
+    { XDLC_SABM>>2,  "Set Asynchronous Balanced Mode" },
+    { XDLC_SARME>>2, "Set Asynchronous Response Mode Extended" },
+    { XDLC_SABME>>2, "Set Asynchronous Balanced Mode Extended" },
+    { XDLC_RESET>>2, "Reset" },
+    { XDLC_XID>>2,   "Exchange identification" },
+    { XDLC_SNRME>>2, "Set Normal Response Mode Extended" },
+    { XDLC_BCN>>2,   "Beacon" },
+    { 0,             NULL }
 };
 
 static const value_string modifier_short_vals_resp[] = {
@@ -133,25 +113,25 @@ static const value_string modifier_short_vals_resp[] = {
     { 0,          NULL }
 };
 
-static const value_string modifier_vals_resp[] = {
-    { XDLC_UI,    "Unnumbered Information" },
-    { XDLC_UP,    "Unnumbered Poll" },
-    { XDLC_RD,    "Request Disconnect" },
-    { XDLC_UA,    "Unnumbered Acknowledge" },
-    { XDLC_SNRM,  "Set Normal Response Mode" },
-    { XDLC_TEST,  "Test" },
-    { XDLC_RIM,   "Request Initialization Mode" },
-    { XDLC_FRMR,  "Frame reject" },
-    { XDLC_CFGR,  "Configure" },
-    { XDLC_DM,    "Disconnected mode" },
-    { XDLC_SABM,  "Set Asynchronous Balanced Mode" },
-    { XDLC_SARME, "Set Asynchronous Response Mode Extended" },
-    { XDLC_SABME, "Set Asynchronous Balanced Mode Extended" },
-    { XDLC_RESET, "Reset" },
-    { XDLC_XID,   "Exchange identification" },
-    { XDLC_SNRME, "Set Normal Response Mode Extended" },
-    { XDLC_BCN,   "Beacon" },
-    { 0,          NULL }
+const value_string modifier_vals_resp[] = {
+    { XDLC_UI>>2,    "Unnumbered Information" },
+    { XDLC_UP>>2,    "Unnumbered Poll" },
+    { XDLC_RD>>2,    "Request Disconnect" },
+    { XDLC_UA>>2,    "Unnumbered Acknowledge" },
+    { XDLC_SNRM>>2,  "Set Normal Response Mode" },
+    { XDLC_TEST>>2,  "Test" },
+    { XDLC_RIM>>2,   "Request Initialization Mode" },
+    { XDLC_FRMR>>2,  "Frame reject" },
+    { XDLC_CFGR>>2,  "Configure" },
+    { XDLC_DM>>2,    "Disconnected mode" },
+    { XDLC_SABM>>2,  "Set Asynchronous Balanced Mode" },
+    { XDLC_SARME>>2, "Set Asynchronous Response Mode Extended" },
+    { XDLC_SABME>>2, "Set Asynchronous Balanced Mode Extended" },
+    { XDLC_RESET>>2, "Reset" },
+    { XDLC_XID>>2,   "Exchange identification" },
+    { XDLC_SNRME>>2, "Set Normal Response Mode Extended" },
+    { XDLC_BCN>>2,   "Beacon" },
+    { 0,             NULL }
 };
 
 int
@@ -192,9 +172,14 @@ get_xdlc_control(const guchar *pd, int offset, int is_extended)
 int
 dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
   proto_tree *xdlc_tree, int hf_xdlc_control, gint ett_xdlc_control,
+  const xdlc_cf_items *cf_items_nonext, const xdlc_cf_items *cf_items_ext,
   int is_response, int is_extended, int append_info)
 {
     guint16 control;
+    int control_len;
+    const xdlc_cf_items *cf_items;
+    char *control_format;
+    guint16 poll_final;
     char info[80];
     proto_tree *tc, *control_tree;
     gchar *frame_type = NULL;
@@ -203,13 +188,20 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
     switch (tvb_get_guint8(tvb, offset) & 0x03) {
 
     case XDLC_S:
+       if (is_extended) {
+           control = tvb_get_letohs(tvb, offset);
+           control_len = 2;
+           cf_items = cf_items_ext;
+           control_format = "Control field: %s (0x%04X)";
+       } else {
+           control = tvb_get_guint8(tvb, offset);
+           control_len = 1;
+           cf_items = cf_items_nonext;
+           control_format = "Control field: %s (0x%02X)";
+       }
         /*
         * Supervisory frame.
         */
-       if (is_extended)
-               control = tvb_get_letohs(tvb, offset);
-       else
-               control = tvb_get_guint8(tvb, offset);
        switch (control & XDLC_S_FTYPE_MASK) {
        case XDLC_RR:
            frame_type = "RR";
@@ -228,14 +220,16 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
            break;
        }
        if (is_extended) {
+           poll_final = (control & XDLC_P_F_EXT);
            sprintf(info, "S%s, %sN(R) = %u", frame_type,
-                       ((control & XDLC_P_F_EXT) ?
+                       (poll_final ?
                            (is_response ? "func = F, " : "func = P, ") :
                            ""),
                        (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT);
        } else {
+           poll_final = (control & XDLC_P_F);
            sprintf(info, "S%s, %sN(R) = %u", frame_type,
-                       ((control & XDLC_P_F) ?
+                       (poll_final ?
                            (is_response ? "func = F, " : "func = P, ") :
                            ""),
                        (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT);
@@ -248,49 +242,22 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
                col_add_str(pinfo->cinfo, COL_INFO, info);
        }
        if (xdlc_tree) {
-           if (is_extended) {
-               tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
-                       offset, 2,
-                       control,
-                       "Control field: %s (0x%04X)", info, control);
-               control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
-               proto_tree_add_text(control_tree, tvb, offset, 2,
-                   decode_numeric_bitfield(control, XDLC_N_R_EXT_MASK, 2*8,
-                       "N(R) = %u"));
-               if (control & XDLC_P_F_EXT) {
-                   proto_tree_add_text(control_tree, tvb, offset, 2,
-                       decode_boolean_bitfield(control, XDLC_P_F_EXT, 2*8,
-                           (is_response ? "Final" : "Poll"), NULL));
-               }
-               proto_tree_add_text(control_tree, tvb, offset, 2,
-                   decode_enumerated_bitfield(control, XDLC_S_FTYPE_MASK, 2*8,
-                       stype_vals, "Supervisory frame - %s"));
-               /* This will always say it's a supervisory frame */
-               proto_tree_add_text(control_tree, tvb, offset, 2,
-                   decode_boolean_bitfield(control, 0x03, 2*8,
-                       "Supervisory frame", NULL));
-           } else {
-               tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
-                       offset, 1,
-                       control,
-                       "Control field: %s (0x%02X)", info, control);
-               control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
-               proto_tree_add_text(control_tree, tvb, offset, 1,
-                   decode_numeric_bitfield(control, XDLC_N_R_MASK, 1*8,
-                       "N(R) = %u"));
-               if (control & XDLC_P_F) {
-                   proto_tree_add_text(control_tree, tvb, offset, 1,
-                       decode_boolean_bitfield(control, XDLC_P_F, 1*8,
-                           (is_response ? "Final" : "Poll"), NULL));
-               }
-               proto_tree_add_text(control_tree, tvb, offset, 1,
-                   decode_enumerated_bitfield(control, XDLC_S_FTYPE_MASK, 1*8,
-                       stype_vals, "%s"));
-               /* This will always say it's a supervisory frame */
-               proto_tree_add_text(control_tree, tvb, offset, 1,
-                   decode_boolean_bitfield(control, 0x03, 1*8,
-                       "Supervisory frame", NULL));
+           tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
+               offset, control_len, control, control_format, info, control);
+           control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
+           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_r,
+               tvb, offset, control_len, control);
+           if (poll_final) {
+               proto_tree_add_boolean(control_tree,
+                       (is_response ? *cf_items->hf_xdlc_f :
+                                      *cf_items->hf_xdlc_p),
+                       tvb, offset, control_len, control);
            }
+           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_s_ftype,
+               tvb, offset, control_len, control);
+           /* This will always say it's a supervisory frame */
+           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u,
+               tvb, offset, control_len, control);
        }
        break;
 
@@ -306,6 +273,9 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
         * need for it to be 2 bytes in extended operation.
         */
        control = tvb_get_guint8(tvb, offset);
+       control_len = 1;
+       cf_items = cf_items_nonext;
+       control_format = "Control field: %s (0x%02X)";
        if (is_response) {
                modifier = match_strval(control & XDLC_U_MODIFIER_MASK,
                        modifier_short_vals_resp);
@@ -315,8 +285,9 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
        }
        if (modifier == NULL)
                modifier = "Unknown";
+       poll_final = (control & XDLC_P_F);
        sprintf(info, "U%s, func = %s",
-               ((control & XDLC_P_F) ?
+               (poll_final ?
                    (is_response ? " F" : " P") :
                    ""),
                modifier);
@@ -328,24 +299,22 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
                col_add_str(pinfo->cinfo, COL_INFO, info);
        }
        if (xdlc_tree) {
-           tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
-                       offset, 1,
-                       control,
-                       "Control field: %s (0x%02X)", info, control);
+           tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
+               offset, control_len, control, control_format, info, control);
            control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
-           if (control & XDLC_P_F) {
-               proto_tree_add_text(control_tree, tvb, offset, 2,
-                   decode_boolean_bitfield(control, XDLC_P_F, 1*8,
-                       (is_response ? "Final" : "Poll"), NULL));
+           if (poll_final) {
+               proto_tree_add_boolean(control_tree,
+                       (is_response ? *cf_items->hf_xdlc_f:
+                                      *cf_items->hf_xdlc_p),
+                       tvb, offset, control_len, control);
            }
-           proto_tree_add_text(control_tree, tvb, offset, 1,
-               decode_enumerated_bitfield(control, XDLC_U_MODIFIER_MASK, 1*8,
-                   (is_response ? modifier_vals_resp : modifier_vals_cmd),
-                   "%s"));
+           proto_tree_add_uint(control_tree,
+               (is_response ? *cf_items->hf_xdlc_u_modifier_resp :
+                              *cf_items->hf_xdlc_u_modifier_cmd),
+               tvb, offset, control_len, control);
            /* This will always say it's an unnumbered frame */
-           proto_tree_add_text(control_tree, tvb, offset, 1,
-               decode_boolean_bitfield(control, 0x03, 1*8,
-                   "Unnumbered frame", NULL));
+           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u,
+               tvb, offset, control_len, control);
        }
        break;
 
@@ -353,16 +322,22 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /*
         * Information frame.
         */
-       if (is_extended)
-               control = tvb_get_letohs(tvb, offset);
-       else
-               control = tvb_get_guint8(tvb, offset);
        if (is_extended) {
+           control = tvb_get_letohs(tvb, offset);
+           control_len = 2;
+           cf_items = cf_items_ext;
+           control_format = "Control field: %s (0x%04X)";
+           poll_final = (control & XDLC_P_F_EXT);
            sprintf(info, "I%s, N(R) = %u, N(S) = %u",
                        ((control & XDLC_P_F_EXT) ? " P" : ""),
                        (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT,
                        (control & XDLC_N_S_EXT_MASK) >> XDLC_N_S_EXT_SHIFT);
        } else {
+           control = tvb_get_guint8(tvb, offset);
+           control_len = 1;
+           cf_items = cf_items_nonext;
+           control_format = "Control field: %s (0x%02X)";
+           poll_final = (control & XDLC_P_F);
            sprintf(info, "I%s, N(R) = %u, N(S) = %u",
                        ((control & XDLC_P_F) ? " P" : ""),
                        (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT,
@@ -377,46 +352,21 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
        }
        if (xdlc_tree) {
            tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
-                       offset, (is_extended) ? 2 : 1,
-                       control,
-                       (is_extended) ? "Control field: %s (0x%04X)"
-                                     : "Control field: %s (0x%02X)",
-                       info, control);
+               offset, control_len, control, control_format, info, control);
            control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
-           if (is_extended) {
-               proto_tree_add_text(control_tree, tvb, offset, 2,
-                   decode_numeric_bitfield(control, XDLC_N_R_EXT_MASK, 2*8,
-                               "N(R) = %u"));
-               proto_tree_add_text(control_tree, tvb, offset, 2,
-                   decode_numeric_bitfield(control, XDLC_N_S_EXT_MASK, 2*8,
-                               "N(S) = %u"));
-               if (control & XDLC_P_F_EXT) {
-                   proto_tree_add_text(control_tree, tvb, offset, 2,
-                       decode_boolean_bitfield(control, XDLC_P_F_EXT, 2*8,
-                               "Poll", NULL));
-               }
-               /* This will always say it's an information frame */
-               proto_tree_add_text(control_tree, tvb, offset, 2,
-                   decode_boolean_bitfield(control, 0x01, 2*8,
-                       NULL, "Information frame"));
-           } else {
-               proto_tree_add_text(control_tree, tvb, offset, 1,
-                   decode_numeric_bitfield(control, XDLC_N_R_MASK, 1*8,
-                               "N(R) = %u"));
-               proto_tree_add_text(control_tree, tvb, offset, 1,
-                   decode_numeric_bitfield(control, XDLC_N_S_MASK, 1*8,
-                               "N(S) = %u"));
-               if (control & XDLC_P_F) {
-                   proto_tree_add_text(control_tree, tvb, offset, 1,
-                       decode_boolean_bitfield(control, XDLC_P_F, 1*8,
-                               "Poll", NULL));
-               }
-               /* This will always say it's an information frame */
-               proto_tree_add_text(control_tree, tvb, offset, 1,
-                   decode_boolean_bitfield(control, 0x01, 1*8,
-                       NULL, "Information frame"));
+           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_r,
+               tvb, offset, control_len, control);
+           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_s,
+               tvb, offset, control_len, control);
+           if (poll_final) {
+               proto_tree_add_boolean(control_tree, *cf_items->hf_xdlc_p,
+                       tvb, offset, control_len, control);
            }
+           /* This will always say it's an information frame */
+           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_i,
+               tvb, offset, control_len, control);
        }
+       break;
     }
     return control;
 }
diff --git a/xdlc.h b/xdlc.h
index 376eaf595002429b40f7fa4c647cfd2e6ece385a..7b4c30f923a98eca5feb4fe1bcdd7b9ad2639174 100644 (file)
--- a/xdlc.h
+++ b/xdlc.h
@@ -2,13 +2,12 @@
  * Define *DLC frame types, and routine to dissect the control field of
  * a *DLC frame.
  *
- * $Id: xdlc.h,v 1.18 2003/09/02 19:18:52 guy Exp $
+ * $Id: xdlc.h,v 1.19 2004/01/03 03:49:23 guy Exp $
  *
  * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
  * Copyright 1998 Gerald Combs
  *
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * Low-order bits of first (extended) or only (basic) octet of control
  * field, specifying the frame type.
  */
-#define XDLC_I         0x00    /* Information frames */
-#define XDLC_S         0x01    /* Supervisory frames */
-#define XDLC_U         0x03    /* Unnumbered frames */
+#define XDLC_I_MASK            0x01    /* Mask to test for I or not I */
+#define XDLC_I                 0x00    /* Information frames */
+#define XDLC_S_U_MASK          0x03    /* Mask to test for S or U */
+#define XDLC_S                 0x01    /* Supervisory frames */
+#define XDLC_U                 0x03    /* Unnumbered frames */
+
+/*
+ * N(S) and N(R) fields, in basic and extended operation.
+ */
+#define XDLC_N_R_MASK          0xE0    /* basic */
+#define XDLC_N_R_SHIFT         5
+#define XDLC_N_R_EXT_MASK      0xFE00  /* extended */
+#define XDLC_N_R_EXT_SHIFT     9
+#define XDLC_N_S_MASK          0x0E    /* basic */
+#define XDLC_N_S_SHIFT         1
+#define XDLC_N_S_EXT_MASK      0x00FE  /* extended */
+#define XDLC_N_S_EXT_SHIFT     1
+
+/*
+ * Poll/Final bit, in basic and extended operation.
+ */
+#define XDLC_P_F       0x10    /* basic */
+#define XDLC_P_F_EXT   0x0100  /* extended */
+
+/*
+ * S-format frame types.
+ */
+#define XDLC_S_FTYPE_MASK      0x0C
+#define XDLC_RR                        0x00    /* Receiver ready */
+#define XDLC_RNR               0x04    /* Receiver not ready */
+#define XDLC_REJ               0x08    /* Reject */
+#define XDLC_SREJ              0x0C    /* Selective reject */
 
 /*
  * U-format modifiers.
@@ -68,7 +96,7 @@
  * e.g. TEST frames.
  */
 #define XDLC_IS_INFORMATION(control) \
-       (((control) & 0x1) == XDLC_I || (control) == (XDLC_UI|XDLC_U))
+       (((control) & XDLC_I_MASK) == XDLC_I || (control) == (XDLC_UI|XDLC_U))
 
 /*
  * This macro takes the control field of an xDLC frame, and a flag saying
  * in extended mode, it's 1 byte long, otherwise it's 2 bytes long).
  */
 #define XDLC_CONTROL_LEN(control, is_extended) \
-       ((((control) & 0x3) == XDLC_U || !(is_extended)) ? 1 : 2)
+       ((((control) & XDLC_S_U_MASK) == XDLC_U || !(is_extended)) ? 1 : 2)
+
+/*
+ * Structure containing pointers to hf_ values for various subfields of
+ * the control field.
+ */
+typedef struct {
+       int     *hf_xdlc_n_r;
+       int     *hf_xdlc_n_s;
+       int     *hf_xdlc_p;
+       int     *hf_xdlc_f;
+       int     *hf_xdlc_s_ftype;
+       int     *hf_xdlc_u_modifier_cmd;
+       int     *hf_xdlc_u_modifier_resp;
+       int     *hf_xdlc_ftype_i;
+       int     *hf_xdlc_ftype_s_u;
+} xdlc_cf_items;
+
+extern const value_string ftype_vals[];
+extern const value_string stype_vals[];
+extern const value_string modifier_vals_cmd[];
+extern const value_string modifier_vals_resp[];
 
-int get_xdlc_control(const guchar *pd, int offset,
-  int extended);
+extern int get_xdlc_control(const guchar *pd, int offset, int extended);
 
-int dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
+extern int dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
   proto_tree *xdlc_tree, int hf_xdlc_control, gint ett_xdlc_control,
+  const xdlc_cf_items *cf_items_nonext, const xdlc_cf_items *cf_items_ext,
   int is_response, int extended, int append_info);
 
 #endif