3 * Routine to dissect ISO 8327-1 OSI Session Protocol packets
5 * $Id: packet-ses.c,v 1.5 2003/12/12 22:19:45 guy Exp $
7 * Yuriy Sidelnikov <YSidelnikov@hotmail.com>
9 * Ethereal - Network traffic analyzer
10 * By Gerald Combs <gerald@ethereal.com>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #include <epan/packet.h>
38 #include "packet-ses.h"
39 #include "packet-frame.h"
42 #include <epan/strutil.h>
44 /* ses header fields */
45 static int proto_ses = -1;
46 static int hf_ses_type = -1;
47 static int hf_ses_type_0 = -1;
48 static int hf_ses_length = -1;
49 static int hf_ses_version = -1;
50 static int hf_ses_reserved = -1;
52 /* ses fields defining a sub tree */
53 static gint ett_ses = -1;
54 static gint ett_ses_param = -1;
57 ----------------------------------------------------------------------------------------------------------*/
58 static dissector_handle_t pres_handle = NULL;
60 ----------------------------------------------------------------------------------------------------------*/
64 static int hf_connect_protocol_options_flags = -1;
65 static int hf_version_number_options_flags = -1;
66 static int hf_enclosure_item_options_flags = -1;
67 static int hf_token_item_options_flags = -1;
69 static gint ett_connect_protocol_options_flags = -1;
70 static gint ett_protocol_version_flags = -1;
71 static gint ett_enclosure_item_flags = -1;
72 static gint ett_token_item_flags = -1;
73 static gint ett_ses_req_options_flags = -1;
75 /* called SS user reference */
76 static int hf_called_ss_user_reference = -1;
78 /* calling SS user reference */
79 static int hf_calling_ss_user_reference = -1;
81 /* common reference */
82 static int hf_common_reference = -1;
84 /* additional reference information */
85 static int hf_additional_reference_information = -1;
88 static int hf_release_token = -1;
89 static int hf_major_activity_token = -1;
90 static int hf_synchronize_minor_token = -1;
91 static int hf_data_token = -1;
93 /* protocol options */
94 static int hf_able_to_receive_extended_concatenated_SPDU = -1;
96 /* session requirement */
97 static int hf_session_user_req_flags = -1;
98 static int hf_session_exception_report= -1;
99 static int hf_data_separation_function_unit= -1;
100 static int hf_symmetric_synchronize_function_unit= -1;
101 static int hf_typed_data_function_unit= -1;
102 static int hf_exception_function_unit= -1;
103 static int hf_capability_function_unit=-1;
104 static int hf_negotiated_release_function_unit= -1;
105 static int hf_activity_management_function_unit= -1;
106 static int hf_resynchronize_function_unit= -1;
107 static int hf_major_resynchronize_function_unit= -1;
108 static int hf_minor_resynchronize_function_unit= -1;
109 static int hf_expedited_data_resynchronize_function_unit= -1;
110 static int hf_duplex_function_unit= -1;
111 static int hf_half_duplex_function_unit = -1;
113 /* TSDU maximum size */
114 static int hf_proposed_tsdu_maximum_size_i2r = -1;
115 static int hf_proposed_tsdu_maximum_size_r2i = -1;
117 /* protocol version */
118 static int hf_protocol_version_1 = -1;
119 static int hf_protocol_version_2 = -1;
121 /* initial serial number */
122 static int hf_initial_serial_number = -1;
125 static int hf_beginning_of_SSDU = -1;
126 static int hf_end_of_SSDU = -1;
128 /* token setting item */
130 static const value_string token_setting_vals[] = {
131 { 0x00, "initiator's side" },
132 { 0x01, "responder's side" },
133 { 0x02, "called SS user's choice" },
134 { 0x03, "reserved" },
138 static int hf_release_token_setting = -1;
139 static int hf_major_activity_token_setting = -1;
140 static int hf_synchronize_minor_token_setting = -1;
141 static int hf_data_token_setting = -1;
143 /* calling session selector */
144 static int hf_calling_session_selector = -1;
146 /* called session selector */
147 static int hf_called_session_selector = -1;
150 static int hf_serial_number = -1;
152 /* second serial number */
153 static int hf_second_serial_number = -1;
155 /* second initial serial number */
156 static int hf_second_initial_serial_number = -1;
158 /* large initial serial number */
159 static int hf_large_initial_serial_number = -1;
161 /* large second initial serial number */
162 static int hf_large_second_initial_serial_number = -1;
164 static const value_string ses_vals[] =
166 {SES_CONNECTION_REQUEST, "Connection request PDU" },
167 {SES_CONNECTION_ACCEPT, "Connection accept PDU" },
168 {SES_EXCEPTION_REPORT, "Exception report PDU" },
169 {SES_DATA_TRANSFER, "Data transfer PDU" },
170 {SES_PLEASE_TOKENS, "Please tokens PDU" },
171 {SES_EXPEDITED, "Expedited PDU" },
172 {SES_PREPARE, "Prepare PDU" },
173 {SES_NOT_FINISHED, "Not finished PDU" },
174 {SES_FINISH, "Finish PDU" },
175 {SES_DISCONNECT, "Disconnect PDU" },
176 {SES_REFUSE, "Refuse PDU" },
177 {SES_CONNECTION_DATA_OVERFLOW, "Data overflow PDU" },
178 {SES_OVERFLOW_ACCEPT, "Overflow accept PDU" },
179 {SES_GIVE_TOKENS_CONFIRM, "Tokens confirm PDU" },
180 {SES_GIVE_TOKENS_ACK, "Give tokens ACK PDU" },
181 {SES_ABORT, "Abort PDU" },
182 {SES_ABORT_ACCEPT, "Abort accept PDU" },
183 {SES_ACTIVITY_RESUME, "Activity resume PDU" },
184 {SES_TYPED_DATA, "Typed data PDU" },
185 {SES_RESYNCHRONIZE_ACK, "Resynchronize ACK PDU" },
186 {SES_MAJOR_SYNC_POINT, "Session major sync point PDU" },
187 {SES_MAJOR_SYNC_ACK, "Session major sync ACK PDU" },
188 {SES_ACTIVITY_START, "Activity start PDU" },
189 {SES_EXCEPTION_DATA, "Exception data PDU" },
190 {SES_MINOR_SYNC_POINT, "Minor sync point PDU" },
191 {SES_MINOR_SYNC_ACK, "Minor sync ACK PDU" },
192 {SES_RESYNCHRONIZE, "Resynchronize PDU" },
193 {SES_ACTIVITY_DISCARD, "Activity discard PDU" },
194 {SES_ACTIVITY_DISCARD_ACK, "Activity discard ACK PDU" },
195 {SES_CAPABILITY, "Capability PDU" },
196 {SES_CAPABILITY_DATA_ACK, "Capability data ACK PDU" },
200 static const value_string ses_category0_vals[] =
202 {SES_PLEASE_TOKENS, "Please tokens PDU" },
203 {SES_GIVE_TOKENS, "Give tokens PDU" },
208 static const value_string param_vals[] =
210 {Connection_Identifier, "Connection Identifier"},
211 {Connect_Accept_Item, "Connect Accept Item"},
212 {Called_SS_user_Reference, "Called SS user Reference"},
213 {Calling_SS_user_Reference, "Calling SS user Reference"},
214 {Common_Reference, "Common Reference"},
215 {Sync_Type_Item, "Sync Type Item"},
216 {Token_Item, "Token Item"},
217 {Transport_Disconnect, "Transport_Disconnect"},
218 {Additional_Reference_Information, "Additional Reference Information"},
219 {Protocol_Options, "Protocol Options"},
220 {TSDU_Maximum_Size, "TSDU Maximum Size"},
221 {Version_Number, "Version Number"},
222 {Initial_Serial_Number, "Initial Serial Number"},
223 {Prepare_Type, "Prepare Type"},
224 {EnclosureItem, "Enclosure Item"},
225 {Token_Setting_Item, "Token Setting Item"},
226 {Resync_Type, "Resync Type"},
227 {Serial_Number, "Serial Number"},
228 {Linking_Information, "Linking Information"},
229 {Reflect_Parameter, "Reflect Parameter"},
230 {Reason_Code, "Reason Code"},
231 {Calling_Session_Selector, "Calling Session Selector"},
232 {Called_Session_Selector, "Called Session Selector"},
233 {Second_Resync_Type, "Second Resync Type"},
234 {Second_Serial_Number, "Second Serial Number"},
235 {Second_Initial_Serial_Number, "Second Initial Serial Number"},
236 {Upper_Limit_Serial_Number, "Upper Limit Serial Number"},
237 {Large_Initial_Serial_Number, "Large Initial Serial Number"},
238 {Large_Second_Initial_Serial_Number, "Large Second Initial Serial Number"},
239 {Data_Overflow, "Data Overflow"},
240 {Session_Requirement, "Session Requirement"},
241 {User_Data, "Session user data"},
242 {Extended_User_Data, "Session extended user data"},
246 static const value_string reason_vals[] =
248 {reason_not_specified, "Rejection by called SS-user; reason not specified" },
249 {temporary_congestion, "Rejection by called SS-user due to temporary congestion" },
250 {Subsequent, "Rejection by called SS-user." },
251 {Session_Selector_unknown, "Session Selector unknown" },
252 {SS_user_not_attached_to_SSAP, "SS-user not attached to SSAP" },
253 {SPM_congestion_at_connect_time, "SPM congestion at connect time" },
254 {versions_not_supported, "Proposed protocol versions not supported" },
255 {SPM_reason_not_specified, "Rejection by the SPM; reason not specified" },
256 {SPM_implementation_restriction, "Finish PDU" },
257 {SES_DISCONNECT, "Rejection by the SPM; implementation restriction stated in the PICS" },
261 /* desegmentation of OSI over ses */
262 /*static gboolean ses_desegment = TRUE;*/
265 /* find the dissector for data */
266 static dissector_handle_t data_handle;
269 call_pres_dissector(tvbuff_t *tvb, int offset, guint16 param_len,
270 packet_info *pinfo, proto_tree *tree, proto_tree *param_tree)
272 /* do we have OSI presentation packet dissector ? */
275 /* No - display as data */
278 proto_tree_add_text(param_tree, tvb, offset, param_len,
284 /* Yes - call presentation dissector */
287 next_tvb = tvb_new_subset(tvb, offset, param_len, param_len);
290 call_dissector(pres_handle, next_tvb, pinfo, tree);
294 show_exception(tvb, pinfo, tree, EXCEPT_CODE);
300 /* this routine returns length of parameter field, parameter group,
303 get_item_len(tvbuff_t *tvb, int offset, int *len_len)
307 len = tvb_get_guint8(tvb, offset);
308 if(len == TWO_BYTE_LEN)
310 len = tvb_get_ntohs(tvb, offset+1);
319 dissect_parameter(tvbuff_t *tvb, int offset, proto_tree *tree,
320 proto_tree *param_tree, packet_info *pinfo, guint8 param_type,
323 gboolean has_user_information = TRUE;
326 proto_tree *flags_tree;
330 case Called_SS_user_Reference:
335 proto_tree_add_item(param_tree,
336 hf_called_ss_user_reference,
337 tvb, offset, param_len, FALSE);
341 case Calling_SS_user_Reference:
346 proto_tree_add_item(param_tree,
347 hf_calling_ss_user_reference,
348 tvb, offset, param_len, FALSE);
352 case Common_Reference:
357 proto_tree_add_item(param_tree,
359 tvb, offset, param_len, FALSE);
363 case Additional_Reference_Information:
368 proto_tree_add_item(param_tree,
369 hf_additional_reference_information,
370 tvb, offset, param_len, FALSE);
377 proto_tree_add_text(param_tree, tvb, offset,
378 param_len, "Length is %u, should be 1",
384 flags = tvb_get_guint8(tvb, offset);
385 tf = proto_tree_add_uint(param_tree,
386 hf_token_item_options_flags, tvb, offset, 1,
388 flags_tree = proto_item_add_subtree(tf,
389 ett_token_item_flags);
390 proto_tree_add_boolean(flags_tree, hf_release_token,
391 tvb, offset, 1, flags);
392 proto_tree_add_boolean(flags_tree,
393 hf_major_activity_token, tvb, offset, 1, flags);
394 proto_tree_add_boolean(flags_tree,
395 hf_synchronize_minor_token, tvb, offset, 1, flags);
396 proto_tree_add_boolean(flags_tree, hf_data_token, tvb,
401 case Transport_Disconnect:
404 proto_tree_add_text(param_tree, tvb, offset,
405 param_len, "Length is %u, should be 1",
413 flags = tvb_get_guint8(tvb, offset);
414 if(flags & transport_connection_is_released )
416 proto_tree_add_text(param_tree, tvb, offset, 1,
417 "transport connection is released");
421 proto_tree_add_text(param_tree, tvb, offset, 1,
422 "transport connection is kept");
425 if(flags & user_abort )
427 proto_tree_add_text(param_tree, tvb, offset, 1,
431 if(flags & protocol_error )
433 proto_tree_add_text(param_tree, tvb, offset, 1,
437 if(flags & no_reason )
439 proto_tree_add_text(param_tree, tvb, offset, 1,
443 if(flags & implementation_restriction )
445 proto_tree_add_text(param_tree, tvb, offset, 1,
446 "implementation restriction");
451 case Protocol_Options:
454 proto_tree_add_text(param_tree, tvb, offset,
455 param_len, "Length is %u, should be 1",
461 flags = tvb_get_guint8(tvb, offset);
462 tf = proto_tree_add_uint(param_tree,
463 hf_connect_protocol_options_flags, tvb, offset, 1,
465 flags_tree = proto_item_add_subtree(tf,
466 ett_connect_protocol_options_flags);
467 proto_tree_add_boolean(flags_tree,
468 hf_able_to_receive_extended_concatenated_SPDU,
469 tvb, offset, 1, flags);
473 case Session_Requirement:
476 proto_tree_add_text(param_tree, tvb, offset,
477 param_len, "Length is %u, should be 2",
483 flags = tvb_get_ntohs(tvb, offset);
484 tf = proto_tree_add_uint(param_tree,
485 hf_session_user_req_flags, tvb, offset, 2,
487 flags_tree = proto_item_add_subtree(tf,
488 ett_ses_req_options_flags);
489 proto_tree_add_boolean(flags_tree,
490 hf_session_exception_report, tvb, offset, 2, flags);
491 proto_tree_add_boolean(flags_tree,
492 hf_data_separation_function_unit, tvb, offset, 2,
494 proto_tree_add_boolean(flags_tree,
495 hf_symmetric_synchronize_function_unit,
496 tvb, offset, 2, flags);
497 proto_tree_add_boolean(flags_tree,
498 hf_typed_data_function_unit, tvb, offset, 2, flags);
499 proto_tree_add_boolean(flags_tree,
500 hf_exception_function_unit, tvb, offset, 2, flags);
501 proto_tree_add_boolean(flags_tree,
502 hf_capability_function_unit, tvb, offset, 2, flags);
503 proto_tree_add_boolean(flags_tree,
504 hf_negotiated_release_function_unit,
505 tvb, offset, 2, flags);
506 proto_tree_add_boolean(flags_tree,
507 hf_activity_management_function_unit,
508 tvb, offset, 2, flags);
509 proto_tree_add_boolean(flags_tree,
510 hf_resynchronize_function_unit, tvb, offset, 2,
512 proto_tree_add_boolean(flags_tree,
513 hf_major_resynchronize_function_unit,
514 tvb, offset, 2, flags);
515 proto_tree_add_boolean(flags_tree,
516 hf_minor_resynchronize_function_unit,
517 tvb, offset, 2, flags);
518 proto_tree_add_boolean(flags_tree,
519 hf_expedited_data_resynchronize_function_unit,
520 tvb, offset, 2, flags);
521 proto_tree_add_boolean(flags_tree,
522 hf_duplex_function_unit, tvb, offset, 2, flags);
523 proto_tree_add_boolean(flags_tree,
524 hf_half_duplex_function_unit,
525 tvb, offset, 2, flags);
529 case TSDU_Maximum_Size:
532 proto_tree_add_text(param_tree, tvb, offset,
533 param_len, "Length is %u, should be 4",
539 proto_tree_add_item(param_tree,
540 hf_proposed_tsdu_maximum_size_i2r,
541 tvb, offset, 2, FALSE);
542 proto_tree_add_item(param_tree,
543 hf_proposed_tsdu_maximum_size_r2i,
544 tvb, offset+2, 2, FALSE);
551 proto_tree_add_text(param_tree, tvb, offset,
552 param_len, "Length is %u, should be 1",
558 flags = tvb_get_guint8(tvb, offset);
559 tf = proto_tree_add_uint(param_tree,
560 hf_version_number_options_flags, tvb, offset, 1,
562 flags_tree = proto_item_add_subtree(tf,
563 ett_protocol_version_flags);
564 proto_tree_add_boolean(flags_tree,
565 hf_protocol_version_2, tvb, offset, 1, flags);
566 proto_tree_add_boolean(flags_tree,
567 hf_protocol_version_1, tvb, offset, 1, flags);
571 case Initial_Serial_Number:
576 proto_tree_add_item(param_tree,
577 hf_initial_serial_number,
578 tvb, offset, param_len, FALSE);
585 proto_tree_add_text(param_tree, tvb, offset,
586 param_len, "Length is %u, should be 1",
590 flags = tvb_get_guint8(tvb, offset);
593 tf = proto_tree_add_uint(param_tree,
594 hf_enclosure_item_options_flags, tvb, offset, 1,
596 flags_tree = proto_item_add_subtree(tf,
597 ett_enclosure_item_flags);
598 proto_tree_add_boolean(flags_tree, hf_end_of_SSDU,
599 tvb, offset, 1, flags);
600 proto_tree_add_boolean(flags_tree, hf_beginning_of_SSDU,
601 tvb, offset, 1, flags);
603 if (flags & END_SPDU) {
605 * In Data Transfer and Typed Data SPDUs,
606 * "The User Information Field shall be present
607 * if the Enclosure Item is not present, or has
608 * bit 2 = 0", which presumably means it shall
609 * *not* be present if the Enclosure item *is*
610 * present and has bit 2 = 1.
612 has_user_information = FALSE;
616 case Token_Setting_Item:
619 proto_tree_add_text(param_tree, tvb, offset,
620 param_len, "Length is %u, should be 1",
626 proto_tree_add_item(param_tree,
627 hf_release_token_setting,
628 tvb, offset, 1, FALSE);
629 proto_tree_add_item(param_tree,
630 hf_major_activity_token_setting,
631 tvb, offset, 1, FALSE);
632 proto_tree_add_item(param_tree,
633 hf_synchronize_minor_token_setting,
634 tvb, offset, 1, FALSE);
635 proto_tree_add_item(param_tree,
636 hf_data_token_setting,
637 tvb, offset, 1, FALSE);
646 proto_tree_add_item(param_tree,
648 tvb, offset, param_len, FALSE);
654 0: Rejection by called SS-user; reason not specified.
655 1: Rejection by called SS-user due to temporary congestion.
656 2: Rejection by called SS-user. Subsequent octets may be used for user data
657 up to a length of 512 octets if Protocol Version 1 has been selected, and up
658 to a length such that the total length (including SI and LI) of the SPDU
659 does not exceed 65 539 octets if Protocol Version 2 has been selected.
660 128 + 1: Session Selector unknown.
661 128 + 2: SS-user not attached to SSAP.
662 128 + 3: SPM congestion at connect time.
663 128 + 4: Proposed protocol versions not supported.
664 128 + 5: Rejection by the SPM; reason not specified.
665 128 + 6: Rejection by the SPM; implementation restriction stated in the
669 proto_tree_add_text(param_tree, tvb, offset,
670 param_len, "Length is %u, should be >= 1",
678 reason_code = tvb_get_guint8(tvb, offset);
679 proto_tree_add_text(param_tree, tvb, offset, 1,
681 val_to_str(reason_code, reason_vals, "Unknown (%u)"));
687 call_pres_dissector(tvb, offset, param_len,
688 pinfo, tree, param_tree);
692 case Calling_Session_Selector:
697 proto_tree_add_item(param_tree,
698 hf_calling_session_selector,
699 tvb, offset, param_len, FALSE);
703 case Called_Session_Selector:
708 proto_tree_add_item(param_tree,
709 hf_called_session_selector,
710 tvb, offset, param_len, FALSE);
714 case Second_Serial_Number:
719 proto_tree_add_item(param_tree,
720 hf_second_serial_number,
721 tvb, offset, param_len, FALSE);
725 case Second_Initial_Serial_Number:
730 proto_tree_add_item(param_tree,
731 hf_second_initial_serial_number,
732 tvb, offset, param_len, FALSE);
736 case Large_Initial_Serial_Number:
741 proto_tree_add_item(param_tree,
742 hf_large_initial_serial_number,
743 tvb, offset, param_len, FALSE);
747 case Large_Second_Initial_Serial_Number:
752 proto_tree_add_item(param_tree,
753 hf_large_second_initial_serial_number,
754 tvb, offset, param_len, FALSE);
761 return has_user_information;
765 dissect_parameter_group(tvbuff_t *tvb, int offset, proto_tree *tree,
766 proto_tree *pg_tree, packet_info *pinfo, guint16 pg_len)
768 gboolean has_user_information = TRUE;
770 proto_tree *param_tree;
778 param_type = tvb_get_guint8(tvb, offset);
779 ti = proto_tree_add_text(pg_tree, tvb, offset, -1,
780 val_to_str(param_type, param_vals,
781 "Unknown parameter type (0x%02x)"));
782 param_tree = proto_item_add_subtree(ti, ett_ses_param);
783 param_str = match_strval(param_type, param_vals);
784 proto_tree_add_text(param_tree, tvb, offset, 1,
785 "Parameter type: %s",
786 param_str != NULL ? param_str : "Unknown");
789 param_len = get_item_len(tvb, offset, &len_len);
790 if (len_len > pg_len) {
791 proto_item_set_len(ti, pg_len + 1);
792 proto_tree_add_text(param_tree, tvb, offset, pg_len,
793 "Parameter length doesn't fit in parameter");
794 return has_user_information;
797 if (param_len > pg_len) {
798 proto_item_set_len(ti, pg_len + 1 + len_len);
799 proto_tree_add_text(param_tree, tvb, offset, pg_len,
800 "Parameter length: %u, should be <= %u",
802 return has_user_information;
804 proto_item_set_len(ti, 1 + len_len + param_len);
805 proto_tree_add_text(param_tree, tvb, offset, len_len,
806 "Parameter length: %u", param_len);
809 if (param_str != NULL)
813 /* PG's in PG's are invalid, presumably */
814 case Extended_User_Data:
816 case Connect_Accept_Item:
817 case Connection_Identifier:
818 case Linking_Information:
819 proto_tree_add_text(param_tree, tvb, offset,
821 "Parameter group inside parameter group");
825 if (!dissect_parameter(tvb, offset, tree,
826 param_tree, pinfo, param_type, param_len))
827 has_user_information = FALSE;
834 return has_user_information;
838 * Returns TRUE if there's a User Information field in this SPDU, FALSE
842 dissect_parameters(tvbuff_t *tvb, int offset, guint16 len, proto_tree *tree,
843 proto_tree *ses_tree, packet_info *pinfo)
845 gboolean has_user_information = TRUE;
847 proto_tree *param_tree;
855 param_type = tvb_get_guint8(tvb, offset);
856 ti = proto_tree_add_text(ses_tree, tvb, offset, -1,
857 val_to_str(param_type, param_vals,
858 "Unknown parameter type (0x%02x)"));
859 param_tree = proto_item_add_subtree(ti, ett_ses_param);
860 param_str = match_strval(param_type, param_vals);
861 proto_tree_add_text(param_tree, tvb, offset, 1,
862 "Parameter type: %s",
863 param_str != NULL ? param_str : "Unknown");
866 param_len = get_item_len(tvb, offset, &len_len);
868 proto_item_set_len(ti, len + 1 );
869 proto_tree_add_text(param_tree, tvb, offset, len,
870 "Parameter length doesn't fit in parameter");
871 return has_user_information;
874 if (param_len > len) {
875 proto_item_set_len(ti, len + 1 + len_len);
876 proto_tree_add_text(param_tree, tvb, offset, len,
877 "Parameter length: %u, should be <= %u",
879 return has_user_information;
881 proto_item_set_len(ti, 1 + len_len + param_len);
882 proto_tree_add_text(param_tree, tvb, offset, len_len,
883 "Parameter length: %u", param_len);
886 if (param_str != NULL)
890 case Extended_User_Data:
894 call_pres_dissector(tvb, offset, param_len,
895 pinfo, tree, param_tree);
899 case Connect_Accept_Item:
900 case Connection_Identifier:
901 case Linking_Information:
903 if (!dissect_parameter_group(tvb, offset, tree,
904 param_tree, pinfo, param_len))
905 has_user_information = FALSE;
908 /* everything else is a PI */
910 if (!dissect_parameter(tvb, offset, tree,
911 param_tree, pinfo, param_type, param_len))
912 has_user_information = FALSE;
919 return has_user_information;
926 dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
929 gboolean has_user_information = FALSE;
931 proto_item *ti = NULL;
932 proto_tree *ses_tree = NULL;
934 guint16 parameters_len;
940 type = tvb_get_guint8(tvb, offset);
943 if (check_col(pinfo->cinfo, COL_INFO))
944 col_add_str(pinfo->cinfo, COL_INFO,
945 val_to_str(type, ses_category0_vals, "Unknown SPDU type (0x%02x)"));
947 ti = proto_tree_add_item(tree, proto_ses, tvb, offset,
949 ses_tree = proto_item_add_subtree(ti, ett_ses);
950 proto_tree_add_uint(ses_tree, hf_ses_type_0, tvb,
954 if (check_col(pinfo->cinfo, COL_INFO))
955 col_add_str(pinfo->cinfo, COL_INFO,
956 val_to_str(type, ses_vals, "Unknown SPDU type (0x%02x)"));
958 ti = proto_tree_add_item(tree, proto_ses, tvb, offset,
960 ses_tree = proto_item_add_subtree(ti, ett_ses);
961 proto_tree_add_uint(ses_tree, hf_ses_type, tvb,
966 * Might this SPDU have a User Information field?
970 case SES_DATA_TRANSFER:
973 has_user_information = TRUE;
979 /* get length of SPDU parameter field */
980 parameters_len = get_item_len(tvb, offset, &len_len);
982 proto_tree_add_uint(ses_tree, hf_ses_length, tvb, offset,
983 len_len, parameters_len);
986 /* Dissect parameters. */
987 if (!dissect_parameters(tvb, offset, parameters_len, tree, ses_tree,
989 has_user_information = FALSE;
990 offset += parameters_len;
992 proto_item_set_end(ti, tvb, offset);
994 /* Dissect user information, if present */
995 if (has_user_information) {
996 if (tvb_reported_length_remaining(tvb, offset) > 0) {
997 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
999 /* do we have OSI presentation packet dissector ? */
1002 call_dissector(data_handle, next_tvb, pinfo,
1007 call_dissector(pres_handle, next_tvb, pinfo,
1012 * No more SPDUs to dissect. Set the offset to the
1013 * end of the tvbuff.
1015 offset = tvb_length(tvb);
1022 * Dissect SPDUs inside a TSDU.
1025 dissect_ses(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1030 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1031 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SES");
1032 if (check_col(pinfo->cinfo, COL_INFO))
1033 col_clear(pinfo->cinfo, COL_INFO);
1036 * Do we have a category 0 SPDU (GIVE_TOKENS/PLEASE_TOKENS) as
1039 * If so, dissect it as such (GIVE_TOKENS and DATA_TRANSFER have
1040 * the smae SPDU type value).
1042 type = tvb_get_guint8(tvb, offset);
1043 if (type == SES_PLEASE_TOKENS || type == SES_GIVE_TOKENS)
1044 offset = dissect_spdu(tvb, offset, pinfo, tree, TOKENS_SPDU);
1046 /* Dissect the remaining SPDUs. */
1047 while (tvb_reported_length_remaining(tvb, offset) > 0)
1048 offset = dissect_spdu(tvb, offset, pinfo, tree, NON_TOKENS_SPDU);
1052 proto_register_ses(void)
1054 static hf_register_info hf[] =
1075 VALS(ses_category0_vals),
1118 &hf_called_ss_user_reference,
1120 "Called SS User Reference",
1121 "ses.called_ss_user_reference",
1122 FT_BYTES, BASE_NONE,
1125 "Called SS User Reference",
1130 &hf_calling_ss_user_reference,
1132 "Calling SS User Reference",
1133 "ses.calling_ss_user_reference",
1134 FT_BYTES, BASE_NONE,
1137 "Calling SS User Reference",
1142 &hf_common_reference,
1145 "ses.common_reference",
1146 FT_BYTES, BASE_NONE,
1154 &hf_additional_reference_information,
1156 "Additional Reference Information",
1157 "ses.additional_reference_information",
1158 FT_BYTES, BASE_NONE,
1161 "Additional Reference Information",
1169 "ses.release_token",
1178 &hf_major_activity_token,
1180 "major/activity token",
1184 MAJOR_ACTIVITY_TOKEN,
1185 "major/activity token",
1190 &hf_synchronize_minor_token,
1192 "synchronize minor token",
1193 "ses.synchronize_token",
1196 SYNCHRONIZE_MINOR_TOKEN,
1197 "synchronize minor token",
1214 &hf_able_to_receive_extended_concatenated_SPDU,
1216 "Able to receive extended concatenated SPDU",
1221 "Able to receive extended concatenated SPDU",
1226 &hf_session_user_req_flags,
1239 &hf_session_exception_report,
1241 "Session exception report",
1242 "ses.exception_report.",
1245 SES_EXCEPTION_REPORT,
1246 "Session exception report",
1251 &hf_data_separation_function_unit,
1253 "Data separation function unit",
1257 DATA_SEPARATION_FUNCTION_UNIT,
1258 "Data separation function unit",
1263 &hf_symmetric_synchronize_function_unit,
1265 "Symmetric synchronize function unit",
1269 SYMMETRIC_SYNCHRONIZE_FUNCTION_UNIT,
1270 "Symmetric synchronize function unit",
1275 &hf_typed_data_function_unit,
1277 "Typed data function unit",
1281 TYPED_DATA_FUNCTION_UNIT,
1282 "Typed data function unit",
1287 &hf_exception_function_unit,
1289 "Exception function unit",
1290 "ses.exception_data",
1293 EXCEPTION_FUNCTION_UNIT,
1294 "Exception function unit",
1299 &hf_capability_function_unit,
1301 "Capability function unit",
1302 "ses.capability_data",
1305 CAPABILITY_DATA_FUNCTION_UNIT,
1306 "Capability function unit",
1311 &hf_negotiated_release_function_unit,
1313 "Negotiated release function unit",
1314 "ses.negotiated_release",
1317 NEGOTIATED_RELEASE_FUNCTION_UNIT,
1318 "Negotiated release function unit",
1323 &hf_activity_management_function_unit,
1325 "Activity management function unit",
1326 "ses.activity_management",
1329 ACTIVITY_MANAGEMENT_FUNCTION_UNIT,
1330 "Activity management function unit",
1335 &hf_resynchronize_function_unit,
1337 "Resynchronize function unit",
1338 "ses.resynchronize",
1341 RESYNCHRONIZE_FUNCTION_UNIT,
1342 "Resynchronize function unit",
1347 &hf_major_resynchronize_function_unit,
1349 "Major resynchronize function unit",
1350 "ses.major_resynchronize",
1353 MAJOR_SYNCHRONIZE_FUNCTION_UNIT,
1354 "Major resynchronize function unit",
1359 &hf_minor_resynchronize_function_unit,
1361 "Minor resynchronize function unit",
1362 "ses.minor_resynchronize",
1365 MINOR_SYNCHRONIZE_FUNCTION_UNIT,
1366 "Minor resynchronize function unit",
1371 &hf_expedited_data_resynchronize_function_unit,
1373 "Expedited data function unit",
1374 "ses.expedited_data",
1377 EXPEDITED_DATA_FUNCTION_UNIT,
1378 "Expedited data function unit",
1383 &hf_duplex_function_unit,
1385 "Duplex functional unit",
1389 DUPLEX_FUNCTION_UNIT,
1390 "Duplex functional unit",
1395 &hf_half_duplex_function_unit,
1397 "Half-duplex functional unit",
1401 HALF_DUPLEX_FUNCTION_UNIT,
1402 "Half-duplex functional unit",
1407 &hf_proposed_tsdu_maximum_size_i2r,
1409 "Proposed TSDU Maximum Size, Initiator to Responder",
1410 "ses.proposed_tsdu_maximum_size_i2r",
1415 "Proposed TSDU Maximum Size, Initiator to Responder",
1420 &hf_proposed_tsdu_maximum_size_r2i,
1422 "Proposed TSDU Maximum Size, Responder to Initiator",
1423 "ses.proposed_tsdu_maximum_size_r2i",
1428 "Proposed TSDU Maximum Size, Responder to Initiator",
1433 &hf_protocol_version_1,
1435 "Protocol Version 1",
1436 "ses.protocol_version1",
1440 "Protocol Version 1",
1445 &hf_protocol_version_2,
1447 "Protocol Version 2",
1448 "ses.protocol_version2",
1452 "Protocol Version 2",
1457 &hf_initial_serial_number,
1459 "Initial Serial Number",
1460 "ses.initial_serial_number",
1461 FT_STRING, BASE_NONE,
1464 "Initial Serial Number",
1469 &hf_beginning_of_SSDU,
1471 "beginning of SSDU",
1472 "ses.begininng_of_SSDU",
1476 "beginning of SSDU",
1493 &hf_release_token_setting,
1495 "release token setting",
1496 "ses.release_token_setting",
1498 VALS(token_setting_vals),
1500 "release token setting",
1505 &hf_major_activity_token_setting,
1507 "major/activity setting",
1508 "ses.major_activity_token_setting",
1510 VALS(token_setting_vals),
1512 "major/activity token setting",
1517 &hf_synchronize_minor_token_setting,
1519 "synchronize-minor token setting",
1520 "ses.synchronize_minor_token_setting",
1522 VALS(token_setting_vals),
1524 "synchronize-minor token setting",
1529 &hf_data_token_setting,
1531 "data token setting",
1532 "ses.data_token_setting",
1534 VALS(token_setting_vals),
1536 "data token setting",
1544 "ses.serial_number",
1545 FT_STRING, BASE_NONE,
1553 &hf_calling_session_selector,
1555 "Calling Session Selector",
1556 "ses.calling_session_selector",
1557 FT_BYTES, BASE_NONE,
1560 "Calling Session Selector",
1565 &hf_called_session_selector,
1567 "Called Session Selector",
1568 "ses.called_session_selector",
1569 FT_BYTES, BASE_NONE,
1572 "Called Session Selector",
1577 &hf_second_serial_number,
1579 "Second Serial Number",
1580 "ses.second_serial_number",
1581 FT_STRING, BASE_NONE,
1584 "Second Serial Number",
1589 &hf_second_initial_serial_number,
1591 "Second Initial Serial Number",
1592 "ses.second_initial_serial_number",
1593 FT_STRING, BASE_NONE,
1596 "Second Initial Serial Number",
1601 &hf_large_initial_serial_number,
1603 "Large Initial Serial Number",
1604 "ses.large_initial_serial_number",
1605 FT_STRING, BASE_NONE,
1608 "Large Initial Serial Number",
1613 &hf_large_second_initial_serial_number,
1615 "Large Second Initial Serial Number",
1616 "ses.large_second_initial_serial_number",
1617 FT_STRING, BASE_NONE,
1620 "Large Second Initial Serial Number",
1625 &hf_connect_protocol_options_flags,
1628 "ses.connect.flags",
1638 &hf_version_number_options_flags,
1642 "ses.version.flags",
1653 &hf_token_item_options_flags,
1657 "ses.tken_item.flags",
1668 &hf_enclosure_item_options_flags,
1672 "ses.enclosure.flags",
1683 static gint *ett[] =
1687 &ett_connect_protocol_options_flags,
1688 &ett_protocol_version_flags,
1689 &ett_enclosure_item_flags,
1690 &ett_token_item_flags,
1691 &ett_ses_req_options_flags,
1693 module_t *ses_module;
1696 proto_ses = proto_register_protocol(PROTO_STRING_SES, "SES", "ses");
1697 proto_register_field_array(proto_ses, hf, array_length(hf));
1698 proto_register_subtree_array(ett, array_length(ett));
1700 ses_module = prefs_register_protocol(proto_ses, NULL);
1702 prefs_register_bool_preference(ses_module, "desegment",
1703 "Desegment all session packets ",
1704 "Whether the session dissector should desegment all messages spanning multiple SES segments",
1708 * Register the dissector by name, so other dissectors can
1709 * grab it by name rather than just referring to it directly
1710 * (you can't refer to it directly from a plugin dissector
1711 * on Windows without stuffing it into the Big Transfer Vector).
1713 register_dissector("ses", dissect_ses, proto_ses);
1717 dissect_ses_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
1719 /* must check that this really is a ses packet */
1725 /* first, check do we have at least 4 bytes (type+length) */
1726 if (!tvb_bytes_exist(tvb, 0, 4))
1727 return FALSE; /* no */
1729 /* can we regognize session PDU ? Return FALSE if not */
1731 type = tvb_get_guint8(tvb, offset);
1732 /* check SPDU type */
1733 if (match_strval(type, ses_vals) == NULL)
1735 return FALSE; /* no, it isn't a session PDU */
1738 /* OK,let's check SPDU length */
1739 /* get length of SPDU */
1740 len = get_item_len(tvb, offset, &len_len);
1741 /* do we have enough bytes ? */
1742 if (!tvb_bytes_exist(tvb, 0, len))
1743 return FALSE; /* no */
1745 dissect_ses(tvb, pinfo, parent_tree);
1750 proto_reg_handoff_ses(void)
1752 /* find data dissector */
1753 data_handle = find_dissector("data");
1755 /* define sub dissector */
1756 pres_handle = find_dissector("pres");
1758 /* add our session dissector to cotp dissector list */
1759 heur_dissector_add("cotp", dissect_ses_heur, proto_ses);