#.MODULE_IMPORT #.FIELD_RENAME AARQ-apdu/protocol-version aarq-apdu_protocol-version AARE-apdu/protocol-version aare-apdu_protocol-version RLRE-apdu/reason rlre-apdu_response_reason RLRQ-apdu/reason rlrq-apdu_request_reason EXTERNALt/encoding/single-ASN1-type externalt_encoding_single-asn1-type EXTERNALt/encoding/arbitrary externalt_encoding_arbitrary EXTERNALt/encoding/octet-aligned externalt_encoding_octet-aligned PDV-list/presentation-data-values/single-ASN1-type pdv-list_presentation-data-values_single-asn1-type PDV-list/presentation-data-values/arbitrary pdv-list_presentation-data-values_arbitrary #.END #.PDU Fully-encoded-data ACSE-apdu #.END #.FN_PARS Release-request-reason VAL_PTR=&reason #.END #.FN_BODY Presentation-context-identifier offset = dissect_per_constrained_integer( tvb, offset, actx, tree, hf_index, 1U, 127U, &ulcs_context_value, true); #.END #.FN_BODY PDV-list/presentation-data-values/arbitrary packet_info * pinfo = actx->pinfo; tvbuff_t *tvb_usr = NULL; proto_tree *atn_ulcs_tree = NULL; atn_conversation_t *atn_cv = NULL; heur_dtbl_entry_t *hdtbl_entry; /* extract bitstring into new tvb buffer */ offset = dissect_per_bit_string( tvb, offset, actx, tree, hf_index, NO_BOUND, NO_BOUND, false, NULL, 0, &tvb_usr, NULL); if (tvb_usr) { /* call appropriate dissector for bitstring data */ switch(ulcs_context_value){ case 1: /* ACSE PDU*/ atn_ulcs_tree = proto_tree_add_subtree( root_tree, tvb, offset, 0, ett_atn_acse, NULL, ATN_ACSE_PROTO ); dissect_ACSE_apdu_PDU( tvb_new_subset_remaining(tvb_usr, 0), pinfo, atn_ulcs_tree, NULL); break; case 3: /* USER data; call subdissector for CM, CPDLC ... */ /* using dstref for PDV-list only occurrs in DT */ atn_cv = find_atn_conversation( &pinfo->dst, pinfo->clnp_dstref, &pinfo->src); if(atn_cv) { switch(atn_cv->ae_qualifier){ case cma: /* contact management */ call_dissector_with_data( atn_cm_handle, tvb_new_subset_remaining(tvb_usr, 0), pinfo, root_tree, NULL); break; case cpdlc: /* plain old cpdlc */ case pmcpdlc: /* protected mode cpdlc */ call_dissector_with_data( atn_cpdlc_handle, tvb_new_subset_remaining(tvb_usr, 0), pinfo, root_tree, NULL); break; default: /* unknown or unhandled datalink application */ dissector_try_heuristic( atn_ulcs_heur_subdissector_list, tvb_new_subset_remaining(tvb_usr,0), actx->pinfo, root_tree, &hdtbl_entry, NULL); break; } } else{ dissector_try_heuristic( atn_ulcs_heur_subdissector_list, tvb_new_subset_remaining(tvb_usr,0), actx->pinfo, root_tree, &hdtbl_entry, NULL); } break; default: break; } /* switch(ulcs_context_value) */ } #.END #.FN_BODY Authentication-value/other/other-mechanism-value offset=call_ber_oid_callback( object_identifier_id, tvb, offset, actx->pinfo, tree, NULL); #.END #.FN_BODY Mechanism-name offset = dissect_per_object_identifier( tvb, offset, actx, tree, hf_index, NULL); #.END #.FN_BODY Authentication-value/other/other-mechanism-value offset=call_ber_oid_callback( object_identifier_id, tvb, offset, actx->pinfo, tree, NULL); #.END #.FN_BODY AE-qualifier-form2 packet_info * pinfo = actx->pinfo; atn_conversation_t *atn_cv = NULL; uint32_t ae_qualifier = 0; /* dissect ae-qualifier */ offset = dissect_per_integer( tvb, offset, actx, tree, hf_index, &ae_qualifier); /*note: */ /* the field "calling-AE-qualifier" is optional, */ /* which means that we can exploit it only if it is present. */ /* We still depend on heuristical decoding of CM, CPDLC PDU's otherwise. */ /* AARQ/DT: dstref present, srcref is always zero */ if((pinfo->clnp_dstref) && (!pinfo->clnp_srcref)){ atn_cv = find_atn_conversation(&pinfo->dst, pinfo->clnp_dstref, &pinfo->src ); } /* AARQ/CR: srcref present, dstref is always zero */ if((!pinfo->clnp_dstref) && (pinfo->clnp_srcref)){ atn_cv = find_atn_conversation(&pinfo->src, pinfo->clnp_srcref, &pinfo->dst ); } if(atn_cv){ atn_cv->ae_qualifier = ae_qualifier; } #.END #.FN_BODY AARQ-apdu packet_info * pinfo = actx->pinfo; aarq_data_t *aarq_data = NULL; atn_conversation_t *atn_cv = NULL; uint32_t aircraft_24_bit_address = 0; /* AARQ/DT: dstref present, srcref is always zero */ if((pinfo->clnp_dstref) && (!pinfo->clnp_srcref)){ atn_cv = find_atn_conversation( &pinfo->dst, pinfo->clnp_dstref, &pinfo->src ); if(!atn_cv){ atn_cv = wmem_new(wmem_file_scope(), atn_conversation_t); atn_cv->ae_qualifier = unknown; create_atn_conversation(&pinfo->dst, pinfo->clnp_dstref, &pinfo->src , atn_cv); } } /* AARQ/CR: srcref present, dstref is always zero */ if((!pinfo->clnp_dstref) && (pinfo->clnp_srcref)){ atn_cv = find_atn_conversation(&pinfo->src, pinfo->clnp_srcref, &pinfo->dst ); if(!atn_cv){ atn_cv = wmem_new(wmem_file_scope(), atn_conversation_t); atn_cv->ae_qualifier = unknown; create_atn_conversation(&pinfo->src, pinfo->clnp_srcref, &pinfo->dst , atn_cv); } } /* conversation is to be created prior to decoding */ /* of "AE-qualifier-form2" which takes place here: */ %(DEFAULT_BODY)s /* save AARQ packet data to create a conversation */ /* when decoding the following AARE PDU */ /* ATN applications CM and CPDLC are air/ground applications */ /* so there is always an aircraft (with its 24-bit address) */ /* and a ground facility. */ /* the assumption is that there is only one open AARQ/AARE */ /* dialog per aircraft at a time. */ /* the aircraft's 24-bit address is used as a key to each AARQ */ /* data. AARQ data is used to create a conversation with */ /* air and ground endpoints (based on NSAP's and transport references) */ /* when decoding AARE.*/ /* note: */ /* it may be more robust to create the conversation */ /* in the "ositp" dissector an to merely use the conversation here */ aircraft_24_bit_address = get_aircraft_24_bit_address_from_nsap(pinfo); /* search for aarq entry */ aarq_data = (aarq_data_t *) wmem_tree_lookup32( aarq_data_tree, aircraft_24_bit_address); if(!aarq_data){ /* aarq data not found, create new record */ /* alloc aarq data */ aarq_data = wmem_new(wmem_file_scope(), aarq_data_t); aarq_data-> aarq_pending = false; /* insert aarq data */ wmem_tree_insert32(aarq_data_tree ,aircraft_24_bit_address,(void*)aarq_data); } /* check for pending AARQ/AARE sequences */ /* if "aarq_data-> aarq_pending" is set this means that there is already one */ /* AARQ/AARE sequence pending (is unwise to overwrite AARE/AARQ) */ if (aarq_data-> aarq_pending == false ) { /* init aarq data */ memset(aarq_data,0,sizeof(aarq_data_t)); aarq_data->cv = atn_cv; aarq_data-> aarq_pending = true; } #.END #.FN_BODY AARE-apdu packet_info * pinfo = actx->pinfo; uint32_t aircraft_24_bit_address = 0 ; atn_conversation_t *atn_cv = NULL; aarq_data_t *aarq_data = NULL; /* get AARQ data and use it to create a new conversation, */ /* the conversation is used along with */ /* AARQ's "calling ae qualifier" to determine the */ /* type of air/ground application of each subsequent frame.*/ /* we use this information to invoke the correct application dissector. */ /* note: */ /* heuristical decoding of ASN1 will not work for all cases, */ /* for there may be CM PDU's which will exactly look like CPDLC PDU'S */ /* get 24-bit icao address */ aircraft_24_bit_address = get_aircraft_24_bit_address_from_nsap(pinfo); /* search for aarq entry */ aarq_data = (aarq_data_t *) wmem_tree_lookup32( aarq_data_tree, aircraft_24_bit_address); /* no aarq data present, do nothing */ /* without both ends of the conversation and without */ /* the "calling ae-qualifier there is no point in setting up "*/ /* a conversation */ if(!aarq_data) { return offset; } /* AARE/DT: dstref present, srcref is always zero */ if((pinfo->clnp_dstref) && (!pinfo->clnp_srcref)){ atn_cv = find_atn_conversation(&pinfo->dst, pinfo->clnp_dstref, &pinfo->src ); if(!atn_cv){ /* conversation not fond */ /* DT has only dstref - create new conversation */ create_atn_conversation(&pinfo->dst, pinfo->clnp_dstref, &pinfo->src , aarq_data->cv); } } /* AARE/CC: srcref and dstref present */ if((pinfo->clnp_dstref) && (pinfo->clnp_srcref)){ atn_cv = find_atn_conversation( &pinfo->src, pinfo->clnp_srcref, &pinfo->dst); if(atn_cv){ /* conversation found. */ /* create new conversation for dstref */ create_atn_conversation(&pinfo->dst, pinfo->clnp_dstref, &pinfo->src , aarq_data->cv); }else { /* no conversation found */ /* as CC contains srcref *and* dstref we use both to create new records */ create_atn_conversation(&pinfo->src, pinfo->clnp_srcref, &pinfo->dst , aarq_data->cv); create_atn_conversation(&pinfo->dst, pinfo->clnp_dstref, &pinfo->src , aarq_data->cv); } } /* clear aarq data */ memset(aarq_data,0,sizeof(aarq_data_t)); aarq_data-> aarq_pending = false; %(DEFAULT_BODY)s #.END #.FN_BODY Associate-result /* extension present: last param set to true. asn2wrs didn't take notice of that */ offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index, 0U, 2U, NULL, true); #.END #.FN_BODY Release-request-reason /* extension present: last param set to true. asn2wrs didn't take notice of that */ offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index, 0U, 30U, NULL, true); #.END #.FN_BODY Release-response-reason /* extension present: last param set to true. asn2wrs didn't take notice of that */ offset = dissect_per_constrained_integer( tvb, offset, actx, tree, hf_index, 0U, 30U, NULL, true); #.END #.FN_BODY Mechanism-name offset = dissect_per_object_identifier( tvb, offset, actx, tree, hf_index, NULL); #.END #.FN_BODY RDNSequence /* * atn-ulcs.asn currently defines * * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName * RelativeDistinguishedName ::= SET SIZE (1 .. MAX) OF AttributeTypeAndValue * AttributeTypeAndValue ::= SEQUENCE { null NULL} * * which makes it easy to spam the dissection tree with null items. Dissect * the first item only. */ offset = dissect_per_constrained_sequence_of(tvb, offset, actx, tree, hf_index, ett_atn_ulcs_RDNSequence, RDNSequence_sequence_of, 1, 1, false); #.END #.FN_BODY RelativeDistinguishedName /* * Dissect the first null item only, similar to RDNSequence. */ offset = dissect_per_constrained_set_of(tvb, offset, actx, tree, hf_index, ett_atn_ulcs_RelativeDistinguishedName, RelativeDistinguishedName_set_of, 1, 1, false); #.END #.FN_BODY EXTERNALt/data-value-descriptor offset = dissect_per_octet_string( tvb, offset, actx, tree, hf_index, -1, -1, false, &actx->external.data_value_descriptor); actx->external.data_value_descr_present = true; #.END #.FN_BODY EXTERNALt/encoding/single-ASN1-type %(DEFAULT_BODY)s #.END #.FN_BODY EXTERNALt/encoding/octet-aligned %(DEFAULT_BODY)s #.END #.FN_BODY EXTERNALt/encoding/arbitrary tvbuff_t *tvb_usr = NULL; packet_info * pinfo = actx->pinfo; atn_conversation_t *atn_cv = NULL; heur_dtbl_entry_t *hdtbl_entry; /* decode bit-string user data within ACSE */ offset = dissect_per_bit_string( tvb, offset, actx, tree, hf_index, NO_BOUND, NO_BOUND, false, NULL, 0, &tvb_usr, NULL); if (tvb_usr) { /* DT: dstref present, srcref is always zero */ if((pinfo->clnp_dstref) && (!pinfo->clnp_srcref)){ atn_cv = find_atn_conversation( &pinfo->dst, pinfo->clnp_dstref, &pinfo->src); } /* CR: srcref present, dstref always zero */ if((pinfo->clnp_srcref) && (!pinfo->clnp_dstref)){ atn_cv = find_atn_conversation( &pinfo->src, pinfo->clnp_srcref, &pinfo->dst); } /* CC: srcref and dstref present */ if((pinfo->clnp_srcref) && (pinfo->clnp_dstref)){ atn_cv = find_atn_conversation( &pinfo->src, pinfo->clnp_srcref, &pinfo->dst); } if(atn_cv) { switch(atn_cv->ae_qualifier){ case cma: /* contact management */ call_dissector_with_data( atn_cm_handle, tvb_new_subset_remaining(tvb_usr, 0), pinfo, root_tree, NULL); break; case cpdlc: /* plain old cpdlc */ case pmcpdlc: /* protected mode cpdlc */ call_dissector_with_data( atn_cpdlc_handle, tvb_new_subset_remaining(tvb_usr, 0), pinfo, root_tree, NULL); break; default: /* unknown or unhandled datalink application */ dissector_try_heuristic( atn_ulcs_heur_subdissector_list, tvb_new_subset_remaining(tvb_usr,0), actx->pinfo, root_tree, &hdtbl_entry, NULL); break; } }else { dissector_try_heuristic( atn_ulcs_heur_subdissector_list, tvb_new_subset_remaining(tvb_usr,0), actx->pinfo, root_tree, &hdtbl_entry, NULL); } } offset += tvb_reported_length_remaining(tvb, offset); #.END # # Editor modelines - https://www.wireshark.org/tools/modelines.html # # Local variables: # c-basic-offset: 4 # tab-width: 8 # indent-tabs-mode: nil # End: # # vi: set shiftwidth=4 tabstop=8 expandtab: # :indentSize=4:tabSize=8:noTabs=true: #