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