aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorTomas Kukosa <tomas.kukosa@siemens.com>2005-12-02 13:16:58 +0000
committerTomas Kukosa <tomas.kukosa@siemens.com>2005-12-02 13:16:58 +0000
commitdcae7d303f0669cee025a52fbc22d3e7c4d535bc (patch)
treed41f358db1ab3107d4951c04b41d4c148c8d4e06 /epan
parenta809b11b2bee93510dd001a96a7d01f78e2a7030 (diff)
new field type FT_OID for OBJECT IDENTIFIERs
svn path=/trunk/; revision=16652
Diffstat (limited to 'epan')
-rw-r--r--epan/dfilter/semcheck.c5
-rw-r--r--epan/dissectors/packet-ber.c6
-rw-r--r--epan/dissectors/packet-per.c4
-rw-r--r--epan/ftypes/ftype-bytes.c93
-rw-r--r--epan/ftypes/ftypes.h1
-rw-r--r--epan/proto.c96
-rw-r--r--epan/proto.h32
-rw-r--r--epan/strutil.c57
-rw-r--r--epan/strutil.h9
-rw-r--r--epan/to_str.c26
10 files changed, 313 insertions, 16 deletions
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c
index 8316f6d3f9..b575be7a96 100644
--- a/epan/dfilter/semcheck.c
+++ b/epan/dfilter/semcheck.c
@@ -75,7 +75,8 @@ compatible_ftypes(ftenum_t a, ftenum_t b)
case FT_BYTES:
case FT_UINT_BYTES:
case FT_GUID:
- return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES || b == FT_GUID);
+ case FT_OID:
+ return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES || b == FT_GUID || b == FT_OID);
case FT_BOOLEAN:
case FT_FRAMENUM:
@@ -167,6 +168,7 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
case FT_INT64:
case FT_PCRE:
case FT_GUID:
+ case FT_OID:
return FALSE;
case FT_BOOLEAN:
@@ -237,6 +239,7 @@ is_bytes_type(enum ftenum type)
case FT_UINT_BYTES:
case FT_IPv6:
case FT_GUID:
+ case FT_OID:
return TRUE;
case FT_NONE:
diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c
index ed40536ad2..781032b6c5 100644
--- a/epan/dissectors/packet-ber.c
+++ b/epan/dissectors/packet-ber.c
@@ -1775,9 +1775,9 @@ printf("OBJECT IDENTIFIER dissect_ber_object_identifier(%s) entered\n",name);
str = oid_to_str(tvb_get_ptr(tvb, offset, len), len);
hfi = proto_registrar_get_nth(hf_id);
- /*if (hfi->type == FT_OID) {
- item = proto_tree_add_item(tree, hf_index, tvb, offset, len, FALSE);
- } else*/ if (IS_FT_STRING(hfi->type)) {
+ if (hfi->type == FT_OID) {
+ item = proto_tree_add_item(tree, hf_id, tvb, offset, len, FALSE);
+ } else if (IS_FT_STRING(hfi->type)) {
item = proto_tree_add_string(tree, hf_id, tvb, offset, len, str);
} else {
DISSECTOR_ASSERT_NOT_REACHED();
diff --git a/epan/dissectors/packet-per.c b/epan/dissectors/packet-per.c
index a6ecb567cd..ce644a127a 100644
--- a/epan/dissectors/packet-per.c
+++ b/epan/dissectors/packet-per.c
@@ -617,9 +617,9 @@ DEBUG_ENTRY("dissect_per_object_identifier");
str = oid_to_str(tvb_get_ptr(tvb, offset>>3, length), length);
hfi = proto_registrar_get_nth(hf_index);
- /*if (hfi->type == FT_OID) {
+ if (hfi->type == FT_OID) {
item = proto_tree_add_item(tree, hf_index, tvb, offset>>3, length, FALSE);
- } else*/ if (IS_FT_STRING(hfi->type)) {
+ } else if (IS_FT_STRING(hfi->type)) {
item = proto_tree_add_string(tree, hf_index, tvb, offset>>3, length, str);
} else {
DISSECTOR_ASSERT_NOT_REACHED();
diff --git a/epan/ftypes/ftype-bytes.c b/epan/ftypes/ftype-bytes.c
index b2e713d57d..acb9b3373a 100644
--- a/epan/ftypes/ftype-bytes.c
+++ b/epan/ftypes/ftype-bytes.c
@@ -88,6 +88,19 @@ guid_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
guid_to_str_buf(fv->value.bytes->data, buf, GUID_STR_LEN);
}
+static int
+oid_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
+{
+ /* more exact computation will come later */
+ return fv->value.bytes->len * 3 + 16;
+}
+
+static void
+oid_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
+{
+ oid_to_str_buf(fv->value.bytes->data, fv->value.bytes->len, buf, oid_repr_len(fv, rtype));
+}
+
static void
bytes_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
{
@@ -141,6 +154,18 @@ guid_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
common_fvalue_set(fv, value, GUID_LEN);
}
+static void
+oid_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
+{
+ g_assert(already_copied);
+
+ /* Free up the old value, if we have one */
+ bytes_fvalue_free(fv);
+
+ fv->value.bytes = value;
+}
+
+
static gpointer
value_get(fvalue_t *fv)
{
@@ -316,6 +341,38 @@ guid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc
return TRUE;
}
+static gboolean
+oid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, 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.
+ */
+ if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
+ return TRUE;
+ }
+
+ bytes = g_byte_array_new();
+ res = oid_str_to_bytes(s, bytes);
+ if (!res) {
+ if (logfunc != NULL)
+ logfunc("\"%s\" is not a valid OBJECT IDENTIFIER.", 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)
{
@@ -680,9 +737,45 @@ ftype_register_bytes(void)
slice,
};
+ static ftype_t oid_type = {
+ "OID", /* name */
+ "OBJECT IDENTIFIER", /* pretty_name */
+ 0, /* wire_size */
+ bytes_fvalue_new, /* new_value */
+ bytes_fvalue_free, /* free_value */
+ oid_from_unparsed, /* val_from_unparsed */
+ NULL, /* val_from_string */
+ oid_to_repr, /* val_to_string_repr */
+ oid_repr_len, /* len_string_repr */
+
+ oid_fvalue_set, /* set_value */
+ NULL, /* set_value_integer */
+ NULL, /* set_value_integer64 */
+ NULL, /* set_value_floating */
+
+ value_get, /* get_value */
+ NULL, /* get_value_integer */
+ NULL, /* get_value_integer64 */
+ NULL, /* get_value_floating */
+
+ cmp_eq,
+ cmp_ne,
+ cmp_gt,
+ cmp_ge,
+ cmp_lt,
+ cmp_le,
+ cmp_bytes_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_ETHER, &ether_type);
ftype_register(FT_IPv6, &ipv6_type);
ftype_register(FT_GUID, &guid_type);
+ ftype_register(FT_OID, &oid_type);
}
diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h
index 83a24a5ff4..5fbf163dc9 100644
--- a/epan/ftypes/ftypes.h
+++ b/epan/ftypes/ftypes.h
@@ -61,6 +61,7 @@ enum ftenum {
FT_FRAMENUM, /* a UINT32, but if selected lets you go to frame with that numbe */
FT_PCRE, /* a compiled Perl-Compatible Regular Expression object */
FT_GUID, /* GUID, UUID */
+ FT_OID, /* OBJECT IDENTIFIER */
FT_NUM_TYPES /* last item number plus one */
};
diff --git a/epan/proto.c b/epan/proto.c
index 08c97357fc..9f588a1819 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -152,6 +152,10 @@ proto_tree_set_guid(field_info *fi, const guint8* value_ptr);
static void
proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start);
static void
+proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
+static void
+proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
+static void
proto_tree_set_boolean(field_info *fi, guint32 value);
static void
proto_tree_set_float(field_info *fi, float value);
@@ -898,6 +902,10 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, int hfindex,
proto_tree_set_guid_tvb(new_fi, tvb, start);
break;
+ case FT_OID:
+ proto_tree_set_oid_tvb(new_fi, tvb, start, length);
+ break;
+
case FT_FLOAT:
DISSECTOR_ASSERT(length == 4);
if (little_endian)
@@ -1600,6 +1608,83 @@ proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start)
proto_tree_set_guid(fi, tvb_get_ptr(tvb, start, 16));
}
+/* Add a FT_OID to a proto_tree */
+proto_item *
+proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
+ const guint8* value_ptr)
+{
+ proto_item *pi;
+ field_info *new_fi;
+ header_field_info *hfinfo;
+
+ if (!tree)
+ return (NULL);
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+
+ PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
+ DISSECTOR_ASSERT(hfinfo->type == FT_OID);
+
+ pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
+ proto_tree_set_oid(new_fi, value_ptr, length);
+
+ return pi;
+}
+
+proto_item *
+proto_tree_add_oid_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
+ const guint8* value_ptr)
+{
+ proto_item *pi;
+
+ pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
+ if (pi == NULL)
+ return (NULL);
+
+ PROTO_ITEM_SET_HIDDEN(pi);
+
+ return pi;
+}
+
+proto_item *
+proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
+ const guint8* value_ptr, const char *format, ...)
+{
+ proto_item *pi;
+ va_list ap;
+
+ pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
+ if (pi == NULL)
+ return (NULL);
+
+ va_start(ap, format);
+ proto_tree_set_representation(pi, format, ap);
+ va_end(ap);
+
+ return pi;
+}
+
+/* Set the FT_OID value */
+static void
+proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
+{
+ GByteArray *bytes;
+
+ DISSECTOR_ASSERT(value_ptr != NULL);
+
+ bytes = g_byte_array_new();
+ if (length > 0) {
+ g_byte_array_append(bytes, value_ptr, length);
+ }
+ fvalue_set(&fi->value, bytes, TRUE);
+}
+
+static void
+proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
+{
+ proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
+}
+
static void
proto_tree_set_uint64(field_info *fi, guint64 value)
{
@@ -3415,6 +3500,15 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
+ case FT_OID:
+ bytes = fvalue_get(&fi->value);
+ ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ "%s: %s", hfinfo->name,
+ oid_to_str(bytes, fvalue_length(&fi->value)));
+ if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
+ label_str[ITEM_LABEL_LENGTH - 1] = '\0';
+ break;
+
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
@@ -4629,6 +4723,7 @@ proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
case FT_UINT_BYTES:
case FT_PROTOCOL:
case FT_GUID:
+ case FT_OID:
/*
* These all have values, so we can match.
*/
@@ -4791,6 +4886,7 @@ proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
case FT_IPv4:
case FT_IPv6:
case FT_GUID:
+ case FT_OID:
/* Figure out the string length needed.
* The ft_repr length.
* 4 bytes for " == ".
diff --git a/epan/proto.h b/epan/proto.h
index 7962fd0a50..56536b6fa5 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -730,6 +730,38 @@ extern proto_item *
proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, const guint8* value_ptr, const char *format, ...) GNUC_FORMAT_CHECK(printf,7,8);
+/** Add a FT_OID to a proto_tree.
+ @param tree the tree to append this item to
+ @param hfindex field index
+ @param tvb the tv buffer of the current data
+ @param start start of data in tvb
+ @param length length of data in tvb
+ @param value_ptr data to display
+ @return the newly created item */
+extern proto_item *
+proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+ gint length, const guint8* value_ptr);
+
+/** Add a hidden FT_OID to a proto_tree.
+ @deprecated use proto_tree_add_guid() and a subsequent call to PROTO_ITEM_SET_HIDDEN() instead */
+extern proto_item *
+proto_tree_add_oid_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+ gint length, const guint8* value_ptr);
+
+/** Add a formatted FT_OID to a proto_tree.
+ @param tree the tree to append this item to
+ @param hfindex field index
+ @param tvb the tv buffer of the current data
+ @param start start of data in tvb
+ @param length length of data in tvb
+ @param value_ptr data to display
+ @param format printf like format string
+ @param ... printf like parameters
+ @return the newly created item */
+extern proto_item *
+proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+ gint length, const guint8* value_ptr, const char *format, ...) GNUC_FORMAT_CHECK(printf,7,8);
+
/** Add a FT_STRING to a proto_tree.
@param tree the tree to append this item to
@param hfindex field index
diff --git a/epan/strutil.c b/epan/strutil.c
index bba8e19651..53b4780a3d 100644
--- a/epan/strutil.c
+++ b/epan/strutil.c
@@ -393,6 +393,63 @@ hex_str_to_bytes(const char *hex_str, GByteArray *bytes, gboolean force_separato
return TRUE;
}
+#define SUBID_BUF_LEN 5
+gboolean
+oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
+ guint32 subid0, subid, sicnt, i;
+ const char *p, *dot;
+ guint8 buf[SUBID_BUF_LEN];
+
+ g_byte_array_set_size(bytes, 0);
+
+ /* check syntax */
+ p = oid_str;
+ dot = NULL;
+ while (*p) {
+ if (!isdigit(*p) && (*p != '.')) return FALSE;
+ if (*p == '.') {
+ if (p == oid_str) return FALSE;
+ if (!*(p+1)) return FALSE;
+ if ((p-1) == dot) return FALSE;
+ dot = p;
+ }
+ p++;
+ }
+ if (!dot) return FALSE;
+
+ p = oid_str;
+ sicnt = 0;
+ while (*p) {
+ subid = 0;
+ while (isdigit(*p)) {
+ subid *= 10;
+ subid += *p - '0';
+ p++;
+ }
+ if (sicnt == 0) {
+ subid0 = subid;
+ if (subid0 > 2) return FALSE;
+ } else if (sicnt == 1) {
+ if ((subid0 < 2) && (subid > 39)) return FALSE;
+ subid += 40 * subid0;
+ }
+ if (sicnt) {
+ i = SUBID_BUF_LEN;
+ do {
+ i--;
+ buf[i] = 0x80 | (subid % 0x80);
+ subid >>= 7;
+ } while (subid && i);
+ buf[SUBID_BUF_LEN-1] &= 0x7F;
+ g_byte_array_append(bytes, buf + i, SUBID_BUF_LEN - i);
+ }
+ sicnt++;
+ if (*p) p++;
+ }
+
+ return TRUE;
+}
+
/* Return a XML escaped representation of the unescaped string.
* The returned string must be freed when no longer in use. */
diff --git a/epan/strutil.h b/epan/strutil.h
index 9e8c632a09..ac5dc5aaab 100644
--- a/epan/strutil.h
+++ b/epan/strutil.h
@@ -99,6 +99,15 @@ gchar* bytes_to_str_punct(const guint8 *bd, int bd_len, gchar punct);
gboolean hex_str_to_bytes(const char *hex_str, GByteArray *bytes,
gboolean force_separators);
+/** Turn a OID string representation (dot notaion) 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
+ */
+gboolean oid_str_to_bytes(const char *oid_str, GByteArray *bytes);
+
/** Return a XML escaped representation of the unescaped string.
* The returned string must be freed when no longer in use.
*
diff --git a/epan/to_str.c b/epan/to_str.c
index 138d831e99..14ccbcfc8b 100644
--- a/epan/to_str.c
+++ b/epan/to_str.c
@@ -840,26 +840,32 @@ gchar* oid_to_str(const guint8 *oid, gint oid_len) {
gchar* oid_to_str_buf(const guint8 *oid, gint oid_len, gchar *buf, int buf_len) {
gint i;
guint8 byte;
- guint32 value;
+ guint32 subid0, subid;
+ gboolean is_first;
gchar *bufp;
- bufp = buf; value=0;
+ bufp = buf; subid = 0; is_first = TRUE;
for (i=0; i<oid_len; i++){
byte = oid[i];
- if ((bufp - buf) > (MAX_OID_STR_LEN - 16)) { /* "4294967295" + ".>>>" + '\0' + 1 */
+ if ((bufp - buf) > (buf_len - 12)) {
bufp += g_snprintf(bufp, buf_len-(bufp-buf), ".>>>");
break;
}
- if (i == 0) {
- bufp += g_snprintf(bufp, buf_len-(bufp-buf), "%u.%u", byte/40, byte%40);
- continue;
- }
- value = (value << 7) | (byte & 0x7F);
+ subid <<= 7;
+ subid |= byte & 0x7F;
if (byte & 0x80) {
continue;
}
- bufp += g_snprintf(bufp, buf_len-(bufp-buf), ".%u", value);
- value = 0;
+ if (is_first) {
+ subid0 = 0;
+ if (subid >= 40) { subid0++; subid-=40; }
+ if (subid >= 40) { subid0++; subid-=40; }
+ bufp += g_snprintf(bufp, buf_len-(bufp-buf), "%u.%u", subid0, subid);
+ is_first = FALSE;
+ } else {
+ bufp += g_snprintf(bufp, buf_len-(bufp-buf), ".%u", subid);
+ }
+ subid = 0;
}
*bufp = '\0';