warning: overflow in implicit constant conversion
[obnox/wireshark/wip.git] / packet-ses.c
1 /* packet-ses.c
2 *
3 * Routine to dissect ISO 8327-1 OSI Session Protocol packets
4 *
5 * $Id: packet-ses.c,v 1.5 2003/12/12 22:19:45 guy Exp $
6 *
7 * Yuriy Sidelnikov <YSidelnikov@hotmail.com>
8 *
9 * Ethereal - Network traffic analyzer
10 * By Gerald Combs <gerald@ethereal.com>
11 * Copyright 1998 Gerald Combs
12 *
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.
17 *
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.
22 *
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.
26 */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <glib.h>
33 #include <epan/packet.h>
34
35 #include <stdio.h>
36 #include <string.h>
37
38 #include "packet-ses.h"
39 #include "packet-frame.h"
40 #include "prefs.h"
41
42 #include <epan/strutil.h>
43
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;
51
52 /* ses fields defining a sub tree */
53 static gint ett_ses           = -1;
54 static gint ett_ses_param     = -1;
55
56 /* 
57 ----------------------------------------------------------------------------------------------------------*/
58 static dissector_handle_t pres_handle = NULL;
59 /* 
60 ----------------------------------------------------------------------------------------------------------*/
61
62
63 /* flags */
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;
68
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;
74
75 /* called SS user reference */
76 static int hf_called_ss_user_reference = -1;
77
78 /* calling SS user reference */
79 static int hf_calling_ss_user_reference = -1;
80
81 /* common reference */
82 static int hf_common_reference = -1;
83
84 /* additional reference information */
85 static int hf_additional_reference_information = -1;
86
87 /* token item */
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;
92
93 /* protocol options */
94 static int hf_able_to_receive_extended_concatenated_SPDU = -1;
95
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;
112
113 /* TSDU maximum size */
114 static int hf_proposed_tsdu_maximum_size_i2r = -1;
115 static int hf_proposed_tsdu_maximum_size_r2i = -1;
116
117 /* protocol version */
118 static int hf_protocol_version_1 = -1;
119 static int hf_protocol_version_2 = -1;
120
121 /* initial serial number */
122 static int hf_initial_serial_number = -1;
123
124 /* enclosure item */
125 static int hf_beginning_of_SSDU = -1;
126 static int hf_end_of_SSDU = -1;
127
128 /* token setting item */
129
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" },
135         { 0, NULL }
136 };
137         
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;
142
143 /* calling session selector */
144 static int hf_calling_session_selector = -1;
145
146 /* called session selector */
147 static int hf_called_session_selector = -1;
148
149 /* serial number */
150 static int hf_serial_number = -1;
151
152 /* second serial number */
153 static int hf_second_serial_number = -1;
154
155 /* second initial serial number */
156 static int hf_second_initial_serial_number = -1;
157
158 /* large initial serial number */
159 static int hf_large_initial_serial_number = -1;
160
161 /* large second initial serial number */
162 static int hf_large_second_initial_serial_number = -1;
163
164 static const value_string ses_vals[] =
165 {
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"   },
197   {0,             NULL           }
198 };
199
200 static const value_string ses_category0_vals[] =
201 {
202   {SES_PLEASE_TOKENS,    "Please tokens PDU"   },
203   {SES_GIVE_TOKENS,    "Give tokens PDU"   },
204   {0,             NULL           }
205 };
206
207
208 static const value_string param_vals[] =
209 {
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"},
243   {0, NULL}
244 };
245
246 static const value_string reason_vals[] =
247 {
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"   },
258   {0,             NULL           }
259 };
260
261 /* desegmentation of OSI over ses  */
262 /*static gboolean ses_desegment = TRUE;*/
263
264
265 /* find the dissector for data */
266 static dissector_handle_t data_handle;
267
268 static void
269 call_pres_dissector(tvbuff_t *tvb, int offset, guint16 param_len,
270     packet_info *pinfo, proto_tree *tree, proto_tree *param_tree)
271 {
272         /* do we have OSI presentation packet dissector ? */
273         if(!pres_handle)
274         {
275                 /* No - display as data */
276                 if (tree)
277                 {
278                         proto_tree_add_text(param_tree, tvb, offset, param_len,
279                             "User data");
280                 }
281         }
282         else
283         {
284                 /* Yes - call presentation dissector */
285                 tvbuff_t *next_tvb;
286
287                 next_tvb = tvb_new_subset(tvb, offset, param_len, param_len);
288                 TRY
289                 {
290                         call_dissector(pres_handle, next_tvb, pinfo, tree);
291                 }
292                 CATCH_ALL
293                 {
294                         show_exception(tvb, pinfo, tree, EXCEPT_CODE);
295                 }
296                 ENDTRY;
297         }
298 }
299
300 /* this routine returns length of parameter field, parameter group,
301    or parameter */
302 static int
303 get_item_len(tvbuff_t *tvb, int offset, int *len_len)
304 {
305         guint16 len;
306
307         len = tvb_get_guint8(tvb, offset);
308         if(len == TWO_BYTE_LEN)
309         {
310                 len = tvb_get_ntohs(tvb, offset+1);
311                 *len_len = 3;
312         }
313         else
314                 *len_len = 1;
315         return len;
316 }
317
318 static gboolean
319 dissect_parameter(tvbuff_t *tvb, int offset, proto_tree *tree,
320     proto_tree *param_tree, packet_info *pinfo, guint8 param_type,
321     guint16 param_len)
322 {
323         gboolean has_user_information = TRUE;
324         guint16       flags;
325         proto_item   *tf;
326         proto_tree   *flags_tree;
327
328         switch (param_type)
329         {
330         case Called_SS_user_Reference:
331                 if (param_len == 0)
332                         break;
333                 if (tree)
334                 {
335                         proto_tree_add_item(param_tree,
336                             hf_called_ss_user_reference,
337                             tvb, offset, param_len, FALSE);
338                 }
339                 break;
340
341         case Calling_SS_user_Reference:
342                 if (param_len == 0)
343                         break;
344                 if (tree)
345                 {
346                         proto_tree_add_item(param_tree,
347                             hf_calling_ss_user_reference,
348                             tvb, offset, param_len, FALSE);
349                 }
350                 break;
351
352         case Common_Reference:
353                 if (param_len == 0)
354                         break;
355                 if (tree)
356                 {
357                         proto_tree_add_item(param_tree,
358                             hf_common_reference,
359                             tvb, offset, param_len, FALSE);
360                 }
361                 break;
362
363         case Additional_Reference_Information:
364                 if (param_len == 0)
365                         break;
366                 if (tree)
367                 {
368                         proto_tree_add_item(param_tree,
369                             hf_additional_reference_information,
370                             tvb, offset, param_len, FALSE);
371                 }
372                 break;
373
374         case Token_Item:
375                 if (param_len != 1)
376                 {
377                         proto_tree_add_text(param_tree, tvb, offset,
378                             param_len, "Length is %u, should be 1",
379                             param_len);
380                         break;
381                 }
382                 if (tree)
383                 {
384                         flags = tvb_get_guint8(tvb, offset);
385                         tf = proto_tree_add_uint(param_tree,
386                             hf_token_item_options_flags, tvb, offset, 1,
387                             flags);
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,
397                             offset, 1, flags);
398                 }
399                 break;
400
401         case Transport_Disconnect:
402                 if (param_len != 1)
403                 {
404                         proto_tree_add_text(param_tree, tvb, offset,
405                             param_len, "Length is %u, should be 1",
406                             param_len);
407                         break;
408                 }
409                 if (tree)
410                 {
411                         guint8       flags;
412
413                         flags = tvb_get_guint8(tvb, offset);
414                         if(flags & transport_connection_is_released )
415                         {
416                                 proto_tree_add_text(param_tree, tvb, offset, 1,
417                                     "transport connection is released");
418                         }
419                         else
420                         {
421                                 proto_tree_add_text(param_tree, tvb, offset, 1,
422                                     "transport connection is kept");
423                         }
424
425                         if(flags & user_abort )
426                         {
427                                 proto_tree_add_text(param_tree, tvb, offset, 1,
428                                     "user abort");
429                         }
430
431                         if(flags & protocol_error )
432                         {
433                                 proto_tree_add_text(param_tree, tvb, offset, 1,
434                                     "protocol error");
435                         }
436
437                         if(flags & no_reason )
438                         {
439                                 proto_tree_add_text(param_tree, tvb, offset, 1,
440                                     "no reason");
441                         }
442
443                         if(flags & implementation_restriction )
444                         {
445                                 proto_tree_add_text(param_tree, tvb, offset, 1,
446                                     "implementation restriction");
447                         }
448                 }
449                 break;
450
451         case Protocol_Options:
452                 if (param_len != 1)
453                 {
454                         proto_tree_add_text(param_tree, tvb, offset,
455                             param_len, "Length is %u, should be 1",
456                             param_len);
457                         break;
458                 }
459                 if (tree)
460                 {
461                         flags = tvb_get_guint8(tvb, offset);
462                         tf = proto_tree_add_uint(param_tree,
463                             hf_connect_protocol_options_flags, tvb, offset, 1,
464                             flags);
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);
470                 }
471                 break;
472
473         case Session_Requirement:
474                 if (param_len != 2)
475                 {
476                         proto_tree_add_text(param_tree, tvb, offset,
477                             param_len, "Length is %u, should be 2",
478                             param_len);
479                         break;
480                 }
481                 if (tree)
482                 {
483                         flags = tvb_get_ntohs(tvb, offset);
484                         tf = proto_tree_add_uint(param_tree,
485                             hf_session_user_req_flags, tvb, offset, 2,
486                             flags);
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,
493                             flags);
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,
511                             flags);
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);
526                 }
527                 break;
528
529         case TSDU_Maximum_Size:
530                 if (param_len != 4)
531                 {
532                         proto_tree_add_text(param_tree, tvb, offset,
533                             param_len, "Length is %u, should be 4",
534                             param_len);
535                         break;
536                 }
537                 if (tree)
538                 {
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);
545                 }
546                 break;
547
548         case Version_Number:
549                 if (param_len != 1)
550                 {
551                         proto_tree_add_text(param_tree, tvb, offset,
552                             param_len, "Length is %u, should be 1",
553                             param_len);
554                         break;
555                 }
556                 if (tree)
557                 {
558                         flags = tvb_get_guint8(tvb, offset);
559                         tf = proto_tree_add_uint(param_tree,
560                             hf_version_number_options_flags, tvb, offset, 1,
561                             flags);
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);
568                 }
569                 break;
570
571         case Initial_Serial_Number:
572                 if (param_len == 0)
573                         break;
574                 if (tree)
575                 {
576                         proto_tree_add_item(param_tree,
577                             hf_initial_serial_number,
578                             tvb, offset, param_len, FALSE);
579                 }
580                 break;
581
582         case EnclosureItem:
583                 if (param_len != 1)
584                 {
585                         proto_tree_add_text(param_tree, tvb, offset,
586                             param_len, "Length is %u, should be 1",
587                             param_len);
588                         break;
589                 }
590                 flags = tvb_get_guint8(tvb, offset);
591                 if (tree)
592                 {
593                         tf = proto_tree_add_uint(param_tree,
594                             hf_enclosure_item_options_flags, tvb, offset, 1,
595                             flags);
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);
602                 }
603                 if (flags & END_SPDU) {
604                         /*
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.
611                          */
612                         has_user_information = FALSE;
613                 }
614                 break;
615
616         case Token_Setting_Item:
617                 if (param_len != 1)
618                 {
619                         proto_tree_add_text(param_tree, tvb, offset,
620                             param_len, "Length is %u, should be 1",
621                             param_len);
622                         break;
623                 }
624                 if (tree)
625                 {
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);
638                 }
639                 break;
640
641         case Serial_Number:
642                 if (param_len == 0)
643                         break;
644                 if (tree)
645                 {
646                         proto_tree_add_item(param_tree,
647                             hf_serial_number,
648                             tvb, offset, param_len, FALSE);
649                 }
650                 break;
651
652         case Reason_Code:
653 /*
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 
666 PICS.    */
667                 if (param_len < 1)
668                 {
669                         proto_tree_add_text(param_tree, tvb, offset,
670                             param_len, "Length is %u, should be >= 1",
671                             param_len);
672                         break;
673                 }
674                 if (tree)
675                 {
676                         guint8      reason_code;
677
678                         reason_code = tvb_get_guint8(tvb, offset);
679                         proto_tree_add_text(param_tree, tvb, offset, 1,
680                             "Reason Code: %s",
681                             val_to_str(reason_code, reason_vals, "Unknown (%u)"));
682                 }
683                 offset++;
684                 param_len--;
685                 if (param_len != 0)
686                 {
687                         call_pres_dissector(tvb, offset, param_len,
688                             pinfo, tree, param_tree);
689                 }
690                 break;
691
692         case Calling_Session_Selector:
693                 if (param_len == 0)
694                         break;
695                 if (tree)
696                 {
697                         proto_tree_add_item(param_tree,
698                             hf_calling_session_selector,
699                             tvb, offset, param_len, FALSE);
700                 }
701                 break;
702
703         case Called_Session_Selector:
704                 if (param_len == 0)
705                         break;
706                 if (tree)
707                 {
708                         proto_tree_add_item(param_tree,
709                             hf_called_session_selector,
710                             tvb, offset, param_len, FALSE);
711                 }
712                 break;
713
714         case Second_Serial_Number:
715                 if (param_len == 0)
716                         break;
717                 if (tree)
718                 {
719                         proto_tree_add_item(param_tree,
720                             hf_second_serial_number,
721                             tvb, offset, param_len, FALSE);
722                 }
723                 break;
724
725         case Second_Initial_Serial_Number:
726                 if (param_len == 0)
727                         break;
728                 if (tree)
729                 {
730                         proto_tree_add_item(param_tree,
731                             hf_second_initial_serial_number,
732                             tvb, offset, param_len, FALSE);
733                 }
734                 break;
735
736         case Large_Initial_Serial_Number:
737                 if (param_len == 0)
738                         break;
739                 if (tree)
740                 {
741                         proto_tree_add_item(param_tree,
742                             hf_large_initial_serial_number,
743                             tvb, offset, param_len, FALSE);
744                 }
745                 break;
746
747         case Large_Second_Initial_Serial_Number:
748                 if (param_len == 0)
749                         break;
750                 if (tree)
751                 {
752                         proto_tree_add_item(param_tree,
753                             hf_large_second_initial_serial_number,
754                             tvb, offset, param_len, FALSE);
755                 }
756                 break;
757
758         default:
759                 break;
760         }
761         return has_user_information;
762 }
763
764 static gboolean
765 dissect_parameter_group(tvbuff_t *tvb, int offset, proto_tree *tree,
766     proto_tree *pg_tree, packet_info *pinfo, guint16 pg_len)
767 {
768         gboolean has_user_information = TRUE;
769         proto_item *ti;
770         proto_tree *param_tree;
771         guint8 param_type;
772         char *param_str;
773         int len_len;
774         guint16 param_len;
775
776         while(pg_len != 0)
777         {
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");
787                 offset++;
788                 pg_len--;
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;
795                 }
796                 pg_len -= len_len;
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",
801                             param_len, pg_len);
802                         return has_user_information;
803                 }
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);
807                 offset += len_len;
808                     
809                 if (param_str != NULL)
810                 {
811                         switch(param_type)
812                         {
813                         /* PG's in PG's are invalid, presumably */
814                         case Extended_User_Data:
815                         case User_Data:
816                         case Connect_Accept_Item:
817                         case Connection_Identifier:
818                         case Linking_Information:
819                                 proto_tree_add_text(param_tree, tvb, offset,
820                                     param_len,
821                                     "Parameter group inside parameter group");
822                                 break;
823
824                         default:
825                                 if (!dissect_parameter(tvb, offset, tree,
826                                     param_tree, pinfo, param_type, param_len))
827                                         has_user_information = FALSE;
828                                 break;
829                         }
830                 }
831                 offset += param_len;
832                 pg_len -= param_len;
833         }
834         return has_user_information;
835 }
836
837 /*
838  * Returns TRUE if there's a User Information field in this SPDU, FALSE
839  * otherwise.
840  */
841 static gboolean
842 dissect_parameters(tvbuff_t *tvb, int offset, guint16 len, proto_tree *tree,
843     proto_tree *ses_tree, packet_info *pinfo)
844 {
845         gboolean has_user_information = TRUE;
846         proto_item *ti;
847         proto_tree *param_tree;
848         guint8 param_type;
849         char *param_str;
850         int len_len;
851         guint16 param_len;
852
853         while(len != 0)
854         {
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");
864                 offset++;
865                 len--;
866                 param_len = get_item_len(tvb, offset, &len_len);
867                 if (len_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;
872                 }
873                 len -= len_len;
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",
878                             param_len, len);
879                         return has_user_information;
880                 }
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);
884                 offset += len_len;
885                     
886                 if (param_str != NULL)
887                 {
888                         switch(param_type)
889                         {
890                         case Extended_User_Data:
891                                 break;
892
893                         case User_Data:
894                                 call_pres_dissector(tvb, offset, param_len,
895                                     pinfo, tree, param_tree);
896                                 break;
897
898                         /* handle PGI's  */
899                         case Connect_Accept_Item:
900                         case Connection_Identifier:
901                         case Linking_Information:
902                                 /* Yes. */
903                                 if (!dissect_parameter_group(tvb, offset, tree,
904                                     param_tree, pinfo, param_len))
905                                         has_user_information = FALSE;
906                                 break;
907
908                         /* everything else is a PI */
909                         default:
910                                 if (!dissect_parameter(tvb, offset, tree,
911                                     param_tree, pinfo, param_type, param_len))
912                                         has_user_information = FALSE;
913                                 break;
914                         }
915                 }
916                 offset += param_len;
917                 len -= param_len;
918         }
919         return has_user_information;
920 }
921
922 /*
923  * Dissect an SPDU.
924  */
925 static int
926 dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
927     gboolean tokens)
928 {
929         gboolean has_user_information = FALSE;
930         guint8 type;
931         proto_item *ti = NULL;
932         proto_tree *ses_tree = NULL;
933         int len_len;
934         guint16 parameters_len;
935         tvbuff_t *next_tvb;
936
937         /*
938          * Get SPDU type.
939          */
940         type = tvb_get_guint8(tvb, offset);
941
942         if (tokens) {
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)"));
946                 if (tree) {
947                         ti = proto_tree_add_item(tree, proto_ses, tvb, offset,
948                             -1, FALSE);
949                         ses_tree = proto_item_add_subtree(ti, ett_ses);
950                         proto_tree_add_uint(ses_tree, hf_ses_type_0, tvb,
951                             offset, 1, type);
952                 }
953         } else {
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)"));
957                 if (tree) {
958                         ti = proto_tree_add_item(tree, proto_ses, tvb, offset,
959                             -1, FALSE);
960                         ses_tree = proto_item_add_subtree(ti, ett_ses);
961                         proto_tree_add_uint(ses_tree, hf_ses_type, tvb,
962                             offset, 1, type);
963                 }
964
965                 /*
966                  * Might this SPDU have a User Information field?
967                  */
968                 switch (type) {
969
970                 case SES_DATA_TRANSFER:
971                 case SES_EXPEDITED:
972                 case SES_TYPED_DATA:
973                         has_user_information = TRUE;
974                         break;
975                 }
976         }
977         offset++;
978
979         /* get length of SPDU parameter field */
980         parameters_len = get_item_len(tvb, offset, &len_len);
981         if (tree)
982                 proto_tree_add_uint(ses_tree, hf_ses_length, tvb, offset,
983                     len_len, parameters_len);
984         offset += len_len;
985
986         /* Dissect parameters. */
987         if (!dissect_parameters(tvb, offset, parameters_len, tree, ses_tree,
988             pinfo))
989                 has_user_information = FALSE;
990         offset += parameters_len;
991         
992         proto_item_set_end(ti, tvb, offset);
993
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);
998
999                         /* do we have OSI presentation packet dissector ? */
1000                         if(!pres_handle)
1001                         {
1002                                 call_dissector(data_handle, next_tvb, pinfo,
1003                                     tree);
1004                         }
1005                         else
1006                         {
1007                                 call_dissector(pres_handle, next_tvb, pinfo,
1008                                     tree);
1009                         }
1010
1011                         /*
1012                          * No more SPDUs to dissect.  Set the offset to the
1013                          * end of the tvbuff.
1014                          */
1015                         offset = tvb_length(tvb);
1016                 }
1017         }
1018         return offset;
1019 }
1020
1021 /*
1022  * Dissect SPDUs inside a TSDU.
1023  */
1024 static void
1025 dissect_ses(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1026 {
1027         int offset = 0;
1028         guint8 type;
1029
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);
1034
1035         /*
1036          * Do we have a category 0 SPDU (GIVE_TOKENS/PLEASE_TOKENS) as
1037          * the first SPDU?
1038          *
1039          * If so, dissect it as such (GIVE_TOKENS and DATA_TRANSFER have
1040          * the smae SPDU type value).
1041          */
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);
1045
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);
1049 }
1050
1051 void
1052 proto_register_ses(void)
1053 {
1054         static hf_register_info hf[] =
1055         {
1056                 {
1057                         &hf_ses_type,
1058                         {
1059                                 "SPDU Type",
1060                                 "ses.type",
1061                                 FT_UINT8,
1062                                 BASE_DEC,
1063                                 VALS(ses_vals),
1064                                 0x0,
1065                                 "", HFILL
1066                         }
1067                 },
1068                 {
1069                         &hf_ses_type_0,
1070                         {
1071                                 "SPDU Type",
1072                                 "ses.type",
1073                                 FT_UINT8,
1074                                 BASE_DEC,
1075                                 VALS(ses_category0_vals),
1076                                 0x0,
1077                                 "", HFILL
1078                         }
1079                 },
1080                 {
1081                         &hf_ses_length,
1082                         {
1083                                 "Length",
1084                                 "ses.length",
1085                                 FT_UINT16,
1086                                 BASE_DEC,
1087                                 NULL,
1088                                 0x0,
1089                                 "", HFILL
1090                         }
1091                 },
1092
1093                 {
1094                         &hf_ses_version,
1095                         {
1096                                 "Version",
1097                                 "ses.version",
1098                                 FT_UINT8,
1099                                 BASE_DEC,
1100                                 NULL,
1101                                 0x0,
1102                                 "", HFILL
1103                         }
1104                 },
1105                 {
1106                         &hf_ses_reserved,
1107                         {
1108                                 "Reserved",
1109                                 "ses.reserved",
1110                                 FT_UINT8,
1111                                 BASE_DEC,
1112                                 NULL,
1113                                 0x0,
1114                                 "", HFILL
1115                         }
1116                 },
1117                 {
1118                         &hf_called_ss_user_reference,
1119                         {
1120                                 "Called SS User Reference",
1121                                 "ses.called_ss_user_reference",
1122                                 FT_BYTES, BASE_NONE,
1123                                 NULL,
1124                                 0x0,
1125                                 "Called SS User Reference",
1126                                 HFILL
1127                         }
1128                 },
1129                 {
1130                         &hf_calling_ss_user_reference,
1131                         {
1132                                 "Calling SS User Reference",
1133                                 "ses.calling_ss_user_reference",
1134                                 FT_BYTES, BASE_NONE,
1135                                 NULL,
1136                                 0x0,
1137                                 "Calling SS User Reference",
1138                                 HFILL
1139                         }
1140                 },
1141                 {
1142                         &hf_common_reference,
1143                         {
1144                                 "Common Reference",
1145                                 "ses.common_reference",
1146                                 FT_BYTES, BASE_NONE,
1147                                 NULL,
1148                                 0x0,
1149                                 "Common Reference",
1150                                 HFILL
1151                         }
1152                 },
1153                 {
1154                         &hf_additional_reference_information,
1155                         {
1156                                 "Additional Reference Information",
1157                                 "ses.additional_reference_information",
1158                                 FT_BYTES, BASE_NONE,
1159                                 NULL,
1160                                 0x0,
1161                                 "Additional Reference Information",
1162                                 HFILL
1163                         }
1164                 },
1165                 {
1166                         &hf_release_token,
1167                         {
1168                                 "release token",
1169                                 "ses.release_token",
1170                                 FT_BOOLEAN, 8,
1171                                 NULL,
1172                                 RELEASE_TOKEN,
1173                                 "release token",
1174                                 HFILL
1175                         }
1176                 },
1177                 {
1178                         &hf_major_activity_token,
1179                         {
1180                                 "major/activity token",
1181                                 "ses.major.token",
1182                                 FT_BOOLEAN, 8,
1183                                 NULL,
1184                                 MAJOR_ACTIVITY_TOKEN,
1185                                 "major/activity token",
1186                                 HFILL
1187                         }
1188                 },
1189                 {
1190                         &hf_synchronize_minor_token,
1191                         {
1192                                 "synchronize minor token",
1193                                 "ses.synchronize_token",
1194                                 FT_BOOLEAN, 8,
1195                                 NULL,
1196                                 SYNCHRONIZE_MINOR_TOKEN,
1197                                 "synchronize minor token",
1198                                 HFILL
1199                         }
1200                 },
1201                 {
1202                         &hf_data_token,
1203                         {
1204                                 "data token",
1205                                 "ses.data_token",
1206                                 FT_BOOLEAN, 8,
1207                                 NULL,
1208                                 DATA_TOKEN,
1209                                 "data  token",
1210                                 HFILL
1211                         }
1212                 },
1213                 {
1214                         &hf_able_to_receive_extended_concatenated_SPDU,
1215                         {
1216                                 "Able to receive extended concatenated SPDU",
1217                                 "ses.connect.f1",
1218                                 FT_BOOLEAN, 8,
1219                                 NULL,
1220                                 SES_EXT_CONT,
1221                                 "Able to receive extended concatenated SPDU",
1222                                 HFILL
1223                         }
1224                 },
1225                 {
1226                         &hf_session_user_req_flags,
1227                         {
1228                                 "Flags",
1229                                 "ses.req.flags",
1230                                 FT_UINT16,
1231                                 BASE_HEX,
1232                                 NULL,
1233                                 0x0,
1234                                 "",
1235                                 HFILL
1236                         }
1237                 },
1238                 {
1239                         &hf_session_exception_report,
1240                         {
1241                                 "Session exception report",
1242                                 "ses.exception_report.",
1243                                 FT_BOOLEAN, 16,
1244                                 NULL,
1245                                 SES_EXCEPTION_REPORT,
1246                                 "Session exception report",
1247                                 HFILL
1248                         }
1249                 },
1250                 {
1251                         &hf_data_separation_function_unit,
1252                         {
1253                                 "Data separation function unit",
1254                                 "ses.data_sep",
1255                                 FT_BOOLEAN, 16,
1256                                 NULL,
1257                                 DATA_SEPARATION_FUNCTION_UNIT,
1258                                 "Data separation function unit",
1259                                 HFILL
1260                         }
1261                 },
1262                 {
1263                         &hf_symmetric_synchronize_function_unit,
1264                         {
1265                                 "Symmetric synchronize function unit",
1266                                 "ses.symm_sync",
1267                                 FT_BOOLEAN, 16,
1268                                 NULL,
1269                                 SYMMETRIC_SYNCHRONIZE_FUNCTION_UNIT,
1270                                 "Symmetric synchronize function unit",
1271                                 HFILL
1272                         }
1273                 },
1274                 {
1275                         &hf_typed_data_function_unit,
1276                         {
1277                                 "Typed data function unit",
1278                                 "ses.typed_data",
1279                                 FT_BOOLEAN, 16,
1280                                 NULL,
1281                                 TYPED_DATA_FUNCTION_UNIT,
1282                                 "Typed data function unit",
1283                                 HFILL
1284                         }
1285                 },
1286                 {
1287                         &hf_exception_function_unit,
1288                         {
1289                                 "Exception function unit",
1290                                 "ses.exception_data",
1291                                 FT_BOOLEAN, 16,
1292                                 NULL,
1293                                 EXCEPTION_FUNCTION_UNIT,
1294                                 "Exception function unit",
1295                                 HFILL
1296                         }
1297                 },
1298                 {
1299                         &hf_capability_function_unit,
1300                         {
1301                                 "Capability function unit",
1302                                 "ses.capability_data",
1303                                 FT_BOOLEAN, 16,
1304                                 NULL,
1305                                 CAPABILITY_DATA_FUNCTION_UNIT,
1306                                 "Capability function unit",
1307                                 HFILL
1308                         }
1309                 },
1310                 {
1311                         &hf_negotiated_release_function_unit,
1312                         {
1313                                 "Negotiated release function unit",
1314                                 "ses.negotiated_release",
1315                                 FT_BOOLEAN, 16,
1316                                 NULL,
1317                                 NEGOTIATED_RELEASE_FUNCTION_UNIT,
1318                                 "Negotiated release function unit",
1319                                 HFILL
1320                         }
1321                 },
1322                 {
1323                         &hf_activity_management_function_unit,
1324                         {
1325                                 "Activity management function unit",
1326                                 "ses.activity_management",
1327                                 FT_BOOLEAN, 16,
1328                                 NULL,
1329                                 ACTIVITY_MANAGEMENT_FUNCTION_UNIT,
1330                                 "Activity management function unit",
1331                                 HFILL
1332                         }
1333                 },
1334                 {
1335                         &hf_resynchronize_function_unit,
1336                         {
1337                                 "Resynchronize function unit",
1338                                 "ses.resynchronize",
1339                                 FT_BOOLEAN, 16,
1340                                 NULL,
1341                                 RESYNCHRONIZE_FUNCTION_UNIT,
1342                                 "Resynchronize function unit",
1343                                 HFILL
1344                         }
1345                 },
1346                 {
1347                         &hf_major_resynchronize_function_unit,
1348                         {
1349                                 "Major resynchronize function unit",
1350                                 "ses.major_resynchronize",
1351                                 FT_BOOLEAN, 16,
1352                                 NULL,
1353                                 MAJOR_SYNCHRONIZE_FUNCTION_UNIT,
1354                                 "Major resynchronize function unit",
1355                                 HFILL
1356                         }
1357                 },
1358                 {
1359                         &hf_minor_resynchronize_function_unit,
1360                         {
1361                                 "Minor resynchronize function unit",
1362                                 "ses.minor_resynchronize",
1363                                 FT_BOOLEAN, 16,
1364                                 NULL,
1365                                 MINOR_SYNCHRONIZE_FUNCTION_UNIT,
1366                                 "Minor resynchronize function unit",
1367                                 HFILL
1368                         }
1369                 },
1370                 {
1371                         &hf_expedited_data_resynchronize_function_unit,
1372                         {
1373                                 "Expedited data function unit",
1374                                 "ses.expedited_data",
1375                                 FT_BOOLEAN, 16,
1376                                 NULL,
1377                                 EXPEDITED_DATA_FUNCTION_UNIT,
1378                                 "Expedited data function unit",
1379                                 HFILL
1380                         }
1381                 },
1382                 {
1383                         &hf_duplex_function_unit,
1384                         {
1385                                 "Duplex functional unit",
1386                                 "ses.duplex",
1387                                 FT_BOOLEAN, 16,
1388                                 NULL,
1389                                 DUPLEX_FUNCTION_UNIT,
1390                                 "Duplex functional unit",
1391                                 HFILL
1392                         }
1393                 },
1394                 {
1395                         &hf_half_duplex_function_unit,
1396                         {
1397                                 "Half-duplex functional unit",
1398                                 "ses.half_duplex",
1399                                 FT_BOOLEAN, 16,
1400                                 NULL,
1401                                 HALF_DUPLEX_FUNCTION_UNIT,
1402                                 "Half-duplex functional unit",
1403                                 HFILL
1404                         }
1405                 },
1406                 {
1407                         &hf_proposed_tsdu_maximum_size_i2r,
1408                         {
1409                                 "Proposed TSDU Maximum Size, Initiator to Responder",
1410                                 "ses.proposed_tsdu_maximum_size_i2r",
1411                                 FT_UINT16,
1412                                 BASE_DEC,
1413                                 NULL,
1414                                 0x0,
1415                                 "Proposed TSDU Maximum Size, Initiator to Responder",
1416                                 HFILL
1417                         }
1418                 },
1419                 {
1420                         &hf_proposed_tsdu_maximum_size_r2i,
1421                         {
1422                                 "Proposed TSDU Maximum Size, Responder to Initiator",
1423                                 "ses.proposed_tsdu_maximum_size_r2i",
1424                                 FT_UINT16,
1425                                 BASE_DEC,
1426                                 NULL,
1427                                 0x0,
1428                                 "Proposed TSDU Maximum Size, Responder to Initiator",
1429                                 HFILL
1430                         }
1431                 },
1432                 {
1433                         &hf_protocol_version_1,
1434                         {
1435                                 "Protocol Version 1",
1436                                 "ses.protocol_version1",
1437                                 FT_BOOLEAN, 8,
1438                                 NULL,
1439                                 PROTOCOL_VERSION_1,
1440                                 "Protocol Version 1",
1441                                 HFILL
1442                         }
1443                 },
1444                 {
1445                         &hf_protocol_version_2,
1446                         {
1447                                 "Protocol Version 2",
1448                                 "ses.protocol_version2",
1449                                 FT_BOOLEAN, 8,
1450                                 NULL,
1451                                 PROTOCOL_VERSION_2,
1452                                 "Protocol Version 2",
1453                                 HFILL
1454                         }
1455                 },
1456                 {
1457                         &hf_initial_serial_number,
1458                         {
1459                                 "Initial Serial Number",
1460                                 "ses.initial_serial_number",
1461                                 FT_STRING, BASE_NONE,
1462                                 NULL,
1463                                 0x0,
1464                                 "Initial Serial Number",
1465                                 HFILL
1466                         }
1467                 },
1468                 {
1469                         &hf_beginning_of_SSDU,
1470                         {
1471                                 "beginning of SSDU",
1472                                 "ses.begininng_of_SSDU",
1473                                 FT_BOOLEAN, 8,
1474                                 NULL,
1475                                 BEGINNING_SPDU,
1476                                 "beginning of SSDU",
1477                                 HFILL
1478                         }
1479                 },
1480                 {
1481                         &hf_end_of_SSDU,
1482                         {
1483                                 "end of SSDU",
1484                                 "ses.end_of_SSDU",
1485                                 FT_BOOLEAN, 8,
1486                                 NULL,
1487                                 END_SPDU,
1488                                 "end of SSDU",
1489                                 HFILL
1490                         }
1491                 },
1492                 {
1493                         &hf_release_token_setting,
1494                         {
1495                                 "release token setting",
1496                                 "ses.release_token_setting",
1497                                 FT_UINT8, BASE_HEX,
1498                                 VALS(token_setting_vals),
1499                                 0xC0,
1500                                 "release token setting",
1501                                 HFILL
1502                         }
1503                 },
1504                 {
1505                         &hf_major_activity_token_setting,
1506                         {
1507                                 "major/activity setting",
1508                                 "ses.major_activity_token_setting",
1509                                 FT_UINT8, BASE_HEX,
1510                                 VALS(token_setting_vals),
1511                                 0x30,
1512                                 "major/activity token setting",
1513                                 HFILL
1514                         }
1515                 },
1516                 {
1517                         &hf_synchronize_minor_token_setting,
1518                         {
1519                                 "synchronize-minor token setting",
1520                                 "ses.synchronize_minor_token_setting",
1521                                 FT_UINT8, BASE_HEX,
1522                                 VALS(token_setting_vals),
1523                                 0x0C,
1524                                 "synchronize-minor token setting",
1525                                 HFILL
1526                         }
1527                 },
1528                 {
1529                         &hf_data_token_setting,
1530                         {
1531                                 "data token setting",
1532                                 "ses.data_token_setting",
1533                                 FT_UINT8, BASE_HEX,
1534                                 VALS(token_setting_vals),
1535                                 0x03,
1536                                 "data token setting",
1537                                 HFILL
1538                         }
1539                 },
1540                 {
1541                         &hf_serial_number,
1542                         {
1543                                 "Serial Number",
1544                                 "ses.serial_number",
1545                                 FT_STRING, BASE_NONE,
1546                                 NULL,
1547                                 0x0,
1548                                 "Serial Number",
1549                                 HFILL
1550                         }
1551                 },
1552                 {
1553                         &hf_calling_session_selector,
1554                         {
1555                                 "Calling Session Selector",
1556                                 "ses.calling_session_selector",
1557                                 FT_BYTES, BASE_NONE,
1558                                 NULL,
1559                                 0x0,
1560                                 "Calling Session Selector",
1561                                 HFILL
1562                         }
1563                 },
1564                 {
1565                         &hf_called_session_selector,
1566                         {
1567                                 "Called Session Selector",
1568                                 "ses.called_session_selector",
1569                                 FT_BYTES, BASE_NONE,
1570                                 NULL,
1571                                 0x0,
1572                                 "Called Session Selector",
1573                                 HFILL
1574                         }
1575                 },
1576                 {
1577                         &hf_second_serial_number,
1578                         {
1579                                 "Second Serial Number",
1580                                 "ses.second_serial_number",
1581                                 FT_STRING, BASE_NONE,
1582                                 NULL,
1583                                 0x0,
1584                                 "Second Serial Number",
1585                                 HFILL
1586                         }
1587                 },
1588                 {
1589                         &hf_second_initial_serial_number,
1590                         {
1591                                 "Second Initial Serial Number",
1592                                 "ses.second_initial_serial_number",
1593                                 FT_STRING, BASE_NONE,
1594                                 NULL,
1595                                 0x0,
1596                                 "Second Initial Serial Number",
1597                                 HFILL
1598                         }
1599                 },
1600                 {
1601                         &hf_large_initial_serial_number,
1602                         {
1603                                 "Large Initial Serial Number",
1604                                 "ses.large_initial_serial_number",
1605                                 FT_STRING, BASE_NONE,
1606                                 NULL,
1607                                 0x0,
1608                                 "Large Initial Serial Number",
1609                                 HFILL
1610                         }
1611                 },
1612                 {
1613                         &hf_large_second_initial_serial_number,
1614                         {
1615                                 "Large Second Initial Serial Number",
1616                                 "ses.large_second_initial_serial_number",
1617                                 FT_STRING, BASE_NONE,
1618                                 NULL,
1619                                 0x0,
1620                                 "Large Second Initial Serial Number",
1621                                 HFILL
1622                         }
1623                 },
1624                 {
1625                         &hf_connect_protocol_options_flags,
1626                         {
1627                                 "Flags",
1628                                 "ses.connect.flags",
1629                                 FT_UINT8,
1630                                 BASE_HEX,
1631                                 NULL,
1632                                 0x0,
1633                                 "",
1634                                 HFILL
1635                         }
1636                 },
1637                 {
1638                         &hf_version_number_options_flags,
1639
1640                         {
1641                                 "Flags",
1642                                 "ses.version.flags",
1643                                 FT_UINT8,
1644                                 BASE_HEX,
1645                                 NULL,
1646                                 0x0,
1647                                 "",
1648                                 HFILL
1649                         }
1650                 },
1651
1652                 {
1653                         &hf_token_item_options_flags,
1654
1655                         {
1656                                 "Flags",
1657                                 "ses.tken_item.flags",
1658                                 FT_UINT8,
1659                                 BASE_HEX,
1660                                 NULL,
1661                                 0x0,
1662                                 "",
1663                                 HFILL
1664                         }
1665                 },
1666
1667                 {
1668                         &hf_enclosure_item_options_flags,
1669
1670                         {
1671                                 "Flags",
1672                                 "ses.enclosure.flags",
1673                                 FT_UINT8,
1674                                 BASE_HEX,
1675                                 NULL,
1676                                 0x0,
1677                                 "",
1678                                 HFILL
1679                         }
1680                 },
1681         };
1682
1683         static gint *ett[] =
1684         {
1685                 &ett_ses,
1686                 &ett_ses_param,
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,
1692         };
1693         module_t *ses_module;
1694
1695
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));
1699
1700         ses_module = prefs_register_protocol(proto_ses, NULL);
1701 /*
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",
1705             &ses_desegment);  */
1706
1707         /*
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).
1712          */
1713         register_dissector("ses", dissect_ses, proto_ses);
1714 }
1715
1716 static gboolean
1717 dissect_ses_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
1718 {
1719         /* must check that this really is a ses packet */
1720         int offset = 0;
1721         guint8 type;
1722         int len_len;
1723         guint16 len;
1724
1725         /* first, check do we have at least 4 bytes (type+length) */
1726         if (!tvb_bytes_exist(tvb, 0, 4))
1727                 return FALSE;   /* no */
1728
1729         /* can we regognize session PDU ? Return FALSE if  not */
1730         /*   get SPDU type */
1731         type = tvb_get_guint8(tvb, offset);
1732         /* check SPDU type */
1733         if (match_strval(type, ses_vals) == NULL)
1734         {
1735                 return FALSE;  /* no, it isn't a session PDU */
1736         }
1737
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 */
1744
1745         dissect_ses(tvb, pinfo, parent_tree);
1746         return TRUE;
1747 }
1748
1749 void
1750 proto_reg_handoff_ses(void)
1751 {
1752         /*   find data dissector  */
1753         data_handle = find_dissector("data");
1754
1755         /* define sub dissector */
1756         pres_handle = find_dissector("pres");
1757
1758         /* add our session dissector to cotp dissector list */
1759         heur_dissector_add("cotp", dissect_ses_heur, proto_ses);
1760 }