From e8c7975b6f0a83826b13b407b84f941124767080 Mon Sep 17 00:00:00 2001 From: Thomas Wiens Date: Sun, 29 Oct 2017 17:54:39 +0100 Subject: s7comm: Several minor improvements This patch includes several minor improvements: - Special (only for Sinumerik NC): allow NCK address description in data-part - Userdata parameter part: add text definition for second req/res - Don't add data tree in userdata telegrams, when there is no data in there - Cyclic functions: add new subfunction - Alarming: add SCAN message decoding - Improve info column display when there are multiple PDUs in one frame Change-Id: Ib9afd0c6b14cf97ed645084e095f79fb40b07f43 Reviewed-on: https://code.wireshark.org/review/24170 Reviewed-by: Michael Mann Petri-Dish: Michael Mann Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman --- epan/dissectors/packet-s7comm.c | 255 ++++++++++++++++++++++++++-------------- 1 file changed, 170 insertions(+), 85 deletions(-) diff --git a/epan/dissectors/packet-s7comm.c b/epan/dissectors/packet-s7comm.c index 26fde3e4a9..f1cf8bab61 100644 --- a/epan/dissectors/packet-s7comm.c +++ b/epan/dissectors/packet-s7comm.c @@ -478,6 +478,8 @@ static const value_string item_syntaxid_names[] = { #define S7COMM_DATA_TRANSPORT_SIZE_BDINT 6 /* integer access, len is in bytes */ #define S7COMM_DATA_TRANSPORT_SIZE_BREAL 7 /* real access, len is in bytes */ #define S7COMM_DATA_TRANSPORT_SIZE_BSTR 9 /* octet string, len is in bytes */ +#define S7COMM_DATA_TRANSPORT_SIZE_NCKADDR1 17 /* NCK address description, fixed length */ +#define S7COMM_DATA_TRANSPORT_SIZE_NCKADDR2 18 /* NCK address description, fixed length */ static const value_string data_transportsizenames[] = { { S7COMM_DATA_TRANSPORT_SIZE_NULL, "NULL" }, @@ -487,6 +489,8 @@ static const value_string data_transportsizenames[] = { { S7COMM_DATA_TRANSPORT_SIZE_BDINT, "DINTEGER" }, { S7COMM_DATA_TRANSPORT_SIZE_BREAL, "REAL" }, { S7COMM_DATA_TRANSPORT_SIZE_BSTR, "OCTET STRING" }, + { S7COMM_DATA_TRANSPORT_SIZE_NCKADDR1, "NCK ADDRESS1" }, + { S7COMM_DATA_TRANSPORT_SIZE_NCKADDR2, "NCK ADDRESS2" }, { 0, NULL } }; /************************************************************************** @@ -594,6 +598,20 @@ static const value_string blocklanguage_names[] = { { 0, NULL } }; +/************************************************************************** + * Second request/response in userdata parameter part + */ +#define S7COMM_UD_REQRES2_UNDEF 0x00 +#define S7COMM_UD_REQRES2_REQ 0x11 +#define S7COMM_UD_REQRES2_RES 0x12 + +static const value_string userdata_reqres2_names[] = { + { S7COMM_UD_REQRES2_UNDEF, "Undef" }, /* only seen in mode transition events */ + { S7COMM_UD_REQRES2_REQ, "Req" }, + { S7COMM_UD_REQRES2_RES, "Res" }, + { 0, NULL } +}; + /************************************************************************** * Names of types in userdata parameter part */ @@ -762,10 +780,12 @@ static const value_string userdata_prog_subfunc_names[] = { */ #define S7COMM_UD_SUBF_CYCLIC_MEM 0x01 #define S7COMM_UD_SUBF_CYCLIC_UNSUBSCRIBE 0x04 +#define S7COMM_UD_SUBF_CYCLIC_MEM2 0x05 static const value_string userdata_cyclic_subfunc_names[] = { { S7COMM_UD_SUBF_CYCLIC_MEM, "Memory" }, /* read data from memory (DB/M/etc.) */ { S7COMM_UD_SUBF_CYCLIC_UNSUBSCRIBE, "Unsubscribe" }, /* Unsubscribe (disable) cyclic data */ + { S7COMM_UD_SUBF_CYCLIC_MEM2, "Memory2" }, /* same as 0x01, but only S7-400 */ { 0, NULL } }; @@ -786,6 +806,7 @@ static const value_string userdata_block_subfunc_names[] = { /************************************************************************** * Names of userdata subfunctions in group 4 (CPU functions) */ +#define S7COMM_UD_SUBF_CPU_SCAN_IND 0x09 static const value_string userdata_cpu_subfunc_names[] = { { S7COMM_UD_SUBF_CPU_READSZL, "Read SZL" }, @@ -795,6 +816,7 @@ static const value_string userdata_cpu_subfunc_names[] = { { S7COMM_UD_SUBF_CPU_NOTIFY_IND, "NOTIFY indication" }, /* PLC is indicating a NOTIFY message, using NOTIFY SFBs */ { S7COMM_UD_SUBF_CPU_ALARM8LOCK, "ALARM_8 lock" }, /* Lock an ALARM message from HMI/SCADA */ { S7COMM_UD_SUBF_CPU_ALARM8UNLOCK, "ALARM_8 unlock" }, /* Unlock an ALARM message from HMI/SCADA */ + { S7COMM_UD_SUBF_CPU_SCAN_IND, "SCAN indication" }, /* PLC is indicating a SCAN message */ { S7COMM_UD_SUBF_CPU_ALARMS_IND, "ALARM_S indication" }, /* PLC is indicating an ALARM message, using ALARM_S/ALARM_D SFCs */ { S7COMM_UD_SUBF_CPU_ALARMSQ_IND, "ALARM_SQ indication" }, /* PLC is indicating an ALARM message, using ALARM_SQ/ALARM_DQ SFCs */ { S7COMM_UD_SUBF_CPU_ALARMQUERY, "ALARM query" }, /* HMI/SCADA query of ALARMs */ @@ -1118,7 +1140,7 @@ static gint hf_s7comm_userdata_data = -1; static gint hf_s7comm_userdata_param_head = -1; static gint hf_s7comm_userdata_param_len = -1; -static gint hf_s7comm_userdata_param_reqres2 = -1; /* unknown */ +static gint hf_s7comm_userdata_param_reqres2 = -1; static gint hf_s7comm_userdata_param_type = -1; static gint hf_s7comm_userdata_param_funcgroup = -1; static gint hf_s7comm_userdata_param_subfunc_prog = -1; @@ -1502,6 +1524,8 @@ static gint hf_s7comm_cpu_alarm_message_event_coming = -1; static gint hf_s7comm_cpu_alarm_message_event_going = -1; static gint hf_s7comm_cpu_alarm_message_event_lastchanged = -1; static gint hf_s7comm_cpu_alarm_message_event_reserved = -1; +static gint hf_s7comm_cpu_alarm_message_scan_unknown1 = -1; +static gint hf_s7comm_cpu_alarm_message_scan_unknown2 = -1; static gint hf_s7comm_cpu_alarm_message_signal_sig1 = -1; static gint hf_s7comm_cpu_alarm_message_signal_sig2 = -1; @@ -2734,50 +2758,64 @@ s7comm_decode_response_read_data(tvbuff_t *tvb, proto_item *item = NULL; proto_tree *item_tree = NULL; - for (i = 1; i <= item_count; i++) { - ret_val = tvb_get_guint8(tvb, offset); - if (ret_val == S7COMM_ITEM_RETVAL_RESERVED || - ret_val == S7COMM_ITEM_RETVAL_DATA_OK || - ret_val == S7COMM_ITEM_RETVAL_DATA_ERR - ) { - tsize = tvb_get_guint8(tvb, offset + 1); - len = tvb_get_ntohs(tvb, offset + 2); - /* calculate length in bytes */ - if (tsize == S7COMM_DATA_TRANSPORT_SIZE_BBIT || - tsize == S7COMM_DATA_TRANSPORT_SIZE_BBYTE || - tsize == S7COMM_DATA_TRANSPORT_SIZE_BINT - ) { /* given length is in number of bits */ - if (len % 8) { /* len is not a multiple of 8, then round up to next number */ - len /= 8; - len = len + 1; - } else { - len /= 8; + /* Maybe this is only valid for Sinumerik NCK: Pre-check transport-size + * If transport size is 0x11 or 0x12, then an array with requested NCK areas will follow. + */ + tsize = tvb_get_guint8(tvb, offset + 1); + if (tsize == S7COMM_DATA_TRANSPORT_SIZE_NCKADDR1 || tsize == S7COMM_DATA_TRANSPORT_SIZE_NCKADDR2) { + proto_tree_add_item(tree, hf_s7comm_data_returncode, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_uint(tree, hf_s7comm_data_transport_size, tvb, offset + 1, 1, tsize); + offset += 2; + for (i = 0; i < item_count; i++) { + offset = s7comm_decode_param_item(tvb, offset, tree, i); + } + } else { + /* Standard */ + for (i = 1; i <= item_count; i++) { + ret_val = tvb_get_guint8(tvb, offset); + if (ret_val == S7COMM_ITEM_RETVAL_RESERVED || + ret_val == S7COMM_ITEM_RETVAL_DATA_OK || + ret_val == S7COMM_ITEM_RETVAL_DATA_ERR + ) { + tsize = tvb_get_guint8(tvb, offset + 1); + len = tvb_get_ntohs(tvb, offset + 2); + /* calculate length in bytes */ + if (tsize == S7COMM_DATA_TRANSPORT_SIZE_BBIT || + tsize == S7COMM_DATA_TRANSPORT_SIZE_BBYTE || + tsize == S7COMM_DATA_TRANSPORT_SIZE_BINT + ) { /* given length is in number of bits */ + if (len % 8) { /* len is not a multiple of 8, then round up to next number */ + len /= 8; + len = len + 1; + } else { + len /= 8; + } } - } - /* the PLC places extra bytes at the end of all but last result, if length is not a multiple of 2 */ - if ((len % 2) && (i < item_count)) { - len2 = len + 1; - } else { - len2 = len; + /* the PLC places extra bytes at the end of all but last result, if length is not a multiple of 2 */ + if ((len % 2) && (i < item_count)) { + len2 = len + 1; + } else { + len2 = len; + } } - } - /* Insert a new tree for every item */ - item = proto_tree_add_item(tree, hf_s7comm_data_item, tvb, offset, len + head_len, ENC_NA); - item_tree = proto_item_add_subtree(item, ett_s7comm_data_item); - proto_item_append_text(item, " [%d]: (%s)", i, val_to_str(ret_val, s7comm_item_return_valuenames, "Unknown code: 0x%02x")); - - proto_tree_add_uint(item_tree, hf_s7comm_data_returncode, tvb, offset, 1, ret_val); - proto_tree_add_uint(item_tree, hf_s7comm_data_transport_size, tvb, offset + 1, 1, tsize); - proto_tree_add_uint(item_tree, hf_s7comm_data_length, tvb, offset + 2, 2, len); - offset += head_len; - - if (ret_val == S7COMM_ITEM_RETVAL_DATA_OK || ret_val == S7COMM_ITEM_RETVAL_RESERVED) { - proto_tree_add_item(item_tree, hf_s7comm_readresponse_data, tvb, offset, len, ENC_NA); - offset += len; - if (len != len2) { - proto_tree_add_item(item_tree, hf_s7comm_data_fillbyte, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; + /* Insert a new tree for every item */ + item = proto_tree_add_item(tree, hf_s7comm_data_item, tvb, offset, len + head_len, ENC_NA); + item_tree = proto_item_add_subtree(item, ett_s7comm_data_item); + proto_item_append_text(item, " [%d]: (%s)", i, val_to_str(ret_val, s7comm_item_return_valuenames, "Unknown code: 0x%02x")); + + proto_tree_add_uint(item_tree, hf_s7comm_data_returncode, tvb, offset, 1, ret_val); + proto_tree_add_uint(item_tree, hf_s7comm_data_transport_size, tvb, offset + 1, 1, tsize); + proto_tree_add_uint(item_tree, hf_s7comm_data_length, tvb, offset + 2, 2, len); + offset += head_len; + + if (ret_val == S7COMM_ITEM_RETVAL_DATA_OK || ret_val == S7COMM_ITEM_RETVAL_RESERVED) { + proto_tree_add_item(item_tree, hf_s7comm_readresponse_data, tvb, offset, len, ENC_NA); + offset += len; + if (len != len2) { + proto_tree_add_item(item_tree, hf_s7comm_data_fillbyte, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + } } } } @@ -3952,12 +3990,26 @@ s7comm_decode_ud_cpu_alarm_main(tvbuff_t *tvb, msg_item = proto_tree_add_item(data_tree, hf_s7comm_cpu_alarm_message_item, tvb, offset, 0, ENC_NA); msg_item_tree = proto_item_add_subtree(msg_item, ett_s7comm_cpu_alarm_message); - if (subfunc == S7COMM_UD_SUBF_CPU_ALARM8_IND || subfunc == S7COMM_UD_SUBF_CPU_ALARMACK_IND || - subfunc == S7COMM_UD_SUBF_CPU_ALARMSQ_IND || subfunc == S7COMM_UD_SUBF_CPU_ALARMS_IND || - subfunc == S7COMM_UD_SUBF_CPU_NOTIFY_IND || subfunc == S7COMM_UD_SUBF_CPU_NOTIFY8_IND) { - msg_work_item = proto_tree_add_item(msg_item_tree, hf_s7comm_cpu_alarm_message_timestamp_coming, tvb, offset, 8, ENC_NA); - msg_work_item_tree = proto_item_add_subtree(msg_work_item, ett_s7comm_cpu_alarm_message_timestamp); - offset = s7comm_add_timestamp_to_tree(tvb, msg_work_item_tree, offset, TRUE, FALSE); + switch (subfunc) { + case S7COMM_UD_SUBF_CPU_SCAN_IND: + proto_tree_add_item(msg_item_tree, hf_s7comm_cpu_alarm_message_scan_unknown1, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + msg_work_item = proto_tree_add_item(msg_item_tree, hf_s7comm_cpu_alarm_message_timestamp_coming, tvb, offset, 8, ENC_NA); + msg_work_item_tree = proto_item_add_subtree(msg_work_item, ett_s7comm_cpu_alarm_message_timestamp); + offset = s7comm_add_timestamp_to_tree(tvb, msg_work_item_tree, offset, TRUE, FALSE); + proto_tree_add_item(msg_item_tree, hf_s7comm_cpu_alarm_message_scan_unknown2, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + break; + case S7COMM_UD_SUBF_CPU_ALARM8_IND: + case S7COMM_UD_SUBF_CPU_ALARMACK_IND: + case S7COMM_UD_SUBF_CPU_ALARMSQ_IND: + case S7COMM_UD_SUBF_CPU_ALARMS_IND: + case S7COMM_UD_SUBF_CPU_NOTIFY_IND: + case S7COMM_UD_SUBF_CPU_NOTIFY8_IND: + msg_work_item = proto_tree_add_item(msg_item_tree, hf_s7comm_cpu_alarm_message_timestamp_coming, tvb, offset, 8, ENC_NA); + msg_work_item_tree = proto_item_add_subtree(msg_work_item, ett_s7comm_cpu_alarm_message_timestamp); + offset = s7comm_add_timestamp_to_tree(tvb, msg_work_item_tree, offset, TRUE, FALSE); + break; } proto_tree_add_item(msg_item_tree, hf_s7comm_cpu_alarm_message_function, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; @@ -4580,6 +4632,7 @@ s7comm_decode_ud_cyclic_subfunc(tvbuff_t *tvb, switch (subfunc) { case S7COMM_UD_SUBF_CYCLIC_MEM: + case S7COMM_UD_SUBF_CYCLIC_MEM2: item_count = tvb_get_guint8(tvb, offset + 1); /* first byte reserved??? */ proto_tree_add_uint(data_tree, hf_s7comm_param_itemcount, tvb, offset, 2, item_count); offset += 2; @@ -4729,7 +4782,7 @@ s7comm_decode_ud(tvbuff_t *tvb, guint16 len; guint32 errorcode; guint32 offset_temp; - + guint32 reqres2; guint8 type; guint8 funcgroup; guint8 subfunc; @@ -4750,19 +4803,25 @@ s7comm_decode_ud(tvbuff_t *tvb, /* 1 byte length of following parameter (8 or 12 bytes) */ proto_tree_add_item(param_tree, hf_s7comm_userdata_param_len, tvb, offset_temp, 1, ENC_BIG_ENDIAN); offset_temp += 1; - /* 1 byte unknown, maybe indicating request/response */ - proto_tree_add_item(param_tree, hf_s7comm_userdata_param_reqres2, tvb, offset_temp, 1, ENC_BIG_ENDIAN); + /* 1 byte indicating request/response again, but useful in Push telegrams*/ + proto_tree_add_item_ret_uint(param_tree, hf_s7comm_userdata_param_reqres2, tvb, offset, 1, ENC_BIG_ENDIAN, &reqres2); offset_temp += 1; /* High nibble (following/request/response) */ type = (tvb_get_guint8(tvb, offset_temp) & 0xf0) >> 4; funcgroup = (tvb_get_guint8(tvb, offset_temp) & 0x0f); proto_tree_add_item(param_tree, hf_s7comm_userdata_param_type, tvb, offset_temp, 1, ENC_BIG_ENDIAN); - - col_append_fstr(pinfo->cinfo, COL_INFO, " Function:[%s] -> [%s]", - val_to_str(type, userdata_type_names, "Unknown type: 0x%02x"), - val_to_str(funcgroup, userdata_functiongroup_names, "Unknown function: 0x%02x") - ); - + if (type == S7COMM_UD_TYPE_PUSH || type == S7COMM_UD_TYPE_NCPUSH) { + col_append_fstr(pinfo->cinfo, COL_INFO, " Function:[%s-%s] -> [%s]", + val_to_str(type, userdata_type_names, "Unknown type: 0x%02x"), + val_to_str(reqres2, userdata_reqres2_names, "Unknown method: 0x%02x"), + val_to_str(funcgroup, userdata_functiongroup_names, "Unknown function: 0x%02x") + ); + } else { + col_append_fstr(pinfo->cinfo, COL_INFO, " Function:[%s] -> [%s]", + val_to_str(type, userdata_type_names, "Unknown type: 0x%02x"), + val_to_str(funcgroup, userdata_functiongroup_names, "Unknown function: 0x%02x") + ); + } proto_item_append_text(param_tree, ": (%s)", val_to_str(type, userdata_type_names, "Unknown type: 0x%02x")); proto_item_append_text(param_tree, " ->(%s)", val_to_str(funcgroup, userdata_functiongroup_names, "Unknown function: 0x%02x")); @@ -4847,13 +4906,14 @@ s7comm_decode_ud(tvbuff_t *tvb, * Add data tree */ offset += plength; /* set offset to the beginning of the data part */ - item = proto_tree_add_item(tree, hf_s7comm_data, tvb, offset, dlength, ENC_NA); - data_tree = proto_item_add_subtree(item, ett_s7comm_data); - - /* the first 4 bytes of the data part of a userdata telegram are the same for all types */ + /* The first 4 bytes of the data part of a userdata telegram are the same for all types. + * This is also the minumum length of the data part. + */ if (dlength >= 4) { - ret_val = tvb_get_guint8(tvb, offset); + item = proto_tree_add_item(tree, hf_s7comm_data, tvb, offset, dlength, ENC_NA); + data_tree = proto_item_add_subtree(item, ett_s7comm_data); + ret_val = tvb_get_guint8(tvb, offset); proto_tree_add_uint(data_tree, hf_s7comm_data_returncode, tvb, offset, 1, ret_val); offset += 1; /* Not definitely known part, kind of "transport size"? constant 0x09, 1 byte @@ -4870,7 +4930,7 @@ s7comm_decode_ud(tvbuff_t *tvb, * decode only when there is a data part length greater 4 bytes */ if (dlength > 4) { - switch (funcgroup){ + switch (funcgroup) { case S7COMM_UD_FUNCGROUP_PROG: offset = s7comm_decode_ud_prog_subfunc(tvb, data_tree, type, subfunc, dlength, offset); break; @@ -4881,25 +4941,41 @@ s7comm_decode_ud(tvbuff_t *tvb, offset = s7comm_decode_ud_block_subfunc(tvb, pinfo, data_tree, type, subfunc, ret_val, tsize, len, dlength, offset); break; case S7COMM_UD_FUNCGROUP_CPU: - if (subfunc == S7COMM_UD_SUBF_CPU_READSZL) { - offset = s7comm_decode_ud_cpu_szl_subfunc(tvb, pinfo, data_tree, type, ret_val, len, dlength, data_unit_ref, last_data_unit, offset); - } else if (subfunc == S7COMM_UD_SUBF_CPU_NOTIFY_IND || subfunc == S7COMM_UD_SUBF_CPU_NOTIFY8_IND - || subfunc == S7COMM_UD_SUBF_CPU_ALARM8_IND || subfunc == S7COMM_UD_SUBF_CPU_ALARMSQ_IND - || subfunc == S7COMM_UD_SUBF_CPU_ALARMS_IND || subfunc == S7COMM_UD_SUBF_CPU_ALARMACK_IND - || subfunc == S7COMM_UD_SUBF_CPU_ALARMACK - || subfunc == S7COMM_UD_SUBF_CPU_ALARM8LOCK || subfunc == S7COMM_UD_SUBF_CPU_ALARM8LOCK_IND - || subfunc == S7COMM_UD_SUBF_CPU_ALARM8UNLOCK || subfunc == S7COMM_UD_SUBF_CPU_ALARM8UNLOCK_IND - || (subfunc == S7COMM_UD_SUBF_CPU_ALARMQUERY && type != S7COMM_UD_TYPE_RES)) { - offset = s7comm_decode_ud_cpu_alarm_main(tvb, pinfo, data_tree, type, subfunc, offset); - } else if (subfunc == S7COMM_UD_SUBF_CPU_ALARMQUERY && type == S7COMM_UD_TYPE_RES) { - offset = s7comm_decode_ud_cpu_alarm_query_response(tvb, pinfo, data_tree, offset); - } else if (subfunc == S7COMM_UD_SUBF_CPU_DIAGMSG) { - offset = s7comm_decode_ud_cpu_diagnostic_message(tvb, pinfo, TRUE, data_tree, offset); - } else if (subfunc == S7COMM_UD_SUBF_CPU_MSGS) { - offset = s7comm_decode_message_service(tvb, pinfo, data_tree, type, dlength - 4, offset); - } else { - /* print other currently unknown data as raw bytes */ - proto_tree_add_item(data_tree, hf_s7comm_userdata_data, tvb, offset, dlength - 4, ENC_NA); + switch (subfunc) { + case S7COMM_UD_SUBF_CPU_READSZL: + offset = s7comm_decode_ud_cpu_szl_subfunc(tvb, pinfo, data_tree, type, ret_val, len, dlength, data_unit_ref, last_data_unit, offset); + break; + case S7COMM_UD_SUBF_CPU_NOTIFY_IND: + case S7COMM_UD_SUBF_CPU_NOTIFY8_IND: + case S7COMM_UD_SUBF_CPU_ALARMSQ_IND: + case S7COMM_UD_SUBF_CPU_ALARMS_IND: + case S7COMM_UD_SUBF_CPU_SCAN_IND: + case S7COMM_UD_SUBF_CPU_ALARMACK: + case S7COMM_UD_SUBF_CPU_ALARMACK_IND: + case S7COMM_UD_SUBF_CPU_ALARM8_IND: + case S7COMM_UD_SUBF_CPU_ALARM8LOCK: + case S7COMM_UD_SUBF_CPU_ALARM8LOCK_IND: + case S7COMM_UD_SUBF_CPU_ALARM8UNLOCK: + case S7COMM_UD_SUBF_CPU_ALARM8UNLOCK_IND: + offset = s7comm_decode_ud_cpu_alarm_main(tvb, pinfo, data_tree, type, subfunc, offset); + break; + case S7COMM_UD_SUBF_CPU_ALARMQUERY: + if (type == S7COMM_UD_TYPE_RES) { + offset = s7comm_decode_ud_cpu_alarm_query_response(tvb, pinfo, data_tree, offset); + } else { + offset = s7comm_decode_ud_cpu_alarm_main(tvb, pinfo, data_tree, type, subfunc, offset); + } + break; + case S7COMM_UD_SUBF_CPU_DIAGMSG: + offset = s7comm_decode_ud_cpu_diagnostic_message(tvb, pinfo, TRUE, data_tree, offset); + break; + case S7COMM_UD_SUBF_CPU_MSGS: + offset = s7comm_decode_message_service(tvb, pinfo, data_tree, type, dlength - 4, offset); + break; + default: + /* print other currently unknown data as raw bytes */ + proto_tree_add_item(data_tree, hf_s7comm_userdata_data, tvb, offset, dlength - 4, ENC_NA); + break; } break; case S7COMM_UD_FUNCGROUP_SEC: @@ -5120,12 +5196,13 @@ dissect_s7comm(tvbuff_t *tvb, col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_S7COMM); col_clear(pinfo->cinfo, COL_INFO); + col_append_sep_str(pinfo->cinfo, COL_INFO, " | ", ""); rosctr = tvb_get_guint8(tvb, 1); /* Get the type byte */ if (rosctr == 2 || rosctr == 3) hlength = 12; /* Header 10 Bytes, when type 2 or 3 (response) -> 12 Bytes */ /* display some infos in info-column of wireshark */ - col_add_fstr(pinfo->cinfo, COL_INFO, "ROSCTR:[%-8s]", val_to_str(rosctr, rosctr_names, "Unknown: 0x%02x")); + col_append_fstr(pinfo->cinfo, COL_INFO, "ROSCTR:[%-8s]", val_to_str(rosctr, rosctr_names, "Unknown: 0x%02x")); s7comm_item = proto_tree_add_item(tree, proto_s7comm, tvb, 0, -1, ENC_NA); s7comm_tree = proto_item_add_subtree(s7comm_item, ett_s7comm); @@ -5187,6 +5264,8 @@ dissect_s7comm(tvbuff_t *tvb, if (errorcode > 0) { col_append_fstr(pinfo->cinfo, COL_INFO, " -> Errorcode:[0x%04x]", errorcode); } + /* set fence as there may be more than one S7comm PDU in one frame */ + col_set_fence(pinfo->cinfo, COL_INFO); return TRUE; } @@ -5383,8 +5462,8 @@ proto_register_s7comm (void) { "Parameter length", "s7comm.param.userdata.length", FT_UINT8, BASE_DEC, NULL, 0x0, "Length of following parameter data (without head)", HFILL }}, { &hf_s7comm_userdata_param_reqres2, - { "Unknown (Request/Response)", "s7comm.param.userdata.reqres1", FT_UINT8, BASE_HEX, NULL, 0x0, - "Unknown part, possible request/response (0x11, 0x12), but not in programmer commands", HFILL }}, + { "Method (Request/Response)", "s7comm.param.userdata.reqres1", FT_UINT8, BASE_HEX, VALS(userdata_reqres2_names), 0x0, + "Unknown part, second request/response (0x00, 0x11, 0x12)", HFILL }}, { &hf_s7comm_userdata_param_type, { "Type", "s7comm.param.userdata.type", FT_UINT8, BASE_DEC, VALS(userdata_type_names), 0xf0, @@ -6041,6 +6120,12 @@ proto_register_s7comm (void) { &hf_s7comm_cpu_alarm_message_event_reserved, { "Reserved", "s7comm.alarm.event.reserved", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_s7comm_cpu_alarm_message_scan_unknown1, + { "SCAN unknown 1", "s7comm.alarm.scan.unknown1", FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + { &hf_s7comm_cpu_alarm_message_scan_unknown2, + { "SCAN unknown 2", "s7comm.alarm.scan.unknown2", FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, /* Alarm message query */ { &hf_s7comm_cpu_alarm_query_unknown1, { "Unknown/Reserved (1)", "s7comm.alarm.query.unknown1", FT_UINT8, BASE_HEX, NULL, 0x0, -- cgit v1.2.3