summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/README.dissector8
-rwxr-xr-xdoc/dfilter2pod.pl1
-rwxr-xr-xdocbook/dfilter2xml.pl1
-rw-r--r--epan/dfilter/semcheck.c5
-rw-r--r--epan/dissectors/packet-ber.c116
-rw-r--r--epan/dissectors/packet-ber.h5
-rw-r--r--epan/ftypes/ftype-bytes.c93
-rw-r--r--epan/ftypes/ftypes.h1
-rw-r--r--epan/oids.c30
-rw-r--r--epan/oids.h6
-rw-r--r--epan/proto.c27
-rw-r--r--epan/strutil.c9
-rw-r--r--epan/strutil.h11
-rw-r--r--epan/wslua/wslua_field.c1
-rw-r--r--epan/wslua/wslua_proto.c3
-rw-r--r--epan/wslua/wslua_tree.c1
-rwxr-xr-xepan/wspython/wspy_dissector.py3
-rw-r--r--rawshark.c2
-rwxr-xr-xtools/asn2wrs.py2
-rwxr-xr-xtools/convert_proto_tree_add_text.pl2
-rwxr-xr-xtools/fix-encoding-args.pl3
-rw-r--r--ui/packet_list_utils.c2
22 files changed, 308 insertions, 24 deletions
diff --git a/doc/README.dissector b/doc/README.dissector
index a4949d7e83..94871fae5a 100644
--- a/doc/README.dissector
+++ b/doc/README.dissector
@@ -113,7 +113,8 @@ FIELDTYPE FT_NONE, FT_BOOLEAN, FT_UINT8, FT_UINT16, FT_UINT24,
FT_INT64, FT_FLOAT, FT_DOUBLE, FT_ABSOLUTE_TIME,
FT_RELATIVE_TIME, FT_STRING, FT_STRINGZ, FT_EUI64,
FT_UINT_STRING, FT_ETHER, FT_BYTES, FT_UINT_BYTES, FT_IPv4,
- FT_IPv6, FT_IPXNET, FT_FRAMENUM, FT_PROTOCOL, FT_GUID, FT_OID
+ FT_IPv6, FT_IPXNET, FT_FRAMENUM, FT_PROTOCOL, FT_GUID, FT_OID,
+ FT_REL_OID
FIELDDISPLAY --For FT_UINT{8,16,24,32,64} and FT_INT{8,16,24,32,64):
BASE_DEC, BASE_HEX, BASE_OCT, BASE_DEC_HEX, BASE_HEX_DEC,
@@ -725,6 +726,7 @@ The type of value this field holds. The current field types are:
address.
FT_GUID A Globally Unique Identifier
FT_OID An ASN.1 Object Identifier
+ FT_REL_OID An ASN.1 Relative Object Identifier
FT_EUI64 A EUI-64 Address
Some of these field types are still not handled in the display filter
@@ -1331,8 +1333,8 @@ proto_register_*() function) and a value. The value will be fetched
from the tvbuff by proto_tree_add_item(), based on the type of the field
and the encoding of the value as specified by the "encoding" argument.
-For FT_NONE, FT_BYTES, FT_ETHER, FT_IPv6, FT_IPXNET, FT_OID fields,
-and 'protocol' fields the encoding is not relevant; the 'encoding'
+For FT_NONE, FT_BYTES, FT_ETHER, FT_IPv6, FT_IPXNET, FT_OID, FT_REL_OID
+fields, and 'protocol' fields the encoding is not relevant; the 'encoding'
argument should be ENC_NA (Not Applicable).
For integral, floating-point, Boolean, FT_GUID, and FT_EUI64 fields,
diff --git a/doc/dfilter2pod.pl b/doc/dfilter2pod.pl
index 849e695edc..26ff75eea9 100755
--- a/doc/dfilter2pod.pl
+++ b/doc/dfilter2pod.pl
@@ -45,6 +45,7 @@ use Getopt::Std;
'FT_PCRE', 'Perl Compatible Regular Expression',
'FT_GUID', 'Globally Unique Identifier',
'FT_OID', 'Object Identifier',
+ 'FT_REL_OID', 'Relative Object Identifier',
);
getopts('e');
diff --git a/docbook/dfilter2xml.pl b/docbook/dfilter2xml.pl
index 56206ef70f..c38cf11f1e 100755
--- a/docbook/dfilter2xml.pl
+++ b/docbook/dfilter2xml.pl
@@ -43,6 +43,7 @@
'FT_PCRE', 'Perl Compatible Regular Expression',
'FT_GUID', 'Globally Unique Identifier',
'FT_OID', 'Object Identifier',
+ 'FT_REL_OID', 'Relative Object Identifier',
);
# Read all the data into memory
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c
index c2d33bcf06..27b2d3e925 100644
--- a/epan/dfilter/semcheck.c
+++ b/epan/dfilter/semcheck.c
@@ -83,8 +83,9 @@ compatible_ftypes(ftenum_t a, ftenum_t b)
case FT_OID:
case FT_AX25:
case FT_VINES:
+ case FT_REL_OID:
- return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES || b == FT_GUID || b == FT_OID || b == FT_AX25 || b == FT_VINES);
+ return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES || b == FT_GUID || b == FT_OID || b == FT_AX25 || b == FT_VINES || b == FT_REL_OID);
case FT_BOOLEAN:
case FT_FRAMENUM:
@@ -189,6 +190,7 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
case FT_PCRE:
case FT_GUID:
case FT_OID:
+ case FT_REL_OID:
return NULL;
case FT_BOOLEAN:
@@ -296,6 +298,7 @@ is_bytes_type(enum ftenum type)
case FT_IPv6:
case FT_GUID:
case FT_OID:
+ case FT_REL_OID:
return TRUE;
case FT_NONE:
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);
diff --git a/epan/dissectors/packet-ber.h b/epan/dissectors/packet-ber.h
index 28c50228e9..cde878590a 100644
--- a/epan/dissectors/packet-ber.h
+++ b/epan/dissectors/packet-ber.h
@@ -195,6 +195,11 @@ extern int dissect_ber_GeneralString(asn1_ctx_t *actx, proto_tree *tree, tvbuff_
WS_DLL_PUBLIC int dissect_ber_object_identifier(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, tvbuff_t **value_tvb);
WS_DLL_PUBLIC int dissect_ber_object_identifier_str(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint hf_id, const char **value_stringx);
+/* this function dissects a BER Relative Object Identifier
+ */
+WS_DLL_PUBLIC 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);
+WS_DLL_PUBLIC 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);
+
/* this function dissects a BER sequence of
*/
extern int dissect_ber_constrained_sequence_of(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, const ber_sequence_t *seq, gint hf_id, gint ett_id);
diff --git a/epan/ftypes/ftype-bytes.c b/epan/ftypes/ftype-bytes.c
index 07fef709f7..de7adac863 100644
--- a/epan/ftypes/ftype-bytes.c
+++ b/epan/ftypes/ftype-bytes.c
@@ -77,6 +77,8 @@ bytes_repr_len(fvalue_t *fv, ftrepr_t rtype _U_)
* OID_REPR_LEN:
*
* 5 for the first byte ([0-2].[0-39].)
+ *
+ * REL_OID_REPR_LEN:
* for each extra byte if the sub-id is:
* 1 byte it can be at most "127." (4 bytes we give it 4)
* 2 bytes it can be at most "16383." (6 bytes we give it 8)
@@ -87,7 +89,8 @@ bytes_repr_len(fvalue_t *fv, ftrepr_t rtype _U_)
* a 5 bytes encoded subid can already overflow the guint32 that holds a sub-id,
* making it a completely different issue!
*/
-#define OID_REPR_LEN(fv) (5 + (4 * ((fv)->value.bytes->len-1)))
+#define REL_OID_REPR_LEN(fv) (4 * ((fv)->value.bytes->len))
+#define OID_REPR_LEN(fv) (1 + REL_OID_REPR_LEN(fv))
static int
oid_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
@@ -109,6 +112,27 @@ oid_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
strncpy(buf,oid_str,OID_REPR_LEN(fv));
}
+static int
+rel_oid_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
+{
+ return REL_OID_REPR_LEN(fv);
+}
+
+static void
+rel_oid_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
+{
+ const char* oid_str = rel_oid_encoded2string(fv->value.bytes->data,fv->value.bytes->len);
+ /*
+ * XXX:
+ * I'm assuming that oid_repr_len is going to be called before to set buf's size.
+ * or else we might have a BO.
+ * I guess that is why this callback is not passed a length.
+ * -- lego
+ */
+ *buf++ = '.';
+ strncpy(buf,oid_str,REL_OID_REPR_LEN(fv));
+}
+
static void
bytes_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
{
@@ -378,6 +402,34 @@ oid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFu
return TRUE;
}
+static gboolean
+rel_oid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+{
+ GByteArray *bytes;
+ gboolean res;
+
+
+ /*
+ * Don't log a message if this fails; we'll try looking it
+ * up as an OID if it does, and if that fails,
+ * we'll log a message.
+ */
+ bytes = g_byte_array_new();
+ res = rel_oid_str_to_bytes(s, bytes, FALSE);
+ if (!res) {
+ if (logfunc != NULL)
+ logfunc("\"%s\" is not a valid RELATIVE-OID.", s);
+ g_byte_array_free(bytes, TRUE);
+ return FALSE;
+ }
+
+ /* Free up the old value, if we have one */
+ bytes_fvalue_free(fv);
+ fv->value.bytes = bytes;
+
+ return TRUE;
+}
+
static guint
len(fvalue_t *fv)
{
@@ -811,10 +863,49 @@ ftype_register_bytes(void)
slice,
};
+ static ftype_t rel_oid_type = {
+ FT_REL_OID, /* ftype */
+ "FT_REL_OID", /* name */
+ "ASN.1 relative object identifier", /* pretty_name */
+ 0, /* wire_size */
+ bytes_fvalue_new, /* new_value */
+ bytes_fvalue_free, /* free_value */
+ rel_oid_from_unparsed, /* val_from_unparsed */
+ NULL, /* val_from_string */
+ rel_oid_to_repr, /* val_to_string_repr */
+ rel_oid_repr_len, /* len_string_repr */
+
+ oid_fvalue_set, /* set_value (same as full oid) */
+ NULL, /* set_value_uinteger */
+ NULL, /* set_value_sinteger */
+ NULL, /* set_value_integer64 */
+ NULL, /* set_value_floating */
+
+ value_get, /* get_value */
+ NULL, /* get_value_uinteger */
+ NULL, /* get_value_sinteger */
+ NULL, /* get_value_integer64 */
+ NULL, /* get_value_floating */
+
+ cmp_eq,
+ cmp_ne,
+ cmp_gt,
+ cmp_ge,
+ cmp_lt,
+ cmp_le,
+ cmp_bitwise_and,
+ cmp_contains,
+ NULL, /* cmp_matches */
+
+ len,
+ slice,
+ };
+
ftype_register(FT_BYTES, &bytes_type);
ftype_register(FT_UINT_BYTES, &uint_bytes_type);
ftype_register(FT_AX25, &ax25_type);
ftype_register(FT_VINES, &vines_type);
ftype_register(FT_ETHER, &ether_type);
ftype_register(FT_OID, &oid_type);
+ ftype_register(FT_REL_OID, &rel_oid_type);
}
diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h
index 11c850b6ce..5f4183a3b9 100644
--- a/epan/ftypes/ftypes.h
+++ b/epan/ftypes/ftypes.h
@@ -69,6 +69,7 @@ enum ftenum {
FT_EUI64,
FT_AX25,
FT_VINES,
+ FT_REL_OID, /* RELATIVE-OID */
FT_NUM_TYPES /* last item number plus one */
};
diff --git a/epan/oids.c b/epan/oids.c
index 62405bee1a..61177ed0d8 100644
--- a/epan/oids.c
+++ b/epan/oids.c
@@ -829,11 +829,16 @@ void oids_cleanup(void) {
}
const char* oid_subid2string(guint32* subids, guint len) {
+ return rel_oid_subid2string(subids, len, TRUE);
+}
+const char* rel_oid_subid2string(guint32* subids, guint len, gboolean is_absolute) {
char* s = (char *)ep_alloc0(((len)*11)+1);
char* w = s;
if(!subids)
return "*** Empty OID ***";
+ if (!is_absolute)
+ *w++ = '.';
do {
w += g_snprintf(w,12,"%u.",*subids++);
@@ -919,9 +924,12 @@ guint oid_string2subid(const char* str, guint32** subids_p) {
guint oid_encoded2subid(const guint8 *oid_bytes, gint oid_len, guint32** subids_p) {
+ return oid_encoded2subid_sub(oid_bytes, oid_len, subids_p, TRUE);
+}
+guint oid_encoded2subid_sub(const guint8 *oid_bytes, gint oid_len, guint32** subids_p,
+ gboolean is_first) {
gint i;
- guint n = 1;
- gboolean is_first = TRUE;
+ guint n = is_first ? 1 : 0;
guint32* subids;
guint32* subid_overflow;
/*
@@ -939,7 +947,7 @@ guint oid_encoded2subid(const guint8 *oid_bytes, gint oid_len, guint32** subids_
* so initialize our one byte to zero and return. This *seems* to be
* the right thing to do in this situation, and at the very least it
* avoids uninitialized memory errors that would otherwise occur. */
- if (n == 1) {
+ if ((is_first && n == 0) || (!is_first && n == 1)) {
*subids = 0;
return n;
}
@@ -1019,6 +1027,13 @@ const gchar *oid_resolved_from_encoded(const guint8 *oid, gint oid_len) {
return oid_resolved(subid_oid_length, subid_oid);
}
+const gchar *rel_oid_resolved_from_encoded(const guint8 *oid, gint oid_len) {
+ guint32 *subid_oid;
+ guint subid_oid_length = oid_encoded2subid_sub(oid, oid_len, &subid_oid, FALSE);
+
+ return rel_oid_subid2string(subid_oid, subid_oid_length, FALSE);
+}
+
guint oid_subid2encoded(guint subids_len, guint32* subids, guint8** bytes_p) {
guint bytelen = 0;
@@ -1090,7 +1105,16 @@ const gchar* oid_encoded2string(const guint8* encoded, guint len) {
}
}
+const gchar* rel_oid_encoded2string(const guint8* encoded, guint len) {
+ guint32* subids;
+ guint subids_len = oid_encoded2subid_sub(encoded, len, &subids, FALSE);
+ if (subids_len) {
+ return rel_oid_subid2string(subids,subids_len, FALSE);
+ } else {
+ return "";
+ }
+}
guint oid_string2encoded(const char *oid_str, guint8 **bytes) {
guint32* subids;
diff --git a/epan/oids.h b/epan/oids.h
index e8221d4241..3297202ce0 100644
--- a/epan/oids.h
+++ b/epan/oids.h
@@ -142,14 +142,20 @@ guint oid_string2encoded(const gchar *oid_str, guint8** encoded_p);
WS_DLL_PUBLIC
guint oid_encoded2subid(const guint8 *oid, gint len, guint32** subids_p);
WS_DLL_PUBLIC
+guint oid_encoded2subid_sub(const guint8 *oid_bytes, gint oid_len, guint32** subids_pi,
+ gboolean is_first);
+WS_DLL_PUBLIC
guint oid_string2subid(const gchar *oid_str, guint32** subids_p);
WS_DLL_PUBLIC const gchar* oid_encoded2string(const guint8* encoded, guint len);
+WS_DLL_PUBLIC const gchar* rel_oid_encoded2string(const guint8* encoded, guint len);
WS_DLL_PUBLIC const gchar* oid_subid2string(guint32 *subids, guint len);
+WS_DLL_PUBLIC const gchar* rel_oid_subid2string(guint32 *subids, guint len, gboolean is_relative);
/* these return a formated string as human readable as posible */
WS_DLL_PUBLIC const gchar *oid_resolved(guint len, guint32 *subids);
WS_DLL_PUBLIC const gchar *oid_resolved_from_encoded(const guint8 *oid, gint len);
+WS_DLL_PUBLIC const gchar *rel_oid_resolved_from_encoded(const guint8 *oid, gint len);
WS_DLL_PUBLIC const gchar *oid_resolved_from_string(const gchar *oid_str);
/* these yield two formated strings one resolved and one numeric */
diff --git a/epan/proto.c b/epan/proto.c
index 1a8475a241..6743a036fc 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -1406,6 +1406,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
break;
case FT_OID:
+ case FT_REL_OID:
proto_tree_set_oid_tvb(new_fi, tvb, start, length);
break;
@@ -3876,6 +3877,17 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
size-offset_r);
break;
+ case FT_REL_OID:
+ bytes = (guint8 *)fvalue_get(&finfo->value);
+ offset_r += protoo_strlcpy(result+offset_r,
+ rel_oid_resolved_from_encoded(bytes,
+ fvalue_length(&finfo->value)),
+ size-offset_r);
+ offset_e += protoo_strlcpy(expr+offset_e,
+ rel_oid_encoded2string(bytes, fvalue_length(&finfo->value)),
+ size-offset_e);
+ break;
+
case FT_OID:
bytes = (guint8 *)fvalue_get(&finfo->value);
offset_r += protoo_strlcpy(result+offset_r,
@@ -3933,6 +3945,7 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
case FT_INT24:
case FT_INT32:
case FT_OID:
+ case FT_REL_OID:
/* for these types, "expr" is filled in the loop above */
break;
@@ -4785,6 +4798,7 @@ static const value_string hf_types[] = {
{ FT_PCRE, "FT_PCR" },
{ FT_GUID, "FT_GUID" },
{ FT_OID, "FT_OID" },
+ { FT_REL_OID, "FT_REL_OID" },
{ 0, NULL } };
static const value_string hf_display[] = {
@@ -5385,6 +5399,19 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
oid_encoded2string(bytes, fvalue_length(&fi->value)));
}
break;
+
+ case FT_REL_OID:
+ bytes = (guint8 *)fvalue_get(&fi->value);
+ name = rel_oid_resolved_from_encoded(bytes, fvalue_length(&fi->value));
+ if (name) {
+ label_fill_descr(label_str, 0, hfinfo,
+ rel_oid_encoded2string(bytes, fvalue_length(&fi->value)), name);
+ } else {
+ label_fill(label_str, 0, hfinfo,
+ rel_oid_encoded2string(bytes, fvalue_length(&fi->value)));
+ }
+ break;
+
case FT_EUI64:
integer64 = fvalue_get_integer64(&fi->value);
label_fill_descr(label_str, 0, hfinfo,
diff --git a/epan/strutil.c b/epan/strutil.c
index 6c77002b5d..4446a45979 100644
--- a/epan/strutil.c
+++ b/epan/strutil.c
@@ -617,6 +617,10 @@ byte_array_dup(GByteArray *ba) {
#define SUBID_BUF_LEN 5
gboolean
oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
+ return rel_oid_str_to_bytes(oid_str, bytes, TRUE);
+}
+gboolean
+rel_oid_str_to_bytes(const char *oid_str, GByteArray *bytes, gboolean is_absolute) {
guint32 subid0, subid, sicnt, i;
const char *p, *dot;
guint8 buf[SUBID_BUF_LEN];
@@ -629,7 +633,7 @@ oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
while (*p) {
if (!isdigit((guchar)*p) && (*p != '.')) return FALSE;
if (*p == '.') {
- if (p == oid_str) return FALSE;
+ if (p == oid_str && is_absolute) return FALSE;
if (!*(p+1)) return FALSE;
if ((p-1) == dot) return FALSE;
dot = p;
@@ -639,7 +643,8 @@ oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
if (!dot) return FALSE;
p = oid_str;
- sicnt = 0;
+ sicnt = is_absolute ? 0 : 2;
+ if (!is_absolute) p++;
subid0 = 0; /* squelch GCC complaints */
while (*p) {
subid = 0;
diff --git a/epan/strutil.h b/epan/strutil.h
index 2e25d7d172..255993da65 100644
--- a/epan/strutil.h
+++ b/epan/strutil.h
@@ -156,6 +156,17 @@ const gchar* format_uri(const GByteArray *bytes, const gchar *reserved_chars);
* @param oid_str The OID string (dot notaion).
* @param bytes The GByteArray that will receive the bytes. This
* must be initialized by the caller.
+ * @param is_absolute True if this is an absolute OID; false for relative OID.
+ * @return True if the string was converted successfully
+ */
+WS_DLL_PUBLIC
+gboolean rel_oid_str_to_bytes(const char *oid_str, GByteArray *bytes, gboolean is_absolute);
+
+/** Turn a OID string representation (dot notation) into a byte array.
+ *
+ * @param oid_str The OID string (dot notaion).
+ * @param bytes The GByteArray that will receive the bytes. This
+ * must be initialized by the caller.
* @return True if the string was converted successfully
*/
WS_DLL_PUBLIC
diff --git a/epan/wslua/wslua_field.c b/epan/wslua/wslua_field.c
index c4eb7e36e7..6ecd2f44aa 100644
--- a/epan/wslua/wslua_field.c
+++ b/epan/wslua/wslua_field.c
@@ -155,6 +155,7 @@ WSLUA_METAMETHOD FieldInfo__call(lua_State* L) {
case FT_UINT_BYTES:
case FT_GUID:
case FT_PROTOCOL:
+ case FT_REL_OID:
case FT_OID: {
ByteArray ba = g_byte_array_new();
g_byte_array_append(ba, (const guint8 *)tvb_memdup(wmem_packet_scope(),fi->ds_tvb,fi->start,fi->length),fi->length);
diff --git a/epan/wslua/wslua_proto.c b/epan/wslua/wslua_proto.c
index 9d99e55213..3700ed00a6 100644
--- a/epan/wslua/wslua_proto.c
+++ b/epan/wslua/wslua_proto.c
@@ -459,6 +459,7 @@ static const wslua_ft_types_t ftenums[] = {
{"ftypes.FRAMENUM", FT_FRAMENUM},
{"ftypes.GUID", FT_GUID},
{"ftypes.OID", FT_OID},
+ {"ftypes.REL_OID", FT_REL_OID},
{NULL, FT_NONE}
};
@@ -1185,6 +1186,7 @@ PROTOFIELD_OTHER(bytes,FT_BYTES)
PROTOFIELD_OTHER(ubytes,FT_UINT_BYTES)
PROTOFIELD_OTHER(guid,FT_GUID)
PROTOFIELD_OTHER(oid,FT_OID)
+PROTOFIELD_OTHER(rel_oid,FT_REL_OID)
WSLUA_METAMETHOD ProtoField__tostring(lua_State* L) {
/* Returns a string with info about a protofield (for debugging purposes) */
@@ -1246,6 +1248,7 @@ static const luaL_Reg ProtoField_methods[] = {
{"ubytes",ProtoField_ubytes},
{"guid",ProtoField_guid},
{"oid",ProtoField_oid},
+ {"rel_oid",ProtoField_rel_oid},
{ NULL, NULL }
};
diff --git a/epan/wslua/wslua_tree.c b/epan/wslua/wslua_tree.c
index 192f61e318..6246e3862f 100644
--- a/epan/wslua/wslua_tree.c
+++ b/epan/wslua/wslua_tree.c
@@ -225,6 +225,7 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
case FT_IPXNET:
case FT_GUID:
case FT_OID:
+ case FT_REL_OID:
default:
luaL_error(L,"FT_ not yet supported");
return 0;
diff --git a/epan/wspython/wspy_dissector.py b/epan/wspython/wspy_dissector.py
index aee71d090d..e8993cd13e 100755
--- a/epan/wspython/wspy_dissector.py
+++ b/epan/wspython/wspy_dissector.py
@@ -66,7 +66,8 @@ FT_IPXNET,
FT_FRAMENUM,
FT_PCRE,
FT_GUID,
-FT_OID) = map(int, range(31))
+FT_OID,
+FT_REL_OID) = map(int, range(32))
# hf_register_info from usual dissectors
class register_info(object):
diff --git a/rawshark.c b/rawshark.c
index c71c31c638..c36f156b0c 100644
--- a/rawshark.c
+++ b/rawshark.c
@@ -1239,6 +1239,8 @@ static const char* ftenum_to_string(header_field_info *hfi)
return "FT_GUID";
case FT_OID:
return "FT_OID";
+ case FT_REL_OID:
+ return "FT_REL_OID";
case FT_NUM_TYPES:
return "FT_NUM_TYPES";
default:
diff --git a/tools/asn2wrs.py b/tools/asn2wrs.py
index 7475c467b3..8efda1fddf 100755
--- a/tools/asn2wrs.py
+++ b/tools/asn2wrs.py
@@ -5301,7 +5301,7 @@ class RelativeOIDType (Type):
return 'RELATIVE_OID'
def eth_ftype(self, ectx):
- return ('FT_BYTES', 'BASE_NONE')
+ return ('FT_REL_OID', 'BASE_NONE')
def GetTTag(self, ectx):
return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID')
diff --git a/tools/convert_proto_tree_add_text.pl b/tools/convert_proto_tree_add_text.pl
index f1f20396eb..94b8f1f8a4 100755
--- a/tools/convert_proto_tree_add_text.pl
+++ b/tools/convert_proto_tree_add_text.pl
@@ -86,7 +86,7 @@ my %FIELD_TYPE = ('FT_NONE' => "FT_NONE", 'FT_PROTOCOL' => "FT_PROTOCOL", 'FT_BO
'FT_STRING' => "FT_STRING", 'FT_STRINGZ' => "FT_STRINGZ", 'FT_UINT_STRING' => "FT_UINT_STRING",
'FT_ETHER' => "FT_ETHER", 'FT_BYTES' => "FT_BYTES", 'FT_UINT_BYTES' => "FT_UINT_BYTES",
'FT_IPv4' => "FT_IPv4", 'FT_IPv6' => "FT_IPv6", 'FT_IPXNET' => "FT_IPXNET", 'FT_AX25' => "FT_AX25", 'FT_VINES' => "FT_VINES",
- 'FT_FRAMENUM' => "FT_FRAMENUM", 'FT_PCRE' => "FT_PCRE", 'FT_GUID' => "FT_GUID", 'FT_OID' => "FT_OID", 'FT_EUI64' => "FT_EUI64");
+ 'FT_FRAMENUM' => "FT_FRAMENUM", 'FT_PCRE' => "FT_PCRE", 'FT_GUID' => "FT_GUID", 'FT_OID' => "FT_OID", 'FT_REL_OID' => "FT_REL_OID", 'FT_EUI64' => "FT_EUI64");
my %EXPERT_SEVERITY = ('PI_COMMENT' => "PI_COMMENT",
'PI_CHAT' => "PI_CHAT",
diff --git a/tools/fix-encoding-args.pl b/tools/fix-encoding-args.pl
index 63a8d9c8c7..910d106ef1 100755
--- a/tools/fix-encoding-args.pl
+++ b/tools/fix-encoding-args.pl
@@ -76,7 +76,7 @@ my $searchReplaceEncNAHRef =
my @types_NA =
(
- [ qw (FT_NONE FT_BYTES FT_ETHER FT_IPv6 FT_IPXNET FT_OID)],
+ [ qw (FT_NONE FT_BYTES FT_ETHER FT_IPv6 FT_IPXNET FT_OID FT_REL_OID)],
$searchReplaceEncNAHRef
);
@@ -179,6 +179,7 @@ my @types_ALL =
FT_PCRE
FT_GUID
FT_OID
+ FT_REL_OID
FT_EUI64
)],
{# valid encoding args
diff --git a/ui/packet_list_utils.c b/ui/packet_list_utils.c
index 24f0dd47b5..5426334663 100644
--- a/ui/packet_list_utils.c
+++ b/ui/packet_list_utils.c
@@ -92,7 +92,7 @@ resolve_column (gint col, capture_file *cf)
/* Check if this is a valid field */
if (hfi != NULL) {
/* Check if we have an OID or a strings table with integer values */
- if ((hfi->type == FT_OID) ||
+ if ((hfi->type == FT_OID) || (hfi->type == FT_REL_OID) ||
((hfi->strings != NULL) &&
((hfi->type == FT_BOOLEAN) || (hfi->type == FT_FRAMENUM) ||
IS_FT_INT(hfi->type) || IS_FT_UINT(hfi->type)))) {