* Routines for use by various SDLC-derived protocols, such as HDLC
* and its derivatives LAPB, IEEE 802.2 LLC, etc..
*
- * $Id$
- *
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
#include <glib.h>
#include <epan/packet.h>
#include <epan/xdlc.h>
-#include <epan/emem.h>
+#include <wsutil/pint.h>
const value_string ftype_vals[] = {
{ XDLC_I, "Information frame" },
case XDLC_S:
default:
/*
- * Supervisory or Information frame.
- */
- if (is_extended)
- control = pletohs(&pd[offset]);
- else
- control = pd[offset];
- break;
+ * Supervisory or Information frame.
+ */
+ if (is_extended)
+ control = pletoh16(&pd[offset]);
+ else
+ control = pd[offset];
+ break;
case XDLC_U:
- /*
- * Unnumbered frame.
- *
- * XXX - is this two octets, with a P/F bit, in HDLC extended
- * operation? It's one octet in LLC, even though the control
- * field of I and S frames is a 2-byte extended-operation field
- * in LLC. Given that there are no sequence numbers in the
- * control field of a U frame, there doesn't appear to be any
- * need for it to be 2 bytes in extended operation.
- */
- control = pd[offset];
- break;
- }
- return control;
-}
-
-/*
- * Check whether the control field of the packet looks valid.
- */
-gboolean
-check_xdlc_control(tvbuff_t *tvb, int offset,
- const value_string *u_modifier_short_vals_cmd,
- const value_string *u_modifier_short_vals_resp, gboolean is_response,
- gboolean is_extended _U_)
-{
- guint16 control;
-
- if (!tvb_bytes_exist(tvb, offset, 1))
- return FALSE; /* not enough data to check */
- switch (tvb_get_guint8(tvb, offset) & 0x03) {
-
- case XDLC_S:
/*
- * Supervisory frame.
- * No fields to check for validity here.
- */
- return TRUE;
-
- case XDLC_U:
- /*
- * Unnumbered frame.
- *
- * XXX - is this two octets, with a P/F bit, in HDLC extended
- * operation? It's one octet in LLC, even though the control
- * field of I and S frames is a 2-byte extended-operation field
- * in LLC. Given that there are no sequence numbers in the
- * control field of a U frame, there doesn't appear to be any
- * need for it to be 2 bytes in extended operation.
- */
- if (u_modifier_short_vals_cmd == NULL)
- u_modifier_short_vals_cmd = modifier_short_vals_cmd;
- if (u_modifier_short_vals_resp == NULL)
- u_modifier_short_vals_resp = modifier_short_vals_resp;
- control = tvb_get_guint8(tvb, offset);
- if (is_response) {
- if (match_strval(control & XDLC_U_MODIFIER_MASK,
- u_modifier_short_vals_resp) == NULL)
- return FALSE; /* unknown modifier */
- } else {
- if (match_strval(control & XDLC_U_MODIFIER_MASK,
- u_modifier_short_vals_cmd) == NULL)
- return FALSE; /* unknown modifier */
- }
- return TRUE;
-
- default:
- /*
- * Information frame.
- * No fields to check for validity here.
- */
- return TRUE;
+ * Unnumbered frame.
+ *
+ * XXX - is this two octets, with a P/F bit, in HDLC extended
+ * operation? It's one octet in LLC, even though the control
+ * field of I and S frames is a 2-byte extended-operation field
+ * in LLC. Given that there are no sequence numbers in the
+ * control field of a U frame, there doesn't appear to be any
+ * need for it to be 2 bytes in extended operation.
+ */
+ control = pd[offset];
+ break;
}
+ return control;
}
int
const gchar *frame_type = NULL;
const gchar *modifier;
- info=(char *)ep_alloc(80);
+ info=(char *)wmem_alloc(wmem_packet_scope(), 80);
switch (tvb_get_guint8(tvb, offset) & 0x03) {
case XDLC_S:
/*
- * Supervisory frame.
- */
- 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)";
- }
- switch (control & XDLC_S_FTYPE_MASK) {
- case XDLC_RR:
- frame_type = "RR";
- break;
+ * Supervisory frame.
+ */
+ 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)";
+ }
+ switch (control & XDLC_S_FTYPE_MASK) {
+ case XDLC_RR:
+ frame_type = "RR";
+ break;
- case XDLC_RNR:
- frame_type = "RNR";
- break;
+ case XDLC_RNR:
+ frame_type = "RNR";
+ break;
- case XDLC_REJ:
- frame_type = "REJ";
- break;
+ case XDLC_REJ:
+ frame_type = "REJ";
+ break;
- case XDLC_SREJ:
- frame_type = "SREJ";
- break;
- }
- if (is_extended) {
- poll_final = (control & XDLC_P_F_EXT);
- g_snprintf(info, 80, "S%s, func=%s, N(R)=%u",
- (poll_final ?
- (is_response ? " F" : " P") :
- ""),
- frame_type,
- (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT);
- } else {
- poll_final = (control & XDLC_P_F);
- g_snprintf(info, 80, "S%s, func=%s, N(R)=%u",
- (poll_final ?
- (is_response ? " F" : " P") :
- ""),
- frame_type,
- (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT);
- }
- if (check_col(pinfo->cinfo, COL_INFO)) {
- if (append_info) {
- col_append_str(pinfo->cinfo, COL_INFO, ", ");
- col_append_str(pinfo->cinfo, COL_INFO, info);
- } else
- col_add_str(pinfo->cinfo, COL_INFO, info);
- }
- if (xdlc_tree) {
- 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;
+ case XDLC_SREJ:
+ frame_type = "SREJ";
+ break;
+ }
+ if (is_extended) {
+ poll_final = (control & XDLC_P_F_EXT);
+ g_snprintf(info, 80, "S%s, func=%s, N(R)=%u",
+ (poll_final ?
+ (is_response ? " F" : " P") :
+ ""),
+ frame_type,
+ (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT);
+ } else {
+ poll_final = (control & XDLC_P_F);
+ g_snprintf(info, 80, "S%s, func=%s, N(R)=%u",
+ (poll_final ?
+ (is_response ? " F" : " P") :
+ ""),
+ frame_type,
+ (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT);
+ }
+ if (append_info) {
+ col_append_str(pinfo->cinfo, COL_INFO, ", ");
+ col_append_str(pinfo->cinfo, COL_INFO, info);
+ } else {
+ col_add_str(pinfo->cinfo, COL_INFO, info);
+ }
+ if (xdlc_tree) {
+ 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;
case XDLC_U:
- /*
- * Unnumbered frame.
- *
- * XXX - is this two octets, with a P/F bit, in HDLC extended
- * operation? It's one octet in LLC, even though the control
- * field of I and S frames is a 2-byte extended-operation field
- * in LLC. Given that there are no sequence numbers in the
- * control field of a U frame, there doesn't appear to be any
- * need for it to be 2 bytes in extended operation.
- */
- if (u_modifier_short_vals_cmd == NULL)
- u_modifier_short_vals_cmd = modifier_short_vals_cmd;
- if (u_modifier_short_vals_resp == NULL)
- u_modifier_short_vals_resp = modifier_short_vals_resp;
- 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 = val_to_str(control & XDLC_U_MODIFIER_MASK,
- u_modifier_short_vals_resp, "Unknown");
- } else {
- modifier = val_to_str(control & XDLC_U_MODIFIER_MASK,
- u_modifier_short_vals_cmd, "Unknown");
- }
- poll_final = (control & XDLC_P_F);
- g_snprintf(info, 80, "U%s, func=%s",
- (poll_final ?
- (is_response ? " F" : " P") :
- ""),
- modifier);
- if (check_col(pinfo->cinfo, COL_INFO)) {
- if (append_info) {
- col_append_str(pinfo->cinfo, COL_INFO, ", ");
- col_append_str(pinfo->cinfo, COL_INFO, info);
- } else
- col_add_str(pinfo->cinfo, COL_INFO, info);
- }
- if (xdlc_tree) {
- 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 (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,
- (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_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u,
- tvb, offset, control_len, control);
- }
- break;
+ /*
+ * Unnumbered frame.
+ *
+ * XXX - is this two octets, with a P/F bit, in HDLC extended
+ * operation? It's one octet in LLC, even though the control
+ * field of I and S frames is a 2-byte extended-operation field
+ * in LLC. Given that there are no sequence numbers in the
+ * control field of a U frame, there doesn't appear to be any
+ * need for it to be 2 bytes in extended operation.
+ */
+ if (u_modifier_short_vals_cmd == NULL)
+ u_modifier_short_vals_cmd = modifier_short_vals_cmd;
+ if (u_modifier_short_vals_resp == NULL)
+ u_modifier_short_vals_resp = modifier_short_vals_resp;
+ 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 = val_to_str(control & XDLC_U_MODIFIER_MASK,
+ u_modifier_short_vals_resp, "Unknown");
+ } else {
+ modifier = val_to_str(control & XDLC_U_MODIFIER_MASK,
+ u_modifier_short_vals_cmd, "Unknown");
+ }
+ poll_final = (control & XDLC_P_F);
+ g_snprintf(info, 80, "U%s, func=%s",
+ (poll_final ?
+ (is_response ? " F" : " P") :
+ ""),
+ modifier);
+ if (append_info) {
+ col_append_str(pinfo->cinfo, COL_INFO, ", ");
+ col_append_str(pinfo->cinfo, COL_INFO, info);
+ } else {
+ col_add_str(pinfo->cinfo, COL_INFO, info);
+ }
+ if (xdlc_tree) {
+ 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 (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,
+ (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_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u,
+ tvb, offset, control_len, control);
+ }
+ break;
default:
- /*
- * Information frame.
- */
- 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);
- g_snprintf(info, 80, "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);
- g_snprintf(info, 80, "I%s, N(R)=%u, N(S)=%u",
- ((control & XDLC_P_F) ? " P" : ""),
- (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT,
- (control & XDLC_N_S_MASK) >> XDLC_N_S_SHIFT);
- }
- if (check_col(pinfo->cinfo, COL_INFO)) {
- if (append_info) {
- col_append_str(pinfo->cinfo, COL_INFO, ", ");
- col_append_str(pinfo->cinfo, COL_INFO, info);
- } else
- col_add_str(pinfo->cinfo, COL_INFO, info);
- }
- if (xdlc_tree) {
- 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);
- 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;
+ /*
+ * Information frame.
+ */
+ 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);
+ g_snprintf(info, 80, "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);
+ g_snprintf(info, 80, "I%s, N(R)=%u, N(S)=%u",
+ ((control & XDLC_P_F) ? " P" : ""),
+ (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT,
+ (control & XDLC_N_S_MASK) >> XDLC_N_S_SHIFT);
+ }
+ if (append_info) {
+ col_append_str(pinfo->cinfo, COL_INFO, ", ");
+ col_append_str(pinfo->cinfo, COL_INFO, info);
+ } else {
+ col_add_str(pinfo->cinfo, COL_INFO, info);
+ }
+ if (xdlc_tree) {
+ 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);
+ 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;
}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */