checkAPIs.pl: support for new-style dissectors in check_hf_entries
[metze/wireshark/wip.git] / epan / dissectors / packet-atn-ulcs.c
1 /* Do not modify this file. Changes will be overwritten.                      */
2 /* Generated automatically by the ASN.1 to Wireshark dissector compiler       */
3 /* packet-atn-ulcs.c                                                          */
4 /* asn2wrs.py -u -L -p atn-ulcs -c ./atn-ulcs.cnf -s ./packet-atn-ulcs-template -D . -O ../.. atn-ulcs.asn */
5
6 /* Input file: packet-atn-ulcs-template.c */
7
8 #line 1 "./asn1/atn-ulcs/packet-atn-ulcs-template.c"
9 /* packet-atn-ulcs.c
10  * By Mathias Guettler <guettler@web.de>
11  * Copyright 2013
12  *
13  * Routines for ATN upper layer
14  * protocol packet disassembly
15
16  * ATN upper layers are embedded within OSI Layer 4 (COTP).
17  *
18  * ATN upper layers contain:
19  * Session Layer (NUL protocol option)
20  * Presentation Layer (NUL protocol option)
21  * ATN upper Layer/Application (ACSE PDU or PDV-list PDU)
22
23  * ATN applications protocols (i.e. CM or CPDLC) are contained within
24  * ACSE user-information or PDV presentation data.
25
26  * details see:
27  * http://en.wikipedia.org/wiki/CPDLC
28  * http://members.optusnet.com.au/~cjr/introduction.htm
29
30  * standards:
31  * http://legacy.icao.int/anb/panels/acp/repository.cfm
32
33  * note:
34  * We are dealing with ATN/ULCS aka ICAO Doc 9705 Ed2 here
35  * (don't think there is an ULCS equivalent for "FANS-1/A ").
36
37  * Wireshark - Network traffic analyzer
38  * By Gerald Combs <gerald@wireshark.org>
39  * Copyright 1998 Gerald Combs
40  *
41  * SPDX-License-Identifier: GPL-2.0-or-later
42  */
43
44 /*
45  developer comments:
46 why not using existing ses, pres and acse dissectors ?
47     ATN upper layers are derived from OSI standards for session,
48     presentation and application but the encoding differs
49     (it's PER instead of BER encoding to save bandwith).
50     Session and presentation use the "null" encoding option,
51     meaning that they are only present at connection establishment
52     and ommitted otherwise.
53     Instead of adapting existing dissectors it seemed simpler and cleaner
54     to implement everything the new atn-ulcs dissector.
55
56 why using conversations ?
57     PER encoded user data is ambigous; the same encoding may apply to a CM or
58     CPDLC PDU. The workaround is to decode on a transport connection basis.
59     I use my own version of conversations to identify
60     the transport connection the PDU belongs to for the standard functions
61     from "conversation.h" didn't work out.
62
63 what is the use of AARQ/AARE data ?
64     Converstions should be maintained on the COTP layer in a standard way
65     for there are usually more packets available than in the layers above.
66     In the worst case my dissector is called from a DT packet which
67     has destination references but no source reference.
68     I have to guess the reference used the other way round
69     (curently I am using ACSE PDU'S used during OSI connection establishment for that).
70     The idea is that each ACSE AARQ is answered by ACSE AARE and having this sequence
71     I have all the source/destination references for this transport connection.
72     I use AARQ/AARE data to store the source/destination reference of AARQ as well
73     as the optional ae-qualifier which tells me the application and
74     the dissector I have to use.
75     This approach donesn't work well when there are interleaving AARQ/AARE sequences for
76     the same aircraft.
77
78 which ATN standard is supported ?
79     The dissector has been tested with ICAO doc9705 Edition2 compliant traffic.
80     No ATN Secutity is supported.
81     note:
82     The ATN upper layers are derived from OSI standards (ICAO DOC 9705)
83     while ATN/IPS (ICAO DOC 9896) which is entirely based on IPV6.
84
85 */
86
87 /*
88  known defects/deficiencies:
89
90 - user-information within AARE is sometines not decoded due to an unset flag
91     (the field is optional). As far as I can tell asn2wrs is right here,
92     but on the other hand I know that in all of this cases user-information
93     is present and is processed by the ATN end system.
94     Maybe a true ATN expert may help me out here.
95
96   - The conversation handling is based on src/dst addresses as well as
97     source or destination references depending on the TP4 packet type.
98     This means that after some time these references get reused for
99     new conversations. This almost certain happens for traces longer
100     than one day rendering this dissector unsuitable for captures exceeding
101     this one day.
102
103 */
104
105 #include "config.h"
106
107 #ifndef _MSC_VER
108 #include <stdint.h>
109 #endif
110
111
112 #include <epan/packet.h>
113 #include <epan/address.h>
114 #include <epan/conversation.h>
115 #include <epan/osi-utils.h>
116 #include "packet-ber.h"
117 #include "packet-per.h"
118 #include "packet-atn-ulcs.h"
119
120 #define ATN_ACSE_PROTO "ICAO Doc9705 ULCS ACSE (ISO 8649/8650-1:1996)"
121 #define ATN_ULCS_PROTO "ICAO Doc9705 ULCS"
122
123 void proto_register_atn_ulcs(void);
124 void proto_reg_handoff_atn_ulcs(void);
125
126 static heur_dissector_list_t atn_ulcs_heur_subdissector_list;
127
128 /* presentation subdissectors i.e. CM, CPDLC */
129 static dissector_handle_t atn_cm_handle = NULL;
130 static dissector_handle_t atn_cpdlc_handle = NULL;
131
132 static int proto_atn_ulcs          = -1;
133 static guint32 ulcs_context_value = 0;
134 static const char *object_identifier_id;
135
136 static wmem_tree_t *aarq_data_tree = NULL;
137 static wmem_tree_t *atn_conversation_tree = NULL;
138
139
140 static proto_tree *root_tree = NULL;
141
142 /* forward declarations for functions generated from asn1 */
143 static int dissect_atn_ulcs_T_externalt_encoding_single_asn1_type(
144     tvbuff_t *tvb _U_,
145     int offset _U_,
146     asn1_ctx_t *actx _U_,
147     proto_tree *tree _U_,
148     int hf_index
149     _U_);
150
151 static int dissect_atn_ulcs_T_externalt_encoding_octet_aligned(
152     tvbuff_t *tvb _U_,
153     int offset _U_,
154     asn1_ctx_t *actx _U_,
155     proto_tree *tree _U_,
156     int hf_index _U_);
157
158 static int dissect_atn_ulcs_T_externalt_encoding_arbitrary(
159     tvbuff_t *tvb _U_,
160     int offset _U_,
161     asn1_ctx_t *actx _U_,
162     proto_tree *tree _U_,
163     int hf_index _U_);
164
165 static int dissect_ACSE_apdu_PDU(
166     tvbuff_t *tvb _U_,
167     packet_info *pinfo _U_,
168     proto_tree *tree _U_,
169     void *data _U_);
170
171 guint32 dissect_per_object_descriptor_t(
172     tvbuff_t *tvb,
173     guint32 offset,
174     asn1_ctx_t *actx,
175     proto_tree *tree,
176     int hf_index,
177     tvbuff_t **value_tvb);
178
179 static gint dissect_atn_ulcs(
180     tvbuff_t *tvb,
181     packet_info *pinfo,
182     proto_tree  *tree,
183     void *data _U_);
184
185
186 /*--- Included file: packet-atn-ulcs-hf.c ---*/
187 #line 1 "./asn1/atn-ulcs/packet-atn-ulcs-hf.c"
188 static int hf_atn_ulcs_Fully_encoded_data_PDU = -1;  /* Fully_encoded_data */
189 static int hf_atn_ulcs_ACSE_apdu_PDU = -1;        /* ACSE_apdu */
190 static int hf_atn_ulcs_Fully_encoded_data_item = -1;  /* PDV_list */
191 static int hf_atn_ulcs_transfer_syntax_name = -1;  /* Transfer_syntax_name */
192 static int hf_atn_ulcs_presentation_context_identifier = -1;  /* Presentation_context_identifier */
193 static int hf_atn_ulcs_presentation_data_values = -1;  /* T_presentation_data_values */
194 static int hf_atn_ulcs_pdv_list_presentation_data_values_single_asn1_type = -1;  /* T_pdv_list_presentation_data_values_single_asn1_type */
195 static int hf_atn_ulcs_octet_aligned = -1;        /* OCTET_STRING */
196 static int hf_atn_ulcs_pdv_list_presentation_data_values_arbitrary = -1;  /* T_pdv_list_presentation_data_values_arbitrary */
197 static int hf_atn_ulcs_direct_reference = -1;     /* OBJECT_IDENTIFIER */
198 static int hf_atn_ulcs_indirect_reference = -1;   /* INTEGER */
199 static int hf_atn_ulcs_data_value_descriptor = -1;  /* T_data_value_descriptor */
200 static int hf_atn_ulcs_encoding = -1;             /* T_encoding */
201 static int hf_atn_ulcs_externalt_encoding_single_asn1_type = -1;  /* T_externalt_encoding_single_asn1_type */
202 static int hf_atn_ulcs_externalt_encoding_octet_aligned = -1;  /* T_externalt_encoding_octet_aligned */
203 static int hf_atn_ulcs_externalt_encoding_arbitrary = -1;  /* T_externalt_encoding_arbitrary */
204 static int hf_atn_ulcs_aarq = -1;                 /* AARQ_apdu */
205 static int hf_atn_ulcs_aare = -1;                 /* AARE_apdu */
206 static int hf_atn_ulcs_rlrq = -1;                 /* RLRQ_apdu */
207 static int hf_atn_ulcs_rlre = -1;                 /* RLRE_apdu */
208 static int hf_atn_ulcs_abrt = -1;                 /* ABRT_apdu */
209 static int hf_atn_ulcs_aarq_apdu_protocol_version = -1;  /* T_aarq_apdu_protocol_version */
210 static int hf_atn_ulcs_application_context_name = -1;  /* Application_context_name */
211 static int hf_atn_ulcs_called_AP_title = -1;      /* AP_title */
212 static int hf_atn_ulcs_called_AE_qualifier = -1;  /* AE_qualifier */
213 static int hf_atn_ulcs_called_AP_invocation_identifier = -1;  /* AP_invocation_identifier */
214 static int hf_atn_ulcs_called_AE_invocation_identifier = -1;  /* AE_invocation_identifier */
215 static int hf_atn_ulcs_calling_AP_title = -1;     /* AP_title */
216 static int hf_atn_ulcs_calling_AE_qualifier = -1;  /* AE_qualifier */
217 static int hf_atn_ulcs_calling_AP_invocation_identifier = -1;  /* AP_invocation_identifier */
218 static int hf_atn_ulcs_calling_AE_invocation_identifier = -1;  /* AE_invocation_identifier */
219 static int hf_atn_ulcs_sender_acse_requirements = -1;  /* ACSE_requirements */
220 static int hf_atn_ulcs_mechanism_name = -1;       /* Mechanism_name */
221 static int hf_atn_ulcs_calling_authentication_value = -1;  /* Authentication_value */
222 static int hf_atn_ulcs_application_context_name_list = -1;  /* Application_context_name_list */
223 static int hf_atn_ulcs_implementation_information = -1;  /* Implementation_data */
224 static int hf_atn_ulcs_user_information = -1;     /* Association_information */
225 static int hf_atn_ulcs_aare_apdu_protocol_version = -1;  /* T_aare_apdu_protocol_version */
226 static int hf_atn_ulcs_result = -1;               /* Associate_result */
227 static int hf_atn_ulcs_result_source_diagnostic = -1;  /* Associate_source_diagnostic */
228 static int hf_atn_ulcs_responding_AP_title = -1;  /* AP_title */
229 static int hf_atn_ulcs_responding_AE_qualifier = -1;  /* AE_qualifier */
230 static int hf_atn_ulcs_responding_AP_invocation_identifier = -1;  /* AP_invocation_identifier */
231 static int hf_atn_ulcs_responding_AE_invocation_identifier = -1;  /* AE_invocation_identifier */
232 static int hf_atn_ulcs_responder_acse_requirements = -1;  /* ACSE_requirements */
233 static int hf_atn_ulcs_responding_authentication_value = -1;  /* Authentication_value */
234 static int hf_atn_ulcs_rlrq_apdu_request_reason = -1;  /* Release_request_reason */
235 static int hf_atn_ulcs_rlre_apdu_response_reason = -1;  /* Release_response_reason */
236 static int hf_atn_ulcs_abort_source = -1;         /* ABRT_source */
237 static int hf_atn_ulcs_abort_diagnostic = -1;     /* ABRT_diagnostic */
238 static int hf_atn_ulcs_Application_context_name_list_item = -1;  /* Application_context_name */
239 static int hf_atn_ulcs_ap_title_form2 = -1;       /* AP_title_form2 */
240 static int hf_atn_ulcs_ap_title_form1 = -1;       /* AP_title_form1 */
241 static int hf_atn_ulcs_ae_qualifier_form2 = -1;   /* AE_qualifier_form2 */
242 static int hf_atn_ulcs_ae_qualifier_form1 = -1;   /* AE_qualifier_form1 */
243 static int hf_atn_ulcs_acse_service_user = -1;    /* T_acse_service_user */
244 static int hf_atn_ulcs_acse_service_provider = -1;  /* T_acse_service_provider */
245 static int hf_atn_ulcs_Association_information_item = -1;  /* EXTERNALt */
246 static int hf_atn_ulcs_charstring = -1;           /* OCTET_STRING */
247 static int hf_atn_ulcs_bitstring = -1;            /* BIT_STRING */
248 static int hf_atn_ulcs_external = -1;             /* EXTERNAL */
249 static int hf_atn_ulcs_other = -1;                /* T_other */
250 static int hf_atn_ulcs_other_mechanism_name = -1;  /* OBJECT_IDENTIFIER */
251 static int hf_atn_ulcs_other_mechanism_value = -1;  /* T_other_mechanism_value */
252 static int hf_atn_ulcs_rdnSequence = -1;          /* RDNSequence */
253 static int hf_atn_ulcs_RDNSequence_item = -1;     /* RelativeDistinguishedName */
254 static int hf_atn_ulcs_RelativeDistinguishedName_item = -1;  /* AttributeTypeAndValue */
255 static int hf_atn_ulcs_null = -1;                 /* NULL */
256 /* named bits */
257 static int hf_atn_ulcs_T_aarq_apdu_protocol_version_version1 = -1;
258 static int hf_atn_ulcs_T_aare_apdu_protocol_version_version1 = -1;
259 static int hf_atn_ulcs_ACSE_requirements_authentication = -1;
260 static int hf_atn_ulcs_ACSE_requirements_application_context_negotiation = -1;
261
262 /*--- End of included file: packet-atn-ulcs-hf.c ---*/
263 #line 178 "./asn1/atn-ulcs/packet-atn-ulcs-template.c"
264
265
266 /*--- Included file: packet-atn-ulcs-ett.c ---*/
267 #line 1 "./asn1/atn-ulcs/packet-atn-ulcs-ett.c"
268 static gint ett_atn_ulcs_Fully_encoded_data = -1;
269 static gint ett_atn_ulcs_PDV_list = -1;
270 static gint ett_atn_ulcs_T_presentation_data_values = -1;
271 static gint ett_atn_ulcs_EXTERNALt = -1;
272 static gint ett_atn_ulcs_T_encoding = -1;
273 static gint ett_atn_ulcs_ACSE_apdu = -1;
274 static gint ett_atn_ulcs_AARQ_apdu = -1;
275 static gint ett_atn_ulcs_T_aarq_apdu_protocol_version = -1;
276 static gint ett_atn_ulcs_AARE_apdu = -1;
277 static gint ett_atn_ulcs_T_aare_apdu_protocol_version = -1;
278 static gint ett_atn_ulcs_RLRQ_apdu = -1;
279 static gint ett_atn_ulcs_RLRE_apdu = -1;
280 static gint ett_atn_ulcs_ABRT_apdu = -1;
281 static gint ett_atn_ulcs_ACSE_requirements = -1;
282 static gint ett_atn_ulcs_Application_context_name_list = -1;
283 static gint ett_atn_ulcs_AP_title = -1;
284 static gint ett_atn_ulcs_AE_qualifier = -1;
285 static gint ett_atn_ulcs_Associate_source_diagnostic = -1;
286 static gint ett_atn_ulcs_Association_information = -1;
287 static gint ett_atn_ulcs_Authentication_value = -1;
288 static gint ett_atn_ulcs_T_other = -1;
289 static gint ett_atn_ulcs_Name = -1;
290 static gint ett_atn_ulcs_RDNSequence = -1;
291 static gint ett_atn_ulcs_RelativeDistinguishedName = -1;
292 static gint ett_atn_ulcs_AttributeTypeAndValue = -1;
293
294 /*--- End of included file: packet-atn-ulcs-ett.c ---*/
295 #line 180 "./asn1/atn-ulcs/packet-atn-ulcs-template.c"
296 static gint ett_atn_ulcs = -1;
297 static gint ett_atn_acse = -1;
298
299
300 /*--- Included file: packet-atn-ulcs-fn.c ---*/
301 #line 1 "./asn1/atn-ulcs/packet-atn-ulcs-fn.c"
302
303
304 static int
305 dissect_atn_ulcs_Transfer_syntax_name(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
306   offset = dissect_per_object_identifier(tvb, offset, actx, tree, hf_index, NULL);
307
308   return offset;
309 }
310
311
312 static const value_string atn_ulcs_Presentation_context_identifier_vals[] = {
313   {   1, "acse-apdu" },
314   {   2, "reserved" },
315   {   3, "user-ase-apdu" },
316   { 0, NULL }
317 };
318
319
320 static int
321 dissect_atn_ulcs_Presentation_context_identifier(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
322
323     offset = dissect_per_constrained_integer(
324         tvb,
325         offset,
326         actx,
327         tree,
328         hf_index,
329         1U,
330         127U,
331         &ulcs_context_value,
332         TRUE);
333
334
335   return offset;
336 }
337
338
339
340 static int
341 dissect_atn_ulcs_T_pdv_list_presentation_data_values_single_asn1_type(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
342   offset = dissect_per_open_type(tvb, offset, actx, tree, hf_index, NULL);
343
344   return offset;
345 }
346
347
348
349 static int
350 dissect_atn_ulcs_OCTET_STRING(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
351   offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
352                                        NO_BOUND, NO_BOUND, FALSE, NULL);
353
354   return offset;
355 }
356
357
358
359 static int
360 dissect_atn_ulcs_T_pdv_list_presentation_data_values_arbitrary(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
361
362     packet_info * pinfo = actx->pinfo;
363     tvbuff_t *tvb_usr = NULL;
364     proto_tree *atn_ulcs_tree = NULL;
365     atn_conversation_t *atn_cv = NULL;
366     heur_dtbl_entry_t *hdtbl_entry;
367
368     /* extract bitstring into new tvb buffer */
369     offset = dissect_per_bit_string(
370         tvb,
371         offset,
372         actx,
373         tree,
374         hf_index,
375         NO_BOUND,
376         NO_BOUND,
377         FALSE,
378         &tvb_usr,
379         NULL);
380
381     if (tvb_usr) {
382       /* call appropiate dissector for bitstring data */
383       switch(ulcs_context_value){
384           case  1: /* ACSE PDU*/
385               atn_ulcs_tree = proto_tree_add_subtree(
386                   root_tree, tvb, offset, 0,
387                   ett_atn_acse, NULL, ATN_ACSE_PROTO );
388
389               dissect_ACSE_apdu_PDU(
390                   tvb_new_subset_remaining(tvb_usr, 0),
391                   pinfo,
392                   atn_ulcs_tree, NULL);
393               break;
394             case  3: /* USER data; call subdissector for CM, CPDLC ...  */
395
396                 /* using dstref for PDV-list only occurrs in DT */
397                 atn_cv = find_atn_conversation(
398                     &pinfo->dst,
399                     pinfo->clnp_dstref,
400                     &pinfo->src);
401
402                 if(atn_cv) {
403                     switch(atn_cv->ae_qualifier){
404                         case cma: /* contact management */
405                             call_dissector_with_data(
406                                 atn_cm_handle,
407                                 tvb_new_subset_remaining(tvb_usr, 0),
408                                 pinfo,
409                                 root_tree,
410                                 NULL);
411                             break;
412                         case cpdlc: /* plain old cpdlc */
413                         case pmcpdlc: /* protected mode cpdlc */
414                             call_dissector_with_data(
415                                 atn_cpdlc_handle,
416                                 tvb_new_subset_remaining(tvb_usr, 0),
417                                 pinfo,
418                                 root_tree,
419                                 NULL);
420                             break;
421                         default: /* unknown or unhandled datalink application */
422                             dissector_try_heuristic(
423                                 atn_ulcs_heur_subdissector_list,
424                                 tvb_new_subset_remaining(tvb_usr,0),
425                                 actx->pinfo,
426                                 root_tree,
427                                 &hdtbl_entry,
428                                 NULL);
429                             break;
430                     }
431                 }
432                 else{
433                     dissector_try_heuristic(
434                         atn_ulcs_heur_subdissector_list,
435                         tvb_new_subset_remaining(tvb_usr,0),
436                         actx->pinfo,
437                         root_tree,
438                         &hdtbl_entry,
439                         NULL);
440                 }
441                 break;
442             default:
443                 break;
444       } /* switch(ulcs_context_value) */
445     }
446
447
448   return offset;
449 }
450
451
452 static const value_string atn_ulcs_T_presentation_data_values_vals[] = {
453   {   0, "single-ASN1-type" },
454   {   1, "octet-aligned" },
455   {   2, "arbitrary" },
456   { 0, NULL }
457 };
458
459 static const per_choice_t T_presentation_data_values_choice[] = {
460   {   0, &hf_atn_ulcs_pdv_list_presentation_data_values_single_asn1_type, ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_T_pdv_list_presentation_data_values_single_asn1_type },
461   {   1, &hf_atn_ulcs_octet_aligned, ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_OCTET_STRING },
462   {   2, &hf_atn_ulcs_pdv_list_presentation_data_values_arbitrary, ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_T_pdv_list_presentation_data_values_arbitrary },
463   { 0, NULL, 0, NULL }
464 };
465
466 static int
467 dissect_atn_ulcs_T_presentation_data_values(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
468   offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
469                                  ett_atn_ulcs_T_presentation_data_values, T_presentation_data_values_choice,
470                                  NULL);
471
472   return offset;
473 }
474
475
476 static const per_sequence_t PDV_list_sequence[] = {
477   { &hf_atn_ulcs_transfer_syntax_name, ASN1_NO_EXTENSIONS     , ASN1_OPTIONAL    , dissect_atn_ulcs_Transfer_syntax_name },
478   { &hf_atn_ulcs_presentation_context_identifier, ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_Presentation_context_identifier },
479   { &hf_atn_ulcs_presentation_data_values, ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_T_presentation_data_values },
480   { NULL, 0, 0, NULL }
481 };
482
483 static int
484 dissect_atn_ulcs_PDV_list(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
485   offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
486                                    ett_atn_ulcs_PDV_list, PDV_list_sequence);
487
488   return offset;
489 }
490
491
492 static const per_sequence_t Fully_encoded_data_sequence_of[1] = {
493   { &hf_atn_ulcs_Fully_encoded_data_item, ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_PDV_list },
494 };
495
496 static int
497 dissect_atn_ulcs_Fully_encoded_data(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
498   offset = dissect_per_constrained_sequence_of(tvb, offset, actx, tree, hf_index,
499                                                   ett_atn_ulcs_Fully_encoded_data, Fully_encoded_data_sequence_of,
500                                                   1, 1, TRUE);
501
502   return offset;
503 }
504
505
506
507 static int
508 dissect_atn_ulcs_OBJECT_IDENTIFIER(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
509   offset = dissect_per_object_identifier(tvb, offset, actx, tree, hf_index, NULL);
510
511   return offset;
512 }
513
514
515
516 static int
517 dissect_atn_ulcs_INTEGER(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
518   offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, NULL);
519
520   return offset;
521 }
522
523
524
525 static int
526 dissect_atn_ulcs_T_data_value_descriptor(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
527
528   offset = dissect_per_octet_string(
529       tvb,
530       offset,
531       actx,
532       tree,
533       hf_index,
534       -1,
535       -1,
536       FALSE,
537       &actx->external.data_value_descriptor);
538   actx->external.data_value_descr_present = TRUE;
539
540
541   return offset;
542 }
543
544
545
546 static int
547 dissect_atn_ulcs_T_externalt_encoding_single_asn1_type(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
548
549     offset = dissect_per_open_type(tvb, offset, actx, tree, hf_index, NULL);
550
551
552
553   return offset;
554 }
555
556
557
558 static int
559 dissect_atn_ulcs_T_externalt_encoding_octet_aligned(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
560
561     offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
562                                        NO_BOUND, NO_BOUND, FALSE, NULL);
563
564
565
566   return offset;
567 }
568
569
570
571 static int
572 dissect_atn_ulcs_T_externalt_encoding_arbitrary(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
573   tvbuff_t *tvb_usr = NULL;
574   packet_info * pinfo = actx->pinfo;
575   atn_conversation_t *atn_cv = NULL;
576   heur_dtbl_entry_t *hdtbl_entry;
577
578   /* decode bit-string user data within ACSE  */
579   offset = dissect_per_bit_string(
580     tvb,
581     offset,
582     actx,
583     tree, hf_index,
584     NO_BOUND,
585     NO_BOUND,
586     FALSE,
587     &tvb_usr,
588     NULL);
589
590   if (tvb_usr) {
591     /* DT: dstref present, srcref is always zero */
592     if((pinfo->clnp_dstref) && (!pinfo->clnp_srcref)){
593
594       atn_cv = find_atn_conversation(
595           &pinfo->dst,
596           pinfo->clnp_dstref,
597           &pinfo->src);
598     }
599     /* CR: srcref present, dstref always zero */
600     if((pinfo->clnp_srcref) && (!pinfo->clnp_dstref)){
601
602       atn_cv = find_atn_conversation(
603           &pinfo->src,
604           pinfo->clnp_srcref,
605           &pinfo->dst);
606     }
607     /* CC: srcref and dstref present */
608     if((pinfo->clnp_srcref) && (pinfo->clnp_dstref)){
609
610       atn_cv = find_atn_conversation(
611           &pinfo->src,
612           pinfo->clnp_srcref,
613           &pinfo->dst);
614     }
615
616     if(atn_cv) {
617         switch(atn_cv->ae_qualifier){
618           case cma: /* contact management */
619
620               call_dissector_with_data(
621                     atn_cm_handle,
622                     tvb_new_subset_remaining(tvb_usr, 0),
623                     pinfo,
624                     root_tree,
625                     NULL);
626               break;
627           case cpdlc: /* plain old cpdlc */
628           case pmcpdlc: /* protected mode cpdlc */
629
630               call_dissector_with_data(
631                     atn_cpdlc_handle,
632                     tvb_new_subset_remaining(tvb_usr, 0),
633                     pinfo,
634                     root_tree,
635                     NULL);
636               break;
637           default: /* unknown or unhandled datalink application */
638
639               dissector_try_heuristic(
640                   atn_ulcs_heur_subdissector_list,
641                   tvb_new_subset_remaining(tvb_usr,0),
642                   actx->pinfo,
643                   root_tree,
644                   &hdtbl_entry,
645                   NULL);
646                 break;
647           }
648     }else {
649
650       dissector_try_heuristic(
651               atn_ulcs_heur_subdissector_list,
652               tvb_new_subset_remaining(tvb_usr,0),
653               actx->pinfo,
654               root_tree,
655               &hdtbl_entry,
656               NULL);
657     }
658   }
659
660   offset += tvb_reported_length_remaining(tvb, offset);
661
662
663   return offset;
664 }
665
666
667 static const value_string atn_ulcs_T_encoding_vals[] = {
668   {   0, "single-ASN1-type" },
669   {   1, "octet-aligned" },
670   {   2, "arbitrary" },
671   { 0, NULL }
672 };
673
674 static const per_choice_t T_encoding_choice[] = {
675   {   0, &hf_atn_ulcs_externalt_encoding_single_asn1_type, ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_T_externalt_encoding_single_asn1_type },
676   {   1, &hf_atn_ulcs_externalt_encoding_octet_aligned, ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_T_externalt_encoding_octet_aligned },
677   {   2, &hf_atn_ulcs_externalt_encoding_arbitrary, ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_T_externalt_encoding_arbitrary },
678   { 0, NULL, 0, NULL }
679 };
680
681 static int
682 dissect_atn_ulcs_T_encoding(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
683   offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
684                                  ett_atn_ulcs_T_encoding, T_encoding_choice,
685                                  NULL);
686
687   return offset;
688 }
689
690
691 static const per_sequence_t EXTERNALt_sequence[] = {
692   { &hf_atn_ulcs_direct_reference, ASN1_NO_EXTENSIONS     , ASN1_OPTIONAL    , dissect_atn_ulcs_OBJECT_IDENTIFIER },
693   { &hf_atn_ulcs_indirect_reference, ASN1_NO_EXTENSIONS     , ASN1_OPTIONAL    , dissect_atn_ulcs_INTEGER },
694   { &hf_atn_ulcs_data_value_descriptor, ASN1_NO_EXTENSIONS     , ASN1_OPTIONAL    , dissect_atn_ulcs_T_data_value_descriptor },
695   { &hf_atn_ulcs_encoding   , ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_T_encoding },
696   { NULL, 0, 0, NULL }
697 };
698
699 static int
700 dissect_atn_ulcs_EXTERNALt(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
701   offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
702                                    ett_atn_ulcs_EXTERNALt, EXTERNALt_sequence);
703
704   return offset;
705 }
706
707
708
709 static int
710 dissect_atn_ulcs_T_aarq_apdu_protocol_version(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
711   offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
712                                      NO_BOUND, NO_BOUND, FALSE, NULL, NULL);
713
714   return offset;
715 }
716
717
718
719 static int
720 dissect_atn_ulcs_Application_context_name(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
721   offset = dissect_per_object_identifier(tvb, offset, actx, tree, hf_index, NULL);
722
723   return offset;
724 }
725
726
727
728 static int
729 dissect_atn_ulcs_AP_title_form2(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
730   offset = dissect_per_object_identifier(tvb, offset, actx, tree, hf_index, NULL);
731
732   return offset;
733 }
734
735
736
737 static int
738 dissect_atn_ulcs_NULL(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
739   offset = dissect_per_null(tvb, offset, actx, tree, hf_index);
740
741   return offset;
742 }
743
744
745 static const per_sequence_t AttributeTypeAndValue_sequence[] = {
746   { &hf_atn_ulcs_null       , ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_NULL },
747   { NULL, 0, 0, NULL }
748 };
749
750 static int
751 dissect_atn_ulcs_AttributeTypeAndValue(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
752   offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
753                                    ett_atn_ulcs_AttributeTypeAndValue, AttributeTypeAndValue_sequence);
754
755   return offset;
756 }
757
758
759 static const per_sequence_t RelativeDistinguishedName_set_of[1] = {
760   { &hf_atn_ulcs_RelativeDistinguishedName_item, ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_AttributeTypeAndValue },
761 };
762
763 static int
764 dissect_atn_ulcs_RelativeDistinguishedName(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
765   offset = dissect_per_constrained_set_of(tvb, offset, actx, tree, hf_index,
766                                              ett_atn_ulcs_RelativeDistinguishedName, RelativeDistinguishedName_set_of,
767                                              1, NO_BOUND, FALSE);
768
769   return offset;
770 }
771
772
773 static const per_sequence_t RDNSequence_sequence_of[1] = {
774   { &hf_atn_ulcs_RDNSequence_item, ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_RelativeDistinguishedName },
775 };
776
777 static int
778 dissect_atn_ulcs_RDNSequence(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
779   offset = dissect_per_sequence_of(tvb, offset, actx, tree, hf_index,
780                                       ett_atn_ulcs_RDNSequence, RDNSequence_sequence_of);
781
782   return offset;
783 }
784
785
786 static const value_string atn_ulcs_Name_vals[] = {
787   {   0, "rdnSequence" },
788   { 0, NULL }
789 };
790
791 static const per_choice_t Name_choice[] = {
792   {   0, &hf_atn_ulcs_rdnSequence, ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_RDNSequence },
793   { 0, NULL, 0, NULL }
794 };
795
796 static int
797 dissect_atn_ulcs_Name(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
798   offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
799                                  ett_atn_ulcs_Name, Name_choice,
800                                  NULL);
801
802   return offset;
803 }
804
805
806
807 static int
808 dissect_atn_ulcs_AP_title_form1(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
809   offset = dissect_atn_ulcs_Name(tvb, offset, actx, tree, hf_index);
810
811   return offset;
812 }
813
814
815 static const value_string atn_ulcs_AP_title_vals[] = {
816   {   0, "ap-title-form2" },
817   {   1, "ap-title-form1" },
818   { 0, NULL }
819 };
820
821 static const per_choice_t AP_title_choice[] = {
822   {   0, &hf_atn_ulcs_ap_title_form2, ASN1_EXTENSION_ROOT    , dissect_atn_ulcs_AP_title_form2 },
823   {   1, &hf_atn_ulcs_ap_title_form1, ASN1_EXTENSION_ROOT    , dissect_atn_ulcs_AP_title_form1 },
824   { 0, NULL, 0, NULL }
825 };
826
827 static int
828 dissect_atn_ulcs_AP_title(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
829   offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
830                                  ett_atn_ulcs_AP_title, AP_title_choice,
831                                  NULL);
832
833   return offset;
834 }
835
836
837
838 static int
839 dissect_atn_ulcs_AE_qualifier_form2(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
840     packet_info * pinfo = actx->pinfo;
841     atn_conversation_t *atn_cv = NULL;
842     guint32 ae_qualifier = 0;
843
844     /* dissect  ae-qualifier */
845     offset = dissect_per_integer(
846         tvb,
847         offset,
848         actx,
849         tree,
850         hf_index,
851         &ae_qualifier);
852
853
854     /*note: */
855     /* the field "calling-AE-qualifier" is optional, */
856     /* which means that we can exploit it only if it is present. */
857     /* We still depend on heuristical decoding of CM, CPDLC PDU's otherwise. */
858
859     /* AARQ/DT: dstref present, srcref is always zero */
860     if((pinfo->clnp_dstref) && (!pinfo->clnp_srcref)){
861         atn_cv = find_atn_conversation(&pinfo->dst,
862             pinfo->clnp_dstref,
863             &pinfo->src );
864     }
865
866     /* AARQ/CR: srcref present, dstref is always zero */
867     if((!pinfo->clnp_dstref) && (pinfo->clnp_srcref)){
868         atn_cv = find_atn_conversation(&pinfo->src,
869             pinfo->clnp_srcref,
870             &pinfo->dst );
871   }
872
873   if(atn_cv){
874       atn_cv->ae_qualifier = ae_qualifier;
875   }
876
877   return offset;
878 }
879
880
881
882 static int
883 dissect_atn_ulcs_AE_qualifier_form1(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
884   offset = dissect_atn_ulcs_RelativeDistinguishedName(tvb, offset, actx, tree, hf_index);
885
886   return offset;
887 }
888
889
890 static const value_string atn_ulcs_AE_qualifier_vals[] = {
891   {   0, "ae-qualifier-form2" },
892   {   1, "ae-qualifier-form1" },
893   { 0, NULL }
894 };
895
896 static const per_choice_t AE_qualifier_choice[] = {
897   {   0, &hf_atn_ulcs_ae_qualifier_form2, ASN1_EXTENSION_ROOT    , dissect_atn_ulcs_AE_qualifier_form2 },
898   {   1, &hf_atn_ulcs_ae_qualifier_form1, ASN1_EXTENSION_ROOT    , dissect_atn_ulcs_AE_qualifier_form1 },
899   { 0, NULL, 0, NULL }
900 };
901
902 static int
903 dissect_atn_ulcs_AE_qualifier(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
904   offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
905                                  ett_atn_ulcs_AE_qualifier, AE_qualifier_choice,
906                                  NULL);
907
908   return offset;
909 }
910
911
912
913 static int
914 dissect_atn_ulcs_AP_invocation_identifier(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
915   offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, NULL);
916
917   return offset;
918 }
919
920
921
922 static int
923 dissect_atn_ulcs_AE_invocation_identifier(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
924   offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, NULL);
925
926   return offset;
927 }
928
929
930
931 static int
932 dissect_atn_ulcs_ACSE_requirements(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
933   offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
934                                      NO_BOUND, NO_BOUND, FALSE, NULL, NULL);
935
936   return offset;
937 }
938
939
940
941 static int
942 dissect_atn_ulcs_Mechanism_name(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
943
944     offset = dissect_per_object_identifier(
945         tvb,
946         offset,
947         actx,
948         tree,
949         hf_index,
950         NULL);
951
952
953   offset = dissect_per_object_identifier(
954       tvb,
955       offset,
956       actx,
957       tree,
958       hf_index,
959       NULL);
960
961
962   return offset;
963 }
964
965
966
967 static int
968 dissect_atn_ulcs_BIT_STRING(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
969   offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
970                                      NO_BOUND, NO_BOUND, FALSE, NULL, NULL);
971
972   return offset;
973 }
974
975
976
977 static int
978 dissect_atn_ulcs_EXTERNAL(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
979   offset = dissect_per_external_type(tvb, offset, actx, tree, hf_index, NULL);
980
981   return offset;
982 }
983
984
985
986 static int
987 dissect_atn_ulcs_T_other_mechanism_value(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
988
989     offset=call_ber_oid_callback(
990         object_identifier_id,
991         tvb,
992         offset,
993         actx->pinfo,
994         tree, NULL);
995
996
997     offset=call_ber_oid_callback(
998         object_identifier_id,
999         tvb,
1000         offset,
1001         actx->pinfo,
1002         tree, NULL);
1003
1004
1005   return offset;
1006 }
1007
1008
1009 static const per_sequence_t T_other_sequence[] = {
1010   { &hf_atn_ulcs_other_mechanism_name, ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_OBJECT_IDENTIFIER },
1011   { &hf_atn_ulcs_other_mechanism_value, ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_T_other_mechanism_value },
1012   { NULL, 0, 0, NULL }
1013 };
1014
1015 static int
1016 dissect_atn_ulcs_T_other(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1017   offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
1018                                    ett_atn_ulcs_T_other, T_other_sequence);
1019
1020   return offset;
1021 }
1022
1023
1024 static const value_string atn_ulcs_Authentication_value_vals[] = {
1025   {   0, "charstring" },
1026   {   1, "bitstring" },
1027   {   2, "external" },
1028   {   3, "other" },
1029   { 0, NULL }
1030 };
1031
1032 static const per_choice_t Authentication_value_choice[] = {
1033   {   0, &hf_atn_ulcs_charstring , ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_OCTET_STRING },
1034   {   1, &hf_atn_ulcs_bitstring  , ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_BIT_STRING },
1035   {   2, &hf_atn_ulcs_external   , ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_EXTERNAL },
1036   {   3, &hf_atn_ulcs_other      , ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_T_other },
1037   { 0, NULL, 0, NULL }
1038 };
1039
1040 static int
1041 dissect_atn_ulcs_Authentication_value(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1042   offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
1043                                  ett_atn_ulcs_Authentication_value, Authentication_value_choice,
1044                                  NULL);
1045
1046   return offset;
1047 }
1048
1049
1050 static const per_sequence_t Application_context_name_list_sequence_of[1] = {
1051   { &hf_atn_ulcs_Application_context_name_list_item, ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_Application_context_name },
1052 };
1053
1054 static int
1055 dissect_atn_ulcs_Application_context_name_list(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1056   offset = dissect_per_sequence_of(tvb, offset, actx, tree, hf_index,
1057                                       ett_atn_ulcs_Application_context_name_list, Application_context_name_list_sequence_of);
1058
1059   return offset;
1060 }
1061
1062
1063
1064 static int
1065 dissect_atn_ulcs_Implementation_data(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1066   offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
1067                                        NO_BOUND, NO_BOUND, FALSE, NULL);
1068
1069   return offset;
1070 }
1071
1072
1073 static const per_sequence_t Association_information_sequence_of[1] = {
1074   { &hf_atn_ulcs_Association_information_item, ASN1_NO_EXTENSIONS     , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_EXTERNALt },
1075 };
1076
1077 static int
1078 dissect_atn_ulcs_Association_information(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1079   offset = dissect_per_constrained_sequence_of(tvb, offset, actx, tree, hf_index,
1080                                                   ett_atn_ulcs_Association_information, Association_information_sequence_of,
1081                                                   1, 1, TRUE);
1082
1083   return offset;
1084 }
1085
1086
1087 static const per_sequence_t AARQ_apdu_sequence[] = {
1088   { &hf_atn_ulcs_aarq_apdu_protocol_version, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_T_aarq_apdu_protocol_version },
1089   { &hf_atn_ulcs_application_context_name, ASN1_EXTENSION_ROOT    , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_Application_context_name },
1090   { &hf_atn_ulcs_called_AP_title, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AP_title },
1091   { &hf_atn_ulcs_called_AE_qualifier, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AE_qualifier },
1092   { &hf_atn_ulcs_called_AP_invocation_identifier, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AP_invocation_identifier },
1093   { &hf_atn_ulcs_called_AE_invocation_identifier, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AE_invocation_identifier },
1094   { &hf_atn_ulcs_calling_AP_title, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AP_title },
1095   { &hf_atn_ulcs_calling_AE_qualifier, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AE_qualifier },
1096   { &hf_atn_ulcs_calling_AP_invocation_identifier, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AP_invocation_identifier },
1097   { &hf_atn_ulcs_calling_AE_invocation_identifier, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AE_invocation_identifier },
1098   { &hf_atn_ulcs_sender_acse_requirements, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_ACSE_requirements },
1099   { &hf_atn_ulcs_mechanism_name, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Mechanism_name },
1100   { &hf_atn_ulcs_calling_authentication_value, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Authentication_value },
1101   { &hf_atn_ulcs_application_context_name_list, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Application_context_name_list },
1102   { &hf_atn_ulcs_implementation_information, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Implementation_data },
1103   { &hf_atn_ulcs_user_information, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Association_information },
1104   { NULL, 0, 0, NULL }
1105 };
1106
1107 static int
1108 dissect_atn_ulcs_AARQ_apdu(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1109     packet_info * pinfo = actx->pinfo;
1110     aarq_data_t *aarq_data = NULL;
1111     atn_conversation_t *atn_cv = NULL;
1112     guint32 aircraft_24_bit_address = 0;
1113
1114     /* AARQ/DT: dstref present, srcref is always zero */
1115     if((pinfo->clnp_dstref) && (!pinfo->clnp_srcref)){
1116
1117         atn_cv = find_atn_conversation(
1118             &pinfo->dst,
1119             pinfo->clnp_dstref,
1120             &pinfo->src );
1121         if(!atn_cv){
1122             atn_cv = wmem_new(wmem_file_scope(), atn_conversation_t);
1123             atn_cv->ae_qualifier = unknown;
1124             create_atn_conversation(&pinfo->dst,
1125                 pinfo->clnp_dstref,
1126                 &pinfo->src ,
1127                 atn_cv);
1128         }
1129     }
1130
1131   /* AARQ/CR: srcref present, dstref is always zero */
1132     if((!pinfo->clnp_dstref) && (pinfo->clnp_srcref)){
1133         atn_cv = find_atn_conversation(&pinfo->src,
1134             pinfo->clnp_srcref,
1135             &pinfo->dst );
1136         if(!atn_cv){
1137             atn_cv = wmem_new(wmem_file_scope(), atn_conversation_t);
1138             atn_cv->ae_qualifier = unknown;
1139             create_atn_conversation(&pinfo->src,
1140                 pinfo->clnp_srcref,
1141                 &pinfo->dst ,
1142                 atn_cv);
1143         }
1144     }
1145
1146     /* conversation is to be created prior to decoding */
1147     /* of "AE-qualifier-form2" which takes place here: */
1148       offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
1149                                    ett_atn_ulcs_AARQ_apdu, AARQ_apdu_sequence);
1150
1151
1152
1153     /* save AARQ packet data to create a conversation  */
1154     /* when decoding the following AARE PDU */
1155     /* ATN applications CM and CPDLC are air/ground applications */
1156     /* so there is always an aircraft (with its 24-bit address) */
1157     /* and a ground facility. */
1158     /* the assumption is that there is only one open AARQ/AARE */
1159     /* dialog per aircraft at a time. */
1160     /* the aircraft's 24-bit address is used as a key to each AARQ */
1161     /* data. AARQ data is used to create a conversation with */
1162     /* air and ground endpoints (based on NSAP's and transport references) */
1163     /* when decoding AARE.*/
1164     /* note: */
1165     /* it may be more robust to create the conversation */
1166     /* in the "ositp" dissector an to merely use the conversation here */
1167     aircraft_24_bit_address =
1168         get_aircraft_24_bit_address_from_nsap(pinfo);
1169
1170     /* search for aarq entry */
1171     aarq_data = (aarq_data_t *) wmem_tree_lookup32(
1172         aarq_data_tree,
1173         aircraft_24_bit_address);
1174
1175     if(!aarq_data){  /* aarq data not found, create new record */
1176
1177         /* alloc aarq data */
1178         aarq_data = wmem_new(wmem_file_scope(), aarq_data_t);
1179         aarq_data-> aarq_pending = FALSE;
1180
1181         /* insert aarq data */
1182         wmem_tree_insert32(aarq_data_tree ,aircraft_24_bit_address,(void*)aarq_data);
1183     }
1184
1185     /* check for pending AARQ/AARE sequences */
1186     /* if "aarq_data-> aarq_pending" is set this means that there is already one  */
1187     /* AARQ/AARE sequence pending (is unwise to overwrite AARE/AARQ) */
1188     if (aarq_data-> aarq_pending == FALSE ) {
1189
1190       /* init aarq data */
1191       memset(aarq_data,0,sizeof(aarq_data_t));
1192
1193       aarq_data->cv = atn_cv;
1194       aarq_data-> aarq_pending = TRUE;
1195     }
1196
1197
1198   return offset;
1199 }
1200
1201
1202
1203 static int
1204 dissect_atn_ulcs_T_aare_apdu_protocol_version(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1205   offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
1206                                      NO_BOUND, NO_BOUND, FALSE, NULL, NULL);
1207
1208   return offset;
1209 }
1210
1211
1212 static const value_string atn_ulcs_Associate_result_vals[] = {
1213   {   0, "accepted" },
1214   {   1, "rejected-permanent" },
1215   {   2, "rejected-transient" },
1216   { 0, NULL }
1217 };
1218
1219
1220 static int
1221 dissect_atn_ulcs_Associate_result(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1222  /* extension present: last param set to true. asn2wrs didn't take notice of that */
1223  offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index,
1224                                                             0U, 2U, NULL, TRUE);
1225
1226   return offset;
1227 }
1228
1229
1230 static const value_string atn_ulcs_T_acse_service_user_vals[] = {
1231   {   0, "null" },
1232   {   1, "no-reason-given" },
1233   {   2, "application-context-name-not-supported" },
1234   {   3, "calling-AP-title-not-recognized" },
1235   {   4, "calling-AP-invocation-identifier-not-recognized" },
1236   {   5, "calling-AE-qualifier-not-recognized" },
1237   {   6, "calling-AE-invocation-identifier-not-recognized" },
1238   {   7, "called-AP-title-not-recognized" },
1239   {   8, "called-AP-invocation-identifier-not-recognized" },
1240   {   9, "called-AE-qualifier-not-recognized" },
1241   {  10, "called-AE-invocation-identifier-not-recognized" },
1242   {  11, "authentication-mechanism-name-not-recognized" },
1243   {  12, "authentication-mechanism-name-required" },
1244   {  13, "authentication-failure" },
1245   {  14, "authentication-required" },
1246   { 0, NULL }
1247 };
1248
1249
1250 static int
1251 dissect_atn_ulcs_T_acse_service_user(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1252   offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index,
1253                                                             0U, 14U, NULL, TRUE);
1254
1255   return offset;
1256 }
1257
1258
1259 static const value_string atn_ulcs_T_acse_service_provider_vals[] = {
1260   {   0, "null" },
1261   {   1, "no-reason-given" },
1262   {   2, "no-common-acse-version" },
1263   { 0, NULL }
1264 };
1265
1266
1267 static int
1268 dissect_atn_ulcs_T_acse_service_provider(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1269   offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index,
1270                                                             0U, 2U, NULL, TRUE);
1271
1272   return offset;
1273 }
1274
1275
1276 static const value_string atn_ulcs_Associate_source_diagnostic_vals[] = {
1277   {   1, "acse-service-user" },
1278   {   2, "acse-service-provider" },
1279   { 0, NULL }
1280 };
1281
1282 static const per_choice_t Associate_source_diagnostic_choice[] = {
1283   {   1, &hf_atn_ulcs_acse_service_user, ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_T_acse_service_user },
1284   {   2, &hf_atn_ulcs_acse_service_provider, ASN1_NO_EXTENSIONS     , dissect_atn_ulcs_T_acse_service_provider },
1285   { 0, NULL, 0, NULL }
1286 };
1287
1288 static int
1289 dissect_atn_ulcs_Associate_source_diagnostic(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1290   offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
1291                                  ett_atn_ulcs_Associate_source_diagnostic, Associate_source_diagnostic_choice,
1292                                  NULL);
1293
1294   return offset;
1295 }
1296
1297
1298 static const per_sequence_t AARE_apdu_sequence[] = {
1299   { &hf_atn_ulcs_aare_apdu_protocol_version, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_T_aare_apdu_protocol_version },
1300   { &hf_atn_ulcs_application_context_name, ASN1_EXTENSION_ROOT    , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_Application_context_name },
1301   { &hf_atn_ulcs_result     , ASN1_EXTENSION_ROOT    , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_Associate_result },
1302   { &hf_atn_ulcs_result_source_diagnostic, ASN1_EXTENSION_ROOT    , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_Associate_source_diagnostic },
1303   { &hf_atn_ulcs_responding_AP_title, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AP_title },
1304   { &hf_atn_ulcs_responding_AE_qualifier, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AE_qualifier },
1305   { &hf_atn_ulcs_responding_AP_invocation_identifier, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AP_invocation_identifier },
1306   { &hf_atn_ulcs_responding_AE_invocation_identifier, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_AE_invocation_identifier },
1307   { &hf_atn_ulcs_responder_acse_requirements, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_ACSE_requirements },
1308   { &hf_atn_ulcs_mechanism_name, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Mechanism_name },
1309   { &hf_atn_ulcs_responding_authentication_value, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Authentication_value },
1310   { &hf_atn_ulcs_application_context_name_list, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Application_context_name_list },
1311   { &hf_atn_ulcs_implementation_information, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Implementation_data },
1312   { &hf_atn_ulcs_user_information, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Association_information },
1313   { NULL, 0, 0, NULL }
1314 };
1315
1316 static int
1317 dissect_atn_ulcs_AARE_apdu(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1318   packet_info * pinfo = actx->pinfo;
1319   guint32 aircraft_24_bit_address = 0 ;
1320   atn_conversation_t *atn_cv = NULL;
1321   aarq_data_t *aarq_data = NULL;
1322
1323   /* get AARQ data and use it to create a new conversation, */
1324   /* the conversation is used along with  */
1325   /* AARQ's "calling ae qualifier" to determine the */
1326   /* type of air/ground application of each subsequent frame.*/
1327   /* we use this information to invoke the correct application dissector. */
1328   /* note: */
1329   /* heuristical decoding of ASN1 will not work for all cases, */
1330   /* for there may be CM PDU's which will exactly look like CPDLC PDU'S */
1331
1332   /* get 24-bit icao address */
1333   aircraft_24_bit_address = get_aircraft_24_bit_address_from_nsap(pinfo);
1334
1335   /* search for aarq entry */
1336   aarq_data = (aarq_data_t *) wmem_tree_lookup32(
1337       aarq_data_tree,
1338       aircraft_24_bit_address);
1339
1340   /* no aarq data present, do nothing  */
1341   /* without both ends of the conversation and without */
1342   /* the "calling ae-qualifier there is no point in setting up "*/
1343   /* a conversation */
1344   if(!aarq_data) {
1345
1346     return offset;
1347   }
1348
1349   /* AARE/DT: dstref present, srcref is always zero */
1350   if((pinfo->clnp_dstref) && (!pinfo->clnp_srcref)){
1351
1352     atn_cv = find_atn_conversation(&pinfo->dst,
1353                           pinfo->clnp_dstref,
1354                           &pinfo->src );
1355
1356     if(!atn_cv){ /* conversation not fond */
1357
1358       /* DT has only dstref - create new conversation */
1359       create_atn_conversation(&pinfo->dst,
1360                               pinfo->clnp_dstref,
1361                               &pinfo->src ,
1362                               aarq_data->cv);
1363     }
1364   }
1365
1366   /* AARE/CC: srcref and dstref present  */
1367   if((pinfo->clnp_dstref) && (pinfo->clnp_srcref)){
1368
1369     atn_cv = find_atn_conversation(
1370         &pinfo->src,
1371         pinfo->clnp_srcref,
1372         &pinfo->dst);
1373
1374     if(atn_cv){ /* conversation found. */
1375
1376       /* create new conversation for dstref */
1377       create_atn_conversation(&pinfo->dst,
1378                               pinfo->clnp_dstref,
1379                               &pinfo->src ,
1380                               aarq_data->cv);
1381
1382     }else { /* no conversation found  */
1383       /* as CC contains srcref *and* dstref we use both to create new records  */
1384       create_atn_conversation(&pinfo->src,
1385                               pinfo->clnp_srcref,
1386                               &pinfo->dst ,
1387                               aarq_data->cv);
1388       create_atn_conversation(&pinfo->dst,
1389                               pinfo->clnp_dstref,
1390                               &pinfo->src ,
1391                               aarq_data->cv);
1392     }
1393   }
1394
1395   /* clear aarq data */
1396   memset(aarq_data,0,sizeof(aarq_data_t));
1397   aarq_data-> aarq_pending  =  FALSE;
1398
1399     offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
1400                                    ett_atn_ulcs_AARE_apdu, AARE_apdu_sequence);
1401
1402
1403
1404
1405   return offset;
1406 }
1407
1408
1409 static const value_string atn_ulcs_Release_request_reason_vals[] = {
1410   {   0, "normal" },
1411   {   1, "urgent" },
1412   {  30, "user-defined" },
1413   { 0, NULL }
1414 };
1415
1416
1417 static int
1418 dissect_atn_ulcs_Release_request_reason(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1419  /* extension present: last param set to true. asn2wrs didn't take notice of that */
1420  offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index,
1421                                                             0U, 30U, NULL, TRUE);
1422
1423   return offset;
1424 }
1425
1426
1427 static const per_sequence_t RLRQ_apdu_sequence[] = {
1428   { &hf_atn_ulcs_rlrq_apdu_request_reason, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Release_request_reason },
1429   { &hf_atn_ulcs_user_information, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Association_information },
1430   { NULL, 0, 0, NULL }
1431 };
1432
1433 static int
1434 dissect_atn_ulcs_RLRQ_apdu(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1435   offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
1436                                    ett_atn_ulcs_RLRQ_apdu, RLRQ_apdu_sequence);
1437
1438   return offset;
1439 }
1440
1441
1442 static const value_string atn_ulcs_Release_response_reason_vals[] = {
1443   {   0, "normal" },
1444   {   1, "not-finished" },
1445   {  30, "user-defined" },
1446   { 0, NULL }
1447 };
1448
1449
1450 static int
1451 dissect_atn_ulcs_Release_response_reason(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1452
1453  /* extension present: last param set to true. asn2wrs didn't take notice of that */
1454  offset = dissect_per_constrained_integer(
1455     tvb,
1456     offset,
1457     actx,
1458     tree,
1459     hf_index,
1460     0U,
1461     30U,
1462     NULL,
1463     TRUE);
1464
1465
1466   return offset;
1467 }
1468
1469
1470 static const per_sequence_t RLRE_apdu_sequence[] = {
1471   { &hf_atn_ulcs_rlre_apdu_response_reason, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Release_response_reason },
1472   { &hf_atn_ulcs_user_information, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Association_information },
1473   { NULL, 0, 0, NULL }
1474 };
1475
1476 static int
1477 dissect_atn_ulcs_RLRE_apdu(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1478   offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
1479                                    ett_atn_ulcs_RLRE_apdu, RLRE_apdu_sequence);
1480
1481   return offset;
1482 }
1483
1484
1485 static const value_string atn_ulcs_ABRT_source_vals[] = {
1486   {   0, "acse-service-user" },
1487   {   1, "acse-service-provider" },
1488   { 0, NULL }
1489 };
1490
1491
1492 static int
1493 dissect_atn_ulcs_ABRT_source(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1494   offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index,
1495                                                             0U, 1U, NULL, TRUE);
1496
1497   return offset;
1498 }
1499
1500
1501 static const value_string atn_ulcs_ABRT_diagnostic_vals[] = {
1502   {   1, "no-reason-given" },
1503   {   2, "protocol-error" },
1504   {   3, "authentication-mechanism-name-not-recognized" },
1505   {   4, "authentication-mechanism-name-required" },
1506   {   5, "authentication-failure" },
1507   {   6, "authentication-required" },
1508   { 0, NULL }
1509 };
1510
1511 static guint32 ABRT_diagnostic_value_map[6+0] = {1, 2, 3, 4, 5, 6};
1512
1513 static int
1514 dissect_atn_ulcs_ABRT_diagnostic(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1515   offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index,
1516                                      6, NULL, TRUE, 0, ABRT_diagnostic_value_map);
1517
1518   return offset;
1519 }
1520
1521
1522 static const per_sequence_t ABRT_apdu_sequence[] = {
1523   { &hf_atn_ulcs_abort_source, ASN1_EXTENSION_ROOT    , ASN1_NOT_OPTIONAL, dissect_atn_ulcs_ABRT_source },
1524   { &hf_atn_ulcs_abort_diagnostic, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_ABRT_diagnostic },
1525   { &hf_atn_ulcs_user_information, ASN1_EXTENSION_ROOT    , ASN1_OPTIONAL    , dissect_atn_ulcs_Association_information },
1526   { NULL, 0, 0, NULL }
1527 };
1528
1529 static int
1530 dissect_atn_ulcs_ABRT_apdu(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1531   offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
1532                                    ett_atn_ulcs_ABRT_apdu, ABRT_apdu_sequence);
1533
1534   return offset;
1535 }
1536
1537
1538 static const value_string atn_ulcs_ACSE_apdu_vals[] = {
1539   {   0, "aarq" },
1540   {   1, "aare" },
1541   {   2, "rlrq" },
1542   {   3, "rlre" },
1543   {   4, "abrt" },
1544   { 0, NULL }
1545 };
1546
1547 static const per_choice_t ACSE_apdu_choice[] = {
1548   {   0, &hf_atn_ulcs_aarq       , ASN1_EXTENSION_ROOT    , dissect_atn_ulcs_AARQ_apdu },
1549   {   1, &hf_atn_ulcs_aare       , ASN1_EXTENSION_ROOT    , dissect_atn_ulcs_AARE_apdu },
1550   {   2, &hf_atn_ulcs_rlrq       , ASN1_EXTENSION_ROOT    , dissect_atn_ulcs_RLRQ_apdu },
1551   {   3, &hf_atn_ulcs_rlre       , ASN1_EXTENSION_ROOT    , dissect_atn_ulcs_RLRE_apdu },
1552   {   4, &hf_atn_ulcs_abrt       , ASN1_EXTENSION_ROOT    , dissect_atn_ulcs_ABRT_apdu },
1553   { 0, NULL, 0, NULL }
1554 };
1555
1556 static int
1557 dissect_atn_ulcs_ACSE_apdu(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1558   offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
1559                                  ett_atn_ulcs_ACSE_apdu, ACSE_apdu_choice,
1560                                  NULL);
1561
1562   return offset;
1563 }
1564
1565 /*--- PDUs ---*/
1566
1567 static int dissect_Fully_encoded_data_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {
1568   int offset = 0;
1569   asn1_ctx_t asn1_ctx;
1570   asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, FALSE, pinfo);
1571   offset = dissect_atn_ulcs_Fully_encoded_data(tvb, offset, &asn1_ctx, tree, hf_atn_ulcs_Fully_encoded_data_PDU);
1572   offset += 7; offset >>= 3;
1573   return offset;
1574 }
1575 static int dissect_ACSE_apdu_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {
1576   int offset = 0;
1577   asn1_ctx_t asn1_ctx;
1578   asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, FALSE, pinfo);
1579   offset = dissect_atn_ulcs_ACSE_apdu(tvb, offset, &asn1_ctx, tree, hf_atn_ulcs_ACSE_apdu_PDU);
1580   offset += 7; offset >>= 3;
1581   return offset;
1582 }
1583
1584
1585 /*--- End of included file: packet-atn-ulcs-fn.c ---*/
1586 #line 184 "./asn1/atn-ulcs/packet-atn-ulcs-template.c"
1587
1588 #if 0
1589 /* re-implementing external data: packet-per.c */
1590 static const value_string per_External_encoding_vals[] = {
1591 {   0, "single-ASN1-type" },
1592 {   1, "octet-aligned" },
1593 {   2, "arbitrary" },
1594 { 0, NULL }
1595 };
1596
1597 /* re-implementing external data: packet-per.c */
1598 static const per_choice_t External_encoding_choice[] =
1599 {
1600     {   0,
1601         &hf_atn_ulcs_externalt_encoding_single_asn1_type,
1602         ASN1_NO_EXTENSIONS,
1603         dissect_atn_ulcs_T_externalt_encoding_single_asn1_type
1604     },
1605     {   1,
1606         &hf_atn_ulcs_externalt_encoding_octet_aligned,
1607         ASN1_NO_EXTENSIONS,
1608         dissect_atn_ulcs_T_externalt_encoding_octet_aligned
1609     },
1610     {   2,
1611         &hf_atn_ulcs_externalt_encoding_arbitrary,
1612         ASN1_NO_EXTENSIONS,
1613         dissect_atn_ulcs_T_externalt_encoding_arbitrary
1614     },
1615     {   0,
1616         NULL,
1617         0,
1618         NULL
1619     }
1620 };
1621 #endif
1622
1623 /* ATN Session layer */
1624 #define SES_PDU_TYPE_MASK     0xf8
1625 #define SES_PARAM_IND_MASK    0x04
1626 #define SES_PARAM_B2_MASK     0x02
1627 #define SES_PARAM_B1_MASK     0x01
1628
1629 static int hf_atn_ses_type = -1;
1630 static int hf_atn_ses_param_ind = -1;
1631 static int hf_atn_ses_param_b1 = -1;
1632 static int hf_atn_ses_param_b2 = -1;
1633
1634 static gint ett_atn_ses = -1;
1635
1636 #define ATN_SES_PROTO "ICAO Doc9705 ULCS Session (ISO 8326/8327-1:1994)"
1637
1638 const value_string atn_ses_param_ind[] =
1639 {
1640     {0, "No Parameter Indication "},
1641     {1, "Parameter Indication "},
1642     {0, NULL }
1643 };
1644
1645 const value_string srf_b2[] =
1646 {
1647     {0, "Transport Connection is kept"},
1648     {1, "Transport Connection is released" },
1649     {0, NULL }
1650 };
1651
1652 const value_string srf_b1[] =
1653 {
1654     {0, "Transport Connection is transient"},
1655     {1, "Transport Connection is persistent"},
1656     {0, NULL }
1657 };
1658
1659 #define SES_ATN_SCN       0xe8
1660 #define SES_ATN_SCNC      0xf8
1661 #define SES_ATN_SAC       0xf0
1662 #define SES_ATN_SACC      0xd8
1663 #define SES_ATN_SRF       0xe0
1664 #define SES_ATN_SRFC      0xa0
1665
1666 const value_string atn_ses_type[] =
1667 {
1668     { 0x1d, "Short Connect (SCN) SPDU" },
1669     { 0x1f, "Short Connect Accept (SAC) SPDU" },
1670     { 0x1e, "Short Connect Accept Continue (SACC) SPDU" },
1671     { 0x1c, "Short Refuse (SRF) SPDU" },
1672     { 0x14, "Short Refuse Continue (SRFC) SPDU" },
1673     {0, NULL }
1674 };
1675
1676 /* ATN Presentation layer */
1677 #define ATN_PRES_PROTO "ICAO Doc9705 ULCS Presentation (ISO 8822/8823-1:1994)"
1678
1679 static int hf_atn_pres_err   = -1;
1680 static int hf_atn_pres_pdu_type = -1;
1681 static gint ett_atn_pres    = -1;
1682
1683 #define ATN_SES_PRES_MASK 0xf803
1684 #define PRES_CPR_ER_MASK    0x70
1685
1686 /* type determined by SPDU and PPDU */
1687 const value_string atn_pres_vals[] =
1688 {
1689     { 0xe802, "Short Presentation Connect PPDU (CP) " },
1690     { 0xf802, "Short Presentation Connect PPDU (CP) " },
1691     { 0xf002, "Short Presentation Connect Accept PPDU (CPA)" },
1692     { 0xd802, "Short Presentation Connect Accept PPDU (CPA)" },
1693     { 0xe002, "Short Presentation Connect Reject PPDU (CPR)" },
1694     { 0xa002, "Short Presentation Connect Reject PPDU (CPR)" },
1695     {0,         NULL }
1696 };
1697
1698 /* Short Presentation Connect Reject PPDU's 0yyy 00zz */
1699 const value_string atn_pres_err[] =
1700 {
1701     { 0x00, "Presentation-user" },
1702     { 0x01, "Reason not specified (transient)"},
1703     { 0x02, "Temporary congestion (transient)"},
1704     { 0x03, "Local limit exceeded (transient)"},
1705     { 0x04, "Called presentation-address unknown (permanent)"},
1706     { 0x05, "Protocol version not supported (permanent)"},
1707     { 0x06, "Default context not supported (permanent)"},
1708     { 0x07, "User data not readable (permanent)"},
1709     { 0,          NULL }
1710 };
1711
1712 #if 0
1713 /* re-implementing external data: packet-per.c */
1714 static int  atn_ulcs_Externalt_encoding(
1715     tvbuff_t *tvb _U_,
1716     int offset _U_,
1717     asn1_ctx_t *actx _U_,
1718     proto_tree *tree _U_,
1719     int hf_index _U_)
1720 {
1721     offset = dissect_per_choice(
1722         tvb,
1723         offset,
1724         actx,
1725         tree,
1726         hf_index,
1727         ett_atn_ulcs_EXTERNALt,
1728         External_encoding_choice,
1729         &actx->external.encoding);
1730
1731     return offset;
1732 }
1733
1734 /* re-implementing external data: packet-per.c */
1735 static guint32  atn_per_external_type(
1736     tvbuff_t *tvb _U_,
1737     guint32 offset,
1738     asn1_ctx_t *actx,
1739     proto_tree *tree _U_,
1740     int hf_index _U_,
1741     per_type_fn type_cb)
1742 {
1743     memset(&actx->external, '\0', sizeof(actx->external));
1744     actx->external.hf_index = -1;
1745     actx->external.encoding = -1;
1746
1747     actx->external.u.per.type_cb = type_cb;
1748     offset = atn_ulcs_Externalt_encoding(
1749         tvb,
1750         offset,
1751         actx,
1752         tree,
1753         hf_index);
1754
1755     memset(
1756         &actx->external,
1757         '\0',
1758         sizeof(actx->external));
1759
1760     actx->external.hf_index = -1;
1761     actx->external.encoding = -1;
1762
1763     return offset;
1764 }
1765 #endif
1766
1767 /* determine 24-bit aircraft address(ARS) */
1768 /* from 20-byte ATN NSAP. */
1769 guint32 get_aircraft_24_bit_address_from_nsap(
1770     packet_info *pinfo)
1771 {
1772     const guint8* addr = NULL;
1773     guint32 ars =0;
1774     guint32 adr_prefix =0;
1775
1776     /* check NSAP address type*/
1777     if( (pinfo->src.type != get_osi_address_type()) ||
1778         (pinfo->dst.type != get_osi_address_type())) {
1779         return ars; }
1780
1781     /* 20 octets address length required */
1782     /* for ATN */
1783     if( (pinfo->src.len != 20) ||
1784         (pinfo->dst.len != 20)) {
1785         return ars; }
1786
1787     /* first try source address */
1788     /* if the src address originates */
1789     /* from an aircraft it's downlink */
1790
1791     /* convert addr into 32-bit integer */
1792     addr = (const guint8 *)pinfo->src.data;
1793     adr_prefix =
1794         ((addr[0]<<24) |
1795         (addr[1]<<16) |
1796         (addr[2]<<8) |
1797         addr[3] );
1798
1799     /* according to ICAO doc9507 Ed2 SV5  */
1800     /* clause 5.4.3.8.1.5 and  5.4.3.8.1.3 */
1801     /* mobile addresses contain "c1" of "41" */
1802     /* in the VER subfield of the NSAP */
1803     if((adr_prefix == 0x470027c1) ||
1804         (adr_prefix == 0x47002741)) {
1805       /* ICAO doc9507 Ed2 SV5 5.4.3.8.4.4 */
1806       /* states that the ARS subfield containes */
1807       /* the  24-bitaddress of the aircraft */
1808         ars = ((addr[8])<<16) |
1809             ((addr[9])<<8) |
1810             (addr[10]);
1811     }
1812
1813     /* try destination address */
1814     /* if the src address originates */
1815     /* from an aircraft it's downlink */
1816
1817     /* convert addr into 32-bit integer */
1818     addr = (const guint8 *)pinfo->dst.data;
1819     adr_prefix = ((addr[0]<<24) |
1820         (addr[1]<<16) |
1821         (addr[2]<<8) |
1822         addr[3] );
1823
1824     /* according to ICAO doc9507 Ed2 SV5  */
1825     /* clause 5.4.3.8.1.5 and  5.4.3.8.1.3 */
1826     /* mobile addresses contain "c1" of "41" */
1827     /* in the VER subfield of the NSAP */
1828     if((adr_prefix == 0x470027c1) ||
1829         (adr_prefix == 0x47002741)) {
1830       /* ICAO doc9507 Ed2 SV5 5.4.3.8.4.4 */
1831       /* states that the ARS subfield containes */
1832       /* the  24-bitaddress of the aircraft */
1833       ars = ((addr[8])<<16) |
1834             ((addr[9])<<8) |
1835             (addr[10]);
1836     }
1837     return ars;
1838 }
1839
1840 /* determine whether a PDU is uplink or downlink */
1841 /* by checking for known aircraft  address prefices*/
1842 int check_heur_msg_type(packet_info *pinfo  _U_)
1843 {
1844     int t = no_msg;
1845     const guint8* addr = NULL;
1846     guint32 adr_prefix =0;
1847
1848     /* check NSAP address type*/
1849     if( (pinfo->src.type != get_osi_address_type()) || (pinfo->dst.type != get_osi_address_type())) {
1850         return t; }
1851
1852     /* check NSAP address length; 20 octets address length required */
1853     if( (pinfo->src.len != 20) || (pinfo->dst.len != 20)) {
1854         return t; }
1855
1856     addr = (const guint8 *)pinfo->src.data;
1857
1858     /* convert address to 32-bit integer  */
1859     adr_prefix = ((addr[0]<<24) | (addr[1]<<16) | (addr[2]<<8) | addr[3] );
1860
1861     /* According to the published ATN NSAP adddressing scheme */
1862     /* in ICAO doc9705 Ed2 SV5 5.4.3.8.1.3 and 5.4.3.8.1.5  */
1863     /* the "VER" field shall be 0x41 ("all Mobile AINSC") or */
1864     /* 0xc1 ("all Mobile ATSC") for mobile stations (aka aircraft).*/
1865     if((adr_prefix == 0x470027c1) || (adr_prefix == 0x47002741)) {
1866         t = dm; /* source is an aircraft: it's a downlink PDU */
1867     }
1868
1869     addr = (const guint8 *)pinfo->dst.data;
1870
1871     /* convert address to 32-bit integer  */
1872     adr_prefix = ((addr[0]<<24) | (addr[1]<<16) | (addr[2]<<8) | addr[3] );
1873
1874     /* According to the published ATN NSAP adddressing scheme */
1875     /* in ICAO doc9705 Ed2 SV5 5.4.3.8.1.3 and 5.4.3.8.1.5  */
1876     /* the "VER" field shall be 0x41 ("all Mobile AINSC") or */
1877     /* 0xc1 ("all Mobile ATSC") for mobile stations (aka aircraft).*/
1878     if((adr_prefix == 0x470027c1) || (adr_prefix == 0x47002741)) {
1879         t = um; /* destination is aircraft: uplink PDU */
1880     }
1881
1882     return t;
1883 }
1884
1885 /* conversation may be used by other dissectors  */
1886 wmem_tree_t *get_atn_conversation_tree(void){
1887     return atn_conversation_tree;
1888 }
1889
1890
1891 /* find a atn conversation tree node by an endpoint  */
1892 /* an endpoint is identified by atn src and dst addresses */
1893 /* and srcref or dstref (depends on the transport packet type) */
1894 /* IMHO it's a hack - conversations should be maintained */
1895 /* at transport layer (cotp) but this isn't working yet. */
1896 atn_conversation_t * find_atn_conversation(
1897     address *address1,
1898     guint16 clnp_ref1,
1899     address *address2 )
1900 {
1901     atn_conversation_t *cv = NULL;
1902     guint32 key = 0;
1903     guint32 tmp = 0;
1904
1905     tmp = add_address_to_hash( tmp, address1);
1906     key = (tmp << 16) | clnp_ref1 ;
1907
1908     tmp = add_address_to_hash( tmp, address2);
1909     key = (tmp << 24) | key ;
1910
1911     /* search for atn conversation */
1912     cv = (atn_conversation_t *)
1913         wmem_tree_lookup32(get_atn_conversation_tree(),key);
1914
1915     return cv;
1916 }
1917
1918 /* create a atn conversation tree node  */
1919 /* conversation data is to be allocated externally */
1920 /* a conversation may be referenced from both endpoints */
1921 atn_conversation_t * create_atn_conversation(
1922     address *address1,
1923     guint16 clnp_ref1,
1924     address *address2,
1925     atn_conversation_t *conversation)
1926 {
1927     atn_conversation_t *cv = NULL;
1928     guint32 key = 0;
1929     guint32 tmp = 0;
1930
1931     tmp = add_address_to_hash( tmp, address1);
1932     key = (tmp << 16) | clnp_ref1 ;
1933
1934     tmp = add_address_to_hash( tmp, address2);
1935     key = (tmp << 24) | key ;
1936
1937     /* search for aircraft entry */
1938     cv = (atn_conversation_t *)
1939     wmem_tree_lookup32(
1940         get_atn_conversation_tree(),
1941         key);
1942
1943     /* tree node  already present  */
1944     if(cv) {
1945       return NULL; }
1946
1947     /* insert conversation data in tree*/
1948     wmem_tree_insert32(
1949         get_atn_conversation_tree(),
1950         key,
1951         (void*)conversation);
1952
1953     return conversation;
1954 }
1955
1956 static int
1957 dissect_atn_ulcs(
1958     tvbuff_t *tvb,
1959     packet_info *pinfo,
1960     proto_tree *tree,
1961     void *data _U_)
1962 {
1963     int offset = 0;
1964     proto_item *ti = NULL;
1965     proto_tree *atn_ulcs_tree = NULL;
1966     guint8 value_pres = 0;
1967     guint8 value_ses = 0;
1968     guint16 value_ses_pres = 0;
1969
1970     root_tree = tree;
1971
1972     /* data pointer */
1973     /* decode as PDV-list */
1974     if ( (int)(intptr_t)  data == FALSE )
1975     {
1976         ti = proto_tree_add_item(
1977             tree,
1978             proto_atn_ulcs,
1979             tvb,
1980             0,
1981             0 ,
1982             ENC_NA);
1983
1984         atn_ulcs_tree = proto_item_add_subtree(
1985             ti,
1986             ett_atn_ulcs);
1987
1988         dissect_Fully_encoded_data_PDU(
1989             tvb,
1990             pinfo,
1991             atn_ulcs_tree, NULL);
1992
1993         return offset +
1994           tvb_reported_length_remaining(tvb, offset ) ;
1995     }
1996
1997     /* decode as SPDU, PPDU and ACSE PDU */
1998     if ( (int)(intptr_t)  data == TRUE )
1999     {
2000         /* get session and presentation PDU's */
2001         value_ses_pres = tvb_get_ntohs(tvb, offset);
2002
2003         /* SPDU: dissect session layer */
2004         atn_ulcs_tree = proto_tree_add_subtree(
2005             tree, tvb, offset, 0,
2006             ett_atn_ses, NULL, ATN_SES_PROTO );
2007
2008         /* get SPDU (1 octet) */
2009         value_ses = tvb_get_guint8(tvb, offset);
2010
2011         /* SPDU type/identifier  */
2012         proto_tree_add_item(atn_ulcs_tree,
2013             hf_atn_ses_type,
2014             tvb,
2015             offset,
2016             1,
2017             ENC_BIG_ENDIAN );
2018
2019         /* SPDU parameters may be present in Short Refuse */
2020         /* or Short Refuse Continue SPDU's */
2021         switch(value_ses & SES_PDU_TYPE_MASK){
2022             case SES_ATN_SRF:
2023             case SES_ATN_SRFC:
2024
2025                 /* SPDU parameter presence */
2026                 proto_tree_add_item(atn_ulcs_tree,
2027                     hf_atn_ses_param_ind,
2028                     tvb,
2029                     offset,
2030                     1,
2031                     ENC_BIG_ENDIAN );
2032
2033                 /* parameter B2 */
2034                 proto_tree_add_item(atn_ulcs_tree,
2035                     hf_atn_ses_param_b2,
2036                     tvb,
2037                     offset,
2038                     1,
2039                     ENC_BIG_ENDIAN );
2040
2041                 /* parameter B1 */
2042                 proto_tree_add_item(atn_ulcs_tree,
2043                     hf_atn_ses_param_b1,
2044                     tvb,
2045                     offset,
2046                     1,
2047                     ENC_BIG_ENDIAN );
2048
2049               break;
2050             default:
2051               break;
2052         }
2053         offset++;
2054
2055         /* PPDU: dissect presentation layer */
2056         atn_ulcs_tree = proto_tree_add_subtree(
2057             tree, tvb, offset, 0,
2058             ett_atn_pres, NULL, ATN_PRES_PROTO );
2059
2060         value_pres = tvb_get_guint8(tvb, offset);
2061
2062         /* need session context to identify PPDU type */
2063         /* note: */
2064         proto_tree_add_uint_format(atn_ulcs_tree, hf_atn_pres_pdu_type,
2065             tvb,
2066             offset,
2067             1,
2068             value_ses_pres,
2069             "%s (0x%02x)",
2070             val_to_str( value_ses_pres & ATN_SES_PRES_MASK , atn_pres_vals, "?"),
2071             value_pres);
2072
2073         /* PPDU errorcode in case of SRF/CPR */
2074         switch(value_ses & SES_PDU_TYPE_MASK){
2075             case SES_ATN_SRF:
2076             case SES_ATN_SRFC:
2077                 proto_tree_add_item(
2078                     atn_ulcs_tree,
2079                     hf_atn_pres_err,
2080                     tvb,
2081                     offset,
2082                     1,
2083                     ENC_BIG_ENDIAN );
2084                 break;
2085             default:
2086                 break;
2087         }
2088
2089         offset++;
2090
2091         /* ACSE PDU: dissect application layer */
2092         atn_ulcs_tree = proto_tree_add_subtree(
2093             tree, tvb, offset, 0,
2094             ett_atn_acse, NULL, ATN_ACSE_PROTO );
2095
2096         dissect_ACSE_apdu_PDU(
2097             tvb_new_subset_remaining(tvb, offset),
2098             pinfo,
2099             atn_ulcs_tree, NULL);
2100
2101         return offset +
2102             tvb_reported_length_remaining(tvb, offset );
2103     }
2104     return offset;
2105 }
2106
2107 static gboolean dissect_atn_ulcs_heur(
2108     tvbuff_t *tvb,
2109     packet_info *pinfo,
2110     proto_tree *tree,
2111     void *data _U_)
2112 {
2113     /* do we have enough data*/
2114     /* at least session + presentation data or pdv-list */
2115     if (tvb_captured_length(tvb) < 2){
2116         return FALSE; }
2117
2118     /* check for session/presentation/ACSE PDU's  */
2119     /* SPDU and PPDU are one octet each */
2120     switch( tvb_get_ntohs(tvb, 0) & 0xf8ff ){
2121         case 0xe802: /* SCN + CP*/
2122         case 0xf802: /* SCNC + CP */
2123         case 0xf002: /* SAC + CPA */
2124         case 0xd802: /* SACC + CPA */
2125         case 0xe002: /* SRF + CPR + R0 */
2126         case 0xe012: /* SRF + CPR + R1 */
2127         case 0xe022: /* SRF + CPR + R2 */
2128         case 0xe032: /* SRF + CPR + R3 */
2129         case 0xe042: /* SRF + CPR + R4 */
2130         case 0xe052: /* SRF + CPR + R5 */
2131         case 0xe062: /* SRF + CPR + R6 */
2132         case 0xe072: /* SRF + CPR + R7 */
2133         case 0xa002: /* SRFC + CPR + R0*/
2134         case 0xa012: /* SRFC + CPR + R1*/
2135         case 0xa022: /* SRFC + CPR + R2*/
2136         case 0xa032: /* SRFC + CPR + R3*/
2137         case 0xa042: /* SRFC + CPR + R4*/
2138         case 0xa052: /* SRFC + CPR + R5*/
2139         case 0xa062: /* SRFC + CPR + R6*/
2140         case 0xa072: /* SRFC + CPR + R7*/
2141             /* indicate to dissector routine */
2142             /* that a least SPDU, PPDU and */
2143             /* ACSE PDU is present */
2144             dissect_atn_ulcs(
2145                 tvb,
2146                 pinfo,
2147                 tree,
2148                 (void*) TRUE);
2149             return TRUE;
2150         default:  /* no SPDU */
2151             break;
2152     }
2153
2154     /* try to detect "Fully-encoded-data" heuristically */
2155     /* the constants listed match the ASN.1 PER encoding */
2156     /* of PDV-List */
2157     switch(  tvb_get_ntohs(tvb, 0) & 0xfff0 ){
2158         case 0x0020: /* acse-apdu */
2159         case 0x00a0: /* user-ase-apdu */
2160         /* indicate to dissector routine */
2161         /* that a PDV-list PDU is present */
2162         /*  */
2163         /* PDV-list PDU may contain */
2164         /* application protocol data (CM, CPDLC) */
2165         /* or an ACSE PDU */
2166             dissect_atn_ulcs(tvb, pinfo, tree, (void*) FALSE);
2167             return TRUE;
2168             break;
2169         default:  /* no or unsupported PDU */
2170             break;
2171     }
2172     return FALSE;
2173 }
2174
2175 void proto_register_atn_ulcs (void)
2176 {
2177     static hf_register_info hf_atn_ulcs[] = {
2178
2179 /*--- Included file: packet-atn-ulcs-hfarr.c ---*/
2180 #line 1 "./asn1/atn-ulcs/packet-atn-ulcs-hfarr.c"
2181     { &hf_atn_ulcs_Fully_encoded_data_PDU,
2182       { "Fully-encoded-data", "atn-ulcs.Fully_encoded_data",
2183         FT_UINT32, BASE_DEC, NULL, 0,
2184         NULL, HFILL }},
2185     { &hf_atn_ulcs_ACSE_apdu_PDU,
2186       { "ACSE-apdu", "atn-ulcs.ACSE_apdu",
2187         FT_UINT32, BASE_DEC, VALS(atn_ulcs_ACSE_apdu_vals), 0,
2188         NULL, HFILL }},
2189     { &hf_atn_ulcs_Fully_encoded_data_item,
2190       { "PDV-list", "atn-ulcs.PDV_list_element",
2191         FT_NONE, BASE_NONE, NULL, 0,
2192         NULL, HFILL }},
2193     { &hf_atn_ulcs_transfer_syntax_name,
2194       { "transfer-syntax-name", "atn-ulcs.transfer_syntax_name",
2195         FT_OID, BASE_NONE, NULL, 0,
2196         NULL, HFILL }},
2197     { &hf_atn_ulcs_presentation_context_identifier,
2198       { "presentation-context-identifier", "atn-ulcs.presentation_context_identifier",
2199         FT_UINT32, BASE_DEC, VALS(atn_ulcs_Presentation_context_identifier_vals), 0,
2200         NULL, HFILL }},
2201     { &hf_atn_ulcs_presentation_data_values,
2202       { "presentation-data-values", "atn-ulcs.presentation_data_values",
2203         FT_UINT32, BASE_DEC, VALS(atn_ulcs_T_presentation_data_values_vals), 0,
2204         NULL, HFILL }},
2205     { &hf_atn_ulcs_pdv_list_presentation_data_values_single_asn1_type,
2206       { "single-ASN1-type", "atn-ulcs.single_ASN1_type_element",
2207         FT_NONE, BASE_NONE, NULL, 0,
2208         "T_pdv_list_presentation_data_values_single_asn1_type", HFILL }},
2209     { &hf_atn_ulcs_octet_aligned,
2210       { "octet-aligned", "atn-ulcs.octet_aligned",
2211         FT_BYTES, BASE_NONE, NULL, 0,
2212         "OCTET_STRING", HFILL }},
2213     { &hf_atn_ulcs_pdv_list_presentation_data_values_arbitrary,
2214       { "arbitrary", "atn-ulcs.arbitrary",
2215         FT_BYTES, BASE_NONE, NULL, 0,
2216         "T_pdv_list_presentation_data_values_arbitrary", HFILL }},
2217     { &hf_atn_ulcs_direct_reference,
2218       { "direct-reference", "atn-ulcs.direct_reference",
2219         FT_OID, BASE_NONE, NULL, 0,
2220         "OBJECT_IDENTIFIER", HFILL }},
2221     { &hf_atn_ulcs_indirect_reference,
2222       { "indirect-reference", "atn-ulcs.indirect_reference",
2223         FT_INT32, BASE_DEC, NULL, 0,
2224         "INTEGER", HFILL }},
2225     { &hf_atn_ulcs_data_value_descriptor,
2226       { "data-value-descriptor", "atn-ulcs.data_value_descriptor",
2227         FT_STRING, BASE_NONE, NULL, 0,
2228         NULL, HFILL }},
2229     { &hf_atn_ulcs_encoding,
2230       { "encoding", "atn-ulcs.encoding",
2231         FT_UINT32, BASE_DEC, VALS(atn_ulcs_T_encoding_vals), 0,
2232         NULL, HFILL }},
2233     { &hf_atn_ulcs_externalt_encoding_single_asn1_type,
2234       { "single-ASN1-type", "atn-ulcs.single_ASN1_type_element",
2235         FT_NONE, BASE_NONE, NULL, 0,
2236         "T_externalt_encoding_single_asn1_type", HFILL }},
2237     { &hf_atn_ulcs_externalt_encoding_octet_aligned,
2238       { "octet-aligned", "atn-ulcs.octet_aligned",
2239         FT_BYTES, BASE_NONE, NULL, 0,
2240         "T_externalt_encoding_octet_aligned", HFILL }},
2241     { &hf_atn_ulcs_externalt_encoding_arbitrary,
2242       { "arbitrary", "atn-ulcs.arbitrary",
2243         FT_BYTES, BASE_NONE, NULL, 0,
2244         "T_externalt_encoding_arbitrary", HFILL }},
2245     { &hf_atn_ulcs_aarq,
2246       { "aarq", "atn-ulcs.aarq_element",
2247         FT_NONE, BASE_NONE, NULL, 0,
2248         "AARQ_apdu", HFILL }},
2249     { &hf_atn_ulcs_aare,
2250       { "aare", "atn-ulcs.aare_element",
2251         FT_NONE, BASE_NONE, NULL, 0,
2252         "AARE_apdu", HFILL }},
2253     { &hf_atn_ulcs_rlrq,
2254       { "rlrq", "atn-ulcs.rlrq_element",
2255         FT_NONE, BASE_NONE, NULL, 0,
2256         "RLRQ_apdu", HFILL }},
2257     { &hf_atn_ulcs_rlre,
2258       { "rlre", "atn-ulcs.rlre_element",
2259         FT_NONE, BASE_NONE, NULL, 0,
2260         "RLRE_apdu", HFILL }},
2261     { &hf_atn_ulcs_abrt,
2262       { "abrt", "atn-ulcs.abrt_element",
2263         FT_NONE, BASE_NONE, NULL, 0,
2264         "ABRT_apdu", HFILL }},
2265     { &hf_atn_ulcs_aarq_apdu_protocol_version,
2266       { "protocol-version", "atn-ulcs.protocol_version",
2267         FT_BYTES, BASE_NONE, NULL, 0,
2268         "T_aarq_apdu_protocol_version", HFILL }},
2269     { &hf_atn_ulcs_application_context_name,
2270       { "application-context-name", "atn-ulcs.application_context_name",
2271         FT_OID, BASE_NONE, NULL, 0,
2272         NULL, HFILL }},
2273     { &hf_atn_ulcs_called_AP_title,
2274       { "called-AP-title", "atn-ulcs.called_AP_title",
2275         FT_UINT32, BASE_DEC, VALS(atn_ulcs_AP_title_vals), 0,
2276         "AP_title", HFILL }},
2277     { &hf_atn_ulcs_called_AE_qualifier,
2278       { "called-AE-qualifier", "atn-ulcs.called_AE_qualifier",
2279         FT_UINT32, BASE_DEC, VALS(atn_ulcs_AE_qualifier_vals), 0,
2280         "AE_qualifier", HFILL }},
2281     { &hf_atn_ulcs_called_AP_invocation_identifier,
2282       { "called-AP-invocation-identifier", "atn-ulcs.called_AP_invocation_identifier",
2283         FT_INT32, BASE_DEC, NULL, 0,
2284         "AP_invocation_identifier", HFILL }},
2285     { &hf_atn_ulcs_called_AE_invocation_identifier,
2286       { "called-AE-invocation-identifier", "atn-ulcs.called_AE_invocation_identifier",
2287         FT_INT32, BASE_DEC, NULL, 0,
2288         "AE_invocation_identifier", HFILL }},
2289     { &hf_atn_ulcs_calling_AP_title,
2290       { "calling-AP-title", "atn-ulcs.calling_AP_title",
2291         FT_UINT32, BASE_DEC, VALS(atn_ulcs_AP_title_vals), 0,
2292         "AP_title", HFILL }},
2293     { &hf_atn_ulcs_calling_AE_qualifier,
2294       { "calling-AE-qualifier", "atn-ulcs.calling_AE_qualifier",
2295         FT_UINT32, BASE_DEC, VALS(atn_ulcs_AE_qualifier_vals), 0,
2296         "AE_qualifier", HFILL }},
2297     { &hf_atn_ulcs_calling_AP_invocation_identifier,
2298       { "calling-AP-invocation-identifier", "atn-ulcs.calling_AP_invocation_identifier",
2299         FT_INT32, BASE_DEC, NULL, 0,
2300         "AP_invocation_identifier", HFILL }},
2301     { &hf_atn_ulcs_calling_AE_invocation_identifier,
2302       { "calling-AE-invocation-identifier", "atn-ulcs.calling_AE_invocation_identifier",
2303         FT_INT32, BASE_DEC, NULL, 0,
2304         "AE_invocation_identifier", HFILL }},
2305     { &hf_atn_ulcs_sender_acse_requirements,
2306       { "sender-acse-requirements", "atn-ulcs.sender_acse_requirements",
2307         FT_BYTES, BASE_NONE, NULL, 0,
2308         "ACSE_requirements", HFILL }},
2309     { &hf_atn_ulcs_mechanism_name,
2310       { "mechanism-name", "atn-ulcs.mechanism_name",
2311         FT_OID, BASE_NONE, NULL, 0,
2312         NULL, HFILL }},
2313     { &hf_atn_ulcs_calling_authentication_value,
2314       { "calling-authentication-value", "atn-ulcs.calling_authentication_value",
2315         FT_UINT32, BASE_DEC, VALS(atn_ulcs_Authentication_value_vals), 0,
2316         "Authentication_value", HFILL }},
2317     { &hf_atn_ulcs_application_context_name_list,
2318       { "application-context-name-list", "atn-ulcs.application_context_name_list",
2319         FT_UINT32, BASE_DEC, NULL, 0,
2320         NULL, HFILL }},
2321     { &hf_atn_ulcs_implementation_information,
2322       { "implementation-information", "atn-ulcs.implementation_information",
2323         FT_BYTES, BASE_NONE, NULL, 0,
2324         "Implementation_data", HFILL }},
2325     { &hf_atn_ulcs_user_information,
2326       { "user-information", "atn-ulcs.user_information",
2327         FT_UINT32, BASE_DEC, NULL, 0,
2328         "Association_information", HFILL }},
2329     { &hf_atn_ulcs_aare_apdu_protocol_version,
2330       { "protocol-version", "atn-ulcs.protocol_version",
2331         FT_BYTES, BASE_NONE, NULL, 0,
2332         "T_aare_apdu_protocol_version", HFILL }},
2333     { &hf_atn_ulcs_result,
2334       { "result", "atn-ulcs.result",
2335         FT_UINT32, BASE_DEC, VALS(atn_ulcs_Associate_result_vals), 0,
2336         "Associate_result", HFILL }},
2337     { &hf_atn_ulcs_result_source_diagnostic,
2338       { "result-source-diagnostic", "atn-ulcs.result_source_diagnostic",
2339         FT_UINT32, BASE_DEC, VALS(atn_ulcs_Associate_source_diagnostic_vals), 0,
2340         "Associate_source_diagnostic", HFILL }},
2341     { &hf_atn_ulcs_responding_AP_title,
2342       { "responding-AP-title", "atn-ulcs.responding_AP_title",
2343         FT_UINT32, BASE_DEC, VALS(atn_ulcs_AP_title_vals), 0,
2344         "AP_title", HFILL }},
2345     { &hf_atn_ulcs_responding_AE_qualifier,
2346       { "responding-AE-qualifier", "atn-ulcs.responding_AE_qualifier",
2347         FT_UINT32, BASE_DEC, VALS(atn_ulcs_AE_qualifier_vals), 0,
2348         "AE_qualifier", HFILL }},
2349     { &hf_atn_ulcs_responding_AP_invocation_identifier,
2350       { "responding-AP-invocation-identifier", "atn-ulcs.responding_AP_invocation_identifier",
2351         FT_INT32, BASE_DEC, NULL, 0,
2352         "AP_invocation_identifier", HFILL }},
2353     { &hf_atn_ulcs_responding_AE_invocation_identifier,
2354       { "responding-AE-invocation-identifier", "atn-ulcs.responding_AE_invocation_identifier",
2355         FT_INT32, BASE_DEC, NULL, 0,
2356         "AE_invocation_identifier", HFILL }},
2357     { &hf_atn_ulcs_responder_acse_requirements,
2358       { "responder-acse-requirements", "atn-ulcs.responder_acse_requirements",
2359         FT_BYTES, BASE_NONE, NULL, 0,
2360         "ACSE_requirements", HFILL }},
2361     { &hf_atn_ulcs_responding_authentication_value,
2362       { "responding-authentication-value", "atn-ulcs.responding_authentication_value",
2363         FT_UINT32, BASE_DEC, VALS(atn_ulcs_Authentication_value_vals), 0,
2364         "Authentication_value", HFILL }},
2365     { &hf_atn_ulcs_rlrq_apdu_request_reason,
2366       { "reason", "atn-ulcs.reason",
2367         FT_UINT32, BASE_DEC, VALS(atn_ulcs_Release_request_reason_vals), 0,
2368         "Release_request_reason", HFILL }},
2369     { &hf_atn_ulcs_rlre_apdu_response_reason,
2370       { "reason", "atn-ulcs.reason",
2371         FT_UINT32, BASE_DEC, VALS(atn_ulcs_Release_response_reason_vals), 0,
2372         "Release_response_reason", HFILL }},
2373     { &hf_atn_ulcs_abort_source,
2374       { "abort-source", "atn-ulcs.abort_source",
2375         FT_UINT32, BASE_DEC, VALS(atn_ulcs_ABRT_source_vals), 0,
2376         "ABRT_source", HFILL }},
2377     { &hf_atn_ulcs_abort_diagnostic,
2378       { "abort-diagnostic", "atn-ulcs.abort_diagnostic",
2379         FT_UINT32, BASE_DEC, VALS(atn_ulcs_ABRT_diagnostic_vals), 0,
2380         "ABRT_diagnostic", HFILL }},
2381     { &hf_atn_ulcs_Application_context_name_list_item,
2382       { "Application-context-name", "atn-ulcs.Application_context_name",
2383         FT_OID, BASE_NONE, NULL, 0,
2384         NULL, HFILL }},
2385     { &hf_atn_ulcs_ap_title_form2,
2386       { "ap-title-form2", "atn-ulcs.ap_title_form2",
2387         FT_OID, BASE_NONE, NULL, 0,
2388         NULL, HFILL }},
2389     { &hf_atn_ulcs_ap_title_form1,
2390       { "ap-title-form1", "atn-ulcs.ap_title_form1",
2391         FT_UINT32, BASE_DEC, VALS(atn_ulcs_Name_vals), 0,
2392         NULL, HFILL }},
2393     { &hf_atn_ulcs_ae_qualifier_form2,
2394       { "ae-qualifier-form2", "atn-ulcs.ae_qualifier_form2",
2395         FT_INT32, BASE_DEC, NULL, 0,
2396         NULL, HFILL }},
2397     { &hf_atn_ulcs_ae_qualifier_form1,
2398       { "ae-qualifier-form1", "atn-ulcs.ae_qualifier_form1",
2399         FT_UINT32, BASE_DEC, NULL, 0,
2400         NULL, HFILL }},
2401     { &hf_atn_ulcs_acse_service_user,
2402       { "acse-service-user", "atn-ulcs.acse_service_user",
2403         FT_UINT32, BASE_DEC, VALS(atn_ulcs_T_acse_service_user_vals), 0,
2404         NULL, HFILL }},
2405     { &hf_atn_ulcs_acse_service_provider,
2406       { "acse-service-provider", "atn-ulcs.acse_service_provider",
2407         FT_UINT32, BASE_DEC, VALS(atn_ulcs_T_acse_service_provider_vals), 0,
2408         NULL, HFILL }},
2409     { &hf_atn_ulcs_Association_information_item,
2410       { "EXTERNALt", "atn-ulcs.EXTERNALt_element",
2411         FT_NONE, BASE_NONE, NULL, 0,
2412         NULL, HFILL }},
2413     { &hf_atn_ulcs_charstring,
2414       { "charstring", "atn-ulcs.charstring",
2415         FT_BYTES, BASE_NONE, NULL, 0,
2416         "OCTET_STRING", HFILL }},
2417     { &hf_atn_ulcs_bitstring,
2418       { "bitstring", "atn-ulcs.bitstring",
2419         FT_BYTES, BASE_NONE, NULL, 0,
2420         "BIT_STRING", HFILL }},
2421     { &hf_atn_ulcs_external,
2422       { "external", "atn-ulcs.external_element",
2423         FT_NONE, BASE_NONE, NULL, 0,
2424         NULL, HFILL }},
2425     { &hf_atn_ulcs_other,
2426       { "other", "atn-ulcs.other_element",
2427         FT_NONE, BASE_NONE, NULL, 0,
2428         NULL, HFILL }},
2429     { &hf_atn_ulcs_other_mechanism_name,
2430       { "other-mechanism-name", "atn-ulcs.other_mechanism_name",
2431         FT_OID, BASE_NONE, NULL, 0,
2432         "OBJECT_IDENTIFIER", HFILL }},
2433     { &hf_atn_ulcs_other_mechanism_value,
2434       { "other-mechanism-value", "atn-ulcs.other_mechanism_value_element",
2435         FT_NONE, BASE_NONE, NULL, 0,
2436         NULL, HFILL }},
2437     { &hf_atn_ulcs_rdnSequence,
2438       { "rdnSequence", "atn-ulcs.rdnSequence",
2439         FT_UINT32, BASE_DEC, NULL, 0,
2440         NULL, HFILL }},
2441     { &hf_atn_ulcs_RDNSequence_item,
2442       { "RelativeDistinguishedName", "atn-ulcs.RelativeDistinguishedName",
2443         FT_UINT32, BASE_DEC, NULL, 0,
2444         NULL, HFILL }},
2445     { &hf_atn_ulcs_RelativeDistinguishedName_item,
2446       { "AttributeTypeAndValue", "atn-ulcs.AttributeTypeAndValue_element",
2447         FT_NONE, BASE_NONE, NULL, 0,
2448         NULL, HFILL }},
2449     { &hf_atn_ulcs_null,
2450       { "null", "atn-ulcs.null_element",
2451         FT_NONE, BASE_NONE, NULL, 0,
2452         NULL, HFILL }},
2453     { &hf_atn_ulcs_T_aarq_apdu_protocol_version_version1,
2454       { "version1", "atn-ulcs.version1",
2455         FT_BOOLEAN, 8, NULL, 0x80,
2456         NULL, HFILL }},
2457     { &hf_atn_ulcs_T_aare_apdu_protocol_version_version1,
2458       { "version1", "atn-ulcs.version1",
2459         FT_BOOLEAN, 8, NULL, 0x80,
2460         NULL, HFILL }},
2461     { &hf_atn_ulcs_ACSE_requirements_authentication,
2462       { "authentication", "atn-ulcs.authentication",
2463         FT_BOOLEAN, 8, NULL, 0x80,
2464         NULL, HFILL }},
2465     { &hf_atn_ulcs_ACSE_requirements_application_context_negotiation,
2466       { "application-context-negotiation", "atn-ulcs.application-context-negotiation",
2467         FT_BOOLEAN, 8, NULL, 0x40,
2468         NULL, HFILL }},
2469
2470 /*--- End of included file: packet-atn-ulcs-hfarr.c ---*/
2471 #line 776 "./asn1/atn-ulcs/packet-atn-ulcs-template.c"
2472         {&hf_atn_ses_type,
2473         { "SPDU Type",
2474           "atn-ulcs.ses.type",
2475           FT_UINT8,
2476           BASE_HEX,
2477           VALS(atn_ses_type),
2478           0xf8,
2479           "Indicates presence of session parameters",
2480           HFILL}},
2481         {&hf_atn_ses_param_ind,
2482         { "SPDU Parameter Indication",
2483           "atn-ulcs.ses.parameter-indication",
2484           FT_UINT8,
2485           BASE_HEX,
2486           VALS(atn_ses_param_ind),
2487           SES_PARAM_IND_MASK,
2488           "Indicates presence of session parameters",
2489           HFILL}},
2490       {&hf_atn_ses_param_b1,
2491         { "SRF Parameter B1",
2492           "atn-ulcs.ses.srf-b1",
2493           FT_UINT8,
2494           BASE_HEX,
2495           VALS(srf_b1),
2496           0x01,
2497           "Determines if transport connection reject is transient or persistent",
2498           HFILL}},
2499       {&hf_atn_ses_param_b2,
2500         { "SRF Parameter B2",
2501           "atn-ulcs.ses.srf-b2",
2502           FT_UINT8,
2503           BASE_HEX,
2504           VALS(srf_b2),
2505           0x02,
2506           "Determines if transport connection is retained or released",
2507           HFILL}},
2508       { &hf_atn_pres_err,
2509         { "Error Code", "atn-ulcs.pres.cpr-error",
2510           FT_UINT8,
2511           BASE_HEX,
2512           VALS(atn_pres_err),
2513           PRES_CPR_ER_MASK,
2514           NULL,
2515           HFILL}},
2516       { &hf_atn_pres_pdu_type,
2517         { "PDU type", "atn-ulcs.pres.pdu_type",
2518           FT_UINT8,
2519           BASE_HEX,
2520           NULL,
2521           ATN_SES_PRES_MASK,
2522           NULL,
2523           HFILL}},
2524     };
2525
2526     static gint *ett[] = {
2527
2528 /*--- Included file: packet-atn-ulcs-ettarr.c ---*/
2529 #line 1 "./asn1/atn-ulcs/packet-atn-ulcs-ettarr.c"
2530     &ett_atn_ulcs_Fully_encoded_data,
2531     &ett_atn_ulcs_PDV_list,
2532     &ett_atn_ulcs_T_presentation_data_values,
2533     &ett_atn_ulcs_EXTERNALt,
2534     &ett_atn_ulcs_T_encoding,
2535     &ett_atn_ulcs_ACSE_apdu,
2536     &ett_atn_ulcs_AARQ_apdu,
2537     &ett_atn_ulcs_T_aarq_apdu_protocol_version,
2538     &ett_atn_ulcs_AARE_apdu,
2539     &ett_atn_ulcs_T_aare_apdu_protocol_version,
2540     &ett_atn_ulcs_RLRQ_apdu,
2541     &ett_atn_ulcs_RLRE_apdu,
2542     &ett_atn_ulcs_ABRT_apdu,
2543     &ett_atn_ulcs_ACSE_requirements,
2544     &ett_atn_ulcs_Application_context_name_list,
2545     &ett_atn_ulcs_AP_title,
2546     &ett_atn_ulcs_AE_qualifier,
2547     &ett_atn_ulcs_Associate_source_diagnostic,
2548     &ett_atn_ulcs_Association_information,
2549     &ett_atn_ulcs_Authentication_value,
2550     &ett_atn_ulcs_T_other,
2551     &ett_atn_ulcs_Name,
2552     &ett_atn_ulcs_RDNSequence,
2553     &ett_atn_ulcs_RelativeDistinguishedName,
2554     &ett_atn_ulcs_AttributeTypeAndValue,
2555
2556 /*--- End of included file: packet-atn-ulcs-ettarr.c ---*/
2557 #line 832 "./asn1/atn-ulcs/packet-atn-ulcs-template.c"
2558         &ett_atn_ses,
2559         &ett_atn_pres,
2560         &ett_atn_acse,
2561         &ett_atn_ulcs
2562     };
2563
2564     proto_atn_ulcs = proto_register_protocol (
2565         ATN_ULCS_PROTO ,
2566         "ATN-ULCS",
2567         "atn-ulcs");
2568
2569     proto_register_field_array (
2570         proto_atn_ulcs,
2571         hf_atn_ulcs,
2572         array_length(hf_atn_ulcs));
2573
2574     proto_register_subtree_array (
2575         ett,
2576         array_length (ett));
2577
2578     register_dissector(
2579         "atn-ulcs",
2580         dissect_atn_ulcs,
2581         proto_atn_ulcs);
2582
2583     /* initiate sub dissector list */
2584     atn_ulcs_heur_subdissector_list = register_heur_dissector_list("atn-ulcs", proto_atn_ulcs);
2585
2586     /* init aare/aare data */
2587     aarq_data_tree = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2588
2589     atn_conversation_tree = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2590 }
2591
2592 void proto_reg_handoff_atn_ulcs(void)
2593 {
2594     atn_cm_handle = find_dissector_add_dependency("atn-cm", proto_atn_ulcs);
2595     atn_cpdlc_handle = find_dissector_add_dependency("atn-cpdlc", proto_atn_ulcs);
2596
2597     /* add session dissector to cotp dissector list dissector list*/
2598     heur_dissector_add(
2599         "cotp",
2600         dissect_atn_ulcs_heur,
2601         "ATN-ULCS over COTP",
2602         "atn-ucls_cotp",
2603         proto_atn_ulcs, HEURISTIC_ENABLE);
2604 }
2605
2606 /*
2607  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2608  *
2609  * Local variables:
2610  * c-basic-offset: 4
2611  * tab-width: 8
2612  * indent-tabs-mode: nil
2613  * End:
2614  *
2615  * vi: set shiftwidth=4 tabstop=8 expandtab:
2616  * :indentSize=4:tabSize=8:noTabs=true:
2617  */