From Clinton Work: dissect Cisco PID 0x010b as STP (it's actually their
[obnox/wireshark/wip.git] / packet-acse.c
1 /* packet-acse.c
2 *
3 * Routine to dissect OSI ACSE Protocol packets
4 *
5 * $Id: packet-acse.c,v 1.3 2004/01/24 01:53:59 jmayer 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-acse.h"
39 #include "packet-frame.h"
40 #include "prefs.h"
41
42 #include <epan/strutil.h>
43
44 #include "asn1.h"
45 #include "format-oid.h"
46
47 #include "packet-ses.h"
48 extern const value_string ses_vals[];
49
50 /* acse header fields             */
51 static int proto_acse          = -1;
52 /*   type of session envelop */
53 static struct SESSION_DATA_STRUCTURE* session = NULL;
54 /* acse fields defining a sub tree */
55 static gint ett_acse           = -1;
56 static gint ett_acse_param     = -1;
57 static gint ett_acse_rc           = -1;
58 static gint ett_acse_ms           = -1;
59 static gint ett_acse_itm           = -1;
60
61 /*
62 ----------------------------------------------------------------------------------------------------------*/
63 static dissector_handle_t ftam_handle = NULL;
64 static dissector_handle_t cmip_handle = NULL;
65 static dissector_handle_t app_handle = NULL;
66 static int hf_acse_type        = -1;
67 static int hf_cp_type_message_length = -1;
68 static int hf_protocol_version       = -1;
69
70 static  int  type_of_application = 0;
71
72
73 static const value_string acse_vals[] =
74 {
75   {ACSE_AARQ,  "A-associate request" },
76   {ACSE_AARE,  "A-associate response" },
77   {ACSE_RLRQ,  "A-reliase request" },
78   {ACSE_RLRE,  "A-reliase response" },
79   {ACSE_ABRT,  "A-abort" },
80   {0,             NULL           }
81 };
82
83 static const value_string cr_vals[] =
84 {
85   {MODE_SELECTOR, "Mode Selector"},
86   {SEQUENCE_TOP, "Sequence"},
87   {SET_TOP, "Set"},
88   {0, NULL}
89 };
90
91 static const value_string request_sequence_top_vals[] =
92 {
93   {PROTOCOL_VERSION, "Protocol version"},
94   {APPLICATION_CONTEXT_NAME, "Application context name"},
95   {CALLED_AP_TITLE, "Called AP title"},
96   {CALLED_AE_QUALIFIER, "Called AE qualifier"},
97   {CALLED_AP_INVOKATION_ID, "Called AP invokation id"},
98   {CALLED_AE_INVOKATION_ID, "Called AE invokation id"},
99   {CALLING_AP_TITLE, "Calling AP title"},
100   {CALLING_AE_QUALIFIER, "Calling AE qualifier"},
101   {CALLING_AP_INVOKATION_ID, "Calling AP invokation id"},
102   {CALLING_AE_INVOKATION_ID, "Calling AE invokation id"},
103   {IMPLEMENTATION_INFORMATION,"Implementation information"},
104   {USER_INFORMATION,"User information"},
105   {0, NULL}
106 };
107 static const value_string response_sequence_top_vals[] =
108 {
109   {PROTOCOL_VERSION, "Protocol version"},
110   {APPLICATION_CONTEXT_NAME, "Application context name"},
111   {ACSE_RESULT, "Result"},
112   {ACSE_RESULT_SOURCE_DIAGNOSTIC, "Result source diagnostic"},
113   {RESPONDING_AP_TITLE, "Responding AP title"},
114   {RESPONDING_AE_QUALIFIER, "Responding AE qualifier"},
115   {RESPONDING_AP_INVOKATION_ID, "Responding AP invokation id"},
116   {RESPONDING_AE_INVOKATION_ID, "Responding AE invokation id"},
117   {IMPLEMENTATION_INFORMATION,"Implementation information"},
118   {USER_INFORMATION,"User information"},
119   {0, NULL}
120 };
121 static const value_string associate_result_values_vals[] =
122 {
123   {PRESENTATION_RESULT_ACCEPTANCE,"Accepted"},
124   {PRESENTATION_RESULT_USER_REJECTION,"Rejected permanent"},
125   {PRESENTATION_RESULT_PROVIDER_REJECTION,"Rejected transient"},
126   {0, NULL}
127 };
128
129 static const value_string acse_associate_source_diagnostic_vals[] =
130 {
131   {ACSE_SERVICE_USER,"Acse service user"},
132   {ACSE_SERVICE_PROVIDER,"Acse service provider"},
133   {0, NULL}
134 };
135 static const value_string acse_service_user_values_vals[] =
136 {
137   {ACSE_NULL,"null"},
138   {ACSE_NO_REASON_GIVEN,"No reason given"},
139   {ACSE_APPLICATION_CONTEXT_NAME_NOT_SUPPORTED,"Application context name not supported"},
140   {ACSE_CALLING_AP_TITLE_NOT_RECOGNIZED,"Calling AP title not recognized"},
141   {ACSE_CALLING_AP_INVOKATION_IDENTIFIER_NOT_RECOGNIZED,"Calling AP invokation identifier not recognized"},
142   {ACSE_CALLING_AE_QUALIFIER_NOT_RECOGNIZED,"Calling AE qualifier not recognized"},
143   {ACSE_CALLING_AE_INVOKATION_IDENTIFIER_NOT_RECOGNIZED,"Calling AE invokation identifier not recognized"},
144   {ACSE_CALLED_AP_TITLE_NOT_RECOGNIZED,"Called AP title not recognized"},
145   {ACSE_CALLED_AP_INVOKATION_IDENTIFIER_NOT_RECOGNIZED,"Called AP invokation identifier not recognized"},
146   {ACSE_CALLED_AE_QUALIFIER_NOT_RECOGNIZED,"Called AE qualifier not recognized"},
147   {ACSE_CALLED_AE_INVOKATION_IDENTIFIER_NOT_RECOGNIZED,"Called AE invokation identifier not recognized"},
148   {0, NULL}
149 };
150 static const value_string acse_service_provider_values_vals[] =
151 {
152   {ACSE_NULL,"Null"},
153   {ACSE_NO_REASON_GIVEN,"No reason given"},
154   {ACSE_NO_COMMON_ACSE_VERSION,"no_common_acse_version"},
155   {0, NULL}
156 };
157
158 static const value_string acse_user_information_vals[] =
159 {
160   {ACSE_EXTERNAL_USER,"External"},
161   {0, NULL}
162 };
163 static const value_string sequence_list_vals[] =
164 {
165   {PRESENTATION_CONTEXT_IDENTIFIER,"Presentation context identifier"},
166   {ABSTRACT_SYNTAX_NAME,"Abstract syntax name"},
167   {TRANSFER_SYNTAX_NAMES,"Transfer syntax names"},
168   {0, NULL}
169 };
170 static const value_string presentation_context_definition_vals[] =
171 {
172   {SEQUENCE, "Sequence"},
173   {0, NULL}
174 };
175 static const value_string user_data_values_vals[] =
176 {
177   {SIMPLY_ENCODED_DATA,"Simply encoded data"},
178   {FULLY_ENCODED_DATA,"Fully encoded data "},
179   {0, NULL}
180 };
181 static const value_string presentation_data_values[] =
182 {
183   {PRESENTATION_CONTEXT_IDENTIFIER,"Presentation context identifier"},
184   {SINGLE_ASN1_TYPE,"Single ASN.1 type"},
185   {OCTET_ALIGNED,"Octet aligned"},
186   {ARBITRARY,"Arbitrary"},
187   {ABSTRACT_SYNTAX_NAME,"Abstract syntax name"},
188   {0, NULL}
189 };
190 static const value_string release_request_reason[] =
191 {
192   {RRR_NORMAL,"Normal"},
193   {RRR_URGENT,"Urgent"},
194   {RRR_USER_DEFINED,"User defined"},
195   {0, NULL}
196 };
197 static const value_string release_response_reason[] =
198 {
199   {RRPR_NORMAL,"Normal"},
200   {RRPR_URGENT,"Not finished"},
201   {RRPR_USER_DEFINED,"User defined"},
202   {0, NULL}
203 };
204
205 static const value_string abort_reason[] =
206 {
207   {ABRT_ACSE_SERVICE_USER,"Acse service user"},
208   {ABRT_ACSE_SERVICE_PROVIDER,"Acse service provider"},
209   {0, NULL}
210 };
211
212 static const value_string type_app[] =
213 {
214         {0,""},             /*   for unknown dissector   */
215         {FTAM_APP,"FTAM"},
216         {CMIP_APP,"CMIP"},
217         {0, NULL}
218 };
219
220 /*      pointers for acse dissector  */
221 static proto_tree *global_tree  = NULL;
222 static packet_info *global_pinfo = NULL;
223 /* dissector for data */
224 static dissector_handle_t data_handle;
225 static void
226 call_app_dissector(tvbuff_t *tvb, int offset, guint16 param_len,
227     packet_info *pinfo, proto_tree *tree, proto_tree *param_tree)
228 {
229         char* name_of_app_dissect;
230         name_of_app_dissect = val_to_str(type_of_application, type_app,"Unknown type of application dissector (0x%02x)");
231         /* do we have OSI app packet dissector ? */
232         if(!app_handle || !type_of_application)
233         {
234
235                 /* No - display as data */
236                 if (tree)
237                 {
238                         proto_tree_add_text(param_tree, tvb, offset, param_len,
239                             "%s dissector is not available",name_of_app_dissect);
240                 }
241         }
242         else
243         {
244                         /* Yes - call application dissector */
245                         tvbuff_t *next_tvb;
246
247                         next_tvb = tvb_new_subset(tvb, offset, param_len,
248                             param_len);
249                         TRY
250                         {
251                                 call_dissector(app_handle, next_tvb, pinfo,
252                                     tree);
253                         }
254                         CATCH_ALL
255                         {
256                                 show_exception(tvb, pinfo, tree, EXCEPT_CODE);
257                         }
258                         ENDTRY;
259         }
260 }
261 static char*
262 string_to_hex(const unsigned char * in,char * out,int len)
263 {
264         char ascii[MAXSTRING];
265         int  i;
266         memset(&ascii,0x00,sizeof(ascii));
267 for(i=0;i<len;i++)
268                         {
269         unsigned char o_out = *(in+i);
270     sprintf(out+(i<<1),"%.2x",*  (in+i));
271         if(  ( (o_out) >= 'a') & ( (o_out) <='z')  ||
272                  ( (o_out) >= 'A') & ( (o_out) <='Z')  ||
273                  ( (o_out) >= '0') & ( (o_out) <='9')
274            )
275                                         {
276                                         ascii[i] = o_out;
277                                         }
278                                 else
279                                         {
280                                         ascii[i] = '.';
281                                         }
282
283                         }
284                 strcat(out," ");
285                 strcat(out,ascii);
286     return out;
287 }
288
289 static int read_length(ASN1_SCK *a, proto_tree *tree, int hf_id, guint *len)
290 {
291   guint length = 0;
292   gboolean def = FALSE;
293   int start = a->offset;
294   int ret;
295
296   ret = asn1_length_decode(a, &def, &length);
297   if (ret != ASN1_ERR_NOERROR)
298   {
299     if (tree)
300         {
301       proto_tree_add_text(tree, a->tvb, start, 0,
302         "%s: ERROR: Couldn't parse length: %s",
303         proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
304     }
305     return ret;
306   }
307
308   if (len)
309     *len = length;
310
311   if (tree && hf_id)
312     proto_tree_add_uint(tree, hf_id, a->tvb, start, a->offset-start,
313 length);
314
315   return ASN1_ERR_NOERROR;
316 }
317 static int read_integer_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
318         proto_item **new_item, guint *i, int start, guint length)
319 {
320   guint integer = 0;
321   proto_item *temp_item = NULL;
322   int ret;
323
324   ret = asn1_uint32_value_decode(a, length, &integer);
325   if (ret != ASN1_ERR_NOERROR)
326   {
327     if (tree)
328         {
329       proto_tree_add_text(tree, a->tvb, start, 0,
330        "%s: ERROR: Couldn't parse value: %s",
331         proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
332     }
333     return ret;
334   }
335
336   if (i)
337     *i = integer;
338
339   if (tree && hf_id)
340     temp_item = proto_tree_add_uint(tree, hf_id, a->tvb, start,
341 a->offset-start, integer);
342
343   if (new_item)
344     *new_item = temp_item;
345
346   return ASN1_ERR_NOERROR;
347 }
348
349 static int read_integer(ASN1_SCK *a, proto_tree *tree, int hf_id,
350         proto_item **new_item, guint *i)
351 {
352   guint cls, con, tag;
353   gboolean def;
354   guint length;
355   int start = a->offset;
356   int ret;
357
358   ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
359   if (ret != ASN1_ERR_NOERROR)
360   {
361     if (tree)
362         {
363       proto_tree_add_text(tree, a->tvb, start, 0,
364         "%s: ERROR: Couldn't parse header: %s",
365         (hf_id != -1) ? proto_registrar_get_name(hf_id) : "LDAP message",
366         asn1_err_to_str(ret));
367     }
368     return ret;
369   }
370
371   return read_integer_value(a, tree, hf_id, new_item, i, start, length);
372 }
373 /*   display asn.1 Integer type */
374 static void
375 show_integer(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
376 *offset,guint item_len)
377 {
378           proto_tree *acse_tree_itm = NULL;
379           proto_item *itm;
380           int       ret;
381           int           save_len = item_len;
382           int           off      = *offset;
383           itm = proto_tree_add_text(acse_tree, tvb, *offset, item_len,
384                                                                                 "Integer");
385           acse_tree_itm = proto_item_add_subtree(itm, ett_acse_itm);
386           ret = read_integer(asn,acse_tree_itm,0,NULL,&item_len);
387           if (ret == ASN1_ERR_NOERROR )
388                         {
389                                 *offset = asn->offset;
390                                 itm = proto_tree_add_text(acse_tree_itm, tvb, (*offset)-item_len,
391                                                                                         item_len,
392                                                                                         "Integer value: %u",item_len);
393                         }
394           else
395                         {
396                   /* can't dissect item. Skip it. */
397                   *offset = off+ save_len;
398                         }
399
400 }
401 static void
402 show_protocol_version(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
403 *offset,int item_len,int tag)
404 {
405           proto_tree *acse_tree_itm = NULL;
406           proto_item *itm;
407           guint16       flags;
408           gint length;
409 /* do we have enough bytes to dissect this item ? */
410                         if( ( length = tvb_reported_length_remaining(tvb, *offset))  <
411                                                                                 (asn->offset -*offset)+ item_len )
412                         {
413                                         proto_tree_add_text(acse_tree, tvb, *offset, item_len,
414                                                         "Wrong Item.Need %u bytes but have %u", item_len,length);
415                                         return;
416                         }
417
418           itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset -*offset)+
419                                                                 item_len,
420                                                                 val_to_str(tag, request_sequence_top_vals,"Unknown item (0x%02x)"));
421           acse_tree_itm = proto_item_add_subtree(itm, ett_acse_itm);
422           *offset = asn->offset;
423           flags = tvb_get_ntohs(tvb, *offset);
424           proto_tree_add_boolean(acse_tree_itm,hf_protocol_version, tvb, *offset,
425                                                         2, flags);
426           *offset = *offset + item_len;
427           asn->offset = *offset;
428 }
429 static void
430 print_oid_value(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
431 *offset,int item_len)
432 {
433         guint           ret;
434         subid_t         *oid;
435         guint           len;
436         gchar           *display_string;
437         guint           length;
438         guint           start=*offset;
439
440                 ret = asn1_oid_value_decode (asn, item_len, &oid, &len);
441                 if (ret != ASN1_ERR_NOERROR)
442                 {
443                         return ;
444                 }
445                 length = asn->offset - start;
446                 display_string = format_oid(oid, len);
447                 proto_tree_add_text(acse_tree, tvb, *offset,length,"Value:%s",
448                                                         display_string);
449                 g_free(display_string);
450                 (*offset)=start+item_len;
451                 asn->offset = (*offset);
452 }
453 static void
454 print_oid(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int *offset,int
455 item_len,gchar* d_s)
456 {
457         guint           ret;
458         subid_t         *oid;
459         guint           len;
460         guint           nbytes;
461         gchar           *display_string;
462         guint           length;
463         guint           start=*offset;
464
465                 ret = asn1_oid_decode ( asn, &oid, &len, &nbytes);
466
467                 if (ret != ASN1_ERR_NOERROR)
468                 {
469                         return ;
470                 }
471                 length = asn->offset - start;
472                 display_string = format_oid(oid, len);
473                 proto_tree_add_text(acse_tree, tvb, *offset,length,"Value:%s",
474                                                         display_string);
475                 if(d_s)
476                 {
477                         /*   copy OID   */
478                         strcpy(d_s,display_string);
479                 }
480                 g_free(display_string);
481                 (*offset)=start+item_len;
482                 asn->offset = (*offset);
483 }
484
485 static void
486 print_value(proto_tree *acse_tree,tvbuff_t *tvb,int
487 *offset,int item_len)
488 {
489           char    tmp[MAXSTRING];
490                 string_to_hex(tvb_get_ptr(tvb,*offset,item_len),tmp,item_len);
491                 proto_tree_add_text(acse_tree, tvb, *offset, item_len, tmp);
492 }
493 static int
494 get_integer_value(ASN1_SCK *asn,int length,int *offset)
495 {
496         int off = *offset;
497         int asn_off = asn->offset;
498         int item_len = -1;
499         int ret;
500         /* align   pointers */
501         *offset=asn->offset;
502         ret = asn1_uint32_value_decode(asn, length, &item_len);
503         /* return to present position */
504         *offset = off;
505         asn->offset = asn_off;
506
507     if (ret != ASN1_ERR_NOERROR )
508         {
509                 return -1;
510         }
511         else
512         {
513                 return item_len;
514         }
515
516 }
517 static void
518 show_fully_encoded_seq(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
519 *offset,int item_len)
520 {
521           proto_tree *acse_tree_ms = NULL;
522           guint length;
523           guint   type;
524           proto_item *ms;
525           guint   new_item_len;
526           guint   start = *offset;
527           guint   header_len;
528           guint   acse = 0;      /*   no acse   id   */
529           int           old_offset;
530                         /*  print seq */
531                         while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 )
532                         {
533                                 old_offset = *offset ;
534                         /*  get item type  */
535                         type = tvb_get_guint8(tvb, *offset);
536                         /* skip type */
537                         (*offset)++;
538                         asn->offset = *offset;
539                         /* get length  */
540                                 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
541                                 {
542                                         (*offset)=start+item_len;
543                                         asn->offset = (*offset);
544                                         return  ;
545                                 }
546                         /* do we have enough bytes to dissect ? */
547                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  <
548                                                                                                                 new_item_len )
549                         {
550                                         proto_tree_add_text(acse_tree, tvb, *offset, new_item_len,
551                                                         "Wrong item.Need %u bytes but have %u", new_item_len,length);
552                                         (*offset)=start+item_len;
553                                         asn->offset = (*offset);
554                                     return ;
555                         }
556                                 header_len = asn->offset - (*offset) +1;
557                                         ms = proto_tree_add_text(acse_tree, tvb, *offset-1,
558                                                                                 new_item_len+(asn->offset-*offset)+1,
559                                                                                 val_to_str(type, presentation_data_values,
560                                                                                 "Unknown item (0x%02x)"));
561                                 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
562                                 *offset = asn->offset;
563
564
565                         switch(type)
566                                 {
567                         case PRESENTATION_CONTEXT_IDENTIFIER:
568                                 {
569                                 acse    =       get_integer_value(asn,new_item_len,offset);
570                                 print_value(acse_tree_ms,tvb,offset,new_item_len);
571                                 }
572                                         break;
573                         case ABSTRACT_SYNTAX_NAME:
574                                 print_oid_value(asn,acse_tree_ms,tvb,offset,new_item_len);
575                                         break;
576
577                         case OCTET_ALIGNED:
578                                 break;
579                         case SINGLE_ASN1_TYPE:
580                                 {
581                                                 proto_item *acse_ms;
582                                         /*  yes, we have to call ACSE dissector    */
583                                 acse_ms = proto_tree_add_text(acse_tree_ms, tvb, *offset,
584                                                                                 new_item_len+(asn->offset-*offset),
585                                                                                 "user data");
586                                         /*  call acse dissector  */
587                                 call_app_dissector(tvb,*offset,new_item_len,global_pinfo,global_tree,acse_tree_ms);
588                                 }
589                                         break;
590                         case ARBITRARY:
591                                 print_value(acse_tree_ms,tvb,offset,new_item_len);
592                                         break;
593                         default:
594                                         proto_tree_add_text(acse_tree, tvb, *offset,
595                                                                                 new_item_len+(asn->offset-*offset),
596                                         "Unknown asn.1 parameter: (0x%02x)", type);
597                                 }
598                                 *offset = old_offset+new_item_len+header_len;
599                                 item_len-=new_item_len+header_len;
600                         }
601                         /*   align the pointer */
602                         (*offset)=start+item_len;
603                         asn->offset = (*offset);
604
605 }
606
607 static void
608 show_acse_user_information(ASN1_SCK *asn,proto_tree
609 *acse_tree,tvbuff_t *tvb,int *offset,int item_len)
610 {
611           proto_tree *acse_tree_ms = NULL;
612           proto_tree *acse_tree_ab = NULL;
613           guint length;
614           guint   type;
615           proto_item *ms;
616           proto_item *ab;
617           guint   new_item_len;
618           guint   code_item_len;
619           guint   start = *offset;
620           guint   header_len;
621                         /*  get item type  */
622                         type = tvb_get_guint8(tvb, *offset) & 0x1f;
623                         /* skip type */
624                         (*offset)++;
625                         asn->offset = *offset;
626                         /* get length  */
627                                 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
628                                 {
629                                         (*offset)=start+item_len;
630                                         asn->offset = (*offset);
631                                         return  ;
632                                 }
633
634                         /* do we have enough bytes to dissect ? */
635                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  <
636                                                                                                                 new_item_len )
637                         {
638                                         proto_tree_add_text(acse_tree, tvb, *offset, new_item_len,
639                                                         "Wrong item.Need %u bytes but have %u", new_item_len,length);
640                                         (*offset)=start+item_len;
641                                         asn->offset = (*offset);
642                                     return ;
643                         }
644                                 header_len = asn->offset - (*offset) +1;
645                                 ms = proto_tree_add_text(acse_tree, tvb, *offset-1,
646                                                                                 new_item_len+(asn->offset-*offset)+1,
647                                                                                 val_to_str(type,response_sequence_top_vals,
648                                                                                 "Unknown item (0x%02x)"));
649                                 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
650                                 *offset = asn->offset;
651                                 /*  get item type  */
652                                 type = tvb_get_guint8(tvb, *offset) & 0x1f;
653                                 /* do we have user or provider abort ?  */
654                                 ab = proto_tree_add_text(acse_tree_ms, tvb, *offset,
655                                                                                 new_item_len+(asn->offset-*offset),
656                                                                                 val_to_str(type,acse_user_information_vals,
657                                                                                 "Unknown item (0x%02x)"));
658                                 acse_tree_ab = proto_item_add_subtree(ab, ett_acse_ms);
659
660                                 if(type!= ACSE_EXTERNAL)
661                                 {
662                                         (*offset)=start+item_len;
663                                         asn->offset = (*offset);
664                                         return  ;
665                                 }
666
667                                 /*  skip type of item*/
668                                 (*offset)++;
669                                 asn->offset = *offset;
670                                 /* get length  */
671                                 if (read_length(asn, acse_tree_ab, 0, &code_item_len) != 
672 ASN1_ERR_NOERROR)
673                                 {
674                                         (*offset)=start+item_len;
675                                         asn->offset = (*offset);
676                                         return  ;
677                                 }
678                                 /* do we have enough bytes to dissect ? */
679                                 if( ( length =tvb_reported_length_remaining(tvb, *offset))  <
680                                                                                                                 code_item_len )
681                                 {
682                                         proto_tree_add_text(acse_tree_ab, tvb, *offset, code_item_len,
683                                                         "Wrong item.Need %u bytes but have %u", code_item_len,length);
684                                         (*offset)=start+item_len;
685                                         asn->offset = (*offset);
686                                     return ;
687                                 }
688                                 *offset = asn->offset;
689
690                                 show_fully_encoded_seq(asn,acse_tree_ab,tvb,offset,code_item_len);
691                         /*   align the pointer */
692                         (*offset)=start+item_len;
693                         asn->offset = (*offset);
694 }
695
696 static void
697 show_acse_result_source_diagnostic(ASN1_SCK *asn,proto_tree
698 *acse_tree,tvbuff_t *tvb,int *offset,int item_len)
699 {
700           proto_tree *acse_tree_ms = NULL;
701           proto_tree *acse_tree_ab = NULL;
702           guint length;
703           guint   type;
704           proto_item *ms;
705           proto_item *ab;
706           guint   new_item_len;
707           guint   code_item_len;
708           guint   start = *offset;
709           guint   header_len;
710           proto_tree *acse_tree_pr = NULL;
711           proto_item *pr;
712           int   value;
713                         /*  get item type  */
714                         type = tvb_get_guint8(tvb, *offset) & 0x1f;
715                         /* skip type */
716                         (*offset)++;
717                         asn->offset = *offset;
718                         /* get length  */
719                                 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
720                                 {
721                                         (*offset)=start+item_len;
722                                         asn->offset = (*offset);
723                                         return  ;
724                                 }
725
726                         /* do we have enough bytes to dissect ? */
727                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  <
728                                                                                                                 new_item_len )
729                         {
730                                         proto_tree_add_text(acse_tree, tvb, *offset, new_item_len,
731                                                         "Wrong item.Need %u bytes but have %u", new_item_len,length);
732                                         (*offset)=start+item_len;
733                                         asn->offset = (*offset);
734                                     return ;
735                         }
736                                 header_len = asn->offset - (*offset) +1;
737                                 ms = proto_tree_add_text(acse_tree, tvb, *offset-1,
738                                                                                 new_item_len+(asn->offset-*offset)+1,
739                                                                                 val_to_str(type,response_sequence_top_vals,
740                                                                                 "Unknown item (0x%02x)"));
741                                 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
742                                 *offset = asn->offset;
743                         /*  get item type  */
744                         type = tvb_get_guint8(tvb, *offset) & 0x1f;
745                         /* do we have user or provider abort ?  */
746                                 ab = proto_tree_add_text(acse_tree_ms, tvb, *offset,
747                                                                                 new_item_len+(asn->offset-*offset),
748                                                                                 val_to_str(type,acse_associate_source_diagnostic_vals,
749                                                                                 "Unknown item (0x%02x)"));
750                                 acse_tree_ab = proto_item_add_subtree(ab, ett_acse_ms);
751
752                                 /*  skip type of abort*/
753                                 (*offset)++;
754                                 asn->offset = *offset;
755                                 /* get length  */
756                                 if (read_length(asn, acse_tree, 0, &code_item_len) != ASN1_ERR_NOERROR)
757                                 {
758                                         (*offset)=start+item_len;
759                                         asn->offset = (*offset);
760                                         return  ;
761                                 }
762                                 *offset = asn->offset;
763                                 /* do we have enough bytes to dissect ? */
764                                 if( ( length =tvb_reported_length_remaining(tvb, *offset))  <
765                                                                                                                 code_item_len )
766                                 {
767                                         proto_tree_add_text(acse_tree, tvb, *offset, code_item_len,
768                                                         "Wrong item.Need %u bytes but have %u", code_item_len,length);
769                                         (*offset)=start+item_len;
770                                         asn->offset = (*offset);
771                                     return ;
772                                 }
773
774                                 /*  skip type of constant*/
775                                 (*offset)++;
776                                 asn->offset = *offset;
777                                 /* get length  */
778                                 if (read_length(asn, acse_tree_ab, 0, &code_item_len) != 
779 ASN1_ERR_NOERROR)
780                                 {
781                                         (*offset)=start+item_len;
782                                         asn->offset = (*offset);
783                                         return  ;
784                                 }
785                                 /* do we have enough bytes to dissect ? */
786                                 if( ( length =tvb_reported_length_remaining(tvb, *offset))  <
787                                                                                                                 code_item_len )
788                                 {
789                                         proto_tree_add_text(acse_tree_ab, tvb, *offset, code_item_len,
790                                                         "Wrong item.Need %u bytes but have %u", code_item_len,length);
791                                         (*offset)=start+item_len;
792                                         asn->offset = (*offset);
793                                     return ;
794                                 }
795                                 *offset = asn->offset;
796                             value       =       get_integer_value(asn,code_item_len,offset);
797                                 if(type == ACSE_SERVICE_USER )
798                                 {
799                                 pr = proto_tree_add_text(acse_tree_ab, tvb, *offset,
800                                                                 code_item_len+(asn->offset-*offset),
801                                                                 val_to_str(value , acse_service_user_values_vals,
802                                                                 "Unknown item (0x%02x)"));
803                                 }
804                                 else
805                                 {
806                                 pr = proto_tree_add_text(acse_tree_ab, tvb, *offset,
807                                                                 code_item_len+(asn->offset-*offset),
808                                                                 val_to_str(value , acse_service_provider_values_vals,
809                                                                 "Unknown item (0x%02x)"));
810                                 }
811
812                                 acse_tree_pr = proto_item_add_subtree(pr, ett_acse_ms);
813                                 print_value(acse_tree_pr,tvb,offset,code_item_len);
814
815                                 *offset = start+new_item_len+header_len;
816                                 item_len-=new_item_len+header_len;
817                         /*   align the pointer */
818                         (*offset)=start+item_len;
819                         asn->offset = (*offset);
820
821 }
822 static void
823 show_acse_result(ASN1_SCK *asn,proto_tree
824 *acse_tree,tvbuff_t *tvb,int *offset,int item_len)
825 {
826           proto_tree *acse_tree_ms = NULL;
827           guint length;
828           guint   type;
829           proto_item *ms;
830           guint   new_item_len;
831           guint   code_item_len;
832           guint   start = *offset;
833           guint   header_len;
834           proto_tree *acse_tree_pr = NULL;
835           proto_item *pr;
836           int   value;
837                         /*  get item type  */
838                         type = tvb_get_guint8(tvb, *offset) & 0x1f;
839                         /* skip type */
840                         (*offset)++;
841                         asn->offset = *offset;
842                         /* get length  */
843                                 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
844                                 {
845                                         (*offset)=start+item_len;
846                                         asn->offset = (*offset);
847                                         return  ;
848                                 }
849
850                         /* do we have enough bytes to dissect ? */
851                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  <
852                                                                                                                 new_item_len )
853                         {
854                                         proto_tree_add_text(acse_tree, tvb, *offset, new_item_len,
855                                                         "Wrong item.Need %u bytes but have %u", new_item_len,length);
856                                         (*offset)=start+item_len;
857                                         asn->offset = (*offset);
858                                     return ;
859                         }
860                                 header_len = asn->offset - (*offset) +1;
861                                 ms = proto_tree_add_text(acse_tree, tvb, *offset-1,
862                                                                                 new_item_len+(asn->offset-*offset)+1,
863                                                                                 val_to_str(type,response_sequence_top_vals,
864                                                                                 "Unknown item (0x%02x)"));
865                                 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
866                                 *offset = asn->offset;
867                                 /*  skip type */
868                                 (*offset)++;
869                                 asn->offset = *offset;
870                                 /* get length  */
871                                 if (read_length(asn, acse_tree, 0, &code_item_len) != ASN1_ERR_NOERROR)
872                                 {
873                                         (*offset)=start+item_len;
874                                         asn->offset = (*offset);
875                                         return  ;
876                                 }
877                                 /* do we have enough bytes to dissect ? */
878                                 if( ( length =tvb_reported_length_remaining(tvb, *offset))  <
879                                                                                                                 code_item_len )
880                                 {
881                                         proto_tree_add_text(acse_tree, tvb, *offset, code_item_len,
882                                                         "Wrong item.Need %u bytes but have %u", code_item_len,length);
883                                         (*offset)=start+item_len;
884                                         asn->offset = (*offset);
885                                     return ;
886                                 }
887                                 *offset = asn->offset;
888                             value       =       get_integer_value(asn,code_item_len,offset);
889                                 pr = proto_tree_add_text(acse_tree_ms, tvb, *offset,
890                                                                 code_item_len+(asn->offset-*offset),
891                                                                 val_to_str(value , associate_result_values_vals,
892                                                                 "Unknown item (0x%02x)"));
893                                 acse_tree_pr = proto_item_add_subtree(pr, ett_acse_ms);
894                                 print_value(acse_tree_pr,tvb,offset,code_item_len);
895
896                                 *offset = start+new_item_len+header_len;
897                                 item_len-=new_item_len+header_len;
898                         /*   align the pointer */
899                         (*offset)=start+item_len;
900                         asn->offset = (*offset);
901 }
902
903 static void
904 show_oid(ASN1_SCK *asn,proto_tree
905 *acse_tree,tvbuff_t *tvb,int *offset,int item_len,const value_string* 
906 v_s,gchar* oid)
907 {
908           proto_tree *acse_tree_ms = NULL;
909           guint length;
910           guint   type;
911           proto_item *ms;
912           guint   new_item_len;
913           guint   start = *offset;
914           guint   header_len;
915           int           old_offset;
916                                 old_offset = *offset ;
917                         /*  get item type  */
918                         type = tvb_get_guint8(tvb, *offset) & 0x1f;
919                         /* skip type */
920                         (*offset)++;
921                         asn->offset = *offset;
922                         /* get length  */
923                                 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
924                                 {
925                                         (*offset)=start+item_len;
926                                         asn->offset = (*offset);
927                                         return  ;
928                                 }
929
930                         /* do we have enough bytes to dissect ? */
931                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  <
932                                                                                                                 new_item_len )
933                         {
934                                         proto_tree_add_text(acse_tree, tvb, *offset, new_item_len,
935                                                         "Wrong item.Need %u bytes but have %u", new_item_len,length);
936                                         (*offset)=start+item_len;
937                                         asn->offset = (*offset);
938                                     return ;
939                         }
940                                 header_len = asn->offset - (*offset) +1;
941                                 ms = proto_tree_add_text(acse_tree, tvb, *offset-1,
942                                                                                 new_item_len+(asn->offset-*offset)+1,
943                                                                                 val_to_str(type, v_s,
944                                                                                 "Unknown item (0x%02x)"));
945                                 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
946                                 *offset = asn->offset;
947                                 print_oid(asn,acse_tree_ms,tvb,offset,new_item_len,oid);
948                                 *offset = old_offset+new_item_len+header_len;
949                                 item_len-=new_item_len+header_len;
950                         /*   align the pointer */
951                         (*offset)=start+item_len;
952                         asn->offset = (*offset);
953 }
954 static void
955 show_fully_encoded_data(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
956 *tvb,int *offset,int item_len)
957 {
958           proto_tree *acse_tree_ms = NULL;
959           proto_tree *acse_tree_pc = NULL;
960           gint    length;
961           guint   type;
962           guint   header_len;
963           proto_item *ms;
964           guint   new_item_len;
965           guint   start = asn->offset;
966           guint   item_length = item_len;
967           acse_tree_pc = acse_tree;
968
969 /* do we have enough bytes to dissect ? */
970                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  < item_len )
971                         {
972                                         proto_tree_add_text(acse_tree_pc, tvb, *offset, item_len,
973                                                         "Wrong item.Need %u bytes but have %u", item_len,length);
974                                         /*   align the pointer */
975                                         (*offset)=start+item_length;
976                                         asn->offset = (*offset);
977                                         return ;
978                         }
979                         *offset =asn->offset;
980                         start = *offset;
981                         /*  read the rest */
982                         while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 )
983                         {
984                                 int old_offset = *offset;
985                         /*  get item type  */
986                         type = tvb_get_guint8(tvb, *offset);
987                         /* skip type */
988                         (*offset)++;
989                         asn->offset = *offset;
990                         /* get length  */
991                                 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
992                                                                 ASN1_ERR_NOERROR)
993                                 {
994                                         /*   align the pointer */
995                                         (*offset)=start+item_length;
996                                         asn->offset = (*offset);
997                                         return  ;
998                                 }
999                                 header_len = asn->offset - (*offset) +1;
1000                         /* do we have enough bytes to dissect ? */
1001                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  <
1002                                                                                                                 new_item_len )
1003                         {
1004                                         proto_tree_add_text(acse_tree_pc, tvb, *offset, new_item_len,
1005                                                         "Wrong item.Need %u bytes but have %u", new_item_len,length);
1006                                         /*   align the pointer */
1007                                         (*offset)=start+item_length;
1008                                         asn->offset = (*offset);
1009                                         return ;
1010                         }
1011                                 ms = proto_tree_add_text(acse_tree_pc, tvb, *offset-1,
1012                                                                                 new_item_len+(asn->offset-*offset)+1,
1013                                                                                 val_to_str(type, presentation_context_definition_vals,
1014                                                                                 "Unknown item (0x%02x)"));
1015                                 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
1016                                 *offset = asn->offset;
1017
1018
1019                         switch(type)
1020                                 {
1021
1022                         case SEQUENCE:
1023                         show_fully_encoded_seq(asn,acse_tree_ms,tvb,offset,new_item_len);
1024                         *offset = old_offset+(new_item_len+header_len);
1025                                         break;
1026
1027                         default:
1028                                         proto_tree_add_text(acse_tree_ms, tvb, *offset,
1029                                                                                 new_item_len+(asn->offset-*offset),
1030                                         "Unknown asn.1 parameter: (0x%02x)", type);
1031                                         *offset = old_offset+(new_item_len+header_len);
1032                                 }
1033                                 item_len = item_len -  (new_item_len+header_len);
1034
1035                         }
1036
1037
1038                                         /*   align the pointer */
1039                                         (*offset)=start+item_length;
1040                                         asn->offset = (*offset);
1041 }
1042 static void
1043 show_abort_reason(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1044 *tvb,int *offset,int item_len)
1045 {
1046         gint            length;
1047         gint            value;
1048     proto_tree  *acse_tree_pc = NULL;
1049         proto_item      *itu;
1050         guint           new_item_len;
1051         guint           start = *offset;
1052         int                     save_len = item_len;
1053 /* do we have enough bytes to dissect this item ? */
1054                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  < item_len )
1055                         {
1056                                         proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1057                                                         "Wrong Item.Need %u bytes but have %u", item_len,length);
1058                                                         *offset = asn->offset;
1059                                                         return;
1060                         }
1061
1062                         if(item_len <= 0)
1063                         {
1064                                         proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1065                                                         "Reason not specified");
1066                                                         *offset = asn->offset;
1067                                                         return;
1068                         }
1069                         itu = proto_tree_add_text(acse_tree, tvb, *offset,ABORT_REASON_LEN,
1070                                         "Reason");
1071                         acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1072                         (*offset)++; /* skip type  */
1073                         asn->offset =  *offset;
1074                         item_len--;
1075                         /* get length  */
1076                                 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
1077                                                                 ASN1_ERR_NOERROR)
1078                                 {
1079                                                         *offset = asn->offset;
1080                                                         return;
1081                                 }
1082                         /*  try to get reason  */
1083                         value   =       get_integer_value(asn,new_item_len,offset);
1084
1085                         proto_tree_add_text(acse_tree_pc, tvb, *offset+1,new_item_len,
1086                                         val_to_str(value,abort_reason,"Unknown item (0x%02x)"));
1087                         item_len-=(asn->offset-*offset)+new_item_len;
1088                         *offset = asn->offset+new_item_len;
1089                         asn->offset = *offset;
1090                         /*  do we have User information field  ?  */
1091                         if(item_len > 0)
1092                         {
1093                                 show_acse_user_information(asn,acse_tree,tvb,offset,item_len);
1094                         }
1095                         /*   align the pointer */
1096                         (*offset)=start+save_len;
1097                         asn->offset = (*offset);
1098 }
1099
1100 static void
1101 show_disconnect_pdu(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1102 *tvb,int *offset,int item_len)
1103 {
1104         gint            length;
1105         gint            value;
1106     proto_tree  *acse_tree_pc = NULL;
1107         proto_item      *itu;
1108         guint           new_item_len;
1109         guint           start = *offset;
1110         int                     save_len = item_len;
1111 /* do we have enough bytes to dissect this item ? */
1112                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  < item_len )
1113                         {
1114                                         proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1115                                                         "Wrong Item.Need %u bytes but have %u", item_len,length);
1116                                                         *offset = asn->offset;
1117                                                         return;
1118                         }
1119
1120                         if(item_len <= 0)
1121                         {
1122                                         proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1123                                                         "Reason not specified");
1124                                                         *offset = asn->offset;
1125                                                         return;
1126                         }
1127                         itu = proto_tree_add_text(acse_tree, tvb, *offset,ABORT_REASON_LEN,
1128                                         "Reason");
1129                         acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1130                         (*offset)++; /* skip type  */
1131                         asn->offset =  *offset;
1132                         item_len--;
1133                         /* get length  */
1134                                 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
1135                                                                 ASN1_ERR_NOERROR)
1136                                 {
1137                                                         *offset = asn->offset;
1138                                                         return;
1139                                 }
1140                         /*  try to get reason  */
1141                         value   =       get_integer_value(asn,new_item_len,offset);
1142
1143                         proto_tree_add_text(acse_tree_pc, tvb, *offset+1,new_item_len,
1144                                         val_to_str(value,release_response_reason,"Unknown item (0x%02x)"));
1145                         item_len-=(asn->offset-*offset)+new_item_len;
1146                         *offset = asn->offset+new_item_len;
1147                         asn->offset = *offset;
1148                         /*  do we have User information field  ?  */
1149                         if(item_len > 0)
1150                         {
1151                                 show_acse_user_information(asn,acse_tree,tvb,offset,item_len);
1152                         }
1153                         /*   align the pointer */
1154                         (*offset)=start+save_len;
1155                         asn->offset = (*offset);
1156 }
1157
1158 static void
1159 show_finish_pdu(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1160 *tvb,int *offset,int item_len)
1161 {
1162         gint            length;
1163         gint            value;
1164     proto_tree  *acse_tree_pc = NULL;
1165         proto_item      *itu;
1166         guint           new_item_len;
1167         guint           start = *offset;
1168         int                     save_len = item_len;
1169 /* do we have enough bytes to dissect this item ? */
1170                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  < item_len )
1171                         {
1172                                         proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1173                                                         "Wrong Item.Need %u bytes but have %u", item_len,length);
1174                                                         *offset = asn->offset;
1175                                                         return;
1176                         }
1177
1178                         if(item_len <= 0)
1179                         {
1180                                         proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1181                                                         "Reason not specified");
1182                                                         *offset = asn->offset;
1183                                                         return;
1184                         }
1185                         itu = proto_tree_add_text(acse_tree, tvb, *offset,ABORT_REASON_LEN,
1186                                         "Reason");
1187                         acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1188                         (*offset)++; /* skip type  */
1189                         asn->offset =  *offset;
1190                         item_len--;
1191                         /* get length  */
1192                                 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
1193                                                                 ASN1_ERR_NOERROR)
1194                                 {
1195                                                         *offset = asn->offset;
1196                                                         return;
1197                                 }
1198                         /*  try to get reason  */
1199                         value   =       get_integer_value(asn,new_item_len,offset);
1200
1201                         proto_tree_add_text(acse_tree_pc, tvb, *offset+1,new_item_len,
1202                                         val_to_str(value,release_request_reason,"Unknown item (0x%02x)"));
1203                         item_len-=(asn->offset-*offset)+new_item_len;
1204                         *offset = asn->offset+new_item_len;
1205                         asn->offset = *offset;
1206                         /*  do we have User information field  ?  */
1207                         if(item_len > 0)
1208                         {
1209                                 show_acse_user_information(asn,acse_tree,tvb,offset,item_len);
1210                         }
1211                         /*   align the pointer */
1212                         (*offset)=start+save_len;
1213                         asn->offset = (*offset);
1214 }
1215 static void
1216 show_user_data(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
1217 *offset,int item_len,int tag)
1218 {
1219           proto_tree *acse_tree_ud = NULL;
1220           proto_tree *acse_tree_pc = NULL;
1221           proto_item *itm;
1222           proto_item *itu;
1223           guint   start = asn->offset;
1224           guint   item_length = item_len;
1225
1226                         itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset -*offset)+
1227                                                                         item_len,       "User data");
1228                         acse_tree_ud = proto_item_add_subtree(itm, ett_acse_ms);
1229                         itu = proto_tree_add_text(acse_tree_ud, tvb,
1230                                                                                 *offset,item_len+(asn->offset-*offset),
1231                                         val_to_str(tag, user_data_values_vals,"Unknown item (0x%02x)"));
1232                         acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1233                         switch(tag)
1234                         {
1235                         case SIMPLY_ENCODED_DATA:
1236                                 break;
1237                         case FULLY_ENCODED_DATA:
1238                                 show_fully_encoded_data(asn,acse_tree_pc,tvb,offset,item_len);
1239                                 break;
1240                         default:
1241                                 break;
1242                         }
1243
1244
1245                         /*   align the pointer */
1246                         (*offset)=start+item_length;
1247                         asn->offset = (*offset);
1248
1249 }
1250
1251 /* if we can't dissect */
1252 static void
1253 dissect_parse_error(tvbuff_t *tvb, int offset, packet_info *pinfo,
1254                     proto_tree *tree, const char *field_name, int ret)
1255 {
1256         char *errstr;
1257         errstr = asn1_err_to_str(ret);
1258
1259         if (tree != NULL)
1260         {
1261                 proto_tree_add_text(tree, tvb, offset, 0,
1262                     "ERROR: Couldn't parse %s: %s", field_name, errstr);
1263                 call_dissector(data_handle,
1264                     tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
1265         }
1266 }
1267
1268 /* display request top sequence  */
1269 static void
1270 show_request_sequence_top(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1271 *tvb,packet_info *pinfo,int *offset,int item_len)
1272 {
1273         int ret;
1274         guint cls, con, tag,len1;
1275         gint  type;
1276         gboolean def;
1277         proto_item *itm;
1278         gint length;
1279         unsigned char ftam_oid[] = "1.0.8571.1.1";
1280         unsigned char cmip_oid[] ="2.9.0.0.2";
1281
1282         while(item_len > 0 )
1283         {
1284                         int offset_save = *offset;
1285 /* do we have enough bytes to dissect this item ? */
1286                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  < item_len )
1287                         {
1288                                         proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1289                                                         "Wrong Item.Need %u bytes but have %u", item_len,length);
1290                                         break;
1291                         }
1292                 /*   get  tag     */
1293                         type = tvb_get_guint8(tvb, *offset);
1294                 /* decode header  */
1295                         ret = asn1_header_decode(asn, &cls, &con, &tag, &def, &len1);
1296
1297                         if (ret != ASN1_ERR_NOERROR)
1298                         {
1299                                                         dissect_parse_error(tvb, *offset, pinfo, acse_tree,
1300                                                                         "sequence error", ret);
1301                                 break;
1302                         }
1303                         /* add header  */
1304                         item_len = item_len - (asn->offset - *offset);
1305                         offset_save += (asn->offset - *offset);
1306                                                 /*
1307                                                 * [APPLICATION <tag>]
1308                                                 */
1309                                                 switch (tag)
1310                                                         {
1311                                                                 case USER_INFORMATION:
1312                                                                         show_acse_user_information(asn,acse_tree,tvb,offset,len1);
1313                                                                         break;
1314                                                                 case CALLED_AE_QUALIFIER:
1315                                                                 case CALLING_AE_QUALIFIER:
1316                                                                         {
1317                                                                         proto_tree *acse_tree_pr = NULL;
1318                                                                         proto_item *pr;
1319                                                                         pr = proto_tree_add_text(acse_tree,tvb,*offset,
1320                                                                         len1+(asn->offset-*offset),
1321                                                                         val_to_str(tag ,request_sequence_top_vals,
1322                                                                         "Unknown item (0x%02x)"));
1323                                                                         acse_tree_pr = proto_item_add_subtree(pr, ett_acse_ms);
1324                                                                         show_integer(asn,acse_tree_pr,tvb,offset,len1);
1325                                                                         }
1326                                                                         break;
1327                                                                 case APPLICATION_CONTEXT_NAME:
1328                                                                 case CALLED_AP_TITLE:
1329                                                                 case CALLING_AP_TITLE:
1330                                                                 case CALLED_AP_INVOKATION_ID:
1331                                                                 case CALLED_AE_INVOKATION_ID:
1332                                                                 case CALLING_AP_INVOKATION_ID:
1333                                                                 case CALLING_AE_INVOKATION_ID:
1334                                                                 {
1335                                                                         gchar oid_string[MAXSTRING];
1336                                                                         show_oid(asn,acse_tree,tvb,offset,len1,(const 
1337 value_string*)&request_sequence_top_vals,
1338                                                                                                 (gchar*)&oid_string);
1339                                                                         if(tag == APPLICATION_CONTEXT_NAME )
1340                                                                         {
1341                                                                                 if( !strcmp(oid_string,cmip_oid)  )
1342                                                                                 {
1343                                                                                         /* it is CMIP   */
1344                                                                                         type_of_application = CMIP_APP;
1345                                                                                         app_handle = cmip_handle;
1346                                                                                 }
1347                                                                                 else
1348                                                                                 if( !strcmp(oid_string,ftam_oid) )
1349                                                                                 {
1350                                                                                         /* it is CMIP   */
1351                                                                                         type_of_application = FTAM_APP;
1352                                                                                         app_handle = ftam_handle;
1353                                                                                 }
1354                                                                                 else
1355                                                                                 {
1356                                                                                         proto_tree_add_text(acse_tree,tvb,*offset,len1,"Unknown OID");
1357                                                                                 }
1358                                                                         }
1359                                                                 }
1360                                                                         break;
1361                                                                 case PROTOCOL_VERSION:
1362                                                                         show_protocol_version(asn,acse_tree,tvb,offset,len1,tag);
1363                                                                         break;
1364                                                                 default:
1365                                                                         itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset
1366                                                                                                                                 -*offset)+ len1,
1367                                                                                         "Unknown tag: %x",tag);
1368                                                         }
1369                 item_len-=len1;
1370                 *offset = asn->offset = offset_save+len1;;
1371         }
1372 }
1373 /* display response top sequence  */
1374 static void
1375 show_response_sequence_top(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1376 *tvb,packet_info *pinfo,int *offset,int item_len)
1377 {
1378         int ret;
1379         guint cls, con, tag,len1;
1380         gint  type;
1381         gboolean def;
1382         proto_item *itm;
1383         gint length;
1384
1385         while(item_len > 0 )
1386         {
1387                         int offset_save = *offset;
1388 /* do we have enough bytes to dissect this item ? */
1389                         if( ( length =tvb_reported_length_remaining(tvb, *offset))  < item_len )
1390                         {
1391                                         proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1392                                                         "Wrong Item.Need %u bytes but have %u", item_len,length);
1393                                         break;
1394                         }
1395                 /*   get  tag     */
1396                         type = tvb_get_guint8(tvb, *offset);
1397                 /* decode header  */
1398                         ret = asn1_header_decode(asn, &cls, &con, &tag, &def, &len1);
1399
1400                         if (ret != ASN1_ERR_NOERROR)
1401                         {
1402                                                         dissect_parse_error(tvb, *offset, pinfo, acse_tree,
1403                                                                         "sequence error", ret);
1404                                 break;
1405                         }
1406                         /* add header  */
1407                         item_len = item_len - (asn->offset - *offset);
1408                         offset_save += (asn->offset - *offset);
1409                                                 /*
1410                                                 * [APPLICATION <tag>]
1411                                                 */
1412                                                 switch (tag)
1413                                                         {
1414                                                                 case ACSE_RESULT:
1415                                                                         show_acse_result(asn,acse_tree,tvb,offset,len1);
1416                                                                         break;
1417                                                                 case ACSE_RESULT_SOURCE_DIAGNOSTIC:
1418                                                                         show_acse_result_source_diagnostic(asn,acse_tree,tvb,offset,len1);
1419                                                                         break;
1420                                                                 case USER_INFORMATION:
1421                                                                         show_acse_user_information(asn,acse_tree,tvb,offset,len1);
1422                                                                         break;
1423
1424                                                                 case RESPONDING_AE_QUALIFIER:
1425                                                                         {
1426                                                                         proto_tree *acse_tree_pr = NULL;
1427                                                                         proto_item *pr;
1428                                                                         pr = proto_tree_add_text(acse_tree,tvb,*offset,
1429                                                                         len1+(asn->offset-*offset),
1430                                                                         val_to_str(tag ,response_sequence_top_vals,
1431                                                                         "Unknown item (0x%02x)"));
1432                                                                         acse_tree_pr = proto_item_add_subtree(pr, ett_acse_ms);
1433                                                                         show_integer(asn,acse_tree_pr,tvb,offset,len1);
1434                                                                         }
1435                                                                         break;
1436                                                                 case APPLICATION_CONTEXT_NAME:
1437                                                                 case RESPONDING_AP_TITLE:
1438                                                                 case RESPONDING_AP_INVOKATION_ID:
1439                                                                 case RESPONDING_AE_INVOKATION_ID:
1440                                                                         show_oid(asn,acse_tree,tvb,offset,len1,(const 
1441 value_string*)&response_sequence_top_vals,NULL);
1442                                                                         break;
1443                                                                 case PROTOCOL_VERSION:
1444                                                                         show_protocol_version(asn,acse_tree,tvb,offset,len1,tag);
1445                                                                         break;
1446                                                                 default:
1447                                                                         itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset
1448                                                                                                                                 -*offset)+ len1,
1449                                                                                         "Unknown tag: %x",tag);
1450                                                         }
1451                 item_len-=len1;
1452                 *offset = asn->offset = offset_save+len1;
1453         }
1454 }
1455
1456 /*
1457 * Dissect a pdu.
1458 */
1459 static int
1460 dissect_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree
1461                         *tree)
1462 {
1463   proto_item *ti;
1464   proto_tree *acse_tree = NULL;
1465   guint length;
1466   guint       rest_len;
1467   guint  s_type;
1468   ASN1_SCK asn;
1469   guint cp_type_len;
1470 /* get type of tag      */
1471         s_type = tvb_get_guint8(tvb, offset);
1472                 /*  set up type of pdu */
1473         if (check_col(pinfo->cinfo, COL_INFO))
1474                                         col_add_str(pinfo->cinfo, COL_INFO,
1475                                                 val_to_str(session->spdu_type, ses_vals, "Unknown pdu type (0x%02x)"));
1476   if (tree)
1477         {
1478                 ti = proto_tree_add_item(tree, proto_acse, tvb, offset, -1,
1479                     FALSE);
1480                 acse_tree = proto_item_add_subtree(ti, ett_acse);
1481         }
1482         offset++;
1483 /*    open asn.1 stream    */
1484         asn1_open(&asn, tvb, offset);
1485
1486         switch(session->spdu_type)
1487         {
1488                 case SES_REFUSE:
1489                 case SES_CONNECTION_REQUEST:
1490                 case SES_CONNECTION_ACCEPT:
1491                         proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1492
1493                         if (read_length(&asn, acse_tree, hf_cp_type_message_length, &cp_type_len)
1494                                                         != ASN1_ERR_NOERROR)
1495                                         {
1496                                         return  FALSE;
1497                                         }
1498                         /* skip length   */
1499                         offset = asn.offset;
1500                         /* do we have enough bytes to dissect ? */
1501                         if( ( length =tvb_reported_length_remaining(tvb, offset))  < cp_type_len
1502                                         )
1503                         {
1504                                 if(tree)
1505                                 {
1506                                         proto_tree_add_text(acse_tree, tvb, offset, -1,
1507                                                         "Wrong pdu.Need %u bytes but have %u", cp_type_len,length);
1508                                 }
1509                         return FALSE;
1510                         }
1511                         if(tree)
1512                         {
1513                                 if(session->spdu_type == SES_CONNECTION_REQUEST)
1514                                 {
1515                                 show_request_sequence_top(&asn,acse_tree,tvb,pinfo,&offset,cp_type_len);
1516                                 }
1517                                 else
1518                                 {
1519                                 show_response_sequence_top(&asn,acse_tree,tvb,pinfo,&offset,cp_type_len);
1520                                 }
1521
1522                         }
1523                                 break;
1524                 case SES_FINISH:
1525                         proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1526                                 /* get length  */
1527                                 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1528                                                 {
1529                                         return  FALSE;
1530                                                 }
1531                                 /* skip length   */
1532                                 offset = asn.offset;
1533                                 /* do we have enough bytes to dissect ? */
1534                                 if( ( length =tvb_reported_length_remaining(tvb, offset))  < rest_len )
1535                                 {
1536                                         if(tree)
1537                                         {
1538                                         proto_tree_add_text(acse_tree, tvb, offset, -1,
1539                                                         "Wrong pdu.Need %u bytes but have %u", rest_len,length);
1540                                         }
1541                                 return FALSE;
1542                                 }
1543                                 show_finish_pdu(&asn,acse_tree,tvb,&offset,rest_len);
1544                                 break;
1545                 case SES_DISCONNECT:
1546                         proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1547                                 /* get length  */
1548                                 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1549                                                 {
1550                                         return  FALSE;
1551                                                 }
1552                                 /* skip length   */
1553                                 offset = asn.offset;
1554                                 /* do we have enough bytes to dissect ? */
1555                                 if( ( length =tvb_reported_length_remaining(tvb, offset))  < rest_len )
1556                                 {
1557                                         if(tree)
1558                                         {
1559                                         proto_tree_add_text(acse_tree, tvb, offset, -1,
1560                                                         "Wrong pdu.Need %u bytes but have %u", rest_len,length);
1561                                         }
1562                                 return FALSE;
1563                                 }
1564                                 show_disconnect_pdu(&asn,acse_tree,tvb,&offset,rest_len);
1565                                 break;
1566                 case SES_ABORT:
1567                         proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1568                                 /* get length  */
1569                                 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1570                                                 {
1571                                         return  FALSE;
1572                                                 }
1573                                 /* skip length   */
1574                                 offset = asn.offset;
1575                                 /* do we have enough bytes to dissect ? */
1576                                 if( ( length =tvb_reported_length_remaining(tvb, offset))  < rest_len )
1577                                 {
1578                                         if(tree)
1579                                         {
1580                                         proto_tree_add_text(acse_tree, tvb, offset, -1,
1581                                                         "Wrong pdu.Need %u bytes but have %u", rest_len,length);
1582                                         }
1583                                 return FALSE;
1584                                 }
1585                                 show_abort_reason(&asn,acse_tree,tvb,&offset,rest_len);
1586                                 break;
1587                 default:
1588                         {
1589                                 proto_item *ms;
1590                                 proto_tree *acse_tree_ms = NULL;
1591                                 /* back to length  */
1592                                   offset--;
1593                                 /* get length  */
1594                                 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1595                                                 {
1596                                         return  FALSE;
1597                                                 }
1598                                 ms = proto_tree_add_text(acse_tree, tvb, offset, rest_len,
1599                                                                                 val_to_str(session->spdu_type, ses_vals, "Unknown pdu type (0x%02x)"));
1600                                 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
1601                                 show_user_data(&asn,acse_tree_ms,tvb,&offset,rest_len,s_type);
1602                         }
1603         }
1604 /*    close asn.1 stream    */
1605           asn1_close(&asn, &offset);
1606
1607         return offset;
1608 }
1609
1610 /*
1611 * Dissect ACSE PDUs inside a PPDU.
1612 */
1613 static void
1614 dissect_acse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1615 {
1616         int offset = 0;
1617 /* first, try to check length   */
1618 /* do we have at least 2 bytes  */
1619         if (!tvb_bytes_exist(tvb, 0, 2))
1620         {
1621         proto_tree_add_text(tree, tvb, offset, 
1622 tvb_reported_length_remaining(tvb,offset),
1623                                                                 "User data");
1624                         return;  /* no, it isn't a ACSE PDU */
1625         }
1626 /* do we have spdu type from the session dissector?  */
1627         if( !pinfo->private_data )
1628                                 {
1629                                 if(tree)
1630                                                 {
1631                                         proto_tree_add_text(tree, tvb, offset, -1,
1632                                                         "Internal error:can't get spdu type from session dissector.");
1633                                         return  ;
1634                                                 } 
1635                                 }
1636         else
1637                                 {
1638                                         session  = ( (struct SESSION_DATA_STRUCTURE*)(pinfo->private_data) );
1639                                         if(session->spdu_type == 0 )
1640                                         {
1641                                                 if(tree)
1642                                                 {
1643                                         proto_tree_add_text(tree, tvb, offset, -1,
1644                                                         "Internal error:wrong spdu type %x from session dissector.",session->spdu_type);
1645                                         return  ;
1646                                                 }
1647                                         }
1648                                 }
1649 /*  ACSE has only AARQ,AARE,RLRQ,RLRE,ABRT type of pdu */
1650 /*  reject everything else                              */
1651 /*  data pdu is not ACSE pdu and has to go directly to app dissector */
1652                         switch(session->spdu_type)
1653                         {
1654                 case SES_REFUSE:                                        /*   RLRE   */
1655                 case SES_CONNECTION_REQUEST:            /*   AARQ   */
1656                 case SES_CONNECTION_ACCEPT:                     /*   AARE   */
1657                 case SES_DISCONNECT:                            /*   RLRQ   */
1658                 case SES_FINISH:                                        /*   RLRE   */
1659                 case SES_ABORT:                                         /*   ABRT   */
1660                         break;
1661                 case SES_DATA_TRANSFER:
1662                         call_app_dissector(tvb,offset,tvb_reported_length_remaining(tvb, offset) 
1663 ,pinfo,tree,tree);
1664                         return;
1665                 default:
1666                         return;
1667                         }
1668
1669         /*  we can't make any additional checking here   */
1670         /*  postpone it before dissector will have more information */
1671
1672         if (check_col(pinfo->cinfo, COL_PROTOCOL))
1673                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACSE");
1674         if (check_col(pinfo->cinfo, COL_INFO))
1675                 col_clear(pinfo->cinfo, COL_INFO);
1676         /* save pointers for calling the app dissector  */
1677         global_tree = tree;
1678         global_pinfo = pinfo;
1679
1680         while (tvb_reported_length_remaining(tvb, offset) > 0)
1681                         {
1682                 offset = dissect_pdu(tvb, offset, pinfo, tree);
1683                 if(offset == FALSE )
1684                                                         {
1685                                                                         proto_tree_add_text(tree, tvb, offset, -1,"Internal error");
1686                                                                         offset = tvb_length(tvb);
1687                                                                         break;
1688                                                         }
1689                         }
1690 }
1691
1692 void
1693 proto_register_acse(void)
1694 {
1695         static hf_register_info hf[] =
1696         {
1697                 {
1698                         &hf_acse_type,
1699                         {
1700                                 "PDU Type",
1701                                 "acse.type",
1702                                 FT_UINT8,
1703                                 BASE_DEC,
1704                                 VALS(acse_vals),
1705                                 0x0,
1706                                 "", HFILL
1707                         }
1708                 },
1709                 {
1710                         &hf_cp_type_message_length,
1711                         {
1712                                 "Message Length",
1713                                 "cp_type.message_length",
1714                                 FT_UINT32,
1715                                 BASE_DEC,
1716                                 NULL,
1717                                 0x0,
1718                                 "CP type Message Length",
1719                                 HFILL
1720                         }
1721                 },
1722                 {
1723                         &hf_protocol_version,
1724                         {
1725                                 "Protocol version 1",
1726                                 "acse.protocol.version",
1727                                 FT_BOOLEAN, 16,
1728                                 NULL,
1729                                 ACSE_PROTOCOL_VERGION,
1730                                 "Protocol version 1",
1731                                 HFILL
1732                         }
1733                 },
1734         };
1735
1736         static gint *ett[] =
1737         {
1738                 &ett_acse,
1739                 &ett_acse_param,
1740                 &ett_acse_rc,
1741                 &ett_acse_ms,
1742                 &ett_acse_itm,
1743         };
1744         module_t *acse_module;
1745
1746
1747         proto_acse = proto_register_protocol(PROTO_STRING_ACSE, "ACSE", "acse");
1748         proto_register_field_array(proto_acse, hf, array_length(hf));
1749         proto_register_subtree_array(ett, array_length(ett));
1750
1751         acse_module = prefs_register_protocol(proto_acse, NULL);
1752
1753         /*
1754          * Register the dissector by name, so other dissectors can
1755          * grab it by name rather than just referring to it directly
1756          */
1757         register_dissector("acse", dissect_acse, proto_acse);
1758 }
1759
1760 void
1761 proto_reg_handoff_acse(void)
1762 {
1763         /*   find data dissector  */
1764         data_handle = find_dissector("data");
1765         /* define ftam sub dissector */
1766         ftam_handle = find_dissector("ftam");
1767         /* define cmip sub dissector */
1768         cmip_handle = find_dissector("cmip");
1769
1770 }
1771
1772