From 4f9707469dc6edb8792ec811fecebb0f377fc58b Mon Sep 17 00:00:00 2001 From: Michael Mann Date: Tue, 25 Sep 2012 01:00:41 +0000 Subject: replaced decode_boolean_bitfield calls with itemized filters added tfs_no_yes to tfs.[ch] svn path=/trunk/; revision=45115 --- epan/dissectors/packet-v120.c | 291 ++++++++++++++++++++++++------------------ 1 file changed, 170 insertions(+), 121 deletions(-) (limited to 'epan/dissectors/packet-v120.c') diff --git a/epan/dissectors/packet-v120.c b/epan/dissectors/packet-v120.c index f4390ad7ca..de57c9ba67 100644 --- a/epan/dissectors/packet-v120.c +++ b/epan/dissectors/packet-v120.c @@ -32,6 +32,10 @@ static int proto_v120 = -1; static int hf_v120_address = -1; +static int hf_v120_rc = -1; +static int hf_v120_lli = -1; +static int hf_v120_ea0 = -1; +static int hf_v120_ea1 = -1; static int hf_v120_control = -1; static int hf_v120_n_r = -1; static int hf_v120_n_s = -1; @@ -45,7 +49,22 @@ 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 int hf_v120_header8 = -1; +static int hf_v120_header_ext8 = -1; +static int hf_v120_header_break8 = -1; +static int hf_v120_header_error_control8 = -1; +static int hf_v120_header_segb8 = -1; +static int hf_v120_header_segf8 = -1; +static int hf_v120_header16 = -1; +static int hf_v120_header_ext16 = -1; +static int hf_v120_header_break16 = -1; +static int hf_v120_header_error_control16 = -1; +static int hf_v120_header_segb16 = -1; +static int hf_v120_header_segf16 = -1; +static int hf_v120_header_e = -1; +static int hf_v120_header_dr = -1; +static int hf_v120_header_sr = -1; +static int hf_v120_header_rr = -1; static gint ett_v120 = -1; static gint ett_v120_address = -1; @@ -54,6 +73,9 @@ static gint ett_v120_header = -1; static dissector_handle_t data_handle; +static const true_false_string tfs_response_command = { "Response", "Command" }; +static const true_false_string tfs_segmentation_no_segmentation = { "Segmentation", "No segmentation" }; + static int dissect_v120_header(tvbuff_t *tvb, int offset, proto_tree *tree); /* Used only for U frames */ @@ -85,143 +107,113 @@ static const xdlc_cf_items v120_cf_items_ext = { static void dissect_v120(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - proto_tree *v120_tree, *tc, *address_tree; - proto_item *ti; - int is_response; - int addr; - char *info; - int v120len; - guint8 byte0, byte1; - guint16 control; - tvbuff_t *next_tvb; + proto_tree *v120_tree, *address_tree; + proto_item *ti, *tc; + int is_response; + int v120len; + guint8 byte0, byte1; + guint16 control; + tvbuff_t *next_tvb; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "V.120"); + col_clear(pinfo->cinfo, COL_INFO); - info=ep_alloc(80); - col_set_str(pinfo->cinfo, COL_PROTOCOL, "V.120"); - col_clear(pinfo->cinfo, COL_INFO); + byte0 = tvb_get_guint8(tvb, 0); - byte0 = tvb_get_guint8(tvb, 0); + if(check_col(pinfo->cinfo, COL_RES_DL_SRC)) + col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "0x%02X", byte0); - if(check_col(pinfo->cinfo, COL_RES_DL_SRC)) - col_add_fstr(pinfo->cinfo, COL_RES_DL_SRC, "0x%02X", byte0); + byte1 = tvb_get_guint8(tvb, 1); + + if ( ((byte0 & 0x01) != 0x00) && ((byte1 & 0x01) != 0x01) ) + { + col_set_str(pinfo->cinfo, COL_INFO, "Invalid V.120 frame"); + if (tree) + proto_tree_add_protocol_format(tree, proto_v120, tvb, 0, -1, + "Invalid V.120 frame"); + return; + } - byte1 = tvb_get_guint8(tvb, 1); + if (pinfo->p2p_dir == P2P_DIR_SENT) { + is_response = (byte0 & 0x02) ? FALSE: TRUE; + col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE"); + col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE"); + } else { + /* XXX - what if the direction is unknown? */ + is_response = (byte0 & 0x02) ? TRUE : FALSE; + col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE"); + col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE"); + } - if ( ((byte0 & 0x01) != 0x00) && ((byte1 & 0x01) != 0x01) ) - { - col_set_str(pinfo->cinfo, COL_INFO, "Invalid V.120 frame"); - if (tree) - proto_tree_add_protocol_format(tree, proto_v120, tvb, 0, -1, - "Invalid V.120 frame"); - return; - } + if (tree) { + ti = proto_tree_add_protocol_format(tree, proto_v120, tvb, 0, -1, "V.120"); + v120_tree = proto_item_add_subtree(ti, ett_v120); + tc = proto_tree_add_item(v120_tree, hf_v120_address, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_item_append_text(tc, "LLI: %d C/R: %s", + ((byte0 & 0xfc) << 5) | ((byte1 & 0xfe) >> 1), + byte0 & 0x02 ? "R" : "C"); + address_tree = proto_item_add_subtree(tc, ett_v120_address); - if (pinfo->p2p_dir == P2P_DIR_SENT) { - is_response = (byte0 & 0x02) ? FALSE: TRUE; - col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE"); - col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE"); - } else { - /* XXX - what if the direction is unknown? */ - is_response = (byte0 & 0x02) ? TRUE : FALSE; - col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE"); - col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE"); - } + proto_tree_add_item(address_tree, hf_v120_rc, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(address_tree, hf_v120_lli, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(address_tree, hf_v120_ea0, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(address_tree, hf_v120_ea1, tvb, 0, 2, ENC_BIG_ENDIAN); + } + else { + v120_tree = NULL; + ti = NULL; + } + control = dissect_xdlc_control(tvb, 2, pinfo, v120_tree, hf_v120_control, + ett_v120_control, &v120_cf_items, &v120_cf_items_ext, + NULL, NULL, is_response, TRUE, FALSE); + if (tree) { + v120len = 2 + XDLC_CONTROL_LEN(control, TRUE); - if (tree) { - ti = proto_tree_add_protocol_format(tree, proto_v120, tvb, 0, -1, "V.120"); - v120_tree = proto_item_add_subtree(ti, ett_v120); - addr = byte1 << 8 | byte0; - g_snprintf(info, 80, "LLI: %d C/R: %s", - ((byte0 & 0xfc) << 5) | ((byte1 & 0xfe) >> 1), - byte0 & 0x02 ? "R" : "C"); - tc = proto_tree_add_text(v120_tree, tvb, - 0, 2, - "Address field: %s", info); - address_tree = proto_item_add_subtree(tc, ett_v120_address); - proto_tree_add_text(address_tree, tvb, 0, 2, "%s", - decode_boolean_bitfield(addr, 0x0002, 2*8, - "Response", "Command")); - g_snprintf(info, 80, "LLI: %d", ((byte0 & 0xfc) << 5) | ((byte1 & 0xfe) >> 1)); - proto_tree_add_text(address_tree, tvb, 0, 2, "%s", - decode_numeric_bitfield(addr, 0xfefc, 2*8, info)); - proto_tree_add_text(address_tree, tvb, 0, 2, "%s", - decode_boolean_bitfield(addr, 0x0001, 2*8, - "EA0 = 1 (Error)", "EA0 = 0")); - proto_tree_add_text(address_tree, tvb, 0, 2, "%s", - decode_boolean_bitfield(addr, 0x0100, 2*8, - "EA1 = 1", "EA1 = 0 (Error)")); - } - else { - v120_tree = NULL; - ti = NULL; - } - control = dissect_xdlc_control(tvb, 2, pinfo, v120_tree, hf_v120_control, - ett_v120_control, &v120_cf_items, &v120_cf_items_ext, - NULL, NULL, is_response, TRUE, FALSE); - if (tree) { - v120len = 2 + XDLC_CONTROL_LEN(control, TRUE); - if (tvb_bytes_exist(tvb, v120len, 1)) - v120len += dissect_v120_header(tvb, v120len, v120_tree); - proto_item_set_len(ti, v120len); - next_tvb = tvb_new_subset_remaining(tvb, v120len); - call_dissector(data_handle,next_tvb, pinfo, v120_tree); - } + if (tvb_bytes_exist(tvb, v120len, 1)) + v120len += dissect_v120_header(tvb, v120len, v120_tree); + proto_item_set_len(ti, v120len); + next_tvb = tvb_new_subset_remaining(tvb, v120len); + call_dissector(data_handle,next_tvb, pinfo, v120_tree); + } } static int dissect_v120_header(tvbuff_t *tvb, int offset, proto_tree *tree) { - char *info; - int header_len, nbits; - int header; - proto_tree *h_tree, *tc; - guint8 byte0; + int header_len; + guint8 byte0; + proto_tree *h_tree; + proto_item *tc; - info=ep_alloc(80); byte0 = tvb_get_guint8(tvb, offset); - if (byte0 & 0x80) { header_len = 1; - header = byte0; + tc = proto_tree_add_item(tree, hf_v120_header8, tvb, 0, 1, ENC_NA); + + h_tree = proto_item_add_subtree(tc, ett_v120_header); + proto_tree_add_item(h_tree, hf_v120_header_ext8, tvb, 0, 1, ENC_NA); + proto_tree_add_item(h_tree, hf_v120_header_break8, tvb, 0, 1, ENC_NA); + proto_tree_add_item(h_tree, hf_v120_header_error_control8, tvb, 0, 1, ENC_NA); + proto_tree_add_item(h_tree, hf_v120_header_segb8, tvb, 0, 1, ENC_NA); + proto_tree_add_item(h_tree, hf_v120_header_segf8, tvb, 0, 1, ENC_NA); } else { header_len = 2; - header = byte0 | tvb_get_guint8(tvb, offset + 1) << 8; - } - nbits = header_len * 8; - g_snprintf(info, 80, "Header: B: %d F: %d", byte0 & 0x02 ? 1:0, - byte0 & 0x01 ? 1:0); - tc = proto_tree_add_text(tree, tvb, - offset, header_len, - "Header octet: %s (0x%02X)", info, byte0); - h_tree = proto_item_add_subtree(tc, ett_v120_header); - proto_tree_add_text(h_tree, tvb, offset, header_len, "%s", - decode_boolean_bitfield(header, 0x80, nbits, - "No extension octet", "Extension octet follows")); - proto_tree_add_text(h_tree, tvb, offset, header_len, "%s", - decode_boolean_bitfield(header, 0x40, nbits, - "Break condition", "No break condition")); - g_snprintf(info, 80, "Error control C1/C2: %d", (header & 0x0c) >> 2); - proto_tree_add_text(h_tree, tvb, offset, header_len, "%s", - decode_numeric_bitfield(header, 0x0c, nbits, info)); - proto_tree_add_text(h_tree, tvb, offset, header_len, "%s", - decode_boolean_bitfield(header, 0x02, nbits, - "Segmentation bit B", "No segmentation bit B")); - proto_tree_add_text(h_tree, tvb, offset, header_len, "%s", - decode_boolean_bitfield(header, 0x01, nbits, - "Segmentation bit F", "No segmentation bit F")); - if (header_len == 2) { - proto_tree_add_text(h_tree, tvb, offset, header_len, - decode_boolean_bitfield(header, 0x8000, nbits, - "E", "E bit not set (Error)"), NULL); - proto_tree_add_text(h_tree, tvb, offset, header_len, - decode_boolean_bitfield(header, 0x4000, nbits, - "DR", "No DR"), NULL); - proto_tree_add_text(h_tree, tvb, offset, header_len, - decode_boolean_bitfield(header, 0x2000, nbits, - "SR", "No SR"), NULL); - proto_tree_add_text(h_tree, tvb, offset, header_len, - decode_boolean_bitfield(header, 0x1000, nbits, - "RR", "No RR"), NULL); + tc = proto_tree_add_item(tree, hf_v120_header16, tvb, 0, 2, ENC_BIG_ENDIAN); + h_tree = proto_item_add_subtree(tc, ett_v120_header); + proto_tree_add_item(h_tree, hf_v120_header_ext16, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(h_tree, hf_v120_header_break16, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(h_tree, hf_v120_header_error_control16, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(h_tree, hf_v120_header_segb16, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(h_tree, hf_v120_header_segf16, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(h_tree, hf_v120_header_e, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(h_tree, hf_v120_header_dr, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(h_tree, hf_v120_header_sr, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(h_tree, hf_v120_header_rr, tvb, 0, 2, ENC_BIG_ENDIAN); } + + proto_item_append_text(tc, " B: %d F: %d", + byte0 & 0x02 ? 1:0, byte0 & 0x01 ? 1:0); + return header_len; } @@ -232,6 +224,18 @@ proto_register_v120(void) { &hf_v120_address, { "Link Address", "v120.address", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_v120_rc, + { "R/C", "v120.rc", FT_BOOLEAN, 16, TFS(&tfs_response_command), + 0x0002, NULL, HFILL }}, + { &hf_v120_lli, + { "LLI", "v120.lli", FT_UINT16, BASE_HEX, NULL, + 0xfefc, NULL, HFILL }}, + { &hf_v120_ea0, + { "EA0", "v120.ea0", FT_BOOLEAN, 16, TFS(&tfs_error_ok), + 0x0001, NULL, HFILL }}, + { &hf_v120_ea1, + { "EA1", "v120.ea1", FT_BOOLEAN, 16, TFS(&tfs_ok_error), + 0x0100, NULL, HFILL }}, { &hf_v120_control, { "Control Field", "v120.control", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, @@ -271,8 +275,53 @@ proto_register_v120(void) { &hf_v120_ftype_s_u_ext, { "Frame type", "v120.control.ftype", FT_UINT16, BASE_HEX, VALS(ftype_vals), XDLC_S_U_MASK, NULL, HFILL }}, - { &hf_v120_header, - { "Header Field", "v120.header", FT_STRING, BASE_NONE, NULL, 0x0, + { &hf_v120_header8, + { "Header", "v120.header", FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + { &hf_v120_header_ext8, + { "Extension octet", "v120.header.ext", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80, + NULL, HFILL }}, + { &hf_v120_header_break8, + { "Break condition", "v120.header.break", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40, + NULL, HFILL }}, + { &hf_v120_header_error_control8, + { "Error control C1/C2", "v120.error_control", FT_UINT8, BASE_HEX, NULL, 0x0C, + NULL, HFILL }}, + { &hf_v120_header_segb8, + { "Bit B", "v120.header.segb", FT_BOOLEAN, 8, TFS(&tfs_segmentation_no_segmentation), 0x02, + NULL, HFILL }}, + { &hf_v120_header_segf8, + { "Bit F", "v120.header.segf", FT_BOOLEAN, 8, TFS(&tfs_segmentation_no_segmentation), 0x01, + NULL, HFILL }}, + { &hf_v120_header16, + { "Header", "v120.header", FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + { &hf_v120_header_ext16, + { "Extension octet", "v120.header.ext", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x80, + NULL, HFILL }}, + { &hf_v120_header_break16, + { "Break condition", "v120.header.break", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x40, + NULL, HFILL }}, + { &hf_v120_header_error_control16, + { "Error control C1/C2", "v120.error_control", FT_UINT16, BASE_HEX, NULL, 0x0C, + NULL, HFILL }}, + { &hf_v120_header_segb16, + { "Bit B", "v120.header.segb", FT_BOOLEAN, 16, TFS(&tfs_segmentation_no_segmentation), 0x02, + NULL, HFILL }}, + { &hf_v120_header_segf16, + { "Bit F", "v120.header.segf", FT_BOOLEAN, 16, TFS(&tfs_segmentation_no_segmentation), 0x01, + NULL, HFILL }}, + { &hf_v120_header_e, + { "E", "v120.header.e", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x8000, + NULL, HFILL }}, + { &hf_v120_header_dr, + { "DR", "v120.header.dr", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x4000, + NULL, HFILL }}, + { &hf_v120_header_sr, + { "SR", "v120.header.sr", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x2000, + NULL, HFILL }}, + { &hf_v120_header_rr, + { "RR", "v120.header.rr", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x1000, NULL, HFILL }}, }; static gint *ett[] = { -- cgit v1.2.3