From Gavin Heer:

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

svn path=/trunk/; revision=21608
This commit is contained in:
Anders Broman 2007-04-28 14:38:53 +00:00
parent 43bb2aea51
commit 2630b817b0
6 changed files with 273 additions and 10 deletions

View File

@ -21,7 +21,7 @@ IMPORTS
AP-title,
AP-invocation-identifier,
AE-qualifier,
AE-invocation-identifier
AE-invocation-identifier
FROM ISO-8650-ACSE-1;

View 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)");
heur_dissector_add("cotp", dissect_mms_heur, proto_mms);
heur_dissector_add("cotp_is", dissect_mms_heur, proto_mms);
}

View 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_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;

View 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_external(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id);
#define BER_FLAGS_OPTIONAL 0x00000001

View 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,
"%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);

View 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)");
heur_dissector_add("cotp", dissect_mms_heur, proto_mms);
heur_dissector_add("cotp_is", dissect_mms_heur, proto_mms);
}