diff options
author | Michael Mann <mmann78@netscape.net> | 2013-10-06 02:31:10 +0000 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2013-10-06 02:31:10 +0000 |
commit | ee208c8dcc371ca10986b7e8ea28c933e4bfaae9 (patch) | |
tree | 34da4ba8bde2ea6a7f071f47cd24bf2950f39331 /epan/dissectors/packet-ber.c | |
parent | 625fbd5f9a09483485f9c2b0271ab29afb68a597 (diff) | |
download | wireshark-ee208c8dcc371ca10986b7e8ea28c933e4bfaae9.tar.gz |
Add support for RELATIVE-OID ASN.1 type. Bug 9192 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9192)
From Ed Beroset.
svn path=/trunk/; revision=52393
Diffstat (limited to 'epan/dissectors/packet-ber.c')
-rw-r--r-- | epan/dissectors/packet-ber.c | 116 |
1 files changed, 107 insertions, 9 deletions
diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c index 9d5ccf6898..d1f75ecfe8 100644 --- a/epan/dissectors/packet-ber.c +++ b/epan/dissectors/packet-ber.c @@ -849,6 +849,9 @@ try_dissect_unknown_ber(packet_info *pinfo, tvbuff_t *tvb, volatile int offset, case BER_UNI_TAG_OID: offset = dissect_ber_object_identifier_str(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OID, NULL); break; + case BER_UNI_TAG_RELATIVE_OID: + offset = dissect_ber_relative_oid_str(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OID, NULL); + break; case BER_UNI_TAG_NumericString: offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_NumericString, NULL); break; @@ -3229,7 +3232,6 @@ dissect_ber_choice(asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int #ifdef DEBUG_BER_CHOICE { const char *name; -header_field_info *hfinfo; if (hf_id >= 0) { hfinfo = proto_registrar_get_nth(hf_id); name = hfinfo->name; @@ -3356,7 +3358,6 @@ printf("CHOICE testing potential subdissector class[%p]:%d:(expected)%d tag:%d: #ifdef DEBUG_BER_CHOICE { const char *name; -header_field_info *hfinfo; if (hf_id >= 0) { hfinfo = proto_registrar_get_nth(hf_id); name = hfinfo->name; @@ -3381,7 +3382,6 @@ printf("CHOICE dissect_ber_choice(%s) calling subdissector len:%d\n", name, tvb_ #ifdef DEBUG_BER_CHOICE { const char *name; -header_field_info *hfinfo; if (hf_id >= 0) { hfinfo = proto_registrar_get_nth(hf_id); name = hfinfo->name; @@ -3397,7 +3397,6 @@ printf("CHOICE dissect_ber_choice(%s) subdissector ate %d bytes\n", name, count) #ifdef DEBUG_BER_CHOICE { const char *name; -header_field_info *hfinfo; if (hf_id >= 0) { hfinfo = proto_registrar_get_nth(hf_id); name = hfinfo->name; @@ -3465,7 +3464,6 @@ dissect_ber_old_choice(asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, #ifdef DEBUG_BER_CHOICE { const char *name; -header_field_info *hfinfo; if (hf_id >= 0) { hfinfo = proto_registrar_get_nth(hf_id); name = hfinfo->name; @@ -3592,7 +3590,6 @@ printf("CHOICE testing potential subdissector class[%p]:%d:(expected)%d tag:%d: #ifdef DEBUG_BER_CHOICE { const char *name; -header_field_info *hfinfo; if (hf_id >= 0) { hfinfo = proto_registrar_get_nth(hf_id); name = hfinfo->name; @@ -3614,7 +3611,6 @@ printf("CHOICE dissect_ber_old_choice(%s) calling subdissector len:%d\n", name, #ifdef DEBUG_BER_CHOICE { const char *name; -header_field_info *hfinfo; if (hf_id >= 0) { hfinfo = proto_registrar_get_nth(hf_id); name = hfinfo->name; @@ -3630,7 +3626,6 @@ printf("CHOICE dissect_ber_old_choice(%s) subdissector ate %d bytes\n", name, co #ifdef DEBUG_BER_CHOICE { const char *name; -header_field_info *hfinfo; if (hf_id >= 0) { hfinfo = proto_registrar_get_nth(hf_id); name = hfinfo->name; @@ -3833,6 +3828,110 @@ dissect_ber_GeneralString(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int return offset; } +/* 8.19 Encoding of a relative object identifier value. + */ +int +dissect_ber_relative_oid(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, tvbuff_t **value_tvb) +{ + gint8 ber_class; + gboolean pc; + gint32 tag; + guint32 len; + int eoffset; + int hoffset; + const char *str; + proto_item *cause; + const gchar *name; + header_field_info *hfi; + +#ifdef DEBUG_BER +{ +header_field_info *hfinfo; +if (hf_id >= 0) { +hfinfo = proto_registrar_get_nth(hf_id); +name = hfinfo->name; +} else { +name = "unnamed"; +} +if (tvb_length_remaining(tvb, offset) > 3) { +printf("OBJECT IDENTIFIER dissect_ber_relative_oid(%s) entered implicit_tag:%d offset:%d len:%d %02x:%02x:%02x\n", name, implicit_tag, offset, tvb_length_remaining(tvb, offset), tvb_get_guint8(tvb, offset), tvb_get_guint8(tvb, offset+1), tvb_get_guint8(tvb, offset+2)); +} else { +printf("OBJECT IDENTIFIER dissect_ber_relative_oid(%s) entered\n", name); +} +} +#endif + + if (!implicit_tag) { + hoffset = offset; + /* sanity check */ + offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, NULL); + eoffset = offset + len; + if ( (ber_class != BER_CLASS_UNI) + || (tag != BER_UNI_TAG_OID) ) { + tvb_ensure_bytes_exist(tvb, hoffset, 2); + cause = proto_tree_add_string_format( + tree, hf_ber_error, tvb, offset, len, "oid_expected", + "BER Error: Object Identifier expected but class:%s(%d) %s tag:%d was unexpected", + val_to_str_const(ber_class, ber_class_codes, "Unknown"), + ber_class, + pc ? ber_pc_codes_short.true_string : ber_pc_codes_short.false_string, + tag); + expert_add_info(actx->pinfo, cause, &ei_ber_expected_object_identifier); + if (decode_unexpected) { + proto_tree *unknown_tree = proto_item_add_subtree(cause, ett_ber_unknown); + dissect_unknown_ber(actx->pinfo, tvb, hoffset, unknown_tree); + } + return eoffset; + } + } else { + len = tvb_length_remaining(tvb, offset); + eoffset = offset+len; + } + + actx->created_item = NULL; + hfi = proto_registrar_get_nth(hf_id); + if (hfi->type == FT_REL_OID) { + actx->created_item = proto_tree_add_item(tree, hf_id, tvb, offset, len, ENC_BIG_ENDIAN); + } else if (IS_FT_STRING(hfi->type)) { + str = oid_encoded2string(tvb_get_ptr(tvb, offset, len), len); + actx->created_item = proto_tree_add_string(tree, hf_id, tvb, offset, len, str); + if (actx->created_item) { + /* see if we know the name of this oid */ + name = oid_resolved_from_encoded(tvb_get_ptr(tvb, offset, len), len); + if (name) { + proto_item_append_text(actx->created_item, " (%s)", name); + } + } + } else { + DISSECTOR_ASSERT_NOT_REACHED(); + } + + if (value_tvb) + *value_tvb = tvb_new_subset(tvb, offset, len, len); + + return eoffset; +} + +int +dissect_ber_relative_oid_str(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, const char **value_stringx) +{ + tvbuff_t *value_tvb = NULL; + guint length; + + offset = dissect_ber_object_identifier(implicit_tag, actx, tree, tvb, offset, hf_id, (value_stringx) ? &value_tvb : NULL); + + if (value_stringx) { + if (value_tvb && (length = tvb_length(value_tvb))) { + *value_stringx = oid_encoded2string(tvb_get_ptr(value_tvb, 0, length), length); + } else { + *value_stringx = ""; + } + } + + return offset; +} + /* 8.19 Encoding of an object identifier value. */ int @@ -3851,7 +3950,6 @@ dissect_ber_object_identifier(gboolean implicit_tag, asn1_ctx_t *actx, proto_tre #ifdef DEBUG_BER { -const char *name; header_field_info *hfinfo; if (hf_id >= 0) { hfinfo = proto_registrar_get_nth(hf_id); |