summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ses.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-ses.c
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-ses.c')
-rw-r--r--epan/dissectors/packet-ses.c1921
1 files changed, 1921 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ses.c b/epan/dissectors/packet-ses.c
new file mode 100644
index 00000000..88ecd3b9
--- /dev/null
+++ b/epan/dissectors/packet-ses.c
@@ -0,0 +1,1921 @@
+/* packet-ses.c
+ *
+ * Routine to dissect ITU-T Rec. X.225 (1995 E)/ISO 8327-1 OSI Session Protocol packets
+ *
+ * Yuriy Sidelnikov <YSidelnikov@hotmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+#include <epan/prefs.h>
+#include <epan/conversation.h>
+#include <epan/reassemble.h>
+#include <epan/proto_data.h>
+
+#include <wsutil/str_util.h>
+
+#include "packet-ber.h"
+#include "packet-ses.h"
+
+void proto_register_ses(void);
+void proto_reg_handoff_ses(void);
+
+void proto_register_clses(void);
+void proto_reg_handoff_clses(void);
+
+/* ses header fields */
+static int proto_ses = -1;
+static int hf_ses_type = -1;
+static int hf_ses_type_0 = -1;
+static int hf_ses_length = -1;
+/* static int hf_ses_version = -1; */
+/* static int hf_ses_reserved = -1; */
+
+static int hf_ses_segment_data = -1;
+static int hf_ses_segments = -1;
+static int hf_ses_segment = -1;
+static int hf_ses_segment_overlap = -1;
+static int hf_ses_segment_overlap_conflicts = -1;
+static int hf_ses_segment_multiple_tails = -1;
+static int hf_ses_segment_too_long_segment = -1;
+static int hf_ses_segment_error = -1;
+static int hf_ses_segment_count = -1;
+static int hf_ses_reassembled_in = -1;
+static int hf_ses_reassembled_length = -1;
+
+/* ses fields defining a sub tree */
+static gint ett_ses = -1;
+static gint ett_ses_param = -1;
+
+static gint ett_ses_segment = -1;
+static gint ett_ses_segments = -1;
+
+
+/* flags */
+static int hf_connect_protocol_options_flags = -1;
+static int hf_version_number_options_flags = -1;
+static int hf_enclosure_item_options_flags = -1;
+static int hf_token_item_options_flags = -1;
+
+static gint ett_connect_protocol_options_flags = -1;
+static gint ett_transport_options_flags = -1;
+static gint ett_protocol_version_flags = -1;
+static gint ett_enclosure_item_flags = -1;
+static gint ett_token_item_flags = -1;
+static gint ett_ses_req_options_flags = -1;
+
+/* called SS user reference */
+static int hf_called_ss_user_reference = -1;
+
+/* calling SS user reference */
+static int hf_calling_ss_user_reference = -1;
+
+/* common reference */
+static int hf_common_reference = -1;
+
+/* additional reference information */
+static int hf_additional_reference_information = -1;
+
+/* token item */
+static int hf_release_token = -1;
+static int hf_major_activity_token = -1;
+static int hf_synchronize_minor_token = -1;
+static int hf_data_token = -1;
+
+/* protocol options */
+static int hf_able_to_receive_extended_concatenated_SPDU = -1;
+
+/* session requirement */
+static int hf_session_user_req_flags = -1;
+static int hf_session_exception_report= -1;
+static int hf_data_separation_function_unit= -1;
+static int hf_symmetric_synchronize_function_unit= -1;
+static int hf_typed_data_function_unit= -1;
+static int hf_exception_function_unit= -1;
+static int hf_capability_function_unit=-1;
+static int hf_negotiated_release_function_unit= -1;
+static int hf_activity_management_function_unit= -1;
+static int hf_resynchronize_function_unit= -1;
+static int hf_major_resynchronize_function_unit= -1;
+static int hf_minor_resynchronize_function_unit= -1;
+static int hf_expedited_data_resynchronize_function_unit= -1;
+static int hf_duplex_function_unit= -1;
+static int hf_half_duplex_function_unit = -1;
+
+/* TSDU maximum size */
+static int hf_proposed_tsdu_maximum_size_i2r = -1;
+static int hf_proposed_tsdu_maximum_size_r2i = -1;
+
+/* protocol version */
+static int hf_protocol_version_1 = -1;
+static int hf_protocol_version_2 = -1;
+
+/* initial serial number */
+static int hf_initial_serial_number = -1;
+
+/* enclosure item */
+static int hf_beginning_of_SSDU = -1;
+static int hf_end_of_SSDU = -1;
+
+/* token setting item */
+
+static const value_string token_setting_vals[] = {
+ { 0x00, "initiator's side" },
+ { 0x01, "responder's side" },
+ { 0x02, "called SS user's choice" },
+ { 0x03, "reserved" },
+ { 0, NULL }
+};
+
+static const true_false_string tfs_released_kept = { "Released", "Kept" };
+
+static int hf_release_token_setting = -1;
+static int hf_major_activity_token_setting = -1;
+static int hf_synchronize_minor_token_setting = -1;
+static int hf_data_token_setting = -1;
+
+/* calling session selector */
+static int hf_calling_session_selector = -1;
+
+/* called session selector */
+static int hf_called_session_selector = -1;
+
+/* activity id */
+static int hf_activity_identifier = -1;
+
+/* serial number */
+static int hf_serial_number = -1;
+
+/* second serial number */
+static int hf_second_serial_number = -1;
+
+/* second initial serial number */
+static int hf_second_initial_serial_number = -1;
+
+/* large initial serial number */
+static int hf_large_initial_serial_number = -1;
+
+/* large second initial serial number */
+static int hf_large_second_initial_serial_number = -1;
+
+/* Generated from convert_proto_tree_add_text.pl */
+static int hf_ses_reason_code = -1;
+static int hf_ses_transport_implementation_restriction = -1;
+static int hf_ses_transport_no_reason = -1;
+static int hf_ses_parameter_group_inside_parameter_group = -1;
+static int hf_ses_user_data = -1;
+static int hf_ses_parameter_type = -1;
+static int hf_ses_transport_protocol_error = -1;
+static int hf_ses_transport_user_abort = -1;
+static int hf_ses_parameter_length = -1;
+static int hf_ses_transport_connection = -1;
+static int hf_ses_transport_option_flags = -1;
+
+/* clses header fields */
+static int proto_clses = -1;
+
+static expert_field ei_ses_bad_length = EI_INIT;
+static expert_field ei_ses_bad_parameter_length = EI_INIT;
+
+#define PROTO_STRING_CLSES "ISO 9548-1 OSI Connectionless Session Protocol"
+
+static dissector_handle_t pres_handle = NULL;
+
+static reassembly_table ses_reassembly_table;
+
+static const fragment_items ses_frag_items = {
+ /* Segment subtrees */
+ &ett_ses_segment,
+ &ett_ses_segments,
+ /* Segment fields */
+ &hf_ses_segments,
+ &hf_ses_segment,
+ &hf_ses_segment_overlap,
+ &hf_ses_segment_overlap_conflicts,
+ &hf_ses_segment_multiple_tails,
+ &hf_ses_segment_too_long_segment,
+ &hf_ses_segment_error,
+ &hf_ses_segment_count,
+ /* Reassembled in field */
+ &hf_ses_reassembled_in,
+ /* Reassembled length field */
+ &hf_ses_reassembled_length,
+ /* Reassembled data field */
+ NULL,
+ /* Tag */
+ "SES segments"
+};
+
+
+static const value_string ses_vals[] =
+{
+ {SES_DATA_TRANSFER, "DATA TRANSFER (DT) SPDU" }, /* 1 */
+ {SES_PLEASE_TOKENS, "PLEASE TOKENS (PT) SPDU" }, /* 2 */
+ {SES_EXPEDITED, "EXPEDITED (EX) SPDU" }, /* 5 */
+ {SES_PREPARE, "PREPARE (PR) SPDU" }, /* 7 */
+ {SES_NOT_FINISHED, "NOT FINISHED (NF) SPDU" }, /* 8 */
+ {SES_FINISH, "FINISH (FN) SPDU" }, /* 9 */
+ {SES_DISCONNECT, "DISCONNECT (DN) SPDU" }, /* 10 */
+ {SES_REFUSE, "REFUSE (RF) SPDU" }, /* 12 */
+ {SES_CONNECTION_REQUEST, "CONNECT (CN) SPDU" }, /* 13 */
+ {SES_CONNECTION_ACCEPT, "ACCEPT (AC) SPDU" }, /* 14 */
+ {SES_CONNECTION_DATA_OVERFLOW, "CONNECT DATA OVERFLOW (CDO) SPDU"}, /* 15 */
+ {SES_OVERFLOW_ACCEPT, "OVERFLOW ACCEPT (OA) SPDU" }, /* 16 */
+ {SES_GIVE_TOKENS_CONFIRM, "GIVE TOKENS CONFIRM (GTC) SPDU"}, /* 21 */
+ {SES_GIVE_TOKENS_ACK, "GIVE TOKENS ACK (GTA) SPDU" }, /* 22 */
+ {SES_ABORT, "ABORT (AB) SPDU" }, /* 25 */
+ {SES_ABORT_ACCEPT, "ABORT ACCEPT (AA) SPDU" }, /* 26 */
+ {SES_ACTIVITY_RESUME, "ACTIVITY RESUME (AR) SPDU" }, /* 29 */
+ {SES_TYPED_DATA, "TYPED DATA (TD) SPDU" }, /* 33 */
+ {SES_RESYNCHRONIZE_ACK, "RESYNCHRONIZE ACK (RA) SPDU" }, /* 34 */
+ {SES_MAJOR_SYNC_POINT, "MAJOR SYNC POINT (MAP) SPDU" }, /* 41 */
+ {SES_MAJOR_SYNC_ACK, "MAJOR SYNC ACK (MAA) SPDU" }, /* 42 */
+ {SES_ACTIVITY_START, "ACTIVITY START (AS) SPDU" }, /* 45 */
+ {SES_EXCEPTION_DATA, "EXCEPTION DATA (ED) SPDU" }, /* 48 */
+ {SES_MINOR_SYNC_POINT, "MINOR SYNC POINT (MIP) SPDU" }, /* 49 */
+ {SES_MINOR_SYNC_ACK, "MINOR SYNC ACK (MIA) SPDU" }, /* 50 */
+ {SES_RESYNCHRONIZE, "RESYNCHRONIZE (RS) SPDU" }, /* 53 */
+ {SES_ACTIVITY_DISCARD, "ACTIVITY DISCARD (AD) SPDU" }, /* 57 */
+ {SES_ACTIVITY_DISCARD_ACK, "ACTIVITY DISCARD ACK (ADA) SPDU" }, /* 58 */
+ {SES_CAPABILITY, "CAPABILITY DATA (CD) SPDU" }, /* 61 */
+ {SES_CAPABILITY_DATA_ACK, "CAPABILITY DATA ACK (CDA) SPDU" }, /* 62 */
+ {CLSES_UNIT_DATA, "UNIT DATA (UD) SPDU" }, /* 64 */
+ {SES_EXCEPTION_REPORT, "EXCEPTION REPORT (ER) SPDU" }, /* 0x2000 */
+ {0, NULL }
+};
+value_string_ext ses_vals_ext = VALUE_STRING_EXT_INIT(ses_vals);
+
+static const value_string ses_category0_vals[] =
+{
+ {SES_PLEASE_TOKENS, "Please tokens PDU" },
+ {SES_GIVE_TOKENS, "Give tokens PDU" },
+ {0, NULL }
+};
+
+
+static const value_string param_vals[] =
+{
+ {Connection_Identifier, "Connection Identifier"}, /* 1 */
+ {Connect_Accept_Item, "Connect Accept Item"}, /* 5 */
+ {Called_SS_user_Reference, "Called SS user Reference"}, /* 9 */
+ {Calling_SS_user_Reference, "Calling SS user Reference"}, /* 10 */
+ {Common_Reference, "Common Reference"}, /* 11 */
+ {Additional_Reference_Information, "Additional Reference Information"}, /* 12 */
+ {Sync_Type_Item, "Sync Type Item"}, /* 15 */
+ {Token_Item, "Token Item"}, /* 16 */
+ {Transport_Disconnect, "Transport_Disconnect"}, /* 17 */
+ {Protocol_Options, "Protocol Options"}, /* 19 */
+ {Session_Requirement, "Session Requirement"}, /* 20 */
+ {TSDU_Maximum_Size, "TSDU Maximum Size"}, /* 21 */
+ {Version_Number, "Version Number"}, /* 22 */
+ {Initial_Serial_Number, "Initial Serial Number"}, /* 23 */
+ {Prepare_Type, "Prepare Type"}, /* 24 */
+ {EnclosureItem, "Enclosure Item"}, /* 25 */
+ {Token_Setting_Item, "Token Setting Item"}, /* 26 */
+ {Resync_Type, "Resync Type"}, /* 27 */
+ {Linking_Information, "Linking Information"}, /* 33 */
+ {Activity_Identifier, "Activity Identifier"}, /* 41 */
+ {Serial_Number, "Serial Number"}, /* 42 */
+ {Reflect_Parameter, "Reflect Parameter"}, /* 49 */
+ {Reason_Code, "Reason Code"}, /* 50 */
+ {Calling_Session_Selector, "Calling Session Selector"}, /* 51 */
+ {Called_Session_Selector, "Called Session Selector"}, /* 52 */
+ {Second_Resync_Type, "Second Resync Type"}, /* 53 */
+ {Second_Serial_Number, "Second Serial Number"}, /* 54 */
+ {Second_Initial_Serial_Number, "Second Initial Serial Number"}, /* 55 */
+ {Upper_Limit_Serial_Number, "Upper Limit Serial Number"}, /* 56 */
+ {Large_Initial_Serial_Number, "Large Initial Serial Number"}, /* 57 */
+ {Large_Second_Initial_Serial_Number, "Large Second Initial Serial Number"}, /* 58 */
+ {Data_Overflow, "Data Overflow"}, /* 60 */
+ {User_Data, "Session user data"}, /* 193 */
+ {Extended_User_Data, "Session extended user data"}, /* 194 */
+ {0, NULL}
+};
+static value_string_ext param_vals_ext = VALUE_STRING_EXT_INIT(param_vals);
+
+static const value_string reason_vals[] =
+{
+ {reason_not_specified, "Rejection by called SS-user; reason not specified" },
+ {temporary_congestion, "Rejection by called SS-user due to temporary congestion" },
+ {Subsequent, "Rejection by called SS-user." },
+ {SES_DISCONNECT, "Rejection by the SPM; implementation restriction stated in the PICS" },
+ {Session_Selector_unknown, "Session Selector unknown" },
+ {SS_user_not_attached_to_SSAP, "SS-user not attached to SSAP" },
+ {SPM_congestion_at_connect_time, "SPM congestion at connect time" },
+ {versions_not_supported, "Proposed protocol versions not supported" },
+ {SPM_reason_not_specified, "Rejection by the SPM; reason not specified" },
+ {SPM_implementation_restriction, "Finish PDU" },
+ {0, NULL }
+};
+static value_string_ext reason_vals_ext = VALUE_STRING_EXT_INIT(reason_vals);
+
+/* desegmentation of OSI over ses */
+static gboolean ses_desegment = TRUE;
+
+/* RTSE reassembly data */
+static guint ses_pres_ctx_id = 0;
+static gboolean ses_rtse_reassemble = FALSE;
+
+static void
+call_pres_dissector(tvbuff_t *tvb, int offset, guint16 param_len,
+ packet_info *pinfo, proto_tree *tree,
+ proto_tree *param_tree,
+ struct SESSION_DATA_STRUCTURE *session)
+{
+ /* do we have OSI presentation packet dissector ? */
+ if(!pres_handle)
+ {
+ /* No - display as data */
+ if (tree)
+ {
+ proto_tree_add_item(param_tree, hf_ses_user_data, tvb, offset, param_len, ENC_NA);
+ }
+ }
+ else
+ {
+ /* Yes - call presentation dissector */
+ tvbuff_t *next_tvb;
+
+ next_tvb = tvb_new_subset_length(tvb, offset, param_len);
+ /* Pass the session pdu to the presentation dissector */
+ call_dissector_with_data(pres_handle, next_tvb, pinfo, tree, session);
+ }
+}
+
+/* this routine returns length of parameter field, parameter group,
+ or parameter */
+static int
+get_item_len(tvbuff_t *tvb, int offset, int *len_len)
+{
+ guint16 len;
+
+ len = tvb_get_guint8(tvb, offset);
+ if(len == TWO_BYTE_LEN)
+ {
+ len = tvb_get_ntohs(tvb, offset+1);
+ *len_len = 3;
+ }
+ else
+ *len_len = 1;
+ return len;
+}
+
+static gboolean
+dissect_parameter(tvbuff_t *tvb, int offset, proto_tree *tree,
+ proto_tree *param_tree, packet_info *pinfo, guint8 param_type,
+ guint16 param_len, proto_item *param_len_item, guint8 *enclosure_item_flags,
+ struct SESSION_DATA_STRUCTURE *session)
+{
+ gboolean has_user_information = TRUE;
+ guint16 flags;
+ asn1_ctx_t asn1_ctx;
+ static int * const item_option_flags[] = {
+ &hf_release_token,
+ &hf_major_activity_token,
+ &hf_synchronize_minor_token,
+ &hf_data_token,
+ NULL
+ };
+ static int * const transport_option_flags[] = {
+ &hf_ses_transport_connection,
+ &hf_ses_transport_user_abort,
+ &hf_ses_transport_protocol_error,
+ &hf_ses_transport_no_reason,
+ &hf_ses_transport_implementation_restriction,
+ NULL
+ };
+ static int * const protocol_options_flags[] = {
+ &hf_able_to_receive_extended_concatenated_SPDU,
+ NULL
+ };
+ static int * const req_options_flags[] = {
+ &hf_session_exception_report,
+ &hf_data_separation_function_unit,
+ &hf_symmetric_synchronize_function_unit,
+ &hf_typed_data_function_unit,
+ &hf_exception_function_unit,
+ &hf_capability_function_unit,
+ &hf_negotiated_release_function_unit,
+ &hf_activity_management_function_unit,
+ &hf_resynchronize_function_unit,
+ &hf_major_resynchronize_function_unit,
+ &hf_minor_resynchronize_function_unit,
+ &hf_expedited_data_resynchronize_function_unit,
+ &hf_duplex_function_unit,
+ &hf_half_duplex_function_unit,
+ NULL
+ };
+ static int * const version_flags[] = {
+ &hf_protocol_version_2,
+ &hf_protocol_version_1,
+ NULL
+ };
+ static int * const enclosure_flags[] = {
+ &hf_end_of_SSDU,
+ &hf_beginning_of_SSDU,
+ NULL
+ };
+
+ asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
+
+ switch (param_type)
+ {
+ case Called_SS_user_Reference:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_called_ss_user_reference,
+ tvb, offset, param_len, ENC_NA);
+ break;
+
+ case Calling_SS_user_Reference:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_calling_ss_user_reference,
+ tvb, offset, param_len, ENC_NA);
+ break;
+
+ case Common_Reference:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_common_reference,
+ tvb, offset, param_len, ENC_NA);
+ break;
+
+ case Additional_Reference_Information:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_additional_reference_information,
+ tvb, offset, param_len, ENC_NA);
+ break;
+
+ case Token_Item:
+ if (param_len != 1)
+ {
+ expert_add_info_format(pinfo, param_len_item, &ei_ses_bad_length,
+ "Length is %u, should be 1", param_len);
+ break;
+ }
+
+ proto_tree_add_bitmask(param_tree, tvb, offset, hf_token_item_options_flags, ett_token_item_flags, item_option_flags, ENC_NA);
+ break;
+
+ case Transport_Disconnect:
+ if (param_len != 1)
+ {
+ expert_add_info_format(pinfo, param_len_item, &ei_ses_bad_length,
+ "Length is %u, should be 1", param_len);
+ break;
+ }
+ proto_tree_add_bitmask(param_tree, tvb, offset, hf_ses_transport_option_flags, ett_transport_options_flags, transport_option_flags, ENC_NA);
+
+ if(tvb_get_guint8(tvb, offset) & user_abort )
+ {
+ session->abort_type = SESSION_USER_ABORT;
+ }
+ else
+ {
+ session->abort_type = SESSION_PROVIDER_ABORT;
+ }
+ break;
+
+ case Protocol_Options:
+ if (param_len != 1)
+ {
+ expert_add_info_format(pinfo, param_len_item, &ei_ses_bad_length,
+ "Length is %u, should be 1", param_len);
+ break;
+ }
+
+ proto_tree_add_bitmask(param_tree, tvb, offset, hf_connect_protocol_options_flags, ett_connect_protocol_options_flags, protocol_options_flags, ENC_NA);
+ break;
+
+ case Session_Requirement:
+ if (param_len != 2)
+ {
+ expert_add_info_format(pinfo, param_len_item, &ei_ses_bad_length,
+ "Length is %u, should be 2", param_len);
+ break;
+ }
+ proto_tree_add_bitmask(param_tree, tvb, offset, hf_session_user_req_flags, ett_ses_req_options_flags, req_options_flags, ENC_BIG_ENDIAN);
+ break;
+
+ case TSDU_Maximum_Size:
+ if (param_len != 4)
+ {
+ expert_add_info_format(pinfo, param_len_item, &ei_ses_bad_length,
+ "Length is %u, should be 4", param_len);
+ break;
+ }
+ if (tree)
+ {
+ proto_tree_add_item(param_tree,
+ hf_proposed_tsdu_maximum_size_i2r,
+ tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(param_tree,
+ hf_proposed_tsdu_maximum_size_r2i,
+ tvb, offset+2, 2, ENC_BIG_ENDIAN);
+ }
+ break;
+
+ case Version_Number:
+ if (param_len != 1)
+ {
+ expert_add_info_format(pinfo, param_len_item, &ei_ses_bad_length,
+ "Length is %u, should be 1", param_len);
+ break;
+ }
+ proto_tree_add_bitmask(param_tree, tvb, offset, hf_version_number_options_flags, ett_protocol_version_flags, version_flags, ENC_BIG_ENDIAN);
+ break;
+
+ case Initial_Serial_Number:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_initial_serial_number,
+ tvb, offset, param_len, ENC_ASCII);
+ break;
+
+ case EnclosureItem:
+ if (param_len != 1)
+ {
+ expert_add_info_format(pinfo, param_len_item, &ei_ses_bad_length,
+ "Length is %u, should be 1", param_len);
+ break;
+ }
+ flags = tvb_get_guint8(tvb, offset);
+ *enclosure_item_flags = (guint8) flags;
+ proto_tree_add_bitmask(param_tree, tvb, offset, hf_enclosure_item_options_flags, ett_enclosure_item_flags, enclosure_flags, ENC_BIG_ENDIAN);
+
+ if (flags & END_SPDU) {
+ /*
+ * In Data Transfer and Typed Data SPDUs, (X.225: 8.3.{11,13}.4)
+ * "The User Information Field shall be present
+ * if the Enclosure Item is not present, or has
+ * bit 2 = 0", which presumably means it shall
+ * *not* be present if the Enclosure item *is*
+ * present and has bit 2 = 1.
+ */
+
+ if(!(flags & BEGINNING_SPDU)) {
+ /* X.225 7.11.2 also states:
+ * "All DATA TRANSFER SPDUs, except the last DATA TRANSFER SPDU in a sequence greater than one, must have user information"
+ * So if BEGINNING_SPDU and END_SPDU are set in the enclosure item, then this is presumably a sequence of one and
+ * consequently there must be user information.
+ *
+ * So, there is only no user information if *only* END_SPDU is set.
+ */
+
+ has_user_information = FALSE;
+ }
+ }
+ break;
+
+ case Token_Setting_Item:
+ if (param_len != 1)
+ {
+ expert_add_info_format(pinfo, param_len_item, &ei_ses_bad_length,
+ "Length is %u, should be 1", param_len);
+ break;
+ }
+ if (tree)
+ {
+ proto_tree_add_item(param_tree,
+ hf_release_token_setting,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(param_tree,
+ hf_major_activity_token_setting,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(param_tree,
+ hf_synchronize_minor_token_setting,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(param_tree,
+ hf_data_token_setting,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ }
+ break;
+
+ case Activity_Identifier:
+ if (param_len == 0)
+ break;
+
+ /* 8.3.29.2 The parameter fields shall be as specified in Table 37.
+ * Activity Identifier m 41 6 octets maximum
+ */
+ proto_tree_add_item(param_tree,
+ hf_activity_identifier,
+ tvb, offset, param_len, ENC_NA);
+ break;
+
+ case Serial_Number:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_serial_number,
+ tvb, offset, param_len, ENC_ASCII);
+ break;
+
+ case Reason_Code:
+/*
+ 0: Rejection by called SS-user; reason not specified.
+ 1: Rejection by called SS-user due to temporary congestion.
+ 2: Rejection by called SS-user. Subsequent octets may be used for user data
+up to a length of 512 octets if Protocol Version 1 has been selected, and up
+to a length such that the total length (including SI and LI) of the SPDU
+does not exceed 65 539 octets if Protocol Version 2 has been selected.
+ 128 + 1: Session Selector unknown.
+ 128 + 2: SS-user not attached to SSAP.
+ 128 + 3: SPM congestion at connect time.
+ 128 + 4: Proposed protocol versions not supported.
+ 128 + 5: Rejection by the SPM; reason not specified.
+ 128 + 6: Rejection by the SPM; implementation restriction stated in the
+PICS. */
+ if (param_len < 1)
+ {
+ expert_add_info_format(pinfo, param_len_item, &ei_ses_bad_length,
+ "Length is %u, should be >= 1", param_len);
+ break;
+ }
+
+ proto_tree_add_item(param_tree, hf_ses_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ param_len--;
+ if (param_len != 0)
+ {
+ call_pres_dissector(tvb, offset, param_len,
+ pinfo, tree, param_tree, session);
+ }
+ break;
+
+ case Calling_Session_Selector:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_calling_session_selector,
+ tvb, offset, param_len, ENC_NA);
+ break;
+
+ case Called_Session_Selector:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_called_session_selector,
+ tvb, offset, param_len, ENC_NA);
+ break;
+
+ case Second_Serial_Number:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_second_serial_number,
+ tvb, offset, param_len, ENC_ASCII);
+ break;
+
+ case Second_Initial_Serial_Number:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_second_initial_serial_number,
+ tvb, offset, param_len, ENC_ASCII);
+ break;
+
+ case Large_Initial_Serial_Number:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_large_initial_serial_number,
+ tvb, offset, param_len, ENC_ASCII);
+ break;
+
+ case Large_Second_Initial_Serial_Number:
+ if (param_len == 0)
+ break;
+
+ proto_tree_add_item(param_tree,
+ hf_large_second_initial_serial_number,
+ tvb, offset, param_len, ENC_ASCII);
+ break;
+
+ default:
+ break;
+ }
+ return has_user_information;
+}
+
+static gboolean
+dissect_parameter_group(tvbuff_t *tvb, int offset, proto_tree *tree,
+ proto_tree *pg_tree, packet_info *pinfo, guint16 pg_len,
+ guint8 *enclosure_item_flags, struct SESSION_DATA_STRUCTURE *session)
+{
+ gboolean has_user_information = TRUE;
+ proto_item *ti, *param_len_item;
+ proto_tree *param_tree;
+ guint8 param_type;
+ const char *param_str;
+ int len_len;
+ guint16 param_len;
+
+ while(pg_len != 0)
+ {
+ param_type = tvb_get_guint8(tvb, offset);
+ param_tree = proto_tree_add_subtree(pg_tree, tvb, offset, -1,
+ ett_ses_param, &ti,
+ val_to_str_ext(param_type, &param_vals_ext, "Unknown parameter type (0x%02x)"));
+ param_str = val_to_str_ext_const(param_type, &param_vals_ext, "Unknown");
+ proto_tree_add_item(param_tree, hf_ses_parameter_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ pg_len--;
+ param_len = get_item_len(tvb, offset, &len_len);
+ if (len_len > pg_len) {
+ proto_item_set_len(ti, pg_len + 1);
+ proto_tree_add_expert_format(param_tree, pinfo, &ei_ses_bad_parameter_length, tvb, offset, pg_len, "Parameter length doesn't fit in parameter");
+ return has_user_information;
+ }
+ pg_len -= len_len;
+ if (param_len > pg_len) {
+ proto_item_set_len(ti, pg_len + 1 + len_len);
+ proto_tree_add_expert_format(param_tree, pinfo, &ei_ses_bad_parameter_length, tvb, offset, pg_len, "Parameter length: %u, should be <= %u", param_len, pg_len);
+ return has_user_information;
+ }
+ proto_item_set_len(ti, 1 + len_len + param_len);
+ param_len_item = proto_tree_add_uint(param_tree, hf_ses_parameter_length, tvb, offset, len_len, param_len);
+ offset += len_len;
+
+ if (param_str != NULL)
+ {
+ switch(param_type)
+ {
+ /* PG's in PG's are invalid, presumably */
+ case Extended_User_Data:
+ case User_Data:
+ case Connect_Accept_Item:
+ case Connection_Identifier:
+ case Linking_Information:
+ proto_tree_add_item(param_tree, hf_ses_parameter_group_inside_parameter_group, tvb, offset, param_len, ENC_NA);
+ break;
+
+ default:
+ if (!dissect_parameter(tvb, offset, tree,
+ param_tree, pinfo, param_type, param_len, param_len_item,
+ enclosure_item_flags, session))
+ has_user_information = FALSE;
+ break;
+ }
+ }
+ offset += param_len;
+ pg_len -= param_len;
+ }
+ return has_user_information;
+}
+
+/*
+ * Returns TRUE if there's a User Information field in this SPDU, FALSE
+ * otherwise.
+ */
+static gboolean
+dissect_parameters(tvbuff_t *tvb, int offset, guint16 len, proto_tree *tree,
+ proto_tree *ses_tree, packet_info *pinfo,
+ guint8 *enclosure_item_flags, struct SESSION_DATA_STRUCTURE *session)
+{
+ gboolean has_user_information = TRUE;
+ proto_item *ti, *param_len_item;
+ proto_tree *param_tree;
+ guint8 param_type;
+ const char *param_str;
+ int len_len;
+ guint16 param_len;
+
+ while (len != 0)
+ {
+ param_type = tvb_get_guint8(tvb, offset);
+ param_tree = proto_tree_add_subtree(ses_tree, tvb, offset, -1, ett_ses_param, &ti,
+ val_to_str_ext(param_type, &param_vals_ext,
+ "Unknown parameter type (0x%02x)"));
+ param_str = val_to_str_ext_const(param_type, &param_vals_ext, "Unknown");
+ proto_tree_add_item(param_tree, hf_ses_parameter_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ len--;
+ param_len = get_item_len(tvb, offset, &len_len);
+ if (len_len > len) {
+ proto_item_set_len(ti, len + 1 );
+ proto_tree_add_expert_format(param_tree, pinfo, &ei_ses_bad_parameter_length, tvb, offset, len, "Parameter length doesn't fit in parameter");
+ return has_user_information;
+ }
+ len -= len_len;
+ if (param_len > len) {
+ proto_item_set_len(ti, len + 1 + len_len);
+ proto_tree_add_expert_format(param_tree, pinfo, &ei_ses_bad_parameter_length, tvb, offset, len, "Parameter length: %u, should be <= %u", param_len, len);
+ return has_user_information;
+ }
+ proto_item_set_len(ti, 1 + len_len + param_len);
+ param_len_item = proto_tree_add_uint(param_tree, hf_ses_parameter_length, tvb, offset, len_len, param_len);
+ offset += len_len;
+
+ if (param_str != NULL)
+ {
+ switch(param_type)
+ {
+ case Extended_User_Data:
+ call_pres_dissector(tvb, offset, param_len,
+ pinfo, tree, param_tree, session);
+ break;
+
+ case User_Data:
+ call_pres_dissector(tvb, offset, param_len,
+ pinfo, tree, param_tree, session);
+ break;
+
+ /* handle PGI's */
+ case Connect_Accept_Item:
+ case Connection_Identifier:
+ case Linking_Information:
+ /* Yes. */
+ if (!dissect_parameter_group(tvb, offset, tree,
+ param_tree, pinfo, param_len, enclosure_item_flags, session))
+ has_user_information = FALSE;
+ break;
+
+ /* everything else is a PI */
+ default:
+ if (!dissect_parameter(tvb, offset, tree,
+ param_tree, pinfo, param_type, param_len, param_len_item,
+ enclosure_item_flags, session))
+ has_user_information = FALSE;
+ break;
+ }
+ }
+ offset += param_len;
+ len -= param_len;
+ }
+ return has_user_information;
+}
+
+/*
+ * Dissect an SPDU.
+ */
+static int
+dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
+ gboolean tokens, gboolean connectionless)
+{
+ gboolean has_user_information = FALSE;
+ guint8 type;
+ proto_item *ti = NULL;
+ proto_tree *ses_tree = NULL;
+ int len_len;
+ guint16 parameters_len;
+ tvbuff_t *next_tvb = NULL;
+ guint32 *pres_ctx_id = NULL;
+ guint8 enclosure_item_flags = BEGINNING_SPDU|END_SPDU;
+ struct SESSION_DATA_STRUCTURE session;
+
+ /*
+ * Get SPDU type.
+ */
+ type = tvb_get_guint8(tvb, offset);
+ session.spdu_type = type;
+ session.abort_type = SESSION_NO_ABORT;
+ session.pres_ctx_id = 0;
+ session.ros_op = 0;
+ session.rtse_reassemble = FALSE;
+
+ if(connectionless) {
+ col_add_str(pinfo->cinfo, COL_INFO,
+ val_to_str_ext(type, &ses_vals_ext, "Unknown SPDU type (0x%02x)"));
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_clses, tvb, offset,
+ -1, ENC_NA);
+ ses_tree = proto_item_add_subtree(ti, ett_ses);
+ proto_tree_add_uint(ses_tree, hf_ses_type, tvb,
+ offset, 1, type);
+ }
+ has_user_information = TRUE;
+ }
+ else if (tokens) {
+ col_add_str(pinfo->cinfo, COL_INFO,
+ val_to_str(type, ses_category0_vals, "Unknown SPDU type (0x%02x)"));
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_ses, tvb, offset,
+ -1, ENC_NA);
+ ses_tree = proto_item_add_subtree(ti, ett_ses);
+ proto_tree_add_uint(ses_tree, hf_ses_type_0, tvb,
+ offset, 1, type);
+ }
+ } else {
+ col_add_str(pinfo->cinfo, COL_INFO,
+ val_to_str_ext(type, &ses_vals_ext, "Unknown SPDU type (0x%02x)"));
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_ses, tvb, offset,
+ -1, ENC_NA);
+ ses_tree = proto_item_add_subtree(ti, ett_ses);
+ proto_tree_add_uint(ses_tree, hf_ses_type, tvb,
+ offset, 1, type);
+ }
+
+ /*
+ * Might this SPDU have a User Information field?
+ */
+ switch (type) {
+ case SES_DATA_TRANSFER:
+ case SES_EXPEDITED:
+ case SES_TYPED_DATA:
+ has_user_information = TRUE;
+ break;
+ case SES_MAJOR_SYNC_POINT:
+ pres_ctx_id = (guint32 *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ses, 0);
+ if (ses_rtse_reassemble != 0 && !pres_ctx_id) {
+ /* First time visited - save pres_ctx_id */
+ pres_ctx_id = wmem_new(wmem_file_scope(), guint32);
+ *pres_ctx_id = ses_pres_ctx_id;
+ p_add_proto_data(wmem_file_scope(), pinfo, proto_ses, 0, pres_ctx_id);
+ }
+ if (pres_ctx_id) {
+ session.pres_ctx_id = *pres_ctx_id;
+ session.rtse_reassemble = TRUE;
+ has_user_information = TRUE;
+ }
+ ses_rtse_reassemble = FALSE;
+ break;
+ }
+ }
+ offset++;
+
+ /* get length of SPDU parameter field */
+ parameters_len = get_item_len(tvb, offset, &len_len);
+ if (tree)
+ proto_tree_add_uint(ses_tree, hf_ses_length, tvb, offset,
+ len_len, parameters_len);
+ offset += len_len;
+
+ /* Dissect parameters. */
+ if (!dissect_parameters(tvb, offset, parameters_len, tree, ses_tree,
+ pinfo, &enclosure_item_flags, &session))
+ has_user_information = FALSE;
+ offset += parameters_len;
+
+ proto_item_set_end(ti, tvb, offset);
+
+ /* Dissect user information, if present */
+ if (!ses_desegment || enclosure_item_flags == (BEGINNING_SPDU|END_SPDU)) {
+ if (has_user_information) {
+ /* Not desegment or only one segment */
+ if (tvb_reported_length_remaining(tvb, offset) > 0 || type == SES_MAJOR_SYNC_POINT) {
+ next_tvb = tvb_new_subset_remaining(tvb, offset);
+ }
+ }
+ } else {
+ conversation_t *conversation = NULL;
+ fragment_head *frag_msg = NULL;
+ gint fragment_len;
+ guint32 ses_id = 0;
+
+ /* Use conversation index as segment id */
+ conversation = find_conversation_pinfo(pinfo, 0);
+ if (conversation != NULL) {
+ ses_id = conversation->conv_index;
+ }
+ fragment_len = tvb_reported_length_remaining (tvb, offset);
+ ti = proto_tree_add_item (ses_tree, hf_ses_segment_data, tvb, offset,
+ fragment_len, ENC_NA);
+ proto_item_append_text (ti, " (%d byte%s)", fragment_len, plurality (fragment_len, "", "s"));
+ frag_msg = fragment_add_seq_next (&ses_reassembly_table,
+ tvb, offset,
+ pinfo, ses_id, NULL,
+ fragment_len,
+ (enclosure_item_flags & END_SPDU) ? FALSE : TRUE);
+ next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled SES",
+ frag_msg, &ses_frag_items, NULL,
+ (enclosure_item_flags & END_SPDU) ? tree : ses_tree);
+
+ has_user_information = TRUE;
+ offset += fragment_len;
+ }
+
+ if (has_user_information && next_tvb) {
+ if (!pres_handle) {
+ call_data_dissector(next_tvb, pinfo, tree);
+ } else {
+ /* Pass the session pdu to the presentation dissector */
+ call_dissector_with_data(pres_handle, next_tvb, pinfo, tree, &session);
+ }
+
+ /*
+ * No more SPDUs to dissect. Set the offset to the
+ * end of the tvbuff.
+ */
+ offset = tvb_captured_length(tvb);
+ if (session.rtse_reassemble && type == SES_DATA_TRANSFER) {
+ ses_pres_ctx_id = session.pres_ctx_id;
+ ses_rtse_reassemble = TRUE;
+ }
+ }
+ return offset;
+}
+
+/*
+ * Dissect SPDUs inside a TSDU.
+ */
+static int
+dissect_ses(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ int offset = 0;
+ guint8 type;
+ gboolean is_clsp = FALSE;
+
+ type = tvb_get_guint8(tvb, offset);
+ if(type == CLSES_UNIT_DATA)
+ is_clsp = TRUE;
+
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, is_clsp ? "CLSES" : "SES");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+
+ /*
+ * Do we have a category 0 SPDU (GIVE_TOKENS/PLEASE_TOKENS) as
+ * the first SPDU?
+ *
+ * If so, dissect it as such (GIVE_TOKENS and DATA_TRANSFER have
+ * the same SPDU type value).
+ */
+ if ((type == SES_PLEASE_TOKENS) || (type == SES_GIVE_TOKENS))
+ offset = dissect_spdu(tvb, offset, pinfo, tree, TOKENS_SPDU, FALSE);
+
+
+ /* Dissect the remaining SPDUs. */
+ while (tvb_reported_length_remaining(tvb, offset) > 0)
+ offset = dissect_spdu(tvb, offset, pinfo, tree, NON_TOKENS_SPDU, is_clsp);
+ return tvb_captured_length(tvb);
+}
+
+static gboolean
+dissect_ses_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
+{
+ /* must check that this really is a ses packet */
+ int offset = 0;
+ guint8 type;
+ int len_len;
+ guint16 len;
+
+ /* first, check do we have at least 4 bytes (type+length) */
+ if (tvb_captured_length(tvb) < 2)
+ return FALSE; /* no */
+
+ /* can we recognize session PDU ? Return FALSE if not */
+ /* get SPDU type */
+ type = tvb_get_guint8(tvb, offset);
+ /* check SPDU type */
+ if (try_val_to_str_ext(type, &ses_vals_ext) == NULL)
+ {
+ return FALSE; /* no, it isn't a session PDU */
+ }
+
+ /* can we recognize the second session PDU if the first one was
+ * a Give Tokens PDU? Return FALSE if not */
+ if(tvb_bytes_exist(tvb, 2, 2) && type == SES_GIVE_TOKENS) {
+ /* get SPDU type */
+ type = tvb_get_guint8(tvb, offset+2);
+ /* check SPDU type */
+ if (try_val_to_str_ext(type, &ses_vals_ext) == NULL)
+ {
+ return FALSE; /* no, it isn't a session PDU */
+ }
+ }
+
+ /* some Siemens SIMATIC protocols also use COTP, and shouldn't be
+ * misinterpreted as SES.
+ * the starter in this case is fixed to 0x32 (SES_MINOR_SYNC_ACK for SES),
+ * so if the parameter type is unknown, it's probably SIMATIC */
+ if(type == 0x32 && tvb_captured_length(tvb) >= 3) {
+ type = tvb_get_guint8(tvb, offset+2);
+ if (try_val_to_str_ext(type, &param_vals_ext) == NULL) {
+ return FALSE; /* it's probably a SIMATIC protocol */
+ }
+ }
+
+ /* OK,let's check SPDU length */
+ /* get length of SPDU */
+ len = get_item_len(tvb, offset+1, &len_len);
+
+ /* add header length */
+ len+=len_len;
+ /* do we have enough bytes ? */
+ if (tvb_reported_length(tvb) < len)
+ return FALSE; /* no */
+
+ /* final check to see if the next SPDU, if present, is also valid */
+ if (tvb_captured_length(tvb) > 1+(guint) len) {
+ type = tvb_get_guint8(tvb, offset + len + 1);
+ /* check SPDU type */
+ if (try_val_to_str_ext(type, &ses_vals_ext) == NULL) {
+ return FALSE; /* no, it isn't a session PDU */
+ }
+ }
+
+ dissect_ses(tvb, pinfo, parent_tree, data);
+ return TRUE;
+}
+
+void
+proto_register_ses(void)
+{
+ static hf_register_info hf[] =
+ {
+ {
+ &hf_ses_type,
+ {
+ "SPDU Type",
+ "ses.type",
+ FT_UINT8,
+ BASE_DEC | BASE_EXT_STRING,
+ &ses_vals_ext,
+ 0x0,
+ NULL, HFILL
+ }
+ },
+ {
+ &hf_ses_type_0,
+ {
+ "SPDU Type",
+ "ses.type",
+ FT_UINT8,
+ BASE_DEC,
+ VALS(ses_category0_vals),
+ 0x0,
+ NULL, HFILL
+ }
+ },
+ {
+ &hf_ses_length,
+ {
+ "Length",
+ "ses.length",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ NULL, HFILL
+ }
+ },
+
+#if 0
+ {
+ &hf_ses_version,
+ {
+ "Version",
+ "ses.version",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ NULL, HFILL
+ }
+ },
+#endif
+#if 0
+ {
+ &hf_ses_reserved,
+ {
+ "Reserved",
+ "ses.reserved",
+ FT_UINT8,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ NULL, HFILL
+ }
+ },
+#endif
+ {
+ &hf_called_ss_user_reference,
+ {
+ "Called SS User Reference",
+ "ses.called_ss_user_reference",
+ FT_BYTES, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_calling_ss_user_reference,
+ {
+ "Calling SS User Reference",
+ "ses.calling_ss_user_reference",
+ FT_BYTES, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_common_reference,
+ {
+ "Common Reference",
+ "ses.common_reference",
+ FT_BYTES, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_additional_reference_information,
+ {
+ "Additional Reference Information",
+ "ses.additional_reference_information",
+ FT_BYTES, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_release_token,
+ {
+ "release token",
+ "ses.release_token",
+ FT_BOOLEAN, 8,
+ NULL,
+ RELEASE_TOKEN,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_major_activity_token,
+ {
+ "major/activity token",
+ "ses.major.token",
+ FT_BOOLEAN, 8,
+ NULL,
+ MAJOR_ACTIVITY_TOKEN,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_synchronize_minor_token,
+ {
+ "synchronize minor token",
+ "ses.synchronize_token",
+ FT_BOOLEAN, 8,
+ NULL,
+ SYNCHRONIZE_MINOR_TOKEN,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_data_token,
+ {
+ "data token",
+ "ses.data_token",
+ FT_BOOLEAN, 8,
+ NULL,
+ DATA_TOKEN,
+ "data token",
+ HFILL
+ }
+ },
+ {
+ &hf_able_to_receive_extended_concatenated_SPDU,
+ {
+ "Able to receive extended concatenated SPDU",
+ "ses.connect.f1",
+ FT_BOOLEAN, 8,
+ NULL,
+ SES_EXT_CONT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_session_user_req_flags,
+ {
+ "Flags",
+ "ses.req.flags",
+ FT_UINT16,
+ BASE_HEX,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_session_exception_report,
+ {
+ "Session exception report",
+ "ses.exception_report",
+ FT_BOOLEAN, 16,
+ NULL,
+ SES_EXCEPTION_REPORT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_data_separation_function_unit,
+ {
+ "Data separation function unit",
+ "ses.data_sep",
+ FT_BOOLEAN, 16,
+ NULL,
+ DATA_SEPARATION_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_symmetric_synchronize_function_unit,
+ {
+ "Symmetric synchronize function unit",
+ "ses.symm_sync",
+ FT_BOOLEAN, 16,
+ NULL,
+ SYMMETRIC_SYNCHRONIZE_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_typed_data_function_unit,
+ {
+ "Typed data function unit",
+ "ses.typed_data",
+ FT_BOOLEAN, 16,
+ NULL,
+ TYPED_DATA_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_exception_function_unit,
+ {
+ "Exception function unit",
+ "ses.exception_data",
+ FT_BOOLEAN, 16,
+ NULL,
+ EXCEPTION_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_capability_function_unit,
+ {
+ "Capability function unit",
+ "ses.capability_data",
+ FT_BOOLEAN, 16,
+ NULL,
+ CAPABILITY_DATA_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_negotiated_release_function_unit,
+ {
+ "Negotiated release function unit",
+ "ses.negotiated_release",
+ FT_BOOLEAN, 16,
+ NULL,
+ NEGOTIATED_RELEASE_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_activity_management_function_unit,
+ {
+ "Activity management function unit",
+ "ses.activity_management",
+ FT_BOOLEAN, 16,
+ NULL,
+ ACTIVITY_MANAGEMENT_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_resynchronize_function_unit,
+ {
+ "Resynchronize function unit",
+ "ses.resynchronize",
+ FT_BOOLEAN, 16,
+ NULL,
+ RESYNCHRONIZE_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_major_resynchronize_function_unit,
+ {
+ "Major resynchronize function unit",
+ "ses.major_resynchronize",
+ FT_BOOLEAN, 16,
+ NULL,
+ MAJOR_SYNCHRONIZE_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_minor_resynchronize_function_unit,
+ {
+ "Minor resynchronize function unit",
+ "ses.minor_resynchronize",
+ FT_BOOLEAN, 16,
+ NULL,
+ MINOR_SYNCHRONIZE_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_expedited_data_resynchronize_function_unit,
+ {
+ "Expedited data function unit",
+ "ses.expedited_data",
+ FT_BOOLEAN, 16,
+ NULL,
+ EXPEDITED_DATA_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_duplex_function_unit,
+ {
+ "Duplex functional unit",
+ "ses.duplex",
+ FT_BOOLEAN, 16,
+ NULL,
+ DUPLEX_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_half_duplex_function_unit,
+ {
+ "Half-duplex functional unit",
+ "ses.half_duplex",
+ FT_BOOLEAN, 16,
+ NULL,
+ HALF_DUPLEX_FUNCTION_UNIT,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_proposed_tsdu_maximum_size_i2r,
+ {
+ "Proposed TSDU Maximum Size, Initiator to Responder",
+ "ses.proposed_tsdu_maximum_size_i2r",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_proposed_tsdu_maximum_size_r2i,
+ {
+ "Proposed TSDU Maximum Size, Responder to Initiator",
+ "ses.proposed_tsdu_maximum_size_r2i",
+ FT_UINT16,
+ BASE_DEC,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_protocol_version_1,
+ {
+ "Protocol Version 1",
+ "ses.protocol_version1",
+ FT_BOOLEAN, 8,
+ NULL,
+ PROTOCOL_VERSION_1,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_protocol_version_2,
+ {
+ "Protocol Version 2",
+ "ses.protocol_version2",
+ FT_BOOLEAN, 8,
+ NULL,
+ PROTOCOL_VERSION_2,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_initial_serial_number,
+ {
+ "Initial Serial Number",
+ "ses.initial_serial_number",
+ FT_STRING, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_beginning_of_SSDU,
+ {
+ "beginning of SSDU",
+ "ses.beginning_of_SSDU",
+ FT_BOOLEAN, 8,
+ NULL,
+ BEGINNING_SPDU,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_end_of_SSDU,
+ {
+ "end of SSDU",
+ "ses.end_of_SSDU",
+ FT_BOOLEAN, 8,
+ NULL,
+ END_SPDU,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_release_token_setting,
+ {
+ "release token setting",
+ "ses.release_token_setting",
+ FT_UINT8, BASE_HEX,
+ VALS(token_setting_vals),
+ 0xC0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_major_activity_token_setting,
+ {
+ "major/activity setting",
+ "ses.major_activity_token_setting",
+ FT_UINT8, BASE_HEX,
+ VALS(token_setting_vals),
+ 0x30,
+ "major/activity token setting",
+ HFILL
+ }
+ },
+ {
+ &hf_synchronize_minor_token_setting,
+ {
+ "synchronize-minor token setting",
+ "ses.synchronize_minor_token_setting",
+ FT_UINT8, BASE_HEX,
+ VALS(token_setting_vals),
+ 0x0C,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_data_token_setting,
+ {
+ "data token setting",
+ "ses.data_token_setting",
+ FT_UINT8, BASE_HEX,
+ VALS(token_setting_vals),
+ 0x03,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_activity_identifier,
+ {
+ "Activity Identifier",
+ "ses.activity_identifier",
+ FT_BYTES, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_serial_number,
+ {
+ "Serial Number",
+ "ses.serial_number",
+ FT_STRING, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_calling_session_selector,
+ {
+ "Calling Session Selector",
+ "ses.calling_session_selector",
+ FT_BYTES, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_called_session_selector,
+ {
+ "Called Session Selector",
+ "ses.called_session_selector",
+ FT_BYTES, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_second_serial_number,
+ {
+ "Second Serial Number",
+ "ses.second_serial_number",
+ FT_STRING, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_second_initial_serial_number,
+ {
+ "Second Initial Serial Number",
+ "ses.second_initial_serial_number",
+ FT_STRING, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_large_initial_serial_number,
+ {
+ "Large Initial Serial Number",
+ "ses.large_initial_serial_number",
+ FT_STRING, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_large_second_initial_serial_number,
+ {
+ "Large Second Initial Serial Number",
+ "ses.large_second_initial_serial_number",
+ FT_STRING, BASE_NONE,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_connect_protocol_options_flags,
+ {
+ "Flags",
+ "ses.connect.flags",
+ FT_UINT8,
+ BASE_HEX,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+ {
+ &hf_version_number_options_flags,
+
+ {
+ "Flags",
+ "ses.version.flags",
+ FT_UINT8,
+ BASE_HEX,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+
+ {
+ &hf_token_item_options_flags,
+
+ {
+ "Flags",
+ "ses.tken_item.flags",
+ FT_UINT8,
+ BASE_HEX,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+
+ {
+ &hf_enclosure_item_options_flags,
+
+ {
+ "Flags",
+ "ses.enclosure.flags",
+ FT_UINT8,
+ BASE_HEX,
+ NULL,
+ 0x0,
+ NULL,
+ HFILL
+ }
+ },
+
+ { &hf_ses_segment_data,
+ { "SES segment data", "ses.segment.data", FT_NONE, BASE_NONE,
+ NULL, 0x00, NULL, HFILL } },
+ { &hf_ses_segments,
+ { "SES segments", "ses.segments", FT_NONE, BASE_NONE,
+ NULL, 0x00, NULL, HFILL } },
+ { &hf_ses_segment,
+ { "SES segment", "ses.segment", FT_FRAMENUM, BASE_NONE,
+ NULL, 0x00, NULL, HFILL } },
+ { &hf_ses_segment_overlap,
+ { "SES segment overlap", "ses.segment.overlap", FT_BOOLEAN,
+ BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_ses_segment_overlap_conflicts,
+ { "SES segment overlapping with conflicting data",
+ "ses.segment.overlap.conflicts", FT_BOOLEAN, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_ses_segment_multiple_tails,
+ { "SES has multiple tail segments",
+ "ses.segment.multiple_tails", FT_BOOLEAN, BASE_NONE,
+ NULL, 0x0, NULL, HFILL } },
+ { &hf_ses_segment_too_long_segment,
+ { "SES segment too long", "ses.segment.too_long_segment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_ses_segment_error,
+ { "SES desegmentation error", "ses.segment.error", FT_FRAMENUM,
+ BASE_NONE, NULL, 0x00, NULL, HFILL } },
+ { &hf_ses_segment_count,
+ { "SES segment count", "ses.segment.count", FT_UINT32, BASE_DEC,
+ NULL, 0x00, NULL, HFILL } },
+ { &hf_ses_reassembled_in,
+ { "Reassembled SES in frame", "ses.reassembled.in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0x00, "This SES packet is reassembled in this frame", HFILL } },
+ { &hf_ses_reassembled_length,
+ { "Reassembled SES length", "ses.reassembled.length", FT_UINT32, BASE_DEC,
+ NULL, 0x00, "The total length of the reassembled payload", HFILL } },
+
+ /* Generated from convert_proto_tree_add_text.pl */
+ { &hf_ses_user_data, { "User data", "ses.user_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ses_transport_option_flags, { "Flags", "ses.transport_flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+ { &hf_ses_transport_connection, { "Transport connection", "ses.transport_flags.connection", FT_BOOLEAN, 8, TFS(&tfs_released_kept), transport_connection_is_released, NULL, HFILL }},
+ { &hf_ses_transport_user_abort, { "User abort", "ses.transport_flags.user_abort", FT_BOOLEAN, 8, TFS(&tfs_yes_no), user_abort, NULL, HFILL }},
+ { &hf_ses_transport_protocol_error, { "Protocol error", "ses.transport_flags.protocol_error", FT_BOOLEAN, 8, TFS(&tfs_yes_no), protocol_error, NULL, HFILL }},
+ { &hf_ses_transport_no_reason, { "No reason", "ses.transport_flags.no_reason", FT_BOOLEAN, 8, TFS(&tfs_yes_no), no_reason, NULL, HFILL }},
+ { &hf_ses_transport_implementation_restriction, { "Implementation restriction", "ses.transport_flags.implementation_restriction", FT_BOOLEAN, 8, TFS(&tfs_yes_no), implementation_restriction, NULL, HFILL }},
+ { &hf_ses_reason_code, { "Reason Code", "ses.reason_code", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &reason_vals_ext, 0x0, NULL, HFILL }},
+ { &hf_ses_parameter_type, { "Parameter type", "ses.parameter_type", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &param_vals_ext, 0x0, NULL, HFILL }},
+ { &hf_ses_parameter_length, { "Parameter length", "ses.parameter_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_ses_parameter_group_inside_parameter_group, { "Parameter group inside parameter group", "ses.parameter_group_inside_parameter_group", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ };
+
+ static gint *ett[] =
+ {
+ &ett_ses,
+ &ett_ses_param,
+ &ett_connect_protocol_options_flags,
+ &ett_transport_options_flags,
+ &ett_protocol_version_flags,
+ &ett_enclosure_item_flags,
+ &ett_token_item_flags,
+ &ett_ses_req_options_flags,
+ &ett_ses_segment,
+ &ett_ses_segments
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_ses_bad_length, { "ses.bad_length", PI_MALFORMED, PI_ERROR, "Bad length", EXPFILL }},
+ { &ei_ses_bad_parameter_length, { "ses.bad_parameter_length", PI_MALFORMED, PI_ERROR, "Bad parameter length", EXPFILL }},
+ };
+
+ module_t *ses_module;
+ expert_module_t* expert_ses;
+
+ proto_ses = proto_register_protocol(PROTO_STRING_SES, "SES", "ses");
+ proto_register_field_array(proto_ses, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ expert_ses = expert_register_protocol(proto_ses);
+ expert_register_field_array(expert_ses, ei, array_length(ei));
+
+ reassembly_table_register (&ses_reassembly_table,
+ &addresses_reassembly_table_functions);
+
+ ses_module = prefs_register_protocol(proto_ses, NULL);
+
+ prefs_register_bool_preference(ses_module, "desegment",
+ "Reassemble session packets ",
+ "Whether the session dissector should reassemble messages spanning multiple SES segments",
+ &ses_desegment);
+
+ /*
+ * Register the dissector by name, so other dissectors can
+ * grab it by name rather than just referring to it directly
+ * (you can't refer to it directly from a plugin dissector
+ * on Windows without stuffing it into the Big Transfer Vector).
+ */
+ register_dissector("ses", dissect_ses, proto_ses);
+}
+
+void
+proto_reg_handoff_ses(void)
+{
+ /* define sub dissector */
+ pres_handle = find_dissector_add_dependency("pres", proto_ses);
+
+ /* add our session dissector to cotp dissector list
+ * and cotp_is dissector list*/
+ heur_dissector_add("cotp", dissect_ses_heur, "SES over COTP", "ses_cotp", proto_ses, HEURISTIC_ENABLE);
+ heur_dissector_add("cotp_is", dissect_ses_heur, "SES over COTP (inactive subset)", "ses_cotp_is", proto_ses, HEURISTIC_ENABLE);
+}
+
+
+
+void proto_register_clses(void)
+{
+ proto_clses = proto_register_protocol(PROTO_STRING_CLSES, "CLSP", "clsp");
+}
+
+void
+proto_reg_handoff_clses(void)
+{
+ /* add our session dissector to cltp dissector list */
+ heur_dissector_add("cltp", dissect_ses_heur, "CLSP over COTP", "clses_cotp", proto_clses, HEURISTIC_ENABLE);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */