3 * Routine to dissect OSI ACSE Protocol packets
5 * $Id: packet-acse.c,v 1.5 2004/04/30 06:24:35 ulfl 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 /* Subdissector tables */
64 static dissector_table_t application_dissector_table;
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;
72 static const value_string acse_vals[] =
74 {ACSE_AARQ, "A-associate request" },
75 {ACSE_AARE, "A-associate response" },
76 {ACSE_RLRQ, "A-reliase request" },
77 {ACSE_RLRE, "A-reliase response" },
78 {ACSE_ABRT, "A-abort" },
82 static const value_string cr_vals[] =
84 {MODE_SELECTOR, "Mode Selector"},
85 {SEQUENCE_TOP, "Sequence"},
90 static const value_string request_sequence_top_vals[] =
92 {PROTOCOL_VERSION, "Protocol version"},
93 {APPLICATION_CONTEXT_NAME, "Application context name"},
94 {CALLED_AP_TITLE, "Called AP title"},
95 {CALLED_AE_QUALIFIER, "Called AE qualifier"},
96 {CALLED_AP_INVOKATION_ID, "Called AP invokation id"},
97 {CALLED_AE_INVOKATION_ID, "Called AE invokation id"},
98 {CALLING_AP_TITLE, "Calling AP title"},
99 {CALLING_AE_QUALIFIER, "Calling AE qualifier"},
100 {CALLING_AP_INVOKATION_ID, "Calling AP invokation id"},
101 {CALLING_AE_INVOKATION_ID, "Calling AE invokation id"},
102 {IMPLEMENTATION_INFORMATION,"Implementation information"},
103 {USER_INFORMATION,"User information"},
106 static const value_string response_sequence_top_vals[] =
108 {PROTOCOL_VERSION, "Protocol version"},
109 {APPLICATION_CONTEXT_NAME, "Application context name"},
110 {ACSE_RESULT, "Result"},
111 {ACSE_RESULT_SOURCE_DIAGNOSTIC, "Result source diagnostic"},
112 {RESPONDING_AP_TITLE, "Responding AP title"},
113 {RESPONDING_AE_QUALIFIER, "Responding AE qualifier"},
114 {RESPONDING_AP_INVOKATION_ID, "Responding AP invokation id"},
115 {RESPONDING_AE_INVOKATION_ID, "Responding AE invokation id"},
116 {IMPLEMENTATION_INFORMATION,"Implementation information"},
117 {USER_INFORMATION,"User information"},
120 static const value_string associate_result_values_vals[] =
122 {PRESENTATION_RESULT_ACCEPTANCE,"Accepted"},
123 {PRESENTATION_RESULT_USER_REJECTION,"Rejected permanent"},
124 {PRESENTATION_RESULT_PROVIDER_REJECTION,"Rejected transient"},
128 static const value_string acse_associate_source_diagnostic_vals[] =
130 {ACSE_SERVICE_USER,"Acse service user"},
131 {ACSE_SERVICE_PROVIDER,"Acse service provider"},
134 static const value_string acse_service_user_values_vals[] =
137 {ACSE_NO_REASON_GIVEN,"No reason given"},
138 {ACSE_APPLICATION_CONTEXT_NAME_NOT_SUPPORTED,"Application context name not supported"},
139 {ACSE_CALLING_AP_TITLE_NOT_RECOGNIZED,"Calling AP title not recognized"},
140 {ACSE_CALLING_AP_INVOKATION_IDENTIFIER_NOT_RECOGNIZED,"Calling AP invokation identifier not recognized"},
141 {ACSE_CALLING_AE_QUALIFIER_NOT_RECOGNIZED,"Calling AE qualifier not recognized"},
142 {ACSE_CALLING_AE_INVOKATION_IDENTIFIER_NOT_RECOGNIZED,"Calling AE invokation identifier not recognized"},
143 {ACSE_CALLED_AP_TITLE_NOT_RECOGNIZED,"Called AP title not recognized"},
144 {ACSE_CALLED_AP_INVOKATION_IDENTIFIER_NOT_RECOGNIZED,"Called AP invokation identifier not recognized"},
145 {ACSE_CALLED_AE_QUALIFIER_NOT_RECOGNIZED,"Called AE qualifier not recognized"},
146 {ACSE_CALLED_AE_INVOKATION_IDENTIFIER_NOT_RECOGNIZED,"Called AE invokation identifier not recognized"},
149 static const value_string acse_service_provider_values_vals[] =
152 {ACSE_NO_REASON_GIVEN,"No reason given"},
153 {ACSE_NO_COMMON_ACSE_VERSION,"no_common_acse_version"},
157 static const value_string acse_user_information_vals[] =
159 {ACSE_EXTERNAL_USER,"External"},
162 static const value_string sequence_list_vals[] =
164 {PRESENTATION_CONTEXT_IDENTIFIER,"Presentation context identifier"},
165 {ABSTRACT_SYNTAX_NAME,"Abstract syntax name"},
166 {TRANSFER_SYNTAX_NAMES,"Transfer syntax names"},
169 static const value_string presentation_context_definition_vals[] =
171 {SEQUENCE, "Sequence"},
174 static const value_string user_data_values_vals[] =
176 {SIMPLY_ENCODED_DATA,"Simply encoded data"},
177 {FULLY_ENCODED_DATA,"Fully encoded data "},
180 static const value_string presentation_data_values[] =
182 {PRESENTATION_CONTEXT_IDENTIFIER,"Presentation context identifier"},
183 {SINGLE_ASN1_TYPE,"Single ASN.1 type"},
184 {OCTET_ALIGNED,"Octet aligned"},
185 {ARBITRARY,"Arbitrary"},
186 {ABSTRACT_SYNTAX_NAME,"Abstract syntax name"},
189 static const value_string release_request_reason[] =
191 {RRR_NORMAL,"Normal"},
192 {RRR_URGENT,"Urgent"},
193 {RRR_USER_DEFINED,"User defined"},
196 static const value_string release_response_reason[] =
198 {RRPR_NORMAL,"Normal"},
199 {RRPR_URGENT,"Not finished"},
200 {RRPR_USER_DEFINED,"User defined"},
204 static const value_string abort_reason[] =
206 {ABRT_ACSE_SERVICE_USER,"Acse service user"},
207 {ABRT_ACSE_SERVICE_PROVIDER,"Acse service provider"},
211 static const value_string type_app[] =
213 {0,""}, /* for unknown dissector */
219 /* pointers for acse dissector */
220 static proto_tree *global_tree = NULL;
221 static packet_info *global_pinfo = NULL;
222 /* dissector for data */
223 static dissector_handle_t data_handle;
225 call_app_dissector(tvbuff_t *tvb, gint offset, gint param_len,
226 packet_info *pinfo, proto_tree *tree, proto_tree *param_tree)
228 /* do we have OSI app packet dissector ? */
232 /* No - display as data */
235 proto_tree_add_text(param_tree, tvb, offset, param_len,
236 "dissector is not available");
241 /* Yes - call application dissector */
244 next_tvb = tvb_new_subset(tvb, offset, param_len,
248 call_dissector(app_handle, next_tvb, pinfo,
253 show_exception(tvb, pinfo, tree, EXCEPT_CODE);
259 string_to_hex(const unsigned char * in,char * out,int len)
261 char ascii[MAXSTRING];
263 memset(&ascii,0x00,sizeof(ascii));
266 unsigned char o_out = *(in+i);
267 sprintf(out+(i<<1),"%.2x",* (in+i));
268 if( ( (o_out) >= 'a') & ( (o_out) <='z') ||
269 ( (o_out) >= 'A') & ( (o_out) <='Z') ||
270 ( (o_out) >= '0') & ( (o_out) <='9')
286 static int read_length(ASN1_SCK *a, proto_tree *tree, int hf_id, guint *len)
289 gboolean def = FALSE;
290 int start = a->offset;
293 ret = asn1_length_decode(a, &def, &length);
294 if (ret != ASN1_ERR_NOERROR)
298 proto_tree_add_text(tree, a->tvb, start, 0,
299 "%s: ERROR: Couldn't parse length: %s",
300 proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
309 proto_tree_add_uint(tree, hf_id, a->tvb, start, a->offset-start,
312 return ASN1_ERR_NOERROR;
314 static int read_integer_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
315 proto_item **new_item, guint *i, int start, guint length)
318 proto_item *temp_item = NULL;
321 ret = asn1_uint32_value_decode(a, length, &integer);
322 if (ret != ASN1_ERR_NOERROR)
326 proto_tree_add_text(tree, a->tvb, start, 0,
327 "%s: ERROR: Couldn't parse value: %s",
328 proto_registrar_get_name(hf_id), asn1_err_to_str(ret));
337 temp_item = proto_tree_add_uint(tree, hf_id, a->tvb, start,
338 a->offset-start, integer);
341 *new_item = temp_item;
343 return ASN1_ERR_NOERROR;
346 static int read_integer(ASN1_SCK *a, proto_tree *tree, int hf_id,
347 proto_item **new_item, guint *i)
352 int start = a->offset;
355 ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
356 if (ret != ASN1_ERR_NOERROR)
360 proto_tree_add_text(tree, a->tvb, start, 0,
361 "%s: ERROR: Couldn't parse header: %s",
362 (hf_id != -1) ? proto_registrar_get_name(hf_id) : "LDAP message",
363 asn1_err_to_str(ret));
368 return read_integer_value(a, tree, hf_id, new_item, i, start, length);
370 /* display asn.1 Integer type */
372 show_integer(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
373 *offset,guint item_len)
375 proto_tree *acse_tree_itm = NULL;
378 int save_len = item_len;
380 itm = proto_tree_add_text(acse_tree, tvb, *offset, item_len,
382 acse_tree_itm = proto_item_add_subtree(itm, ett_acse_itm);
383 ret = read_integer(asn,acse_tree_itm,0,NULL,&item_len);
384 if (ret == ASN1_ERR_NOERROR )
386 *offset = asn->offset;
387 itm = proto_tree_add_text(acse_tree_itm, tvb, (*offset)-item_len,
389 "Integer value: %u",item_len);
393 /* can't dissect item. Skip it. */
394 *offset = off+ save_len;
399 show_protocol_version(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
400 *offset,int item_len,int tag)
402 proto_tree *acse_tree_itm = NULL;
406 /* do we have enough bytes to dissect this item ? */
407 if( ( length = tvb_reported_length_remaining(tvb, *offset)) <
408 (asn->offset -*offset)+ item_len )
410 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
411 "Wrong Item.Need %u bytes but have %u", item_len,length);
415 itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset -*offset)+
417 val_to_str(tag, request_sequence_top_vals,"Unknown item (0x%02x)"));
418 acse_tree_itm = proto_item_add_subtree(itm, ett_acse_itm);
419 *offset = asn->offset;
420 flags = tvb_get_ntohs(tvb, *offset);
421 proto_tree_add_boolean(acse_tree_itm,hf_protocol_version, tvb, *offset,
423 *offset = *offset + item_len;
424 asn->offset = *offset;
427 print_oid_value(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
428 *offset,int item_len)
433 gchar *display_string;
437 ret = asn1_oid_value_decode (asn, item_len, &oid, &len);
438 if (ret != ASN1_ERR_NOERROR)
442 length = asn->offset - start;
443 display_string = format_oid(oid, len);
444 proto_tree_add_text(acse_tree, tvb, *offset,length,"Value:%s",
446 g_free(display_string);
447 (*offset)=start+item_len;
448 asn->offset = (*offset);
451 print_oid(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int *offset,int
458 gchar *display_string;
462 ret = asn1_oid_decode ( asn, &oid, &len, &nbytes);
464 if (ret != ASN1_ERR_NOERROR)
468 length = asn->offset - start;
469 display_string = format_oid(oid, len);
470 proto_tree_add_text(acse_tree, tvb, *offset,length,"Value:%s",
475 strcpy(d_s,display_string);
477 g_free(display_string);
478 (*offset)=start+item_len;
479 asn->offset = (*offset);
483 print_value(proto_tree *acse_tree,tvbuff_t *tvb,int
484 *offset,int item_len)
487 string_to_hex(tvb_get_ptr(tvb,*offset,item_len),tmp,item_len);
488 proto_tree_add_text(acse_tree, tvb, *offset, item_len, tmp);
491 get_integer_value(ASN1_SCK *asn,int length,int *offset)
494 int asn_off = asn->offset;
499 ret = asn1_uint32_value_decode(asn, length, &item_len);
500 /* return to present position */
502 asn->offset = asn_off;
504 if (ret != ASN1_ERR_NOERROR )
515 show_fully_encoded_seq(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
516 *offset,int item_len)
518 proto_tree *acse_tree_ms = NULL;
523 guint start = *offset;
525 guint acse = 0; /* no acse id */
528 while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 )
530 old_offset = *offset ;
532 type = tvb_get_guint8(tvb, *offset);
535 asn->offset = *offset;
537 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
539 (*offset)=start+item_len;
540 asn->offset = (*offset);
543 /* do we have enough bytes to dissect ? */
544 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
547 proto_tree_add_text(acse_tree, tvb, *offset, new_item_len,
548 "Wrong item.Need %u bytes but have %u", new_item_len,length);
549 (*offset)=start+item_len;
550 asn->offset = (*offset);
553 header_len = asn->offset - (*offset) +1;
554 ms = proto_tree_add_text(acse_tree, tvb, *offset-1,
555 new_item_len+(asn->offset-*offset)+1,
556 val_to_str(type, presentation_data_values,
557 "Unknown item (0x%02x)"));
558 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
559 *offset = asn->offset;
564 case PRESENTATION_CONTEXT_IDENTIFIER:
566 acse = get_integer_value(asn,new_item_len,offset);
567 print_value(acse_tree_ms,tvb,offset,new_item_len);
570 case ABSTRACT_SYNTAX_NAME:
571 print_oid_value(asn,acse_tree_ms,tvb,offset,new_item_len);
576 case SINGLE_ASN1_TYPE:
579 /* yes, we have to call ACSE dissector */
580 acse_ms = proto_tree_add_text(acse_tree_ms, tvb, *offset,
581 new_item_len+(asn->offset-*offset),
583 /* call acse dissector */
584 call_app_dissector(tvb,*offset,new_item_len,global_pinfo,global_tree,acse_tree_ms);
588 print_value(acse_tree_ms,tvb,offset,new_item_len);
591 proto_tree_add_text(acse_tree, tvb, *offset,
592 new_item_len+(asn->offset-*offset),
593 "Unknown asn.1 parameter: (0x%02x)", type);
595 *offset = old_offset+new_item_len+header_len;
596 item_len-=new_item_len+header_len;
598 /* align the pointer */
599 (*offset)=start+item_len;
600 asn->offset = (*offset);
605 show_acse_user_information(ASN1_SCK *asn,proto_tree
606 *acse_tree,tvbuff_t *tvb,int *offset,int item_len)
608 proto_tree *acse_tree_ms = NULL;
609 proto_tree *acse_tree_ab = NULL;
616 guint start = *offset;
619 type = tvb_get_guint8(tvb, *offset) & 0x1f;
622 asn->offset = *offset;
624 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
626 (*offset)=start+item_len;
627 asn->offset = (*offset);
631 /* do we have enough bytes to dissect ? */
632 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
635 proto_tree_add_text(acse_tree, tvb, *offset, new_item_len,
636 "Wrong item.Need %u bytes but have %u", new_item_len,length);
637 (*offset)=start+item_len;
638 asn->offset = (*offset);
641 header_len = asn->offset - (*offset) +1;
642 ms = proto_tree_add_text(acse_tree, tvb, *offset-1,
643 new_item_len+(asn->offset-*offset)+1,
644 val_to_str(type,response_sequence_top_vals,
645 "Unknown item (0x%02x)"));
646 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
647 *offset = asn->offset;
649 type = tvb_get_guint8(tvb, *offset) & 0x1f;
650 /* do we have user or provider abort ? */
651 ab = proto_tree_add_text(acse_tree_ms, tvb, *offset,
652 new_item_len+(asn->offset-*offset),
653 val_to_str(type,acse_user_information_vals,
654 "Unknown item (0x%02x)"));
655 acse_tree_ab = proto_item_add_subtree(ab, ett_acse_ms);
657 if(type!= ACSE_EXTERNAL)
659 (*offset)=start+item_len;
660 asn->offset = (*offset);
664 /* skip type of item*/
666 asn->offset = *offset;
668 if (read_length(asn, acse_tree_ab, 0, &code_item_len) !=
671 (*offset)=start+item_len;
672 asn->offset = (*offset);
675 /* do we have enough bytes to dissect ? */
676 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
679 proto_tree_add_text(acse_tree_ab, tvb, *offset, code_item_len,
680 "Wrong item.Need %u bytes but have %u", code_item_len,length);
681 (*offset)=start+item_len;
682 asn->offset = (*offset);
685 *offset = asn->offset;
687 show_fully_encoded_seq(asn,acse_tree_ab,tvb,offset,code_item_len);
688 /* align the pointer */
689 (*offset)=start+item_len;
690 asn->offset = (*offset);
694 show_acse_result_source_diagnostic(ASN1_SCK *asn,proto_tree
695 *acse_tree,tvbuff_t *tvb,int *offset,int item_len)
697 proto_tree *acse_tree_ms = NULL;
698 proto_tree *acse_tree_ab = NULL;
705 guint start = *offset;
707 proto_tree *acse_tree_pr = NULL;
711 type = tvb_get_guint8(tvb, *offset) & 0x1f;
714 asn->offset = *offset;
716 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
718 (*offset)=start+item_len;
719 asn->offset = (*offset);
723 /* do we have enough bytes to dissect ? */
724 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
727 proto_tree_add_text(acse_tree, tvb, *offset, new_item_len,
728 "Wrong item.Need %u bytes but have %u", new_item_len,length);
729 (*offset)=start+item_len;
730 asn->offset = (*offset);
733 header_len = asn->offset - (*offset) +1;
734 ms = proto_tree_add_text(acse_tree, tvb, *offset-1,
735 new_item_len+(asn->offset-*offset)+1,
736 val_to_str(type,response_sequence_top_vals,
737 "Unknown item (0x%02x)"));
738 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
739 *offset = asn->offset;
741 type = tvb_get_guint8(tvb, *offset) & 0x1f;
742 /* do we have user or provider abort ? */
743 ab = proto_tree_add_text(acse_tree_ms, tvb, *offset,
744 new_item_len+(asn->offset-*offset),
745 val_to_str(type,acse_associate_source_diagnostic_vals,
746 "Unknown item (0x%02x)"));
747 acse_tree_ab = proto_item_add_subtree(ab, ett_acse_ms);
749 /* skip type of abort*/
751 asn->offset = *offset;
753 if (read_length(asn, acse_tree, 0, &code_item_len) != ASN1_ERR_NOERROR)
755 (*offset)=start+item_len;
756 asn->offset = (*offset);
759 *offset = asn->offset;
760 /* do we have enough bytes to dissect ? */
761 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
764 proto_tree_add_text(acse_tree, tvb, *offset, code_item_len,
765 "Wrong item.Need %u bytes but have %u", code_item_len,length);
766 (*offset)=start+item_len;
767 asn->offset = (*offset);
771 /* skip type of constant*/
773 asn->offset = *offset;
775 if (read_length(asn, acse_tree_ab, 0, &code_item_len) !=
778 (*offset)=start+item_len;
779 asn->offset = (*offset);
782 /* do we have enough bytes to dissect ? */
783 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
786 proto_tree_add_text(acse_tree_ab, tvb, *offset, code_item_len,
787 "Wrong item.Need %u bytes but have %u", code_item_len,length);
788 (*offset)=start+item_len;
789 asn->offset = (*offset);
792 *offset = asn->offset;
793 value = get_integer_value(asn,code_item_len,offset);
794 if(type == ACSE_SERVICE_USER )
796 pr = proto_tree_add_text(acse_tree_ab, tvb, *offset,
797 code_item_len+(asn->offset-*offset),
798 val_to_str(value , acse_service_user_values_vals,
799 "Unknown item (0x%02x)"));
803 pr = proto_tree_add_text(acse_tree_ab, tvb, *offset,
804 code_item_len+(asn->offset-*offset),
805 val_to_str(value , acse_service_provider_values_vals,
806 "Unknown item (0x%02x)"));
809 acse_tree_pr = proto_item_add_subtree(pr, ett_acse_ms);
810 print_value(acse_tree_pr,tvb,offset,code_item_len);
812 *offset = start+new_item_len+header_len;
813 item_len-=new_item_len+header_len;
814 /* align the pointer */
815 (*offset)=start+item_len;
816 asn->offset = (*offset);
820 show_acse_result(ASN1_SCK *asn,proto_tree
821 *acse_tree,tvbuff_t *tvb,int *offset,int item_len)
823 proto_tree *acse_tree_ms = NULL;
829 guint start = *offset;
831 proto_tree *acse_tree_pr = NULL;
835 type = tvb_get_guint8(tvb, *offset) & 0x1f;
838 asn->offset = *offset;
840 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
842 (*offset)=start+item_len;
843 asn->offset = (*offset);
847 /* do we have enough bytes to dissect ? */
848 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
851 proto_tree_add_text(acse_tree, tvb, *offset, new_item_len,
852 "Wrong item.Need %u bytes but have %u", new_item_len,length);
853 (*offset)=start+item_len;
854 asn->offset = (*offset);
857 header_len = asn->offset - (*offset) +1;
858 ms = proto_tree_add_text(acse_tree, tvb, *offset-1,
859 new_item_len+(asn->offset-*offset)+1,
860 val_to_str(type,response_sequence_top_vals,
861 "Unknown item (0x%02x)"));
862 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
863 *offset = asn->offset;
866 asn->offset = *offset;
868 if (read_length(asn, acse_tree, 0, &code_item_len) != ASN1_ERR_NOERROR)
870 (*offset)=start+item_len;
871 asn->offset = (*offset);
874 /* do we have enough bytes to dissect ? */
875 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
878 proto_tree_add_text(acse_tree, tvb, *offset, code_item_len,
879 "Wrong item.Need %u bytes but have %u", code_item_len,length);
880 (*offset)=start+item_len;
881 asn->offset = (*offset);
884 *offset = asn->offset;
885 value = get_integer_value(asn,code_item_len,offset);
886 pr = proto_tree_add_text(acse_tree_ms, tvb, *offset,
887 code_item_len+(asn->offset-*offset),
888 val_to_str(value , associate_result_values_vals,
889 "Unknown item (0x%02x)"));
890 acse_tree_pr = proto_item_add_subtree(pr, ett_acse_ms);
891 print_value(acse_tree_pr,tvb,offset,code_item_len);
893 *offset = start+new_item_len+header_len;
894 item_len-=new_item_len+header_len;
895 /* align the pointer */
896 (*offset)=start+item_len;
897 asn->offset = (*offset);
901 show_oid(ASN1_SCK *asn,proto_tree
902 *acse_tree,tvbuff_t *tvb,int *offset,int item_len,const value_string*
905 proto_tree *acse_tree_ms = NULL;
910 guint start = *offset;
913 old_offset = *offset ;
915 type = tvb_get_guint8(tvb, *offset) & 0x1f;
918 asn->offset = *offset;
920 if (read_length(asn, acse_tree, 0, &new_item_len) != ASN1_ERR_NOERROR)
922 (*offset)=start+item_len;
923 asn->offset = (*offset);
927 /* do we have enough bytes to dissect ? */
928 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
931 proto_tree_add_text(acse_tree, tvb, *offset, new_item_len,
932 "Wrong item.Need %u bytes but have %u", new_item_len,length);
933 (*offset)=start+item_len;
934 asn->offset = (*offset);
937 header_len = asn->offset - (*offset) +1;
938 ms = proto_tree_add_text(acse_tree, tvb, *offset-1,
939 new_item_len+(asn->offset-*offset)+1,
940 val_to_str(type, v_s,
941 "Unknown item (0x%02x)"));
942 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
943 *offset = asn->offset;
944 print_oid(asn,acse_tree_ms,tvb,offset,new_item_len,oid);
945 *offset = old_offset+new_item_len+header_len;
946 item_len-=new_item_len+header_len;
947 /* align the pointer */
948 (*offset)=start+item_len;
949 asn->offset = (*offset);
952 show_fully_encoded_data(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
953 *tvb,int *offset,int item_len)
955 proto_tree *acse_tree_ms = NULL;
956 proto_tree *acse_tree_pc = NULL;
962 guint start = asn->offset;
963 guint item_length = item_len;
964 acse_tree_pc = acse_tree;
966 /* do we have enough bytes to dissect ? */
967 if( ( length =tvb_reported_length_remaining(tvb, *offset)) < (guint)item_len )
969 proto_tree_add_text(acse_tree_pc, tvb, *offset, item_len,
970 "Wrong item.Need %u bytes but have %u", item_len,length);
971 /* align the pointer */
972 (*offset)=start+item_length;
973 asn->offset = (*offset);
976 *offset =asn->offset;
979 while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 )
981 int old_offset = *offset;
983 type = tvb_get_guint8(tvb, *offset);
986 asn->offset = *offset;
988 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
991 /* align the pointer */
992 (*offset)=start+item_length;
993 asn->offset = (*offset);
996 header_len = asn->offset - (*offset) +1;
997 /* do we have enough bytes to dissect ? */
998 if( ( length =tvb_reported_length_remaining(tvb, *offset)) <
1001 proto_tree_add_text(acse_tree_pc, tvb, *offset, new_item_len,
1002 "Wrong item.Need %u bytes but have %u", new_item_len,length);
1003 /* align the pointer */
1004 (*offset)=start+item_length;
1005 asn->offset = (*offset);
1008 ms = proto_tree_add_text(acse_tree_pc, tvb, *offset-1,
1009 new_item_len+(asn->offset-*offset)+1,
1010 val_to_str(type, presentation_context_definition_vals,
1011 "Unknown item (0x%02x)"));
1012 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
1013 *offset = asn->offset;
1020 show_fully_encoded_seq(asn,acse_tree_ms,tvb,offset,new_item_len);
1021 *offset = old_offset+(new_item_len+header_len);
1025 proto_tree_add_text(acse_tree_ms, tvb, *offset,
1026 new_item_len+(asn->offset-*offset),
1027 "Unknown asn.1 parameter: (0x%02x)", type);
1028 *offset = old_offset+(new_item_len+header_len);
1030 item_len = item_len - (new_item_len+header_len);
1035 /* align the pointer */
1036 (*offset)=start+item_length;
1037 asn->offset = (*offset);
1040 show_abort_reason(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1041 *tvb,int *offset,int item_len)
1045 proto_tree *acse_tree_pc = NULL;
1048 guint start = *offset;
1049 int save_len = item_len;
1050 /* do we have enough bytes to dissect this item ? */
1051 if( ( length =tvb_reported_length_remaining(tvb, *offset)) < item_len )
1053 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1054 "Wrong Item.Need %u bytes but have %u", item_len,length);
1055 *offset = asn->offset;
1061 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1062 "Reason not specified");
1063 *offset = asn->offset;
1066 itu = proto_tree_add_text(acse_tree, tvb, *offset,ABORT_REASON_LEN,
1068 acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1069 (*offset)++; /* skip type */
1070 asn->offset = *offset;
1073 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
1076 *offset = asn->offset;
1079 /* try to get reason */
1080 value = get_integer_value(asn,new_item_len,offset);
1082 proto_tree_add_text(acse_tree_pc, tvb, *offset+1,new_item_len,
1083 val_to_str(value,abort_reason,"Unknown item (0x%02x)"));
1084 item_len-=(asn->offset-*offset)+new_item_len;
1085 *offset = asn->offset+new_item_len;
1086 asn->offset = *offset;
1087 /* do we have User information field ? */
1090 show_acse_user_information(asn,acse_tree,tvb,offset,item_len);
1092 /* align the pointer */
1093 (*offset)=start+save_len;
1094 asn->offset = (*offset);
1098 show_disconnect_pdu(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1099 *tvb,int *offset,int item_len)
1103 proto_tree *acse_tree_pc = NULL;
1106 guint start = *offset;
1107 int save_len = item_len;
1108 /* do we have enough bytes to dissect this item ? */
1109 if( ( length =tvb_reported_length_remaining(tvb, *offset)) < item_len )
1111 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1112 "Wrong Item.Need %u bytes but have %u", item_len,length);
1113 *offset = asn->offset;
1119 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1120 "Reason not specified");
1121 *offset = asn->offset;
1124 itu = proto_tree_add_text(acse_tree, tvb, *offset,ABORT_REASON_LEN,
1126 acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1127 (*offset)++; /* skip type */
1128 asn->offset = *offset;
1131 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
1134 *offset = asn->offset;
1137 /* try to get reason */
1138 value = get_integer_value(asn,new_item_len,offset);
1140 proto_tree_add_text(acse_tree_pc, tvb, *offset+1,new_item_len,
1141 val_to_str(value,release_response_reason,"Unknown item (0x%02x)"));
1142 item_len-=(asn->offset-*offset)+new_item_len;
1143 *offset = asn->offset+new_item_len;
1144 asn->offset = *offset;
1145 /* do we have User information field ? */
1148 show_acse_user_information(asn,acse_tree,tvb,offset,item_len);
1150 /* align the pointer */
1151 (*offset)=start+save_len;
1152 asn->offset = (*offset);
1156 show_finish_pdu(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1157 *tvb,int *offset,int item_len)
1161 proto_tree *acse_tree_pc = NULL;
1164 guint start = *offset;
1165 int save_len = item_len;
1166 /* do we have enough bytes to dissect this item ? */
1167 if( ( length =tvb_reported_length_remaining(tvb, *offset)) < item_len )
1169 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1170 "Wrong Item.Need %u bytes but have %u", item_len,length);
1171 *offset = asn->offset;
1177 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1178 "Reason not specified");
1179 *offset = asn->offset;
1182 itu = proto_tree_add_text(acse_tree, tvb, *offset,ABORT_REASON_LEN,
1184 acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1185 (*offset)++; /* skip type */
1186 asn->offset = *offset;
1189 if (read_length(asn, acse_tree_pc, 0, &new_item_len) !=
1192 *offset = asn->offset;
1195 /* try to get reason */
1196 value = get_integer_value(asn,new_item_len,offset);
1198 proto_tree_add_text(acse_tree_pc, tvb, *offset+1,new_item_len,
1199 val_to_str(value,release_request_reason,"Unknown item (0x%02x)"));
1200 item_len-=(asn->offset-*offset)+new_item_len;
1201 *offset = asn->offset+new_item_len;
1202 asn->offset = *offset;
1203 /* do we have User information field ? */
1206 show_acse_user_information(asn,acse_tree,tvb,offset,item_len);
1208 /* align the pointer */
1209 (*offset)=start+save_len;
1210 asn->offset = (*offset);
1213 show_user_data(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t *tvb,int
1214 *offset,int item_len,int tag)
1216 proto_tree *acse_tree_ud = NULL;
1217 proto_tree *acse_tree_pc = NULL;
1220 guint start = asn->offset;
1221 guint item_length = item_len;
1223 itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset -*offset)+
1224 item_len, "User data");
1225 acse_tree_ud = proto_item_add_subtree(itm, ett_acse_ms);
1226 itu = proto_tree_add_text(acse_tree_ud, tvb,
1227 *offset,item_len+(asn->offset-*offset),
1228 val_to_str(tag, user_data_values_vals,"Unknown item (0x%02x)"));
1229 acse_tree_pc = proto_item_add_subtree(itu, ett_acse_ms);
1232 case SIMPLY_ENCODED_DATA:
1234 case FULLY_ENCODED_DATA:
1235 show_fully_encoded_data(asn,acse_tree_pc,tvb,offset,item_len);
1242 /* align the pointer */
1243 (*offset)=start+item_length;
1244 asn->offset = (*offset);
1248 /* if we can't dissect */
1250 dissect_parse_error(tvbuff_t *tvb, int offset, packet_info *pinfo,
1251 proto_tree *tree, const char *field_name, int ret)
1254 errstr = asn1_err_to_str(ret);
1258 proto_tree_add_text(tree, tvb, offset, 0,
1259 "ERROR: Couldn't parse %s: %s", field_name, errstr);
1260 call_dissector(data_handle,
1261 tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
1265 /* display request top sequence */
1267 show_request_sequence_top(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1268 *tvb,packet_info *pinfo,int *offset,int item_len)
1271 guint cls, con, tag,len1;
1277 while(item_len > 0 )
1279 int offset_save = *offset;
1280 /* do we have enough bytes to dissect this item ? */
1281 if( ( length =tvb_reported_length_remaining(tvb, *offset)) < item_len )
1283 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1284 "Wrong Item.Need %u bytes but have %u", item_len,length);
1288 type = tvb_get_guint8(tvb, *offset);
1290 ret = asn1_header_decode(asn, &cls, &con, &tag, &def, &len1);
1292 if (ret != ASN1_ERR_NOERROR)
1294 dissect_parse_error(tvb, *offset, pinfo, acse_tree,
1295 "sequence error", ret);
1299 item_len = item_len - (asn->offset - *offset);
1300 offset_save += (asn->offset - *offset);
1302 * [APPLICATION <tag>]
1306 case USER_INFORMATION:
1307 show_acse_user_information(asn,acse_tree,tvb,offset,len1);
1309 case CALLED_AE_QUALIFIER:
1310 case CALLING_AE_QUALIFIER:
1312 proto_tree *acse_tree_pr = NULL;
1314 pr = proto_tree_add_text(acse_tree,tvb,*offset,
1315 len1+(asn->offset-*offset),
1316 val_to_str(tag ,request_sequence_top_vals,
1317 "Unknown item (0x%02x)"));
1318 acse_tree_pr = proto_item_add_subtree(pr, ett_acse_ms);
1319 show_integer(asn,acse_tree_pr,tvb,offset,len1);
1322 case APPLICATION_CONTEXT_NAME:
1323 case CALLED_AP_TITLE:
1324 case CALLING_AP_TITLE:
1325 case CALLED_AP_INVOKATION_ID:
1326 case CALLED_AE_INVOKATION_ID:
1327 case CALLING_AP_INVOKATION_ID:
1328 case CALLING_AE_INVOKATION_ID:
1330 gchar oid_string[MAXSTRING];
1331 show_oid(asn,acse_tree,tvb,offset,len1,(const
1332 value_string*)&request_sequence_top_vals,
1333 (gchar*)&oid_string);
1334 if(tag == APPLICATION_CONTEXT_NAME )
1336 guint pos_in_string;
1337 /* try to find real OID string from given */
1338 /* function could return "1.0.8571.1.1" or "1.0.8571.1.1 iso.0.8571.1.1" */
1339 /* so try to find first blank and strip string */
1340 for(pos_in_string=0;pos_in_string<strlen(oid_string);pos_in_string++)
1342 if( oid_string[pos_in_string] == ' ' )
1344 oid_string[pos_in_string] = 0x00;
1348 /* try to get subdissector handler using given OID */
1351 if( !(app_handle = dissector_get_string_handle(application_dissector_table, oid_string) ))
1353 proto_tree_add_text(acse_tree,tvb,*offset,len1,"Unknown OID");
1359 case PROTOCOL_VERSION:
1360 show_protocol_version(asn,acse_tree,tvb,offset,len1,tag);
1363 itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset
1365 "Unknown tag: %x",tag);
1368 *offset = asn->offset = offset_save+len1;;
1371 /* display response top sequence */
1373 show_response_sequence_top(ASN1_SCK *asn,proto_tree *acse_tree,tvbuff_t
1374 *tvb,packet_info *pinfo,int *offset,int item_len)
1377 guint cls, con, tag,len1;
1383 while(item_len > 0 )
1385 int offset_save = *offset;
1386 /* do we have enough bytes to dissect this item ? */
1387 if( ( length =tvb_reported_length_remaining(tvb, *offset)) < item_len )
1389 proto_tree_add_text(acse_tree, tvb, *offset, item_len,
1390 "Wrong Item.Need %u bytes but have %u", item_len,length);
1394 type = tvb_get_guint8(tvb, *offset);
1396 ret = asn1_header_decode(asn, &cls, &con, &tag, &def, &len1);
1398 if (ret != ASN1_ERR_NOERROR)
1400 dissect_parse_error(tvb, *offset, pinfo, acse_tree,
1401 "sequence error", ret);
1405 item_len = item_len - (asn->offset - *offset);
1406 offset_save += (asn->offset - *offset);
1408 * [APPLICATION <tag>]
1413 show_acse_result(asn,acse_tree,tvb,offset,len1);
1415 case ACSE_RESULT_SOURCE_DIAGNOSTIC:
1416 show_acse_result_source_diagnostic(asn,acse_tree,tvb,offset,len1);
1418 case USER_INFORMATION:
1419 show_acse_user_information(asn,acse_tree,tvb,offset,len1);
1422 case RESPONDING_AE_QUALIFIER:
1424 proto_tree *acse_tree_pr = NULL;
1426 pr = proto_tree_add_text(acse_tree,tvb,*offset,
1427 len1+(asn->offset-*offset),
1428 val_to_str(tag ,response_sequence_top_vals,
1429 "Unknown item (0x%02x)"));
1430 acse_tree_pr = proto_item_add_subtree(pr, ett_acse_ms);
1431 show_integer(asn,acse_tree_pr,tvb,offset,len1);
1434 case APPLICATION_CONTEXT_NAME:
1435 case RESPONDING_AP_TITLE:
1436 case RESPONDING_AP_INVOKATION_ID:
1437 case RESPONDING_AE_INVOKATION_ID:
1438 show_oid(asn,acse_tree,tvb,offset,len1,(const
1439 value_string*)&response_sequence_top_vals,NULL);
1441 case PROTOCOL_VERSION:
1442 show_protocol_version(asn,acse_tree,tvb,offset,len1,tag);
1445 itm = proto_tree_add_text(acse_tree, tvb, *offset,(asn->offset
1447 "Unknown tag: %x",tag);
1450 *offset = asn->offset = offset_save+len1;
1458 dissect_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree
1462 proto_tree *acse_tree = NULL;
1468 /* get type of tag */
1469 s_type = tvb_get_guint8(tvb, offset);
1470 /* set up type of pdu */
1471 if (check_col(pinfo->cinfo, COL_INFO))
1472 col_add_str(pinfo->cinfo, COL_INFO,
1473 val_to_str(session->spdu_type, ses_vals, "Unknown pdu type (0x%02x)"));
1476 ti = proto_tree_add_item(tree, proto_acse, tvb, offset, -1,
1478 acse_tree = proto_item_add_subtree(ti, ett_acse);
1481 /* open asn.1 stream */
1482 asn1_open(&asn, tvb, offset);
1484 switch(session->spdu_type)
1487 case SES_CONNECTION_REQUEST:
1488 case SES_CONNECTION_ACCEPT:
1489 proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1491 if (read_length(&asn, acse_tree, hf_cp_type_message_length, &cp_type_len)
1492 != ASN1_ERR_NOERROR)
1497 offset = asn.offset;
1498 /* do we have enough bytes to dissect ? */
1499 if( ( length =tvb_reported_length_remaining(tvb, offset)) < cp_type_len
1504 proto_tree_add_text(acse_tree, tvb, offset, -1,
1505 "Wrong pdu.Need %u bytes but have %u", cp_type_len,length);
1511 if(session->spdu_type == SES_CONNECTION_REQUEST)
1513 show_request_sequence_top(&asn,acse_tree,tvb,pinfo,&offset,cp_type_len);
1517 show_response_sequence_top(&asn,acse_tree,tvb,pinfo,&offset,cp_type_len);
1523 proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1525 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1530 offset = asn.offset;
1531 /* do we have enough bytes to dissect ? */
1532 if( ( length =tvb_reported_length_remaining(tvb, offset)) < rest_len )
1536 proto_tree_add_text(acse_tree, tvb, offset, -1,
1537 "Wrong pdu.Need %u bytes but have %u", rest_len,length);
1541 show_finish_pdu(&asn,acse_tree,tvb,&offset,rest_len);
1543 case SES_DISCONNECT:
1544 proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1546 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1551 offset = asn.offset;
1552 /* do we have enough bytes to dissect ? */
1553 if( ( length =tvb_reported_length_remaining(tvb, offset)) < rest_len )
1557 proto_tree_add_text(acse_tree, tvb, offset, -1,
1558 "Wrong pdu.Need %u bytes but have %u", rest_len,length);
1562 show_disconnect_pdu(&asn,acse_tree,tvb,&offset,rest_len);
1565 proto_tree_add_uint(acse_tree, hf_acse_type, tvb, offset-1, 1, s_type);
1567 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1572 offset = asn.offset;
1573 /* do we have enough bytes to dissect ? */
1574 if( ( length =tvb_reported_length_remaining(tvb, offset)) < rest_len )
1578 proto_tree_add_text(acse_tree, tvb, offset, -1,
1579 "Wrong pdu.Need %u bytes but have %u", rest_len,length);
1583 show_abort_reason(&asn,acse_tree,tvb,&offset,rest_len);
1588 proto_tree *acse_tree_ms = NULL;
1589 /* back to length */
1592 if (read_length(&asn, acse_tree, 0, &rest_len) != ASN1_ERR_NOERROR)
1596 ms = proto_tree_add_text(acse_tree, tvb, offset, rest_len,
1597 val_to_str(session->spdu_type, ses_vals, "Unknown pdu type (0x%02x)"));
1598 acse_tree_ms = proto_item_add_subtree(ms, ett_acse_ms);
1599 show_user_data(&asn,acse_tree_ms,tvb,&offset,rest_len,s_type);
1602 /* close asn.1 stream */
1603 asn1_close(&asn, &offset);
1609 * Dissect ACSE PDUs inside a PPDU.
1612 dissect_acse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1615 /* first, try to check length */
1616 /* do we have at least 2 bytes */
1617 if (!tvb_bytes_exist(tvb, 0, 2))
1619 proto_tree_add_text(tree, tvb, offset,
1620 tvb_reported_length_remaining(tvb,offset),
1622 return; /* no, it isn't a ACSE PDU */
1624 /* do we have spdu type from the session dissector? */
1625 if( !pinfo->private_data )
1629 proto_tree_add_text(tree, tvb, offset, -1,
1630 "Internal error:can't get spdu type from session dissector.");
1636 session = ( (struct SESSION_DATA_STRUCTURE*)(pinfo->private_data) );
1637 if(session->spdu_type == 0 )
1641 proto_tree_add_text(tree, tvb, offset, -1,
1642 "Internal error:wrong spdu type %x from session dissector.",session->spdu_type);
1647 /* ACSE has only AARQ,AARE,RLRQ,RLRE,ABRT type of pdu */
1648 /* reject everything else */
1649 /* data pdu is not ACSE pdu and has to go directly to app dissector */
1650 switch(session->spdu_type)
1652 case SES_REFUSE: /* RLRE */
1653 case SES_CONNECTION_REQUEST: /* AARQ */
1654 case SES_CONNECTION_ACCEPT: /* AARE */
1655 case SES_DISCONNECT: /* RLRQ */
1656 case SES_FINISH: /* RLRE */
1657 case SES_ABORT: /* ABRT */
1659 case SES_DATA_TRANSFER:
1660 call_app_dissector(tvb,offset,tvb_reported_length_remaining(tvb, offset)
1667 /* we can't make any additional checking here */
1668 /* postpone it before dissector will have more information */
1670 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1671 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACSE");
1672 if (check_col(pinfo->cinfo, COL_INFO))
1673 col_clear(pinfo->cinfo, COL_INFO);
1674 /* save pointers for calling the app dissector */
1676 global_pinfo = pinfo;
1678 while (tvb_reported_length_remaining(tvb, offset) > 0)
1680 offset = dissect_pdu(tvb, offset, pinfo, tree);
1681 if(offset == FALSE )
1683 proto_tree_add_text(tree, tvb, offset, -1,"Internal error");
1684 offset = tvb_length(tvb);
1691 proto_register_acse(void)
1693 static hf_register_info hf[] =
1708 &hf_cp_type_message_length,
1711 "cp_type.message_length",
1716 "CP type Message Length",
1721 &hf_protocol_version,
1723 "Protocol version 1",
1724 "acse.protocol.version",
1727 ACSE_PROTOCOL_VERGION,
1728 "Protocol version 1",
1734 static gint *ett[] =
1742 module_t *acse_module;
1745 proto_acse = proto_register_protocol(PROTO_STRING_ACSE, "ACSE", "acse");
1746 proto_register_field_array(proto_acse, hf, array_length(hf));
1747 proto_register_subtree_array(ett, array_length(ett));
1749 acse_module = prefs_register_protocol(proto_acse, NULL);
1752 * Register the dissector by name, so other dissectors can
1753 * grab it by name rather than just referring to it directly
1755 register_dissector("acse", dissect_acse, proto_acse);
1756 application_dissector_table = register_dissector_table("acse.application_context", "Application context OID", FT_STRING, BASE_NONE);
1760 proto_reg_handoff_acse(void)
1762 /* find data dissector */
1763 data_handle = find_dissector("data");