From 380dbe41d03730947ec9c3057c3088c369df278a Mon Sep 17 00:00:00 2001 From: Alexis La Goutte Date: Sun, 4 Dec 2011 18:40:19 +0000 Subject: Enhance Elcom dissector Fix indent and update modelines svn path=/trunk/; revision=40092 --- epan/dissectors/packet-elcom.c | 1173 ++++++++++++++++++++-------------------- 1 file changed, 589 insertions(+), 584 deletions(-) (limited to 'epan/dissectors/packet-elcom.c') diff --git a/epan/dissectors/packet-elcom.c b/epan/dissectors/packet-elcom.c index 06e36e16e2..fdaa907b46 100644 --- a/epan/dissectors/packet-elcom.c +++ b/epan/dissectors/packet-elcom.c @@ -34,21 +34,21 @@ #include -#define TCP_PORT_ELCOM 5997 +#define TCP_PORT_ELCOM 5997 /* Application level: */ -#define A_CONRQ 0x04 -#define A_CONRS 0x05 +#define A_CONRQ 0x04 +#define A_CONRS 0x05 /* Presentation level: */ -#define P_CONRQ 0x00 -#define P_CONRS 0x10 -#define P_RELRQ 0x20 -#define P_RELRS 0x30 -#define P_DATRQ 0x80 +#define P_CONRQ 0x00 +#define P_CONRS 0x10 +#define P_RELRQ 0x20 +#define P_RELRS 0x30 +#define P_DATRQ 0x80 -#define TC_REQ 0x40 -#define TC_RSP 0x41 +#define TC_REQ 0x40 +#define TC_RSP 0x41 #define LOWADR_LEN 17 #define SUFFIX_LEN 2 @@ -162,239 +162,239 @@ static const value_string type_vals[] = { static gint dissect_lower_address(proto_item *ti_arg, gint ett_arg, - tvbuff_t *tvb, gint arg_offset, - int hf_endian, int hf_ip, int hf_port, int hf_suff) + tvbuff_t *tvb, gint arg_offset, + int hf_endian, int hf_ip, int hf_port, int hf_suff) { - gint offset = arg_offset; - guint8 len1, len2; - guint8 *suffix; - proto_tree *tree; - proto_item *ti; - - tree = proto_item_add_subtree(ti_arg, ett_arg); - - /* - * Coding of address: - * ELCOM-90 TRA3825.02 User Element conventions, p. 5-2 and Appendix G - */ - len1 = tvb_get_guint8(tvb, offset); - if (tvb_length_remaining(tvb, offset+len1+1) <= 0) - return offset; - len2 = tvb_get_guint8(tvb, offset+len1+1); - if (tvb_length_remaining(tvb, offset+len1+len2+2) <= 0) - return offset; - if ((len1 != LOWADR_LEN) || (len2 != SUFFIX_LEN)) { - proto_item_append_text(tree, " Invalid structure"); - return offset; - } - - - /* Show pre stuff */ - if (0x82 != tvb_get_guint8(tvb, offset+1)) { - proto_item_append_text(tree, " Not IPV4 address"); - return offset; - } - offset += 2; - - - /* endian */ - proto_tree_add_item(tree, hf_endian, tvb, offset, 2, ENC_BIG_ENDIAN); - offset += 2; - - /* port */ - proto_tree_add_item(tree, hf_port, tvb, offset, 2, ENC_BIG_ENDIAN); - offset += 2; - - /* ip-addr */ - proto_tree_add_item(tree, hf_ip, tvb, offset, 4, ENC_BIG_ENDIAN); - offset += 4; - - offset += 8; /* skip the zero bytes */ - - /* SUFFIX */ - suffix = tvb_get_string(tvb, offset+1, len2); - ti = proto_tree_add_item(tree, hf_suff, tvb, offset, 1, TRUE); - offset += len2+1; - - if (!(suffix[0] == 'A' || suffix[0] == 'B')) { - g_free(suffix); - proto_item_append_text(ti, " (invalid)"); - return offset; - } - - proto_item_append_text(ti, " (%s)", val_to_str(suffix[1], suffix_vals, "<<-- WHAT?") ); - - g_free(suffix); - return offset; + gint offset = arg_offset; + guint8 len1, len2; + guint8 *suffix; + proto_tree *tree; + proto_item *ti; + + tree = proto_item_add_subtree(ti_arg, ett_arg); + + /* + * Coding of address: + * ELCOM-90 TRA3825.02 User Element conventions, p. 5-2 and Appendix G + */ + len1 = tvb_get_guint8(tvb, offset); + if (tvb_length_remaining(tvb, offset+len1+1) <= 0) + return offset; + len2 = tvb_get_guint8(tvb, offset+len1+1); + if (tvb_length_remaining(tvb, offset+len1+len2+2) <= 0) + return offset; + if ((len1 != LOWADR_LEN) || (len2 != SUFFIX_LEN)) { + proto_item_append_text(tree, " Invalid structure"); + return offset; + } + + + /* Show pre stuff */ + if (0x82 != tvb_get_guint8(tvb, offset+1)) { + proto_item_append_text(tree, " Not IPV4 address"); + return offset; + } + offset += 2; + + + /* endian */ + proto_tree_add_item(tree, hf_endian, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + /* port */ + proto_tree_add_item(tree, hf_port, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + /* ip-addr */ + proto_tree_add_item(tree, hf_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + + offset += 8; /* skip the zero bytes */ + + /* SUFFIX */ + suffix = tvb_get_string(tvb, offset+1, len2); + ti = proto_tree_add_item(tree, hf_suff, tvb, offset, 1, TRUE); + offset += len2+1; + + if (!(suffix[0] == 'A' || suffix[0] == 'B')) { + g_free(suffix); + proto_item_append_text(ti, " (invalid)"); + return offset; + } + + proto_item_append_text(ti, " (%s)", val_to_str(suffix[1], suffix_vals, "<<-- WHAT?") ); + + g_free(suffix); + return offset; } static gint dissect_userdata(proto_item *ti_arg, gint ett_arg, tvbuff_t *tvb, gint arg_offset) { - gint offset = arg_offset; - guint8 flen, lenbytes; - guint8 year, month, day, hour, min, sec; - guint16 msec; - proto_tree *tree; - proto_item *ti; - - tree = proto_item_add_subtree(ti_arg, ett_arg); - - /* length of User Data, should be 1 byte field ... */ - flen = tvb_get_guint8(tvb, offset); - lenbytes = 1; - - /* ... but sometimes it seems to be 2 bytes; try to be clever */ - if (flen == 0) { - flen = tvb_get_guint8(tvb, offset+1); - lenbytes = 2; - } - if (flen == 0 || flen > 79) /* invalid */ - return offset; - - ti = proto_tree_add_item(tree, hf_elcom_userdata_length, tvb, offset, lenbytes, ENC_BIG_ENDIAN); - offset += lenbytes; - if (lenbytes == 2) { - proto_item_append_text(ti, " (2 bytes, should be 1 byte)"); - } - - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - proto_tree_add_item(tree, hf_elcom_userdata_pduid, tvb, offset, 1, ENC_BIG_ENDIAN); - offset++; - - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - proto_tree_add_item(tree, hf_elcom_userdata_version, tvb, offset, 1, ENC_BIG_ENDIAN); - offset++; - - - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - proto_tree_add_item(tree, hf_elcom_userdata_result, tvb, offset, 1, ENC_BIG_ENDIAN); - offset++; - - /* show the rest */ - /* tree2 = proto_tree_add_text(tree, tvb, offset, -1, "User Data"); */ - - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - ti = proto_tree_add_item(tree, hf_elcom_userdata_restmark, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_item_append_text(ti, " <-- '0' = no restart etc."); - offset +=1; - - if (tvb_length_remaining(tvb, offset+8) <= 0) - return offset; - year = tvb_get_guint8(tvb, offset); - month = tvb_get_guint8(tvb, offset+1); - day = tvb_get_guint8(tvb, offset+2); - hour = tvb_get_guint8(tvb, offset+3); - min = tvb_get_guint8(tvb, offset+4); - sec = tvb_get_guint8(tvb, offset+5); - msec = tvb_get_ntohs(tvb, offset+6); - - proto_tree_add_none_format(tree, hf_elcom_userdata_cf, tvb, offset, 8, - "Control Field: %4d-%02d-%02d %02d:%02d:%02d.%d", - year+1900, month, day, hour, min, sec, msec); - - offset += 12; - if (tvb_length_remaining(tvb, offset+12) > 0) { - proto_item_append_text(ti, " Security info: "); - } - /* security info field, if present */ - while (tvb_length_remaining(tvb, offset) > 0) { - proto_item_append_text(ti, elcom_show_hex ? " %02x" : " %03o", - tvb_get_guint8(tvb, offset)); - offset++; - } - - return offset; + gint offset = arg_offset; + guint8 flen, lenbytes; + guint8 year, month, day, hour, min, sec; + guint16 msec; + proto_tree *tree; + proto_item *ti; + + tree = proto_item_add_subtree(ti_arg, ett_arg); + + /* length of User Data, should be 1 byte field ... */ + flen = tvb_get_guint8(tvb, offset); + lenbytes = 1; + + /* ... but sometimes it seems to be 2 bytes; try to be clever */ + if (flen == 0) { + flen = tvb_get_guint8(tvb, offset+1); + lenbytes = 2; + } + if (flen == 0 || flen > 79) /* invalid */ + return offset; + + ti = proto_tree_add_item(tree, hf_elcom_userdata_length, tvb, offset, lenbytes, ENC_BIG_ENDIAN); + offset += lenbytes; + if (lenbytes == 2) { + proto_item_append_text(ti, " (2 bytes, should be 1 byte)"); + } + + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + proto_tree_add_item(tree, hf_elcom_userdata_pduid, tvb, offset, 1, ENC_BIG_ENDIAN); + offset++; + + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + proto_tree_add_item(tree, hf_elcom_userdata_version, tvb, offset, 1, ENC_BIG_ENDIAN); + offset++; + + + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + proto_tree_add_item(tree, hf_elcom_userdata_result, tvb, offset, 1, ENC_BIG_ENDIAN); + offset++; + + /* show the rest */ + /* tree2 = proto_tree_add_text(tree, tvb, offset, -1, "User Data"); */ + + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + ti = proto_tree_add_item(tree, hf_elcom_userdata_restmark, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_item_append_text(ti, " <-- '0' = no restart etc."); + offset +=1; + + if (tvb_length_remaining(tvb, offset+8) <= 0) + return offset; + year = tvb_get_guint8(tvb, offset); + month = tvb_get_guint8(tvb, offset+1); + day = tvb_get_guint8(tvb, offset+2); + hour = tvb_get_guint8(tvb, offset+3); + min = tvb_get_guint8(tvb, offset+4); + sec = tvb_get_guint8(tvb, offset+5); + msec = tvb_get_ntohs(tvb, offset+6); + + proto_tree_add_none_format(tree, hf_elcom_userdata_cf, tvb, offset, 8, + "Control Field: %4d-%02d-%02d %02d:%02d:%02d.%d", + year+1900, month, day, hour, min, sec, msec); + + offset += 12; + if (tvb_length_remaining(tvb, offset+12) > 0) { + proto_item_append_text(ti, " Security info: "); + } + /* security info field, if present */ + while (tvb_length_remaining(tvb, offset) > 0) { + proto_item_append_text(ti, elcom_show_hex ? " %02x" : " %03o", + tvb_get_guint8(tvb, offset)); + offset++; + } + + return offset; } static gint dissect_datarequest(proto_item *ti_arg, gint ett_arg, tvbuff_t *tvb, gint arg_offset) { - gint offset = arg_offset; - guint8 gtype, oidlen; - proto_tree *tree, *tree2; - proto_item *ti; - - tree = proto_item_add_subtree(ti_arg, ett_arg); - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - gtype = tvb_get_guint8(tvb, offset); - ti = proto_tree_add_item(tree, hf_elcom_datarequest_grouptype, - tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - - switch (gtype) { - - case TC_RSP: - - proto_tree_add_uint(tree, hf_elcom_datarequest_result, - tvb, offset, 1, ENC_BIG_ENDIAN); - offset++; - - break; - - default: - proto_item_append_text(ti, " <<--- meaning WHAT?"); - return offset; - } - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - proto_tree_add_item(tree, hf_elcom_datarequest_groupnumber, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - proto_tree_add_item(tree, hf_elcom_datarequest_grouppriority, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - proto_tree_add_item(tree, hf_elcom_datarequest_groupsize, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - proto_tree_add_item(tree, hf_elcom_datarequest_groupindex1, tvb, offset, 2, ENC_BIG_ENDIAN); - offset += 2; - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - proto_tree_add_uint(tree, hf_elcom_datarequest_groupindex2, tvb, offset, 2, ENC_BIG_ENDIAN); - offset += 2; - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - while (1) { - oidlen = tvb_get_guint8(tvb, offset); - if (oidlen == 0) /* normal termination */ - break; - if (tvb_length_remaining(tvb, offset+oidlen+1) <= 0) - return offset; - proto_tree_add_item(tree, hf_elcom_datarequest_oid, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN); - offset += oidlen+1; - } - offset += 1; /* the loop exited at the 0 length byte */ - if (tvb_length_remaining(tvb, offset) <= 0) - return offset; - - /* show the rest */ - tree2 = proto_tree_add_text(tree, tvb, offset, -1, "leftover ="); - while (tvb_length_remaining(tvb, offset) > 0) { - proto_item_append_text(tree2, elcom_show_hex ? " %02x" : " %03o", - tvb_get_guint8(tvb, offset)); - offset++; - } - - return offset; + gint offset = arg_offset; + guint8 gtype, oidlen; + proto_tree *tree, *tree2; + proto_item *ti; + + tree = proto_item_add_subtree(ti_arg, ett_arg); + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + gtype = tvb_get_guint8(tvb, offset); + ti = proto_tree_add_item(tree, hf_elcom_datarequest_grouptype, + tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + switch (gtype) { + + case TC_RSP: + + proto_tree_add_uint(tree, hf_elcom_datarequest_result, + tvb, offset, 1, ENC_BIG_ENDIAN); + offset++; + + break; + + default: + proto_item_append_text(ti, " <<--- meaning WHAT?"); + return offset; + } + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + proto_tree_add_item(tree, hf_elcom_datarequest_groupnumber, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + proto_tree_add_item(tree, hf_elcom_datarequest_grouppriority, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + proto_tree_add_item(tree, hf_elcom_datarequest_groupsize, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + proto_tree_add_item(tree, hf_elcom_datarequest_groupindex1, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + proto_tree_add_uint(tree, hf_elcom_datarequest_groupindex2, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + while (1) { + oidlen = tvb_get_guint8(tvb, offset); + if (oidlen == 0) /* normal termination */ + break; + if (tvb_length_remaining(tvb, offset+oidlen+1) <= 0) + return offset; + proto_tree_add_item(tree, hf_elcom_datarequest_oid, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN); + offset += oidlen+1; + } + offset += 1; /* the loop exited at the 0 length byte */ + if (tvb_length_remaining(tvb, offset) <= 0) + return offset; + + /* show the rest */ + tree2 = proto_tree_add_text(tree, tvb, offset, -1, "leftover ="); + while (tvb_length_remaining(tvb, offset) > 0) { + proto_item_append_text(tree2, elcom_show_hex ? " %02x" : " %03o", + tvb_get_guint8(tvb, offset)); + offset++; + } + + return offset; } static void @@ -403,374 +403,379 @@ dissect_elcom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) gboolean is_request, length_ok; proto_tree *elcom_tree; proto_item *ti, *hidden_item; - gint offset = 0; - guint16 elcom_len; - guint8 elcom_msg_type; - guint8 *suffix; - - /* Check that there's enough data */ - if (tvb_length(tvb) < 3) - return; - - if (check_col(pinfo->cinfo, COL_PROTOCOL)) - col_set_str(pinfo->cinfo, COL_PROTOCOL, "ELCOM"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_clear(pinfo->cinfo, COL_INFO); - - is_request = (pinfo->match_port == pinfo->destport); - elcom_len = tvb_get_ntohs(tvb, 0); - length_ok = (tvb_length(tvb) == (guint16)(elcom_len+2)); - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "%s Len=%d%s", - is_request ? "Request" : "Response", - elcom_len, - length_ok ? "" : " (incorrect)"); - - elcom_msg_type = tvb_get_guint8(tvb, 2); - switch (elcom_msg_type) { - case P_CONRQ: - case P_CONRS: - /* starting after elcom_len and elcom_msg_type, - initiator + responder + userdata fields must be there */ - if (tvb_length_remaining(tvb, 3+TOTAL_LEN+TOTAL_LEN+3) < 0) return; - /* check also that those field lengths are valid */ - if (tvb_get_guint8(tvb, 3) != LOWADR_LEN) return; - if (tvb_get_guint8(tvb, 3+1+LOWADR_LEN) != SUFFIX_LEN) return; - if (tvb_get_guint8(tvb, 3+TOTAL_LEN) != LOWADR_LEN) return; - if (tvb_get_guint8(tvb, 3+1+TOTAL_LEN+LOWADR_LEN) != SUFFIX_LEN) return; - /* finally believe that there is valid suffix */ - suffix = tvb_get_string(tvb, 3+2+LOWADR_LEN, 2); - col_append_fstr(pinfo->cinfo, COL_INFO, " %s Connect", suffix); - g_free(suffix); - break; - - case P_RELRQ: - case P_RELRS: - col_append_str(pinfo->cinfo, COL_INFO, " Release"); - break; - - case P_DATRQ: - col_append_str(pinfo->cinfo, COL_INFO, " Data"); - break; - } - - switch (elcom_msg_type) { - case P_CONRQ: - case P_RELRQ: - col_append_str(pinfo->cinfo, COL_INFO, " Request"); - break; - - case P_CONRS: - case P_RELRS: - col_append_str(pinfo->cinfo, COL_INFO, " Response"); - break; - } - - return; - } - - if (!tree) - return; - - ti = proto_tree_add_item(tree, proto_elcom, tvb, offset, -1, ENC_NA); - elcom_tree = proto_item_add_subtree(ti, ett_elcom); - - hidden_item = proto_tree_add_boolean(elcom_tree, - is_request ? hf_elcom_request : hf_elcom_response, - tvb, 0, 0, TRUE); - PROTO_ITEM_SET_HIDDEN(hidden_item); - - /* 2 first bytes are the frame length */ - offset = 0; - ti = proto_tree_add_item(elcom_tree, hf_elcom_length, tvb, offset, 2, ENC_BIG_ENDIAN); - offset = +2; - if (! length_ok) { - proto_item_append_text(ti, " (incorrect)"); - } - - elcom_msg_type = tvb_get_guint8(tvb, offset); - ti = proto_tree_add_item(elcom_tree, hf_elcom_type, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_item_append_text(elcom_tree, " ( %s)", val_to_str(elcom_msg_type, type_vals, "Unknown %d")); - - offset++; - if (tvb_length_remaining(tvb, offset) <= 0) - return; - - switch (elcom_msg_type) { - case P_CONRQ: - case P_CONRS: - /* - * Connection request/release assiciated PDU's, - * /ELCOM-90 P Protocol spec/ p. 85... - */ - - /* We need the lenght here, hardcode the LOWADR_LEN = 21 */ - ti = proto_tree_add_item(elcom_tree, hf_elcom_initiator, tvb, offset, TOTAL_LEN, ENC_BIG_ENDIAN); - offset = dissect_lower_address(ti, ett_elcom_initiator, tvb, offset, - hf_elcom_initiator_endian, - hf_elcom_initiator_ip, - hf_elcom_initiator_port, - hf_elcom_initiator_suff); - if (tvb_length_remaining(tvb, offset) <= 0) - return; - - ti = proto_tree_add_item(elcom_tree, hf_elcom_responder, tvb, offset, TOTAL_LEN, ENC_BIG_ENDIAN); - offset = dissect_lower_address(ti, ett_elcom_responder, tvb, offset, - hf_elcom_responder_endian, - hf_elcom_responder_ip, - hf_elcom_responder_port, - hf_elcom_responder_suff); - if (tvb_length_remaining(tvb, offset) <= 0) - return; - - /* Rest of the payload is USER-DATA, 0..82 bytes */ - ti = proto_tree_add_item(elcom_tree, hf_elcom_userdata, tvb, offset, -1, ENC_NA); - offset = dissect_userdata(ti, ett_elcom_userdata, tvb, offset); - - break; - - case P_RELRQ: - - proto_tree_add_item(elcom_tree, hf_elcom_release_reason, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - - break; - case P_RELRS: - - proto_tree_add_item(elcom_tree, hf_elcom_release_result, tvb, offset, 1, ENC_BIG_ENDIAN); - - offset += 1; - - break; - - case P_DATRQ: - ti = proto_tree_add_item(elcom_tree, hf_elcom_datarequest, tvb, offset, -1, ENC_NA); - offset = dissect_datarequest(ti, ett_elcom_datarequest, tvb, offset); - break; - - default: - proto_item_append_text(ti, " <<--- meaning WHAT??"); - break; - } - - - if (tvb_length_remaining(tvb, offset) <= 0) - return; - - /* We should not get here, but if we do, show what is left over: */ - ti = proto_tree_add_item(elcom_tree, hf_elcom_strangeleftover, tvb, offset, -1, ENC_NA); - while (tvb_length_remaining(tvb, offset) > 0) { - proto_item_append_text(ti, elcom_show_hex ? " %02x" : " %03o", - tvb_get_guint8(tvb, offset)); - offset++; - } + gint offset = 0; + guint16 elcom_len; + guint8 elcom_msg_type; + guint8 *suffix; + + /* Check that there's enough data */ + if (tvb_length(tvb) < 3) + return; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ELCOM"); + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + is_request = (pinfo->match_port == pinfo->destport); + elcom_len = tvb_get_ntohs(tvb, 0); + length_ok = (tvb_length(tvb) == (guint16)(elcom_len+2)); + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "%s Len=%d%s", + is_request ? "Request" : "Response", + elcom_len, + length_ok ? "" : " (incorrect)"); + + elcom_msg_type = tvb_get_guint8(tvb, 2); + switch (elcom_msg_type) { + case P_CONRQ: + case P_CONRS: + /* starting after elcom_len and elcom_msg_type, + initiator + responder + userdata fields must be there */ + if (tvb_length_remaining(tvb, 3+TOTAL_LEN+TOTAL_LEN+3) < 0) return; + /* check also that those field lengths are valid */ + if (tvb_get_guint8(tvb, 3) != LOWADR_LEN) return; + if (tvb_get_guint8(tvb, 3+1+LOWADR_LEN) != SUFFIX_LEN) return; + if (tvb_get_guint8(tvb, 3+TOTAL_LEN) != LOWADR_LEN) return; + if (tvb_get_guint8(tvb, 3+1+TOTAL_LEN+LOWADR_LEN) != SUFFIX_LEN) return; + /* finally believe that there is valid suffix */ + suffix = tvb_get_string(tvb, 3+2+LOWADR_LEN, 2); + col_append_fstr(pinfo->cinfo, COL_INFO, " %s Connect", suffix); + g_free(suffix); + break; + + case P_RELRQ: + case P_RELRS: + col_append_str(pinfo->cinfo, COL_INFO, " Release"); + break; + + case P_DATRQ: + col_append_str(pinfo->cinfo, COL_INFO, " Data"); + break; + } + + switch (elcom_msg_type) { + case P_CONRQ: + case P_RELRQ: + col_append_str(pinfo->cinfo, COL_INFO, " Request"); + break; + + case P_CONRS: + case P_RELRS: + col_append_str(pinfo->cinfo, COL_INFO, " Response"); + break; + } + + return; + } + + if (!tree) + return; + + ti = proto_tree_add_item(tree, proto_elcom, tvb, offset, -1, ENC_NA); + elcom_tree = proto_item_add_subtree(ti, ett_elcom); + + hidden_item = proto_tree_add_boolean(elcom_tree, + is_request ? hf_elcom_request : hf_elcom_response, + tvb, 0, 0, TRUE); + PROTO_ITEM_SET_HIDDEN(hidden_item); + + /* 2 first bytes are the frame length */ + offset = 0; + ti = proto_tree_add_item(elcom_tree, hf_elcom_length, tvb, offset, 2, ENC_BIG_ENDIAN); + offset = +2; + if (! length_ok) { + proto_item_append_text(ti, " (incorrect)"); + } + + elcom_msg_type = tvb_get_guint8(tvb, offset); + ti = proto_tree_add_item(elcom_tree, hf_elcom_type, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_item_append_text(elcom_tree, " ( %s)", val_to_str(elcom_msg_type, type_vals, "Unknown %d")); + + offset++; + if (tvb_length_remaining(tvb, offset) <= 0) + return; + + switch (elcom_msg_type) { + case P_CONRQ: + case P_CONRS: + /* + * Connection request/release assiciated PDU's, + * /ELCOM-90 P Protocol spec/ p. 85... + */ + + /* We need the lenght here, hardcode the LOWADR_LEN = 21 */ + ti = proto_tree_add_item(elcom_tree, hf_elcom_initiator, tvb, offset, TOTAL_LEN, ENC_BIG_ENDIAN); + offset = dissect_lower_address(ti, ett_elcom_initiator, tvb, offset, + hf_elcom_initiator_endian, + hf_elcom_initiator_ip, + hf_elcom_initiator_port, + hf_elcom_initiator_suff); + if (tvb_length_remaining(tvb, offset) <= 0) + return; + + ti = proto_tree_add_item(elcom_tree, hf_elcom_responder, tvb, offset, TOTAL_LEN, ENC_BIG_ENDIAN); + offset = dissect_lower_address(ti, ett_elcom_responder, tvb, offset, + hf_elcom_responder_endian, + hf_elcom_responder_ip, + hf_elcom_responder_port, + hf_elcom_responder_suff); + if (tvb_length_remaining(tvb, offset) <= 0) + return; + + /* Rest of the payload is USER-DATA, 0..82 bytes */ + ti = proto_tree_add_item(elcom_tree, hf_elcom_userdata, tvb, offset, -1, ENC_NA); + offset = dissect_userdata(ti, ett_elcom_userdata, tvb, offset); + + break; + + case P_RELRQ: + + proto_tree_add_item(elcom_tree, hf_elcom_release_reason, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + break; + case P_RELRS: + + proto_tree_add_item(elcom_tree, hf_elcom_release_result, tvb, offset, 1, ENC_BIG_ENDIAN); + + offset += 1; + + break; + + case P_DATRQ: + ti = proto_tree_add_item(elcom_tree, hf_elcom_datarequest, tvb, offset, -1, ENC_NA); + offset = dissect_datarequest(ti, ett_elcom_datarequest, tvb, offset); + break; + + default: + proto_item_append_text(ti, " <<--- meaning WHAT??"); + break; + } + + + if (tvb_length_remaining(tvb, offset) <= 0) + return; + + /* We should not get here, but if we do, show what is left over: */ + ti = proto_tree_add_item(elcom_tree, hf_elcom_strangeleftover, tvb, offset, -1, ENC_NA); + while (tvb_length_remaining(tvb, offset) > 0) { + proto_item_append_text(ti, elcom_show_hex ? " %02x" : " %03o", + tvb_get_guint8(tvb, offset)); + offset++; + } } void proto_register_elcom(void) { - /* Setup list of header fields See Section 1.6.1 for details*/ - static hf_register_info hf[] = { - { &hf_elcom_response, - { "Response", "elcom.response", - FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_request, - { "Request", "elcom.request", - FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_length, - { "Lenght", "elcom.length", - FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_type, - { "Type", "elcom.type", - FT_UINT8, BASE_HEX, VALS(type_vals), 0, NULL, HFILL } - }, - - { &hf_elcom_initiator, - { "Initiator", "elcom.initiator", - FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_initiator_endian, - { "Endian", "elcom.initiator.endian", - FT_UINT16, BASE_HEX, VALS(endian_vals), 0, NULL, HFILL } - }, - - { &hf_elcom_initiator_ip, - { "IP", "elcom.initiator.ip", - FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_initiator_port, - { "Port", "elcom.initiator.port", - FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_initiator_suff, - { "Suffix", "elcom.initiator.suffix", - FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_responder, - { "Responder", "elcom.responder", - FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_responder_endian, - { "Endian", "elcom.responder.endian", - FT_UINT16, BASE_HEX, VALS(endian_vals), 0, NULL, HFILL } - }, - - { &hf_elcom_responder_ip, - { "IP", "elcom.responder.ip", - FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_responder_port, - { "Port", "elcom.responder.port", - FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_responder_suff, - { "Suffix", "elcom.responder.suffix", - FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_userdata, - { "User Data", "elcom.userdata", - FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_userdata_length, - { "Lenght", "elcom.userdata.length", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_userdata_pduid, - { "PDU-ID", "elcom.userdata.pduid", - FT_UINT8, BASE_DEC, VALS(userdata_pduid_vals), 0, NULL, HFILL } - }, - - { &hf_elcom_userdata_version, - { "Version", "elcom.userdata.version", - FT_UINT8, BASE_DEC, VALS(userdata_version_vals), 0, NULL, HFILL } - }, - - { &hf_elcom_userdata_result, - { "Result", "elcom.userdata.result", - FT_UINT8, BASE_DEC, VALS(userdata_result_vals), 0, NULL, HFILL } - }, - - { &hf_elcom_userdata_restmark, - { "Restart marking", "elcom.userdata.response.restartcode", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_userdata_cf, - { "Control Field", "elcom.userdata.response.controlfield", - FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_release_reason, - { "Reason", "elcom.release.reason", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_release_result, - { "Result", "elcom.release.result", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_datarequest, - { "Data Request", "elcom.datarequest", - FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_datarequest_grouptype, - { "Group Type", "elcom.datarequest.grouptype", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_datarequest_result, - { "Result", "elcom.datarequest.result", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_datarequest_groupnumber, - { "Group Number", "elcom.datarequest.groupnumber", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_datarequest_grouppriority, - { "Group Priority", "elcom.datarequest.grouppriority", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_datarequest_groupsize, - { "Group Size", "elcom.datarequest.groupsize", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_datarequest_groupindex1, - { "Group Index1", "elcom.datarequest.groupindex1", - FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_datarequest_groupindex2, - { "Group Index2", "elcom.datarequest.groupindex2", - FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } - }, - - { &hf_elcom_datarequest_oid, - { "Obkect Name", "elcom.datarequest.oid", - FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } - }, - { &hf_elcom_strangeleftover, - { "Strange Leftover", "elcom.leftover", - FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } - } - }; - - /* Setup protocol subtree array */ - static gint *ett[] = { - &ett_elcom, - &ett_elcom_initiator, - &ett_elcom_responder, - &ett_elcom_userdata, - &ett_elcom_datarequest - }; - - /* Register the protocol name and description */ - proto_elcom = proto_register_protocol ( - "ELCOM Communication Protocol", - "ELCOM", - "elcom" - ); - - /* Required function calls to register the header fields and subtrees used */ - proto_register_field_array(proto_elcom, hf, array_length(hf)); - proto_register_subtree_array(ett, array_length(ett)); + /* Setup list of header fields See Section 1.6.1 for details*/ + static hf_register_info hf[] = { + { &hf_elcom_response, + { "Response", "elcom.response", + FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_request, + { "Request", "elcom.request", + FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_length, + { "Lenght", "elcom.length", + FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_type, + { "Type", "elcom.type", + FT_UINT8, BASE_HEX, VALS(type_vals), 0, NULL, HFILL } + }, + + { &hf_elcom_initiator, + { "Initiator", "elcom.initiator", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_initiator_endian, + { "Endian", "elcom.initiator.endian", + FT_UINT16, BASE_HEX, VALS(endian_vals), 0, NULL, HFILL } + }, + + { &hf_elcom_initiator_ip, + { "IP", "elcom.initiator.ip", + FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_initiator_port, + { "Port", "elcom.initiator.port", + FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_initiator_suff, + { "Suffix", "elcom.initiator.suffix", + FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_responder, + { "Responder", "elcom.responder", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_responder_endian, + { "Endian", "elcom.responder.endian", + FT_UINT16, BASE_HEX, VALS(endian_vals), 0, NULL, HFILL } + }, + + { &hf_elcom_responder_ip, + { "IP", "elcom.responder.ip", + FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_responder_port, + { "Port", "elcom.responder.port", + FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_responder_suff, + { "Suffix", "elcom.responder.suffix", + FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_userdata, + { "User Data", "elcom.userdata", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_userdata_length, + { "Lenght", "elcom.userdata.length", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_userdata_pduid, + { "PDU-ID", "elcom.userdata.pduid", + FT_UINT8, BASE_DEC, VALS(userdata_pduid_vals), 0, NULL, HFILL } + }, + + { &hf_elcom_userdata_version, + { "Version", "elcom.userdata.version", + FT_UINT8, BASE_DEC, VALS(userdata_version_vals), 0, NULL, HFILL } + }, + + { &hf_elcom_userdata_result, + { "Result", "elcom.userdata.result", + FT_UINT8, BASE_DEC, VALS(userdata_result_vals), 0, NULL, HFILL } + }, + + { &hf_elcom_userdata_restmark, + { "Restart marking", "elcom.userdata.response.restartcode", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_userdata_cf, + { "Control Field", "elcom.userdata.response.controlfield", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_release_reason, + { "Reason", "elcom.release.reason", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_release_result, + { "Result", "elcom.release.result", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_datarequest, + { "Data Request", "elcom.datarequest", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_datarequest_grouptype, + { "Group Type", "elcom.datarequest.grouptype", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_datarequest_result, + { "Result", "elcom.datarequest.result", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_datarequest_groupnumber, + { "Group Number", "elcom.datarequest.groupnumber", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_datarequest_grouppriority, + { "Group Priority", "elcom.datarequest.grouppriority", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_datarequest_groupsize, + { "Group Size", "elcom.datarequest.groupsize", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_datarequest_groupindex1, + { "Group Index1", "elcom.datarequest.groupindex1", + FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_datarequest_groupindex2, + { "Group Index2", "elcom.datarequest.groupindex2", + FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_elcom_datarequest_oid, + { "Obkect Name", "elcom.datarequest.oid", + FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } + }, + { &hf_elcom_strangeleftover, + { "Strange Leftover", "elcom.leftover", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } + } + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_elcom, + &ett_elcom_initiator, + &ett_elcom_responder, + &ett_elcom_userdata, + &ett_elcom_datarequest + }; + + /* Register the protocol name and description */ + proto_elcom = proto_register_protocol ( + "ELCOM Communication Protocol", + "ELCOM", + "elcom" + ); + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_elcom, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); } void proto_reg_handoff_elcom(void) { - dissector_handle_t elcom_handle; + dissector_handle_t elcom_handle; - elcom_handle = create_dissector_handle(dissect_elcom, proto_elcom); - dissector_add_uint("tcp.port", TCP_PORT_ELCOM, elcom_handle); + elcom_handle = create_dissector_handle(dissect_elcom, proto_elcom); + dissector_add_uint("tcp.port", TCP_PORT_ELCOM, elcom_handle); } /* - * Local variables: + * Editor modelines + * + * Local Variables: * c-basic-offset: 8 * tab-width: 8 - * indent-tabs-mode: t + * indent-tabs-mode: nil * End: + * + * ex: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: */ -- cgit v1.2.3