diff options
-rw-r--r-- | asn1/mms/mms.asn | 2 | ||||
-rw-r--r-- | asn1/mms/packet-mms-template.c | 52 | ||||
-rw-r--r-- | epan/dissectors/packet-ber.c | 161 | ||||
-rw-r--r-- | epan/dissectors/packet-ber.h | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-h263.c | 15 | ||||
-rw-r--r-- | epan/dissectors/packet-mms.c | 52 |
6 files changed, 273 insertions, 10 deletions
diff --git a/asn1/mms/mms.asn b/asn1/mms/mms.asn index bc11a5f8ae..d7d9a7b895 100644 --- a/asn1/mms/mms.asn +++ b/asn1/mms/mms.asn @@ -21,7 +21,7 @@ IMPORTS AP-title, AP-invocation-identifier, AE-qualifier, - AE-invocation-identifier + AE-invocation-identifier FROM ISO-8650-ACSE-1; diff --git a/asn1/mms/packet-mms-template.c b/asn1/mms/packet-mms-template.c index b3567c3e1b..776d7b8a8e 100644 --- a/asn1/mms/packet-mms-template.c +++ b/asn1/mms/packet-mms-template.c @@ -110,9 +110,59 @@ void proto_register_mms(void) { } +static gboolean +dissect_mms_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) +{ + /* must check that this really is an mms packet */ + int offset = 0; + guint32 length = 0 ; + guint32 oct; + gint idx = 0 ; + + gint8 tmp_class; + gboolean tmp_pc; + gint32 tmp_tag; + + /* first, check do we have at least 2 bytes (pdu) */ + if (!tvb_bytes_exist(tvb, 0, 2)) + return FALSE; /* no */ + + /* can we recognize MMS PDU ? Return FALSE if not */ + /* get MMS PDU type */ + offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag); + + /* check MMS type */ + + /* Class should be constructed */ + if (tmp_class!=BER_CLASS_CON) + return FALSE; + + /* see if the tag is a valid MMS PDU */ + match_strval_idx(tmp_tag, mms_MMSpdu_vals, &idx); + if (idx == -1) { + return FALSE; /* no, it isn't an MMS PDU */ + } + + /* check MMS length */ + oct = tvb_get_guint8(tvb, offset)& 0x7F; + if (oct==0) + /* MMS requires length after tag so not MMS if indefinite length*/ + return FALSE; + + offset = get_ber_length(NULL, tvb, offset, &length, NULL); + /* do we have enough bytes? */ + if (!tvb_bytes_exist(tvb, offset, length)) + return FALSE; + + dissect_mms(tvb, pinfo, parent_tree); + return TRUE; +} + /*--- proto_reg_handoff_mms --- */ void proto_reg_handoff_mms(void) { register_ber_oid_dissector("1.0.9506.2.3", dissect_mms, proto_mms,"MMS"); register_ber_oid_dissector("1.0.9506.2.1", dissect_mms, proto_mms,"mms-abstract-syntax-version1(1)"); - + heur_dissector_add("cotp", dissect_mms_heur, proto_mms); + heur_dissector_add("cotp_is", dissect_mms_heur, proto_mms); } + diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c index 0fa56cbb4a..9422278bc2 100644 --- a/epan/dissectors/packet-ber.c +++ b/epan/dissectors/packet-ber.c @@ -105,10 +105,19 @@ static gint hf_ber_unknown_GeneralizedTime = -1; static gint hf_ber_unknown_INTEGER = -1; static gint hf_ber_unknown_BITSTRING = -1; static gint hf_ber_unknown_ENUMERATED = -1; +static gint hf_ber_direct_reference = -1; /* OBJECT_IDENTIFIER */ +static gint hf_ber_indirect_reference = -1; /* INTEGER */ +static gint hf_ber_data_value_descriptor = -1; /* ObjectDescriptor */ +static gint hf_ber_encoding = -1; /* T_encoding */ +static gint hf_ber_single_ASN1_type = -1; /* T_single_ASN1_type */ +static gint hf_ber_octet_aligned = -1; /* OCTET_STRING */ +static gint hf_ber_arbitrary = -1; /* BIT_STRING */ static gint ett_ber_octet_string = -1; static gint ett_ber_unknown = -1; static gint ett_ber_SEQUENCE = -1; +static gint ett_ber_EXTERNAL = -1; +static gint ett_ber_encoding = -1; static gboolean show_internal_ber_fields = FALSE; static gboolean decode_octetstring_as_ber = FALSE; @@ -117,6 +126,7 @@ static gchar *decode_as_syntax = NULL; static gchar *ber_filename = NULL; proto_item *ber_last_created_item=NULL; +static const char *single_ASN1_type_obj_id; static dissector_table_t ber_oid_dissector_table=NULL; static dissector_table_t ber_syntax_dissector_table=NULL; @@ -2171,8 +2181,127 @@ int dissect_ber_object_identifier_str(gboolean implicit_tag, packet_info *pinfo, return offset; } +/* + * EXTERNAL::= [UNIVERSAL 8] IMPLICIT SEQUENCE { + * direct-reference OBJECT IDENTIFIER OPTIONAL, + * indirect-reference INTEGER OPTIONAL, + * data-value-descriptor ObjectDescriptor OPTIONAL, + * encoding CHOICE { + * single-ASN1-type [0] ABSTRACT-SYNTAX.&Type, + * octet-aligned [1] IMPLICIT OCTET STRING, + * arbitrary [2] IMPLICIT BIT STRING } } + */ +static int dissect_single_ASN1_type(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_) { + /* hf_ber_single_ASN1_type */ + tvbuff_t *next_tvb; + proto_item *item; + gint8 class; + gboolean pc; + gint tag; + guint32 len; + gint ind_field; + + offset = dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag); + offset = dissect_ber_length(pinfo, tree, tvb, offset, &len, &ind_field); + + next_tvb = tvb_new_subset(tvb, offset, len, len); + if (!next_tvb) + return offset; + g_warning("%s",single_ASN1_type_obj_id); + if(single_ASN1_type_obj_id){ + call_ber_oid_callback(single_ASN1_type_obj_id, next_tvb, 0, pinfo, tree); + }else{ + item = proto_tree_add_text(tree, next_tvb, 0, -1,"dissector is not available"); + offset = dissect_ber_octet_string(TRUE, pinfo, tree, tvb, offset, -1,NULL); + } + + return offset; +} + + +static int dissect_octet_aligned_impl(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_) { + offset = dissect_ber_octet_string(TRUE, pinfo, tree, tvb, offset, hf_ber_octet_aligned, + NULL); + + return offset; +} + +static int dissect_arbitrary_impl(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_) { + offset = dissect_ber_bitstring(TRUE, pinfo, tree, tvb, offset, + NULL, hf_ber_arbitrary, -1, + NULL); + + return offset; +} + +static int dissect_indirect_reference(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_) { + offset = dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_ber_indirect_reference, + NULL); + return offset; + +} + +static int dissect_direct_reference(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_) { + offset = dissect_ber_object_identifier_str(FALSE, pinfo, tree, tvb, offset, hf_ber_direct_reference, &single_ASN1_type_obj_id); + return offset; +} + +static int dissect_data_value_descriptor(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_) { + offset = dissect_ber_restricted_string(FALSE, BER_UNI_TAG_ObjectDescriptor, + pinfo, tree, tvb, offset, hf_ber_data_value_descriptor, + NULL); + return offset; +} + +static const value_string ber_T_encoding_vals[] = { + { 0, "single-ASN1-type" }, + { 1, "octet-aligned" }, + { 2, "arbitrary" }, + { 0, NULL } +}; + +static const ber_choice_t ber_T_encoding_choice[] = { + { 0, BER_CLASS_CON, 0, 0, dissect_single_ASN1_type }, + { 1, BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_octet_aligned_impl }, + { 2, BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_arbitrary_impl }, + { 0, 0, 0, 0, NULL } +}; + +static int dissect_encoding(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_) { + offset = dissect_ber_choice(pinfo, tree, tvb, offset, + ber_T_encoding_choice, hf_ber_encoding, ett_ber_encoding, + NULL); + return offset; +} + +static const ber_sequence_t EXTERNAL_sequence[] = { + { BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_direct_reference }, + { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_indirect_reference }, + { BER_CLASS_UNI, BER_UNI_TAG_ObjectDescriptor, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_data_value_descriptor }, + { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_encoding }, + { 0, 0, 0, NULL } +}; + +int dissect_ber_external(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id) +{ + gint8 class; + gboolean pc, ind = FALSE; + gint32 tag; + guint32 len; + + if(!implicit_tag){ + offset = dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag); + offset = dissect_ber_length(pinfo, tree, tvb, offset, &len, &ind); + } + + offset = dissect_ber_sequence(TRUE, pinfo, tree, tvb, offset, + EXTERNAL_sequence, hf_id, ett_ber_EXTERNAL); + + return offset; + +} static int dissect_ber_sq_of(gboolean implicit_tag, gint32 type, packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_sequence_t *seq, gint hf_id, gint ett_id) { gint8 class; gboolean pc, ind = FALSE, ind_field; @@ -2709,12 +2838,44 @@ proto_register_ber(void) { &hf_ber_unknown_ENUMERATED, { "ENUMERATED", "ber.unknown.ENUMERATED", FT_UINT32, BASE_DEC, NULL, 0, "This is an unknown ENUMERATED", HFILL }}, + { &hf_ber_direct_reference, + { "direct-reference", "ber.direct_reference", + FT_OID, BASE_NONE, NULL, 0, + "ber.OBJECT_IDENTIFIER", HFILL }}, + { &hf_ber_indirect_reference, + { "indirect-reference", "ber.indirect_reference", + FT_INT32, BASE_DEC, NULL, 0, + "ber.INTEGER", HFILL }}, + { &hf_ber_data_value_descriptor, + { "data-value-descriptor", "ber.data_value_descriptor", + FT_STRING, BASE_NONE, NULL, 0, + "ber.ObjectDescriptor", HFILL }}, + { &hf_ber_encoding, + { "encoding", "ber.encoding", + FT_UINT32, BASE_DEC, VALS(ber_T_encoding_vals), 0, + "ber.T_encoding", HFILL }}, + { &hf_ber_octet_aligned, + { "octet-aligned", "ber.octet_aligned", + FT_BYTES, BASE_HEX, NULL, 0, + "ber.OCTET_STRING", HFILL }}, + { &hf_ber_arbitrary, + { "arbitrary", "ber.arbitrary", + FT_BYTES, BASE_HEX, NULL, 0, + "ber.BIT_STRING", HFILL }}, + + { &hf_ber_single_ASN1_type, + { "single-ASN1-type", "ber.single_ASN1_type", + FT_NONE, BASE_NONE, NULL, 0, + "ber.T_single_ASN1_type", HFILL }}, + }; static gint *ett[] = { &ett_ber_octet_string, &ett_ber_unknown, &ett_ber_SEQUENCE, + &ett_ber_encoding, + &ett_ber_EXTERNAL, }; module_t *ber_module; diff --git a/epan/dissectors/packet-ber.h b/epan/dissectors/packet-ber.h index 381d281956..336bbe9c1a 100644 --- a/epan/dissectors/packet-ber.h +++ b/epan/dissectors/packet-ber.h @@ -113,6 +113,7 @@ extern int dissect_ber_null(gboolean implicit_tag, packet_info *pinfo, proto_tre extern int dissect_ber_boolean(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id); extern int dissect_ber_boolean_value(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, gboolean *value); +extern int dissect_ber_external(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id); #define BER_FLAGS_OPTIONAL 0x00000001 diff --git a/epan/dissectors/packet-h263.c b/epan/dissectors/packet-h263.c index cb187cb191..f939d4761c 100644 --- a/epan/dissectors/packet-h263.c +++ b/epan/dissectors/packet-h263.c @@ -561,9 +561,10 @@ h263_proto_tree_add_bits(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint bit if (hf_field->strings) { return proto_tree_add_uint_format(tree, hf_index, tvb, offset, length, value, - "%s: %s", + "%s: %s (%u)", str, - val_to_str(value, cVALS(hf_field->strings), "Unknown")); + val_to_str(value, cVALS(hf_field->strings), "Unknown "), + value); } switch(hf_field->display){ case BASE_DEC: @@ -604,7 +605,7 @@ dissect_h263_group_of_blocks_layer( tvbuff_t *tvb, proto_tree *tree, gint offset if(is_rfc4626){ /* GBSC 1xxx xxxx */ - h263_proto_tree_add_bits(tree, hf_h263_gbsc, tvb, offset_in_bits, 1, NULL); + proto_tree_add_bits_ret_val(tree, hf_h263_gbsc, tvb, offset_in_bits, 1, NULL, FALSE); offset_in_bits++; }else{ /* Group of Block Start Code (GBSC) (17 bits) @@ -655,18 +656,18 @@ dissect_h263_picture_layer( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, if(is_rfc4626){ /* PC 1000 00xx */ - h263_proto_tree_add_bits(tree, hf_h263_psc, tvb, offset_in_bits, 6, NULL); + proto_tree_add_bits_ret_val(tree, hf_h263_psc, tvb, offset_in_bits+7, 39, NULL, FALSE); offset_in_bits = offset_in_bits +6; }else{ /* Check for PSC, PSC is a word of 22 bits. * Its value is 0000 0000 0000 0000' 1000 00xx xxxx xxxx. */ - h263_proto_tree_add_bits(tree, hf_h263_psc, tvb, offset_in_bits, 22, NULL); + proto_tree_add_bits_ret_val(tree, hf_h263_psc, tvb, offset_in_bits+4, 64, NULL, FALSE); offset_in_bits = offset_in_bits +22; } - h263_proto_tree_add_bits(tree, hf_h263_TR, tvb, offset_in_bits, 8, NULL); + proto_tree_add_bits_ret_val(tree, hf_h263_TR, tvb, offset_in_bits, 8, NULL, FALSE); offset_in_bits = offset_in_bits +8; /* * Bit 1: Always "1", in order to avoid start code emulation. @@ -674,7 +675,7 @@ dissect_h263_picture_layer( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, */ offset_in_bits = offset_in_bits +2; /* Bit 3: Split screen indicator, "0" off, "1" on. */ - h263_proto_tree_add_bits( tree, hf_h263_split_screen_indicator, tvb, offset_in_bits, 1, NULL); + proto_tree_add_bits_ret_val( tree, hf_h263_split_screen_indicator, tvb, offset_in_bits, 1, NULL, FALSE); offset_in_bits++; /* Bit 4: Document camera indicator, */ h263_proto_tree_add_bits( tree, hf_h263_document_camera_indicator, tvb, offset_in_bits, 1, NULL); diff --git a/epan/dissectors/packet-mms.c b/epan/dissectors/packet-mms.c index c3f9c7fe6f..f703f39c8f 100644 --- a/epan/dissectors/packet-mms.c +++ b/epan/dissectors/packet-mms.c @@ -11466,9 +11466,59 @@ void proto_register_mms(void) { } +static gboolean +dissect_mms_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) +{ + /* must check that this really is an mms packet */ + int offset = 0; + guint32 length = 0 ; + guint32 oct; + gint idx = 0 ; + + gint8 tmp_class; + gboolean tmp_pc; + gint32 tmp_tag; + + /* first, check do we have at least 2 bytes (pdu) */ + if (!tvb_bytes_exist(tvb, 0, 2)) + return FALSE; /* no */ + + /* can we recognize MMS PDU ? Return FALSE if not */ + /* get MMS PDU type */ + offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag); + + /* check MMS type */ + + /* Class should be constructed */ + if (tmp_class!=BER_CLASS_CON) + return FALSE; + + /* see if the tag is a valid MMS PDU */ + match_strval_idx(tmp_tag, mms_MMSpdu_vals, &idx); + if (idx == -1) { + return FALSE; /* no, it isn't an MMS PDU */ + } + + /* check MMS length */ + oct = tvb_get_guint8(tvb, offset)& 0x7F; + if (oct==0) + /* MMS requires length after tag so not MMS if indefinite length*/ + return FALSE; + + offset = get_ber_length(NULL, tvb, offset, &length, NULL); + /* do we have enough bytes? */ + if (!tvb_bytes_exist(tvb, offset, length)) + return FALSE; + + dissect_mms(tvb, pinfo, parent_tree); + return TRUE; +} + /*--- proto_reg_handoff_mms --- */ void proto_reg_handoff_mms(void) { register_ber_oid_dissector("1.0.9506.2.3", dissect_mms, proto_mms,"MMS"); register_ber_oid_dissector("1.0.9506.2.1", dissect_mms, proto_mms,"mms-abstract-syntax-version1(1)"); - + heur_dissector_add("cotp", dissect_mms_heur, proto_mms); + heur_dissector_add("cotp_is", dissect_mms_heur, proto_mms); } + |