epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / asn1 / atn-ulcs / packet-atn-ulcs-template.c
blob33b22531f7c6963f8ae9c5b5e018d634af9491ea
1 /* packet-atn-ulcs.c
2 * By Mathias Guettler <guettler@web.de>
3 * Copyright 2013
5 * Routines for ATN upper layer
6 * protocol packet disassembly
8 * ATN upper layers are embedded within OSI Layer 4 (COTP).
10 * ATN upper layers contain:
11 * Session Layer (NUL protocol option)
12 * Presentation Layer (NUL protocol option)
13 * ATN upper Layer/Application (ACSE PDU or PDV-list PDU)
15 * ATN applications protocols (i.e. CM or CPDLC) are contained within
16 * ACSE user-information or PDV presentation data.
18 * details see:
19 * https://en.wikipedia.org/wiki/CPDLC
20 * https://members.optusnet.com.au/~cjr/introduction.htm
22 * standards:
23 * We are dealing with ATN/ULCS aka ICAO Doc 9705 Second Edition here
24 * (don't think there is an ULCS equivalent for "FANS-1/A ").
25 * https://www.icao.int/safety/acp/repository/_%20Doc9705_ed2_1999.pdf
27 * Wireshark - Network traffic analyzer
28 * By Gerald Combs <gerald@wireshark.org>
29 * Copyright 1998 Gerald Combs
31 * SPDX-License-Identifier: GPL-2.0-or-later
35 developer comments:
36 why not using existing ses, pres and acse dissectors ?
37 ATN upper layers are derived from OSI standards for session,
38 presentation and application but the encoding differs
39 (it's PER instead of BER encoding to save bandwidth).
40 Session and presentation use the "null" encoding option,
41 meaning that they are only present at connection establishment
42 and omitted otherwise.
43 Instead of adapting existing dissectors it seemed simpler and cleaner
44 to implement everything the new atn-ulcs dissector.
46 why using conversations ?
47 PER encoded user data is ambigous; the same encoding may apply to a CM or
48 CPDLC PDU. The workaround is to decode on a transport connection basis.
49 I use my own version of conversations to identify
50 the transport connection the PDU belongs to for the standard functions
51 from "conversation.h" didn't work out.
53 what is the use of AARQ/AARE data ?
54 Converstions should be maintained on the COTP layer in a standard way
55 for there are usually more packets available than in the layers above.
56 In the worst case my dissector is called from a DT packet which
57 has destination references but no source reference.
58 I have to guess the reference used the other way round
59 (curently I am using ACSE PDU'S used during OSI connection establishment for that).
60 The idea is that each ACSE AARQ is answered by ACSE AARE and having this sequence
61 I have all the source/destination references for this transport connection.
62 I use AARQ/AARE data to store the source/destination reference of AARQ as well
63 as the optional ae-qualifier which tells me the application and
64 the dissector I have to use.
65 This approach donesn't work well when there are interleaving AARQ/AARE sequences for
66 the same aircraft.
68 which ATN standard is supported ?
69 The dissector has been tested with ICAO doc9705 Edition2 compliant traffic.
70 No ATN Secutity is supported.
71 note:
72 The ATN upper layers are derived from OSI standards (ICAO DOC 9705)
73 while ATN/IPS (ICAO DOC 9896) which is entirely based on IPV6.
78 known defects/deficiencies:
80 - user-information within AARE is sometines not decoded due to an unset flag
81 (the field is optional). As far as I can tell asn2wrs is right here,
82 but on the other hand I know that in all of this cases user-information
83 is present and is processed by the ATN end system.
84 Maybe a true ATN expert may help me out here.
86 - The conversation handling is based on src/dst addresses as well as
87 source or destination references depending on the TP4 packet type.
88 This means that after some time these references get reused for
89 new conversations. This almost certain happens for traces longer
90 than one day rendering this dissector unsuitable for captures exceeding
91 this one day.
95 #include "config.h"
97 #ifndef _MSC_VER
98 #include <stdint.h>
99 #endif
102 #include <epan/packet.h>
103 #include <epan/address.h>
104 #include <epan/conversation.h>
105 #include <wsutil/array.h>
106 #include <epan/osi-utils.h>
107 #include "packet-ber.h"
108 #include "packet-per.h"
109 #include "packet-atn-ulcs.h"
111 #define ATN_ACSE_PROTO "ICAO Doc9705 ULCS ACSE (ISO 8649/8650-1:1996)"
112 #define ATN_ULCS_PROTO "ICAO Doc9705 ULCS"
114 void proto_register_atn_ulcs(void);
115 void proto_reg_handoff_atn_ulcs(void);
117 static heur_dissector_list_t atn_ulcs_heur_subdissector_list;
119 /* presentation subdissectors i.e. CM, CPDLC */
120 static dissector_handle_t atn_cm_handle;
121 static dissector_handle_t atn_cpdlc_handle;
123 static int proto_atn_ulcs;
124 static uint32_t ulcs_context_value;
125 static const char *object_identifier_id;
127 static wmem_tree_t *aarq_data_tree;
128 static wmem_tree_t *atn_conversation_tree;
131 static proto_tree *root_tree;
133 /* forward declarations for functions generated from asn1 */
134 static int dissect_atn_ulcs_T_externalt_encoding_single_asn1_type(
135 tvbuff_t *tvb _U_,
136 int offset _U_,
137 asn1_ctx_t *actx _U_,
138 proto_tree *tree _U_,
139 int hf_index
140 _U_);
142 static int dissect_atn_ulcs_T_externalt_encoding_octet_aligned(
143 tvbuff_t *tvb _U_,
144 int offset _U_,
145 asn1_ctx_t *actx _U_,
146 proto_tree *tree _U_,
147 int hf_index _U_);
149 static int dissect_atn_ulcs_T_externalt_encoding_arbitrary(
150 tvbuff_t *tvb _U_,
151 int offset _U_,
152 asn1_ctx_t *actx _U_,
153 proto_tree *tree _U_,
154 int hf_index _U_);
156 static int dissect_ACSE_apdu_PDU(
157 tvbuff_t *tvb _U_,
158 packet_info *pinfo _U_,
159 proto_tree *tree _U_,
160 void *data _U_);
162 uint32_t dissect_per_object_descriptor_t(
163 tvbuff_t *tvb,
164 uint32_t offset,
165 asn1_ctx_t *actx,
166 proto_tree *tree,
167 int hf_index,
168 tvbuff_t **value_tvb);
170 static int dissect_atn_ulcs(
171 tvbuff_t *tvb,
172 packet_info *pinfo,
173 proto_tree *tree,
174 void *data _U_);
176 #include "packet-atn-ulcs-hf.c"
178 #include "packet-atn-ulcs-ett.c"
179 static int ett_atn_ulcs;
180 static int ett_atn_acse;
182 #include "packet-atn-ulcs-fn.c"
184 #if 0
185 /* re-implementing external data: packet-per.c */
186 static const value_string per_External_encoding_vals[] = {
187 { 0, "single-ASN1-type" },
188 { 1, "octet-aligned" },
189 { 2, "arbitrary" },
190 { 0, NULL }
193 /* re-implementing external data: packet-per.c */
194 static const per_choice_t External_encoding_choice[] =
196 { 0,
197 &hf_atn_ulcs_externalt_encoding_single_asn1_type,
198 ASN1_NO_EXTENSIONS,
199 dissect_atn_ulcs_T_externalt_encoding_single_asn1_type
201 { 1,
202 &hf_atn_ulcs_externalt_encoding_octet_aligned,
203 ASN1_NO_EXTENSIONS,
204 dissect_atn_ulcs_T_externalt_encoding_octet_aligned
206 { 2,
207 &hf_atn_ulcs_externalt_encoding_arbitrary,
208 ASN1_NO_EXTENSIONS,
209 dissect_atn_ulcs_T_externalt_encoding_arbitrary
211 { 0,
212 NULL,
214 NULL
217 #endif
219 /* ATN Session layer */
220 #define SES_PDU_TYPE_MASK 0xf8
221 #define SES_PARAM_IND_MASK 0x04
222 #define SES_PARAM_B2_MASK 0x02
223 #define SES_PARAM_B1_MASK 0x01
225 static int hf_atn_ses_type;
226 static int hf_atn_ses_param_ind;
227 static int hf_atn_ses_param_b1;
228 static int hf_atn_ses_param_b2;
230 static int ett_atn_ses;
232 #define ATN_SES_PROTO "ICAO Doc9705 ULCS Session (ISO 8326/8327-1:1994)"
234 static const value_string atn_ses_param_ind[] =
236 {0, "No Parameter Indication "},
237 {1, "Parameter Indication "},
238 {0, NULL }
241 static const value_string srf_b2[] =
243 {0, "Transport Connection is kept"},
244 {1, "Transport Connection is released" },
245 {0, NULL }
248 static const value_string srf_b1[] =
250 {0, "Transport Connection is transient"},
251 {1, "Transport Connection is persistent"},
252 {0, NULL }
255 #define SES_ATN_SCN 0xe8
256 #define SES_ATN_SCNC 0xf8
257 #define SES_ATN_SAC 0xf0
258 #define SES_ATN_SACC 0xd8
259 #define SES_ATN_SRF 0xe0
260 #define SES_ATN_SRFC 0xa0
262 static const value_string atn_ses_type[] =
264 { 0x1d, "Short Connect (SCN) SPDU" },
265 { 0x1f, "Short Connect Accept (SAC) SPDU" },
266 { 0x1e, "Short Connect Accept Continue (SACC) SPDU" },
267 { 0x1c, "Short Refuse (SRF) SPDU" },
268 { 0x14, "Short Refuse Continue (SRFC) SPDU" },
269 {0, NULL }
272 /* ATN Presentation layer */
273 #define ATN_PRES_PROTO "ICAO Doc9705 ULCS Presentation (ISO 8822/8823-1:1994)"
275 static int hf_atn_pres_err;
276 static int hf_atn_pres_pdu_type;
277 static int ett_atn_pres;
279 #define ATN_SES_PRES_MASK 0xf803
280 #define PRES_CPR_ER_MASK 0x70
282 /* type determined by SPDU and PPDU */
283 static const value_string atn_pres_vals[] =
285 { 0xe802, "Short Presentation Connect PPDU (CP) " },
286 { 0xf802, "Short Presentation Connect PPDU (CP) " },
287 { 0xf002, "Short Presentation Connect Accept PPDU (CPA)" },
288 { 0xd802, "Short Presentation Connect Accept PPDU (CPA)" },
289 { 0xe002, "Short Presentation Connect Reject PPDU (CPR)" },
290 { 0xa002, "Short Presentation Connect Reject PPDU (CPR)" },
291 {0, NULL }
294 /* Short Presentation Connect Reject PPDU's 0yyy 00zz */
295 static const value_string atn_pres_err[] =
297 { 0x00, "Presentation-user" },
298 { 0x01, "Reason not specified (transient)"},
299 { 0x02, "Temporary congestion (transient)"},
300 { 0x03, "Local limit exceeded (transient)"},
301 { 0x04, "Called presentation-address unknown (permanent)"},
302 { 0x05, "Protocol version not supported (permanent)"},
303 { 0x06, "Default context not supported (permanent)"},
304 { 0x07, "User data not readable (permanent)"},
305 { 0, NULL }
308 #if 0
309 /* re-implementing external data: packet-per.c */
310 static int atn_ulcs_Externalt_encoding(
311 tvbuff_t *tvb _U_,
312 int offset _U_,
313 asn1_ctx_t *actx _U_,
314 proto_tree *tree _U_,
315 int hf_index _U_)
317 offset = dissect_per_choice(
318 tvb,
319 offset,
320 actx,
321 tree,
322 hf_index,
323 ett_atn_ulcs_EXTERNALt,
324 External_encoding_choice,
325 &actx->external.encoding);
327 return offset;
330 /* re-implementing external data: packet-per.c */
331 static uint32_t atn_per_external_type(
332 tvbuff_t *tvb _U_,
333 uint32_t offset,
334 asn1_ctx_t *actx,
335 proto_tree *tree _U_,
336 int hf_index _U_,
337 per_type_fn type_cb)
339 memset(&actx->external, '\0', sizeof(actx->external));
340 actx->external.hf_index = -1;
341 actx->external.encoding = -1;
343 actx->external.u.per.type_cb = type_cb;
344 offset = atn_ulcs_Externalt_encoding(
345 tvb,
346 offset,
347 actx,
348 tree,
349 hf_index);
351 memset(
352 &actx->external,
353 '\0',
354 sizeof(actx->external));
356 actx->external.hf_index = -1;
357 actx->external.encoding = -1;
359 return offset;
361 #endif
363 /* determine 24-bit aircraft address(ARS) */
364 /* from 20-byte ATN NSAP. */
365 uint32_t get_aircraft_24_bit_address_from_nsap(
366 packet_info *pinfo)
368 const uint8_t* addr = NULL;
369 uint32_t ars =0;
370 uint32_t adr_prefix =0;
372 /* check NSAP address type*/
373 if( (pinfo->src.type != get_osi_address_type()) ||
374 (pinfo->dst.type != get_osi_address_type())) {
375 return ars; }
377 /* 20 octets address length required */
378 /* for ATN */
379 if( (pinfo->src.len != 20) ||
380 (pinfo->dst.len != 20)) {
381 return ars; }
383 /* first try source address */
384 /* if the src address originates */
385 /* from an aircraft it's downlink */
387 /* convert addr into 32-bit integer */
388 addr = (const uint8_t *)pinfo->src.data;
389 adr_prefix =
390 ((addr[0]<<24) |
391 (addr[1]<<16) |
392 (addr[2]<<8) |
393 addr[3] );
395 /* according to ICAO doc9507 Ed2 SV5 */
396 /* clause 5.4.3.8.1.5 and 5.4.3.8.1.3 */
397 /* mobile addresses contain "c1" of "41" */
398 /* in the VER subfield of the NSAP */
399 if((adr_prefix == 0x470027c1) ||
400 (adr_prefix == 0x47002741)) {
401 /* ICAO doc9507 Ed2 SV5 5.4.3.8.4.4 */
402 /* states that the ARS subfield contains */
403 /* the 24-bitaddress of the aircraft */
404 ars = ((addr[8])<<16) |
405 ((addr[9])<<8) |
406 (addr[10]);
409 /* try destination address */
410 /* if the src address originates */
411 /* from an aircraft it's downlink */
413 /* convert addr into 32-bit integer */
414 addr = (const uint8_t *)pinfo->dst.data;
415 adr_prefix = ((addr[0]<<24) |
416 (addr[1]<<16) |
417 (addr[2]<<8) |
418 addr[3] );
420 /* according to ICAO doc9507 Ed2 SV5 */
421 /* clause 5.4.3.8.1.5 and 5.4.3.8.1.3 */
422 /* mobile addresses contain "c1" of "41" */
423 /* in the VER subfield of the NSAP */
424 if((adr_prefix == 0x470027c1) ||
425 (adr_prefix == 0x47002741)) {
426 /* ICAO doc9507 Ed2 SV5 5.4.3.8.4.4 */
427 /* states that the ARS subfield contains */
428 /* the 24-bitaddress of the aircraft */
429 ars = ((addr[8])<<16) |
430 ((addr[9])<<8) |
431 (addr[10]);
433 return ars;
436 /* determine whether a PDU is uplink or downlink */
437 /* by checking for known aircraft address prefixes*/
438 int check_heur_msg_type(packet_info *pinfo _U_)
440 int t = no_msg;
441 const uint8_t* addr = NULL;
442 uint32_t adr_prefix =0;
444 /* check NSAP address type*/
445 if( (pinfo->src.type != get_osi_address_type()) || (pinfo->dst.type != get_osi_address_type())) {
446 return t; }
448 /* check NSAP address length; 20 octets address length required */
449 if( (pinfo->src.len != 20) || (pinfo->dst.len != 20)) {
450 return t; }
452 addr = (const uint8_t *)pinfo->src.data;
454 /* convert address to 32-bit integer */
455 adr_prefix = ((addr[0]<<24) | (addr[1]<<16) | (addr[2]<<8) | addr[3] );
457 /* According to the published ATN NSAP adddressing scheme */
458 /* in ICAO doc9705 Ed2 SV5 5.4.3.8.1.3 and 5.4.3.8.1.5 */
459 /* the "VER" field shall be 0x41 ("all Mobile AINSC") or */
460 /* 0xc1 ("all Mobile ATSC") for mobile stations (aka aircraft).*/
461 if((adr_prefix == 0x470027c1) || (adr_prefix == 0x47002741)) {
462 t = dm; /* source is an aircraft: it's a downlink PDU */
465 addr = (const uint8_t *)pinfo->dst.data;
467 /* convert address to 32-bit integer */
468 adr_prefix = ((addr[0]<<24) | (addr[1]<<16) | (addr[2]<<8) | addr[3] );
470 /* According to the published ATN NSAP adddressing scheme */
471 /* in ICAO doc9705 Ed2 SV5 5.4.3.8.1.3 and 5.4.3.8.1.5 */
472 /* the "VER" field shall be 0x41 ("all Mobile AINSC") or */
473 /* 0xc1 ("all Mobile ATSC") for mobile stations (aka aircraft).*/
474 if((adr_prefix == 0x470027c1) || (adr_prefix == 0x47002741)) {
475 t = um; /* destination is aircraft: uplink PDU */
478 return t;
481 /* conversation may be used by other dissectors */
482 wmem_tree_t *get_atn_conversation_tree(void){
483 return atn_conversation_tree;
487 /* find a atn conversation tree node by an endpoint */
488 /* an endpoint is identified by atn src and dst addresses */
489 /* and srcref or dstref (depends on the transport packet type) */
490 /* IMHO it's a hack - conversations should be maintained */
491 /* at transport layer (cotp) but this isn't working yet. */
492 atn_conversation_t * find_atn_conversation(
493 address *address1,
494 uint16_t clnp_ref1,
495 address *address2 )
497 atn_conversation_t *cv = NULL;
498 uint32_t key = 0;
499 uint32_t tmp = 0;
501 tmp = add_address_to_hash( tmp, address1);
502 key = (tmp << 16) | clnp_ref1 ;
504 tmp = add_address_to_hash( tmp, address2);
505 key = (tmp << 24) | key ;
507 /* search for atn conversation */
508 cv = (atn_conversation_t *)
509 wmem_tree_lookup32(get_atn_conversation_tree(),key);
511 return cv;
514 /* create a atn conversation tree node */
515 /* conversation data is to be allocated externally */
516 /* a conversation may be referenced from both endpoints */
517 atn_conversation_t * create_atn_conversation(
518 address *address1,
519 uint16_t clnp_ref1,
520 address *address2,
521 atn_conversation_t *conversation)
523 atn_conversation_t *cv = NULL;
524 uint32_t key = 0;
525 uint32_t tmp = 0;
527 tmp = add_address_to_hash( tmp, address1);
528 key = (tmp << 16) | clnp_ref1 ;
530 tmp = add_address_to_hash( tmp, address2);
531 key = (tmp << 24) | key ;
533 /* search for aircraft entry */
534 cv = (atn_conversation_t *)
535 wmem_tree_lookup32(
536 get_atn_conversation_tree(),
537 key);
539 /* tree node already present */
540 if(cv) {
541 return NULL; }
543 /* insert conversation data in tree*/
544 wmem_tree_insert32(
545 get_atn_conversation_tree(),
546 key,
547 (void*)conversation);
549 return conversation;
552 static int
553 dissect_atn_ulcs(
554 tvbuff_t *tvb,
555 packet_info *pinfo,
556 proto_tree *tree,
557 void *data _U_)
559 int offset = 0;
560 proto_item *ti = NULL;
561 proto_tree *atn_ulcs_tree = NULL;
562 uint8_t value_pres = 0;
563 uint8_t value_ses = 0;
564 uint16_t value_ses_pres = 0;
566 root_tree = tree;
568 /* data pointer */
569 /* decode as PDV-list */
570 if ( (int)(intptr_t) data == false )
572 ti = proto_tree_add_item(
573 tree,
574 proto_atn_ulcs,
575 tvb,
578 ENC_NA);
580 atn_ulcs_tree = proto_item_add_subtree(
582 ett_atn_ulcs);
584 dissect_Fully_encoded_data_PDU(
585 tvb,
586 pinfo,
587 atn_ulcs_tree, NULL);
589 return offset +
590 tvb_reported_length_remaining(tvb, offset ) ;
593 /* decode as SPDU, PPDU and ACSE PDU */
594 if ( (int)(intptr_t) data == true )
596 /* get session and presentation PDU's */
597 value_ses_pres = tvb_get_ntohs(tvb, offset);
599 /* SPDU: dissect session layer */
600 atn_ulcs_tree = proto_tree_add_subtree(
601 tree, tvb, offset, 0,
602 ett_atn_ses, NULL, ATN_SES_PROTO );
604 /* get SPDU (1 octet) */
605 value_ses = tvb_get_uint8(tvb, offset);
607 /* SPDU type/identifier */
608 proto_tree_add_item(atn_ulcs_tree,
609 hf_atn_ses_type,
610 tvb,
611 offset,
613 ENC_BIG_ENDIAN );
615 /* SPDU parameters may be present in Short Refuse */
616 /* or Short Refuse Continue SPDU's */
617 switch(value_ses & SES_PDU_TYPE_MASK){
618 case SES_ATN_SRF:
619 case SES_ATN_SRFC:
621 /* SPDU parameter presence */
622 proto_tree_add_item(atn_ulcs_tree,
623 hf_atn_ses_param_ind,
624 tvb,
625 offset,
627 ENC_BIG_ENDIAN );
629 /* parameter B2 */
630 proto_tree_add_item(atn_ulcs_tree,
631 hf_atn_ses_param_b2,
632 tvb,
633 offset,
635 ENC_BIG_ENDIAN );
637 /* parameter B1 */
638 proto_tree_add_item(atn_ulcs_tree,
639 hf_atn_ses_param_b1,
640 tvb,
641 offset,
643 ENC_BIG_ENDIAN );
645 break;
646 default:
647 break;
649 offset++;
651 /* PPDU: dissect presentation layer */
652 atn_ulcs_tree = proto_tree_add_subtree(
653 tree, tvb, offset, 0,
654 ett_atn_pres, NULL, ATN_PRES_PROTO );
656 value_pres = tvb_get_uint8(tvb, offset);
658 /* need session context to identify PPDU type */
659 /* note: */
660 proto_tree_add_uint_format(atn_ulcs_tree, hf_atn_pres_pdu_type,
661 tvb,
662 offset,
664 value_ses_pres,
665 "%s (0x%02x)",
666 val_to_str_const( value_ses_pres & ATN_SES_PRES_MASK, atn_pres_vals, "?"),
667 value_pres);
669 /* PPDU errorcode in case of SRF/CPR */
670 switch(value_ses & SES_PDU_TYPE_MASK){
671 case SES_ATN_SRF:
672 case SES_ATN_SRFC:
673 proto_tree_add_item(
674 atn_ulcs_tree,
675 hf_atn_pres_err,
676 tvb,
677 offset,
679 ENC_BIG_ENDIAN );
680 break;
681 default:
682 break;
685 offset++;
687 /* ACSE PDU: dissect application layer */
688 atn_ulcs_tree = proto_tree_add_subtree(
689 tree, tvb, offset, 0,
690 ett_atn_acse, NULL, ATN_ACSE_PROTO );
692 dissect_ACSE_apdu_PDU(
693 tvb_new_subset_remaining(tvb, offset),
694 pinfo,
695 atn_ulcs_tree, NULL);
697 return offset +
698 tvb_reported_length_remaining(tvb, offset );
700 return offset;
703 static bool dissect_atn_ulcs_heur(
704 tvbuff_t *tvb,
705 packet_info *pinfo,
706 proto_tree *tree,
707 void *data _U_)
709 /* do we have enough data*/
710 /* at least session + presentation data or pdv-list */
711 if (tvb_captured_length(tvb) < 2){
712 return false; }
714 /* check for session/presentation/ACSE PDU's */
715 /* SPDU and PPDU are one octet each */
716 switch( tvb_get_ntohs(tvb, 0) & 0xf8ff ){
717 case 0xe802: /* SCN + CP*/
718 case 0xf802: /* SCNC + CP */
719 case 0xf002: /* SAC + CPA */
720 case 0xd802: /* SACC + CPA */
721 case 0xe002: /* SRF + CPR + R0 */
722 case 0xe012: /* SRF + CPR + R1 */
723 case 0xe022: /* SRF + CPR + R2 */
724 case 0xe032: /* SRF + CPR + R3 */
725 case 0xe042: /* SRF + CPR + R4 */
726 case 0xe052: /* SRF + CPR + R5 */
727 case 0xe062: /* SRF + CPR + R6 */
728 case 0xe072: /* SRF + CPR + R7 */
729 case 0xa002: /* SRFC + CPR + R0*/
730 case 0xa012: /* SRFC + CPR + R1*/
731 case 0xa022: /* SRFC + CPR + R2*/
732 case 0xa032: /* SRFC + CPR + R3*/
733 case 0xa042: /* SRFC + CPR + R4*/
734 case 0xa052: /* SRFC + CPR + R5*/
735 case 0xa062: /* SRFC + CPR + R6*/
736 case 0xa072: /* SRFC + CPR + R7*/
737 /* indicate to dissector routine */
738 /* that a least SPDU, PPDU and */
739 /* ACSE PDU is present */
740 dissect_atn_ulcs(
741 tvb,
742 pinfo,
743 tree,
744 (void*) true);
745 return true;
746 default: /* no SPDU */
747 break;
750 /* try to detect "Fully-encoded-data" heuristically */
751 /* the constants listed match the ASN.1 PER encoding */
752 /* of PDV-List */
753 switch( tvb_get_ntohs(tvb, 0) & 0xfff0 ){
754 case 0x0020: /* acse-apdu */
755 case 0x00a0: /* user-ase-apdu */
756 /* indicate to dissector routine */
757 /* that a PDV-list PDU is present */
758 /* */
759 /* PDV-list PDU may contain */
760 /* application protocol data (CM, CPDLC) */
761 /* or an ACSE PDU */
762 dissect_atn_ulcs(tvb, pinfo, tree, (void*) false);
763 return true;
764 default: /* no or unsupported PDU */
765 break;
767 return false;
770 void proto_register_atn_ulcs (void)
772 static hf_register_info hf_atn_ulcs[] = {
773 #include "packet-atn-ulcs-hfarr.c"
774 {&hf_atn_ses_type,
775 { "SPDU Type",
776 "atn-ulcs.ses.type",
777 FT_UINT8,
778 BASE_HEX,
779 VALS(atn_ses_type),
780 0xf8,
781 "Indicates presence of session parameters",
782 HFILL}},
783 {&hf_atn_ses_param_ind,
784 { "SPDU Parameter Indication",
785 "atn-ulcs.ses.parameter-indication",
786 FT_UINT8,
787 BASE_HEX,
788 VALS(atn_ses_param_ind),
789 SES_PARAM_IND_MASK,
790 "Indicates presence of session parameters",
791 HFILL}},
792 {&hf_atn_ses_param_b1,
793 { "SRF Parameter B1",
794 "atn-ulcs.ses.srf-b1",
795 FT_UINT8,
796 BASE_HEX,
797 VALS(srf_b1),
798 0x01,
799 "Determines if transport connection reject is transient or persistent",
800 HFILL}},
801 {&hf_atn_ses_param_b2,
802 { "SRF Parameter B2",
803 "atn-ulcs.ses.srf-b2",
804 FT_UINT8,
805 BASE_HEX,
806 VALS(srf_b2),
807 0x02,
808 "Determines if transport connection is retained or released",
809 HFILL}},
810 { &hf_atn_pres_err,
811 { "Error Code", "atn-ulcs.pres.cpr-error",
812 FT_UINT8,
813 BASE_HEX,
814 VALS(atn_pres_err),
815 PRES_CPR_ER_MASK,
816 NULL,
817 HFILL}},
818 { &hf_atn_pres_pdu_type,
819 { "PDU type", "atn-ulcs.pres.pdu_type",
820 FT_UINT16,
821 BASE_HEX,
822 NULL,
823 ATN_SES_PRES_MASK,
824 NULL,
825 HFILL}},
828 static int *ett[] = {
829 #include "packet-atn-ulcs-ettarr.c"
830 &ett_atn_ses,
831 &ett_atn_pres,
832 &ett_atn_acse,
833 &ett_atn_ulcs
836 proto_atn_ulcs = proto_register_protocol (
837 ATN_ULCS_PROTO ,
838 "ATN-ULCS",
839 "atn-ulcs");
841 proto_register_field_array (
842 proto_atn_ulcs,
843 hf_atn_ulcs,
844 array_length(hf_atn_ulcs));
846 proto_register_subtree_array (
847 ett,
848 array_length (ett));
850 register_dissector(
851 "atn-ulcs",
852 dissect_atn_ulcs,
853 proto_atn_ulcs);
855 /* initiate sub dissector list */
856 atn_ulcs_heur_subdissector_list = register_heur_dissector_list_with_description("atn-ulcs", "ATN-ULCS unhandled data", proto_atn_ulcs);
858 /* init aare/aare data */
859 aarq_data_tree = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
861 atn_conversation_tree = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
864 void proto_reg_handoff_atn_ulcs(void)
866 atn_cm_handle = find_dissector_add_dependency("atn-cm", proto_atn_ulcs);
867 atn_cpdlc_handle = find_dissector_add_dependency("atn-cpdlc", proto_atn_ulcs);
869 /* add session dissector to cotp dissector list dissector list*/
870 heur_dissector_add(
871 "cotp",
872 dissect_atn_ulcs_heur,
873 "ATN-ULCS over COTP",
874 "atn-ucls_cotp",
875 proto_atn_ulcs, HEURISTIC_ENABLE);
879 * Editor modelines - https://www.wireshark.org/tools/modelines.html
881 * Local variables:
882 * c-basic-offset: 4
883 * tab-width: 8
884 * indent-tabs-mode: nil
885 * End:
887 * vi: set shiftwidth=4 tabstop=8 expandtab:
888 * :indentSize=4:tabSize=8:noTabs=true: