aboutsummaryrefslogtreecommitdiffstats
path: root/xdlc.c
diff options
context:
space:
mode:
Diffstat (limited to 'xdlc.c')
-rw-r--r--xdlc.c302
1 files changed, 126 insertions, 176 deletions
diff --git a/xdlc.c b/xdlc.c
index 85bd1df316..0f492458cc 100644
--- 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>
@@ -34,39 +34,19 @@
#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;
}