3 * Routine to dissect OSI ACSE Protocol packets
5 * $Id: packet-acse.c,v 1.3 2004/01/24 01:53:59 jmayer Exp $
7 * Yuriy Sidelnikov <YSidelnikov@hotmail.com>
9 * Ethereal - Network traffic analyzer
10 * By Gerald Combs <gerald@ethereal.com>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #include <epan/packet.h>
38 #include "packet-acse.h"
39 #include "packet-frame.h"
42 #include <epan/strutil.h>
45 #include "format-oid.h"
47 #include "packet-ses.h"
48 extern const value_string ses_vals[];
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;
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;
70 static int type_of_application = 0;
73 static const value_string acse_vals[] =
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" },
83 static const value_string cr_vals[] =
85 {MODE_SELECTOR, "Mode Selector"},
86 {SEQUENCE_TOP, "Sequence"},
91 static const value_string request_sequence_top_vals[] =
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"},
107 static const value_string response_sequence_top_vals[] =
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"},
121 static const value_string associate_result_values_vals[] =
123 {PRESENTATION_RESULT_ACCEPTANCE,"Accepted"},
124 {PRESENTATION_RESULT_USER_REJECTION,"Rejected permanent"},
125 {PRESENTATION_RESULT_PROVIDER_REJECTION,"Rejected transient"},
129 static const value_string acse_associate_source_diagnostic_vals[] =
131 {ACSE_SERVICE_USER,"Acse service user"},
132 {ACSE_SERVICE_PROVIDER,"Acse service provider"},
135 static const value_string acse_service_user_values_vals[] =
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"},
150 static const value_string acse_service_provider_values_vals[] =
153 {ACSE_NO_REASON_GIVEN,"No reason given"},
154 {ACSE_NO_COMMON_ACSE_VERSION,"no_common_acse_version"},
158 static const value_string acse_user_information_vals[] =
160 {ACSE_EXTERNAL_USER,"External"},
163 static const value_string sequence_list_vals[] =
165 {PRESENTATION_CONTEXT_IDENTIFIER,"Presentation context identifier"},
166 {ABSTRACT_SYNTAX_NAME,"Abstract syntax name"},
167 {TRANSFER_SYNTAX_NAMES,"Transfer syntax names"},
170 static const value_string presentation_context_definition_vals[] =
172 {SEQUENCE, "Sequence"},
175 static const value_string user_data_values_vals[] =
177 {SIMPLY_ENCODED_DATA,"Simply encoded data"},
178 {FULLY_ENCODED_DATA,"Fully encoded data "},
181 static const value_string presentation_data_values[] =
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"},
190 static const value_string release_request_reason[] =
192 {RRR_NORMAL,"Normal"},
193 {RRR_URGENT,"Urgent"},
194 {RRR_USER_DEFINED,"User defined"},
197 static const value_string release_response_reason[] =
199 {RRPR_NORMAL,"Normal"},
200 {RRPR_URGENT,"Not finished"},
201 {RRPR_USER_DEFINED,"User defined"},
205 static const value_string abort_reason[] =
207 {ABRT_ACSE_SERVICE_USER,"Acse service user"},
208 {ABRT_ACSE_SERVICE_PROVIDER,"Acse service provider"},
212 static const value_string type_app[] =
214 {0,""}, /* for unknown dissector */
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;
226 call_app_dissector(tvbuff_t *tvb, int offset, guint16 param_len,
227 packet_info *pinfo, proto_tree *tree, proto_tree *param_tree)
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)
235 /* No - display as data */
238 proto_tree_add_text(param_tree, tvb, offset, param_len,
239 "%s dissector is not available",name_of_app_dissect);
244 /* Yes - call application dissector */
247 next_tvb = tvb_new_subset(tvb, offset, param_len,
251 call_dissector(app_handle, next_tvb, pinfo,
256 show_exception(tvb, pinfo, tree, EXCEPT_CODE);
262 string_to_hex(const unsigned char * in,char * out,int len)
264 char ascii[MAXSTRING];
266 memset(&ascii,0x00,sizeof(ascii));
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')
289 static int read_length(ASN1_SCK *a, proto_tree *tree, int hf_id, guint *len)
292 gboolean def = FALSE;
293 int start = a->offset;
296 ret = asn1_length_decode(a, &def, &length);
297 if (ret != ASN1_ERR_NOERROR)
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));
312 proto_tree_add_uint(tree, hf_id, a->tvb, start, a->offset-start,
315 return ASN1_ERR_NOERROR;
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)
321 proto_item *temp_item = NULL;
324 ret = asn1_uint32_value_decode(a, length, &integer);
325 if (ret != ASN1_ERR_NOERROR)
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));
340 temp_item = proto_tree_add_uint(tree, hf_id, a->tvb, start,
341 a->offset-start, integer);
344 *new_item = temp_item;
346 return ASN1_ERR_NOERROR;
349 static int read_integer(ASN1_SCK *a, proto_tree *tree, int hf_id,
350 proto_item **new_item, guint *i)
355 int start = a->offset;
358 ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
359 if (ret != ASN1_ERR_NOERROR)
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));
371 return read_integer_value(a, tree, hf_id, new_item, i, start, length);
373 /* display asn.1 Integer type */
375 show_integer(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
376 *offset,guint item_len)
378 proto_tree *acse_tree_itm = NULL;
381 int save_len = item_len;
383 itm = proto_tree_add_text(acse_tree, tvb, *offset, item_len,
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 )
389 *offset = asn->offset;
390 itm = proto_tree_add_text(acse_tree_itm, tvb, (*offset)-item_len,
392 "Integer value: %u",item_len);
396 /* can't dissect item. Skip it. */
397 *offset = off+ save_len;
402 show_protocol_version(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
403 *offset,int item_len,int tag)
405 proto_tree *acse_tree_itm = NULL;
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 )
413 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
414 "Wrong Item.Need %u bytes but have %u", item_len,length);
418 itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset -*offset)+
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,
426 *offset = *offset + item_len;
427 asn->offset = *offset;
430 print_oid_value(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
431 *offset,int item_len)
436 gchar *display_string;
440 ret = asn1_oid_value_decode (asn, item_len, &oid, &len);
441 if (ret != ASN1_ERR_NOERROR)
445 length = asn->offset - start;
446 display_string = format_oid(oid, len);
447 proto_tree_add_text(acse_tree, tvb, *offset,length,"Value:%s",
449 g_free(display_string);
450 (*offset)=start+item_len;
451 asn->offset = (*offset);
454 print_oid(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int *offset,int
461 gchar *display_string;
465 ret = asn1_oid_decode ( asn, &oid, &len, &nbytes);
467 if (ret != ASN1_ERR_NOERROR)
471 length = asn->offset - start;
472 display_string = format_oid(oid, len);
473 proto_tree_add_text(acse_tree, tvb, *offset,length,"Value:%s",
478 strcpy(d_s,display_string);
480 g_free(display_string);
481 (*offset)=start+item_len;
482 asn->offset = (*offset);
486 print_value(proto_tree *acse_tree,tvbuff_t *tvb,int
487 *offset,int item_len)
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);
494 get_integer_value(ASN1_SCK *asn,int length,int *offset)
497 int asn_off = asn->offset;
502 ret = asn1_uint32_value_decode(asn, length, &item_len);
503 /* return to present position */
505 asn->offset = asn_off;
507 if (ret != ASN1_ERR_NOERROR )
518 show_fully_encoded_seq(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
519 *offset,int item_len)
521 proto_tree *acse_tree_ms = NULL;
526 guint start = *offset;
528 guint acse = 0; /* no acse id */
531 while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 )
533 old_offset = *offset ;
535 type = tvb_get_guint8(tvb, *offset);
538 asn->offset = *offset;
540 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
542 (*offset)=start+item_len;
543 asn->offset = (*offset);
546 /* do we have enough bytes to dissect ? */
547 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
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);
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;
567 case PRESENTATION_CONTEXT_IDENTIFIER:
569 acse = get_integer_value(asn,new_item_len,offset);
570 print_value(acse_tree_ms,tvb,offset,new_item_len);
573 case ABSTRACT_SYNTAX_NAME:
574 print_oid_value(asn,acse_tree_ms,tvb,offset,new_item_len);
579 case SINGLE_ASN1_TYPE:
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),
586 /* call acse dissector */
587 call_app_dissector(tvb,*offset,new_item_len,global_pinfo,global_tree,acse_tree_ms);
591 print_value(acse_tree_ms,tvb,offset,new_item_len);
594 proto_tree_add_text(acse_tree, tvb, *offset,
595 new_item_len+(asn->offset-*offset),
596 "Unknown asn.1 parameter: (0x%02x)", type);
598 *offset = old_offset+new_item_len+header_len;
599 item_len-=new_item_len+header_len;
601 /* align the pointer */
602 (*offset)=start+item_len;
603 asn->offset = (*offset);
608 show_acse_user_information(ASN1_SCK *asn,proto_tree
609 *acse_tree,tvbuff_t *tvb,int *offset,int item_len)
611 proto_tree *acse_tree_ms = NULL;
612 proto_tree *acse_tree_ab = NULL;
619 guint start = *offset;
622 type = tvb_get_guint8(tvb, *offset) & 0x1f;
625 asn->offset = *offset;
627 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
629 (*offset)=start+item_len;
630 asn->offset = (*offset);
634 /* do we have enough bytes to dissect ? */
635 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
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);
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;
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);
660 if(type!= ACSE_EXTERNAL)
662 (*offset)=start+item_len;
663 asn->offset = (*offset);
667 /* skip type of item*/
669 asn->offset = *offset;
671 if (read_length(asn, acse_tree_ab, 0, &code_item_len) !=
674 (*offset)=start+item_len;
675 asn->offset = (*offset);
678 /* do we have enough bytes to dissect ? */
679 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
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);
688 *offset = asn->offset;
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);
697 show_acse_result_source_diagnostic(ASN1_SCK *asn,proto_tree
698 *acse_tree,tvbuff_t *tvb,int *offset,int item_len)
700 proto_tree *acse_tree_ms = NULL;
701 proto_tree *acse_tree_ab = NULL;
708 guint start = *offset;
710 proto_tree *acse_tree_pr = NULL;
714 type = tvb_get_guint8(tvb, *offset) & 0x1f;
717 asn->offset = *offset;
719 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
721 (*offset)=start+item_len;
722 asn->offset = (*offset);
726 /* do we have enough bytes to dissect ? */
727 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
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);
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;
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);
752 /* skip type of abort*/
754 asn->offset = *offset;
756 if (read_length(asn, acse_tree, 0, &code_item_len) != ASN1_ERR_NOERROR)
758 (*offset)=start+item_len;
759 asn->offset = (*offset);
762 *offset = asn->offset;
763 /* do we have enough bytes to dissect ? */
764 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
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);
774 /* skip type of constant*/
776 asn->offset = *offset;
778 if (read_length(asn, acse_tree_ab, 0, &code_item_len) !=
781 (*offset)=start+item_len;
782 asn->offset = (*offset);
785 /* do we have enough bytes to dissect ? */
786 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
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);
795 *offset = asn->offset;
796 value = get_integer_value(asn,code_item_len,offset);
797 if(type == ACSE_SERVICE_USER )
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)"));
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)"));
812 acse_tree_pr = proto_item_add_subtree(pr, ett_acse_ms);
813 print_value(acse_tree_pr,tvb,offset,code_item_len);
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);
823 show_acse_result(ASN1_SCK *asn,proto_tree
824 *acse_tree,tvbuff_t *tvb,int *offset,int item_len)
826 proto_tree *acse_tree_ms = NULL;
832 guint start = *offset;
834 proto_tree *acse_tree_pr = NULL;
838 type = tvb_get_guint8(tvb, *offset) & 0x1f;
841 asn->offset = *offset;
843 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
845 (*offset)=start+item_len;
846 asn->offset = (*offset);
850 /* do we have enough bytes to dissect ? */
851 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
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);
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;
869 asn->offset = *offset;
871 if (read_length(asn, acse_tree, 0, &code_item_len) != ASN1_ERR_NOERROR)
873 (*offset)=start+item_len;
874 asn->offset = (*offset);
877 /* do we have enough bytes to dissect ? */
878 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
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);
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);
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);
904 show_oid(ASN1_SCK *asn,proto_tree
905 *acse_tree,tvbuff_t *tvb,int *offset,int item_len,const value_string*
908 proto_tree *acse_tree_ms = NULL;
913 guint start = *offset;
916 old_offset = *offset ;
918 type = tvb_get_guint8(tvb, *offset) & 0x1f;
921 asn->offset = *offset;
923 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
925 (*offset)=start+item_len;
926 asn->offset = (*offset);
930 /* do we have enough bytes to dissect ? */
931 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
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);
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);
955 show_fully_encoded_data(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
956 *tvb,int *offset,int item_len)
958 proto_tree *acse_tree_ms = NULL;
959 proto_tree *acse_tree_pc = NULL;
965 guint start = asn->offset;
966 guint item_length = item_len;
967 acse_tree_pc = acse_tree;
969 /* do we have enough bytes to dissect ? */
970 if( ( length =tvb_reported_length_remaining(tvb, *offset)) < item_len )
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);
979 *offset =asn->offset;
982 while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 )
984 int old_offset = *offset;
986 type = tvb_get_guint8(tvb, *offset);
989 asn->offset = *offset;
991 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
994 /* align the pointer */
995 (*offset)=start+item_length;
996 asn->offset = (*offset);
999 header_len = asn->offset - (*offset) +1;
1000 /* do we have enough bytes to dissect ? */
1001 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
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);
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;
1023 show_fully_encoded_seq(asn,acse_tree_ms,tvb,offset,new_item_len);
1024 *offset = old_offset+(new_item_len+header_len);
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);
1033 item_len = item_len - (new_item_len+header_len);
1038 /* align the pointer */
1039 (*offset)=start+item_length;
1040 asn->offset = (*offset);
1043 show_abort_reason(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1044 *tvb,int *offset,int item_len)
1048 proto_tree *acse_tree_pc = NULL;
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 )
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;
1064 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1065 "Reason not specified");
1066 *offset = asn->offset;
1069 itu = proto_tree_add_text(acse_tree, tvb, *offset,ABORT_REASON_LEN,
1071 acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1072 (*offset)++; /* skip type */
1073 asn->offset = *offset;
1076 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
1079 *offset = asn->offset;
1082 /* try to get reason */
1083 value = get_integer_value(asn,new_item_len,offset);
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 ? */
1093 show_acse_user_information(asn,acse_tree,tvb,offset,item_len);
1095 /* align the pointer */
1096 (*offset)=start+save_len;
1097 asn->offset = (*offset);
1101 show_disconnect_pdu(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1102 *tvb,int *offset,int item_len)
1106 proto_tree *acse_tree_pc = NULL;
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 )
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;
1122 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1123 "Reason not specified");
1124 *offset = asn->offset;
1127 itu = proto_tree_add_text(acse_tree, tvb, *offset,ABORT_REASON_LEN,
1129 acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1130 (*offset)++; /* skip type */
1131 asn->offset = *offset;
1134 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
1137 *offset = asn->offset;
1140 /* try to get reason */
1141 value = get_integer_value(asn,new_item_len,offset);
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 ? */
1151 show_acse_user_information(asn,acse_tree,tvb,offset,item_len);
1153 /* align the pointer */
1154 (*offset)=start+save_len;
1155 asn->offset = (*offset);
1159 show_finish_pdu(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1160 *tvb,int *offset,int item_len)
1164 proto_tree *acse_tree_pc = NULL;
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 )
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;
1180 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1181 "Reason not specified");
1182 *offset = asn->offset;
1185 itu = proto_tree_add_text(acse_tree, tvb, *offset,ABORT_REASON_LEN,
1187 acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1188 (*offset)++; /* skip type */
1189 asn->offset = *offset;
1192 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
1195 *offset = asn->offset;
1198 /* try to get reason */
1199 value = get_integer_value(asn,new_item_len,offset);
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 ? */
1209 show_acse_user_information(asn,acse_tree,tvb,offset,item_len);
1211 /* align the pointer */
1212 (*offset)=start+save_len;
1213 asn->offset = (*offset);
1216 show_user_data(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
1217 *offset,int item_len,int tag)
1219 proto_tree *acse_tree_ud = NULL;
1220 proto_tree *acse_tree_pc = NULL;
1223 guint start = asn->offset;
1224 guint item_length = item_len;
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);
1235 case SIMPLY_ENCODED_DATA:
1237 case FULLY_ENCODED_DATA:
1238 show_fully_encoded_data(asn,acse_tree_pc,tvb,offset,item_len);
1245 /* align the pointer */
1246 (*offset)=start+item_length;
1247 asn->offset = (*offset);
1251 /* if we can't dissect */
1253 dissect_parse_error(tvbuff_t *tvb, int offset, packet_info *pinfo,
1254 proto_tree *tree, const char *field_name, int ret)
1257 errstr = asn1_err_to_str(ret);
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);
1268 /* display request top sequence */
1270 show_request_sequence_top(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1271 *tvb,packet_info *pinfo,int *offset,int item_len)
1274 guint cls, con, tag,len1;
1279 unsigned char ftam_oid[] = "1.0.8571.1.1";
1280 unsigned char cmip_oid[] ="2.9.0.0.2";
1282 while(item_len > 0 )
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 )
1288 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1289 "Wrong Item.Need %u bytes but have %u", item_len,length);
1293 type = tvb_get_guint8(tvb, *offset);
1295 ret = asn1_header_decode(asn, &cls, &con, &tag, &def, &len1);
1297 if (ret != ASN1_ERR_NOERROR)
1299 dissect_parse_error(tvb, *offset, pinfo, acse_tree,
1300 "sequence error", ret);
1304 item_len = item_len - (asn->offset - *offset);
1305 offset_save += (asn->offset - *offset);
1307 * [APPLICATION <tag>]
1311 case USER_INFORMATION:
1312 show_acse_user_information(asn,acse_tree,tvb,offset,len1);
1314 case CALLED_AE_QUALIFIER:
1315 case CALLING_AE_QUALIFIER:
1317 proto_tree *acse_tree_pr = NULL;
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);
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:
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 )
1341 if( !strcmp(oid_string,cmip_oid) )
1344 type_of_application = CMIP_APP;
1345 app_handle = cmip_handle;
1348 if( !strcmp(oid_string,ftam_oid) )
1351 type_of_application = FTAM_APP;
1352 app_handle = ftam_handle;
1356 proto_tree_add_text(acse_tree,tvb,*offset,len1,"Unknown OID");
1361 case PROTOCOL_VERSION:
1362 show_protocol_version(asn,acse_tree,tvb,offset,len1,tag);
1365 itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset
1367 "Unknown tag: %x",tag);
1370 *offset = asn->offset = offset_save+len1;;
1373 /* display response top sequence */
1375 show_response_sequence_top(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1376 *tvb,packet_info *pinfo,int *offset,int item_len)
1379 guint cls, con, tag,len1;
1385 while(item_len > 0 )
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 )
1391 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1392 "Wrong Item.Need %u bytes but have %u", item_len,length);
1396 type = tvb_get_guint8(tvb, *offset);
1398 ret = asn1_header_decode(asn, &cls, &con, &tag, &def, &len1);
1400 if (ret != ASN1_ERR_NOERROR)
1402 dissect_parse_error(tvb, *offset, pinfo, acse_tree,
1403 "sequence error", ret);
1407 item_len = item_len - (asn->offset - *offset);
1408 offset_save += (asn->offset - *offset);
1410 * [APPLICATION <tag>]
1415 show_acse_result(asn,acse_tree,tvb,offset,len1);
1417 case ACSE_RESULT_SOURCE_DIAGNOSTIC:
1418 show_acse_result_source_diagnostic(asn,acse_tree,tvb,offset,len1);
1420 case USER_INFORMATION:
1421 show_acse_user_information(asn,acse_tree,tvb,offset,len1);
1424 case RESPONDING_AE_QUALIFIER:
1426 proto_tree *acse_tree_pr = NULL;
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);
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);
1443 case PROTOCOL_VERSION:
1444 show_protocol_version(asn,acse_tree,tvb,offset,len1,tag);
1447 itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset
1449 "Unknown tag: %x",tag);
1452 *offset = asn->offset = offset_save+len1;
1460 dissect_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree
1464 proto_tree *acse_tree = NULL;
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)"));
1478 ti = proto_tree_add_item(tree, proto_acse, tvb, offset, -1,
1480 acse_tree = proto_item_add_subtree(ti, ett_acse);
1483 /* open asn.1 stream */
1484 asn1_open(&asn, tvb, offset);
1486 switch(session->spdu_type)
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);
1493 if (read_length(&asn, acse_tree, hf_cp_type_message_length, &cp_type_len)
1494 != ASN1_ERR_NOERROR)
1499 offset = asn.offset;
1500 /* do we have enough bytes to dissect ? */
1501 if( ( length =tvb_reported_length_remaining(tvb, offset)) < cp_type_len
1506 proto_tree_add_text(acse_tree, tvb, offset, -1,
1507 "Wrong pdu.Need %u bytes but have %u", cp_type_len,length);
1513 if(session->spdu_type == SES_CONNECTION_REQUEST)
1515 show_request_sequence_top(&asn,acse_tree,tvb,pinfo,&offset,cp_type_len);
1519 show_response_sequence_top(&asn,acse_tree,tvb,pinfo,&offset,cp_type_len);
1525 proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1527 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1532 offset = asn.offset;
1533 /* do we have enough bytes to dissect ? */
1534 if( ( length =tvb_reported_length_remaining(tvb, offset)) < rest_len )
1538 proto_tree_add_text(acse_tree, tvb, offset, -1,
1539 "Wrong pdu.Need %u bytes but have %u", rest_len,length);
1543 show_finish_pdu(&asn,acse_tree,tvb,&offset,rest_len);
1545 case SES_DISCONNECT:
1546 proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1548 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1553 offset = asn.offset;
1554 /* do we have enough bytes to dissect ? */
1555 if( ( length =tvb_reported_length_remaining(tvb, offset)) < rest_len )
1559 proto_tree_add_text(acse_tree, tvb, offset, -1,
1560 "Wrong pdu.Need %u bytes but have %u", rest_len,length);
1564 show_disconnect_pdu(&asn,acse_tree,tvb,&offset,rest_len);
1567 proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1569 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1574 offset = asn.offset;
1575 /* do we have enough bytes to dissect ? */
1576 if( ( length =tvb_reported_length_remaining(tvb, offset)) < rest_len )
1580 proto_tree_add_text(acse_tree, tvb, offset, -1,
1581 "Wrong pdu.Need %u bytes but have %u", rest_len,length);
1585 show_abort_reason(&asn,acse_tree,tvb,&offset,rest_len);
1590 proto_tree *acse_tree_ms = NULL;
1591 /* back to length */
1594 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
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);
1604 /* close asn.1 stream */
1605 asn1_close(&asn, &offset);
1611 * Dissect ACSE PDUs inside a PPDU.
1614 dissect_acse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1617 /* first, try to check length */
1618 /* do we have at least 2 bytes */
1619 if (!tvb_bytes_exist(tvb, 0, 2))
1621 proto_tree_add_text(tree, tvb, offset,
1622 tvb_reported_length_remaining(tvb,offset),
1624 return; /* no, it isn't a ACSE PDU */
1626 /* do we have spdu type from the session dissector? */
1627 if( !pinfo->private_data )
1631 proto_tree_add_text(tree, tvb, offset, -1,
1632 "Internal error:can't get spdu type from session dissector.");
1638 session = ( (struct SESSION_DATA_STRUCTURE*)(pinfo->private_data) );
1639 if(session->spdu_type == 0 )
1643 proto_tree_add_text(tree, tvb, offset, -1,
1644 "Internal error:wrong spdu type %x from session dissector.",session->spdu_type);
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)
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 */
1661 case SES_DATA_TRANSFER:
1662 call_app_dissector(tvb,offset,tvb_reported_length_remaining(tvb, offset)
1669 /* we can't make any additional checking here */
1670 /* postpone it before dissector will have more information */
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 */
1678 global_pinfo = pinfo;
1680 while (tvb_reported_length_remaining(tvb, offset) > 0)
1682 offset = dissect_pdu(tvb, offset, pinfo, tree);
1683 if(offset == FALSE )
1685 proto_tree_add_text(tree, tvb, offset, -1,"Internal error");
1686 offset = tvb_length(tvb);
1693 proto_register_acse(void)
1695 static hf_register_info hf[] =
1710 &hf_cp_type_message_length,
1713 "cp_type.message_length",
1718 "CP type Message Length",
1723 &hf_protocol_version,
1725 "Protocol version 1",
1726 "acse.protocol.version",
1729 ACSE_PROTOCOL_VERGION,
1730 "Protocol version 1",
1736 static gint *ett[] =
1744 module_t *acse_module;
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));
1751 acse_module = prefs_register_protocol(proto_acse, NULL);
1754 * Register the dissector by name, so other dissectors can
1755 * grab it by name rather than just referring to it directly
1757 register_dissector("acse", dissect_acse, proto_acse);
1761 proto_reg_handoff_acse(void)
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");