summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-ber.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2013-10-06 02:31:10 +0000
committerMichael Mann <mmann78@netscape.net>2013-10-06 02:31:10 +0000
commitee208c8dcc371ca10986b7e8ea28c933e4bfaae9 (patch)
tree34da4ba8bde2ea6a7f071f47cd24bf2950f39331 /epan/dissectors/packet-ber.c
parent625fbd5f9a09483485f9c2b0271ab29afb68a597 (diff)
downloadwireshark-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.c116
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);