TCAP: Don't attempt to decode content when a subdissector has done it.

This commit is contained in:
Anders Broman 2021-02-05 08:57:33 +01:00 committed by AndersBroman
parent 51f6be91e7
commit 1bb97c5973
3 changed files with 189 additions and 183 deletions

View File

@ -105,7 +105,7 @@ static dissector_handle_t data_handle;
static dissector_handle_t ansi_tcap_handle;
static int dissect_tcap_param(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset);
static int dissect_tcap_ITU_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_);
static gboolean dissect_tcap_ITU_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_);
static dissector_table_t ansi_sub_dissectors = NULL;
static dissector_table_t itu_sub_dissectors = NULL;
@ -2195,8 +2195,8 @@ dissect_tcap_param(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset
/*
* Call ITU Subdissector to decode the Tcap Component
*/
static int
dissect_tcap_ITU_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_)
static gboolean
dissect_tcap_ITU_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset _U_, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_)
{
dissector_handle_t subdissector_handle=NULL;
gboolean is_subdissector=FALSE;
@ -2223,107 +2223,109 @@ dissect_tcap_ITU_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offs
}
}
if (p_tcap_context) {
if (cur_oid) {
if (p_tcap_context->oid_present) {
/* We have already an Application Context, check if we have
to fallback to a lower version */
if ( strncmp(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid))!=0) {
/* ACN, changed, Fallback to lower version
* and update the subdissector (purely formal)
*/
g_strlcpy(p_tcap_context->oid,cur_oid, sizeof(p_tcap_context->oid));
if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
p_tcap_context->subdissector_handle=subdissector_handle;
p_tcap_context->subdissector_present=TRUE;
}
}
if (cur_oid) {
if (p_tcap_context->oid_present) {
/* We have already an Application Context, check if we have
to fallback to a lower version */
if (strncmp(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid)) != 0) {
/* ACN, changed, Fallback to lower version
* and update the subdissector (purely formal)
*/
g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
if ((subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
p_tcap_context->subdissector_handle = subdissector_handle;
p_tcap_context->subdissector_present = TRUE;
}
}
} else {
/* We do not have the OID in the TCAP context, so store it */
g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
p_tcap_context->oid_present = TRUE;
/* Try to find a subdissector according to OID */
if ((subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
p_tcap_context->subdissector_handle = subdissector_handle;
p_tcap_context->subdissector_present = TRUE;
} else {
/* Not found, so try to find a subdissector according to SSN */
if ((subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
p_tcap_context->subdissector_handle = subdissector_handle;
p_tcap_context->subdissector_present = TRUE;
}
}
} /* context OID */
} else {
/* We do not have the OID in the TCAP context, so store it */
g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
p_tcap_context->oid_present=TRUE;
/* Try to find a subdissector according to OID */
if ( (subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
p_tcap_context->subdissector_handle=subdissector_handle;
p_tcap_context->subdissector_present=TRUE;
} else {
/* Not found, so try to find a subdissector according to SSN */
if ( (subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
p_tcap_context->subdissector_handle=subdissector_handle;
p_tcap_context->subdissector_present=TRUE;
/* Copy the OID from the TCAP context to the current oid */
if (p_tcap_context->oid_present) {
p_tcap_private->oid = (void*)p_tcap_context->oid;
p_tcap_private->acv = TRUE;
}
}
} /* context OID */
} else {
/* Copy the OID from the TCAP context to the current oid */
if (p_tcap_context->oid_present) {
p_tcap_private->oid= (void*) p_tcap_context->oid;
p_tcap_private->acv=TRUE;
}
} /* no OID */
} /* no OID */
} /* no TCAP context */
if ( p_tcap_context
&& p_tcap_context->subdissector_present) {
/* Take the subdissector from the context */
subdissector_handle=p_tcap_context->subdissector_handle;
is_subdissector=TRUE;
if (p_tcap_context
&& p_tcap_context->subdissector_present) {
/* Take the subdissector from the context */
subdissector_handle = p_tcap_context->subdissector_handle;
is_subdissector = TRUE;
}
/* Have SccpUsersTable protocol taking precedence over sccp.ssn table */
if (!is_subdissector && requested_subdissector_handle) {
is_subdissector = TRUE;
subdissector_handle = requested_subdissector_handle;
is_subdissector = TRUE;
subdissector_handle = requested_subdissector_handle;
}
if (!is_subdissector) {
/*
* If we do not currently know the subdissector, we have to find it
* - first, according to the OID
* - then according to the SSN
* - and at least, take the default Data handler
*/
if (ber_oid_dissector_table && cur_oid) {
/* Search if we can find the sub protocol according to the A.C.N */
if ( (subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
/* found */
is_subdissector=TRUE;
/*
* If we do not currently know the subdissector, we have to find it
* - first, according to the OID
* - then according to the SSN
* - and at least, take the default Data handler
*/
if (ber_oid_dissector_table && cur_oid) {
/* Search if we can find the sub protocol according to the A.C.N */
if ((subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
/* found */
is_subdissector = TRUE;
} else {
/* Search if we can found the sub protocol according to the SSN table */
if ((subdissector_handle
= get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
is_subdissector = TRUE;
} else {
/* Nothing found, take the Data handler */
subdissector_handle = data_handle;
is_subdissector = TRUE;
} /* SSN */
} /* ACN */
} else {
/* Search if we can found the sub protocol according to the SSN table */
if ( (subdissector_handle
= get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
is_subdissector=TRUE;
} else {
/* Nothing found, take the Data handler */
subdissector_handle = data_handle;
is_subdissector=TRUE;
} /* SSN */
} /* ACN */
} else {
/* There is no A.C.N for this transaction, so search in the SSN table */
if ( (subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
is_subdissector=TRUE;
} else {
subdissector_handle = data_handle;
is_subdissector=TRUE;
}
} /* OID */
/* There is no A.C.N for this transaction, so search in the SSN table */
if ((subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
is_subdissector = TRUE;
} else {
subdissector_handle = data_handle;
is_subdissector = TRUE;
}
} /* OID */
} else {
/* We have it already */
/* We have it already */
}
/* Call the sub dissector if present, and not already called */
if (is_subdissector) {
call_dissector_with_data(subdissector_handle, tvb, actx->pinfo, tree, actx->value_ptr);
col_set_fence(actx->pinfo->cinfo, COL_INFO);
gboolean is_active = call_dissector_only(subdissector_handle, tvb, actx->pinfo, tree, actx->value_ptr);
col_set_fence(actx->pinfo->cinfo, COL_INFO);
if(!is_active){
return FALSE;
}
}
return offset;
return TRUE;
}
void

View File

@ -94,6 +94,9 @@ ABRT-apdu/_untag/user-information abrt_user_information
if (!next_tvb)
return comp_offset;
if(dissect_tcap_ITU_ComponentPDU(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index)){
return comp_offset;
}
_offset = offset;
TRY {
@ -107,8 +110,6 @@ ABRT-apdu/_untag/user-information abrt_user_information
ENDTRY;
offset = _offset;
dissect_tcap_ITU_ComponentPDU(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index);
/* return comp_offset+len; or return offset (will be automatically added) */
#----------------------------------------------------------------------------------------

View File

@ -223,7 +223,7 @@ static dissector_handle_t data_handle;
static dissector_handle_t ansi_tcap_handle;
static int dissect_tcap_param(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset);
static int dissect_tcap_ITU_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_);
static gboolean dissect_tcap_ITU_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_);
static dissector_table_t ansi_sub_dissectors = NULL;
static dissector_table_t itu_sub_dissectors = NULL;
@ -669,6 +669,9 @@ dissect_tcap_Component(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset
if (!next_tvb)
return comp_offset;
if(dissect_tcap_ITU_ComponentPDU(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index)){
return comp_offset;
}
_offset = offset;
TRY {
@ -682,8 +685,6 @@ dissect_tcap_Component(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset
ENDTRY;
offset = _offset;
dissect_tcap_ITU_ComponentPDU(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index);
/* return comp_offset+len; or return offset (will be automatically added) */
@ -743,7 +744,7 @@ dissect_tcap_OCTET_STRING_SIZE_1_4(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
static int
dissect_tcap_OrigTransactionID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
#line 140 "./asn1/tcap/tcap.cnf"
#line 141 "./asn1/tcap/tcap.cnf"
tvbuff_t *parameter_tvb;
guint8 len, i;
proto_tree *subtree;
@ -808,7 +809,7 @@ static const ber_sequence_t Begin_sequence[] = {
static int
dissect_tcap_Begin(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
#line 236 "./asn1/tcap/tcap.cnf"
#line 237 "./asn1/tcap/tcap.cnf"
gp_tcapsrt_info->ope=TC_BEGIN;
/* Do not change col_add_str() to col_append_str() here: we _want_ this call
@ -830,7 +831,7 @@ gp_tcapsrt_info->ope=TC_BEGIN;
static int
dissect_tcap_DestTransactionID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
#line 189 "./asn1/tcap/tcap.cnf"
#line 190 "./asn1/tcap/tcap.cnf"
tvbuff_t *parameter_tvb;
guint8 len , i;
proto_tree *subtree;
@ -894,7 +895,7 @@ static const ber_sequence_t End_sequence[] = {
static int
dissect_tcap_End(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
#line 250 "./asn1/tcap/tcap.cnf"
#line 251 "./asn1/tcap/tcap.cnf"
gp_tcapsrt_info->ope=TC_END;
col_set_str(actx->pinfo->cinfo, COL_INFO, "End ");
@ -916,7 +917,7 @@ static const ber_sequence_t Continue_sequence[] = {
static int
dissect_tcap_Continue(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
#line 257 "./asn1/tcap/tcap.cnf"
#line 258 "./asn1/tcap/tcap.cnf"
gp_tcapsrt_info->ope=TC_CONT;
col_set_str(actx->pinfo->cinfo, COL_INFO, "Continue ");
@ -987,7 +988,7 @@ static const ber_sequence_t Abort_sequence[] = {
static int
dissect_tcap_Abort(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
#line 264 "./asn1/tcap/tcap.cnf"
#line 265 "./asn1/tcap/tcap.cnf"
gp_tcapsrt_info->ope=TC_ABORT;
col_set_str(actx->pinfo->cinfo, COL_INFO, "Abort ");
@ -1036,7 +1037,7 @@ dissect_tcap_AUDT_protocol_version(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
static int
dissect_tcap_AUDT_application_context_name(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
#line 116 "./asn1/tcap/tcap.cnf"
#line 117 "./asn1/tcap/tcap.cnf"
struct tcap_private_t *p_tcap_private = (struct tcap_private_t*)actx->value_ptr;
offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &cur_oid);
@ -1136,7 +1137,7 @@ dissect_tcap_AARQ_protocol_version(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
static int
dissect_tcap_AARQ_application_context_name(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
#line 124 "./asn1/tcap/tcap.cnf"
#line 125 "./asn1/tcap/tcap.cnf"
struct tcap_private_t *p_tcap_private = (struct tcap_private_t*)actx->value_ptr;
offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &cur_oid);
@ -1207,7 +1208,7 @@ dissect_tcap_AARE_protocol_version(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
static int
dissect_tcap_AARE_application_context_name(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
#line 132 "./asn1/tcap/tcap.cnf"
#line 133 "./asn1/tcap/tcap.cnf"
struct tcap_private_t *p_tcap_private = (struct tcap_private_t*)actx->value_ptr;
offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &cur_oid);
@ -3801,8 +3802,8 @@ dissect_tcap_param(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset
/*
* Call ITU Subdissector to decode the Tcap Component
*/
static int
dissect_tcap_ITU_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_)
static gboolean
dissect_tcap_ITU_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset _U_, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_)
{
dissector_handle_t subdissector_handle=NULL;
gboolean is_subdissector=FALSE;
@ -3829,107 +3830,109 @@ dissect_tcap_ITU_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offs
}
}
if (p_tcap_context) {
if (cur_oid) {
if (p_tcap_context->oid_present) {
/* We have already an Application Context, check if we have
to fallback to a lower version */
if ( strncmp(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid))!=0) {
/* ACN, changed, Fallback to lower version
* and update the subdissector (purely formal)
*/
g_strlcpy(p_tcap_context->oid,cur_oid, sizeof(p_tcap_context->oid));
if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
p_tcap_context->subdissector_handle=subdissector_handle;
p_tcap_context->subdissector_present=TRUE;
}
}
if (cur_oid) {
if (p_tcap_context->oid_present) {
/* We have already an Application Context, check if we have
to fallback to a lower version */
if (strncmp(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid)) != 0) {
/* ACN, changed, Fallback to lower version
* and update the subdissector (purely formal)
*/
g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
if ((subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
p_tcap_context->subdissector_handle = subdissector_handle;
p_tcap_context->subdissector_present = TRUE;
}
}
} else {
/* We do not have the OID in the TCAP context, so store it */
g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
p_tcap_context->oid_present = TRUE;
/* Try to find a subdissector according to OID */
if ((subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
p_tcap_context->subdissector_handle = subdissector_handle;
p_tcap_context->subdissector_present = TRUE;
} else {
/* Not found, so try to find a subdissector according to SSN */
if ((subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
p_tcap_context->subdissector_handle = subdissector_handle;
p_tcap_context->subdissector_present = TRUE;
}
}
} /* context OID */
} else {
/* We do not have the OID in the TCAP context, so store it */
g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
p_tcap_context->oid_present=TRUE;
/* Try to find a subdissector according to OID */
if ( (subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
p_tcap_context->subdissector_handle=subdissector_handle;
p_tcap_context->subdissector_present=TRUE;
} else {
/* Not found, so try to find a subdissector according to SSN */
if ( (subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
p_tcap_context->subdissector_handle=subdissector_handle;
p_tcap_context->subdissector_present=TRUE;
/* Copy the OID from the TCAP context to the current oid */
if (p_tcap_context->oid_present) {
p_tcap_private->oid = (void*)p_tcap_context->oid;
p_tcap_private->acv = TRUE;
}
}
} /* context OID */
} else {
/* Copy the OID from the TCAP context to the current oid */
if (p_tcap_context->oid_present) {
p_tcap_private->oid= (void*) p_tcap_context->oid;
p_tcap_private->acv=TRUE;
}
} /* no OID */
} /* no OID */
} /* no TCAP context */
if ( p_tcap_context
&& p_tcap_context->subdissector_present) {
/* Take the subdissector from the context */
subdissector_handle=p_tcap_context->subdissector_handle;
is_subdissector=TRUE;
if (p_tcap_context
&& p_tcap_context->subdissector_present) {
/* Take the subdissector from the context */
subdissector_handle = p_tcap_context->subdissector_handle;
is_subdissector = TRUE;
}
/* Have SccpUsersTable protocol taking precedence over sccp.ssn table */
if (!is_subdissector && requested_subdissector_handle) {
is_subdissector = TRUE;
subdissector_handle = requested_subdissector_handle;
is_subdissector = TRUE;
subdissector_handle = requested_subdissector_handle;
}
if (!is_subdissector) {
/*
* If we do not currently know the subdissector, we have to find it
* - first, according to the OID
* - then according to the SSN
* - and at least, take the default Data handler
*/
if (ber_oid_dissector_table && cur_oid) {
/* Search if we can find the sub protocol according to the A.C.N */
if ( (subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
/* found */
is_subdissector=TRUE;
/*
* If we do not currently know the subdissector, we have to find it
* - first, according to the OID
* - then according to the SSN
* - and at least, take the default Data handler
*/
if (ber_oid_dissector_table && cur_oid) {
/* Search if we can find the sub protocol according to the A.C.N */
if ((subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
/* found */
is_subdissector = TRUE;
} else {
/* Search if we can found the sub protocol according to the SSN table */
if ((subdissector_handle
= get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
is_subdissector = TRUE;
} else {
/* Nothing found, take the Data handler */
subdissector_handle = data_handle;
is_subdissector = TRUE;
} /* SSN */
} /* ACN */
} else {
/* Search if we can found the sub protocol according to the SSN table */
if ( (subdissector_handle
= get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
is_subdissector=TRUE;
} else {
/* Nothing found, take the Data handler */
subdissector_handle = data_handle;
is_subdissector=TRUE;
} /* SSN */
} /* ACN */
} else {
/* There is no A.C.N for this transaction, so search in the SSN table */
if ( (subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
is_subdissector=TRUE;
} else {
subdissector_handle = data_handle;
is_subdissector=TRUE;
}
} /* OID */
/* There is no A.C.N for this transaction, so search in the SSN table */
if ((subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
/* Found according to SSN */
is_subdissector = TRUE;
} else {
subdissector_handle = data_handle;
is_subdissector = TRUE;
}
} /* OID */
} else {
/* We have it already */
/* We have it already */
}
/* Call the sub dissector if present, and not already called */
if (is_subdissector) {
call_dissector_with_data(subdissector_handle, tvb, actx->pinfo, tree, actx->value_ptr);
col_set_fence(actx->pinfo->cinfo, COL_INFO);
gboolean is_active = call_dissector_only(subdissector_handle, tvb, actx->pinfo, tree, actx->value_ptr);
col_set_fence(actx->pinfo->cinfo, COL_INFO);
if(!is_active){
return FALSE;
}
}
return offset;
return TRUE;
}
void