From Gavin Heer:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 28 Apr 2007 14:38:53 +0000 (14:38 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 28 Apr 2007 14:38:53 +0000 (14:38 +0000)
 Here's a patch that decodes MMS(Manufacturing Messaging
Specification) when transported over COTP/TPKT/TCP.  Previously, MMS would only be decoded if the OSI Presentation Layers were present. Now MMS/COTP/TPKT/TCP is dissected.
With a change to use more functions from packet-ber

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@21608 f5534014-38df-0310-8fa8-9805f1628bb7

asn1/mms/mms.asn
asn1/mms/packet-mms-template.c
epan/dissectors/packet-ber.c
epan/dissectors/packet-ber.h
epan/dissectors/packet-h263.c
epan/dissectors/packet-mms.c

index bc11a5f8aee5b7cbda66ed748b17a8935096030e..d7d9a7b8958fa3a9ca310cb553764a41d5071b26 100644 (file)
@@ -21,7 +21,7 @@ IMPORTS
        AP-title,
        AP-invocation-identifier,
        AE-qualifier,
        AP-title,
        AP-invocation-identifier,
        AE-qualifier,
-        AE-invocation-identifier
+    AE-invocation-identifier
 FROM ISO-8650-ACSE-1;
 
 
 FROM ISO-8650-ACSE-1;
 
 
index b3567c3e1bde7d702a017e4e15d00275a1cead71..776d7b8a8e05830a529a81e60c401cdc5b7f1cf0 100644 (file)
@@ -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)");
 /*--- 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);
 }
 }
+
index 0fa56cbb4a3ba0c5a8143e353b25e768059068d2..9422278bc2aa8dc41666f75e5ebb0402ddf14f50 100644 (file)
@@ -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_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_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;
 
 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 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;
 
 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;
 }
 
   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;
 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_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,
     };
 
     static gint *ett[] = {
        &ett_ber_octet_string,
        &ett_ber_unknown,
        &ett_ber_SEQUENCE,
+       &ett_ber_encoding,
+       &ett_ber_EXTERNAL,
     };
     module_t *ber_module;
 
     };
     module_t *ber_module;
 
index 381d2819562dfd9bbe20209435657d98eb69d054..336bbe9c1a9fa127daabcc67d932fdb23bbb1c67 100644 (file)
@@ -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_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
 
 
 #define BER_FLAGS_OPTIONAL     0x00000001
index cb187cb191dea67aeecb265f7ecedf0316471a6f..f939d4761c65b9af5a5aee31d8718fa9ac764176 100644 (file)
@@ -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,
 
        if (hf_field->strings) {
                return proto_tree_add_uint_format(tree, hf_index, tvb, offset, length, value,
-                      "%s: %s",
+                      "%s: %s (%u)",
                                          str,
                                          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:
        }
        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 */
 
        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) 
                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 */ 
 
        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.
         */
                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;
 
        }
                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. 
        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. */
         */
        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);
        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);
index c3f9c7fe6fe937f83e2eb8be6cb824040bd89358..f703f39c8fe861cbe820d3c369d4b74042e6ef6a 100644 (file)
@@ -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)");
 /*--- 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);
 }
 }
+