new field type FT_OID for OBJECT IDENTIFIERs

svn path=/trunk/; revision=16652
This commit is contained in:
Tomas Kukosa 2005-12-02 13:16:58 +00:00
parent a809b11b2b
commit dcae7d303f
11 changed files with 314 additions and 17 deletions

View File

@ -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:

View File

@ -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();

View File

@ -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();

View File

@ -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);
}

View File

@ -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 */
};

View File

@ -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 " == ".

View File

@ -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

View File

@ -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. */

View File

@ -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.
*

View File

@ -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';

View File

@ -3063,7 +3063,7 @@ class ObjectIdentifierType (Type):
return 'OBJECT_IDENTIFIER'
def eth_ftype(self, ectx):
return ('FT_STRING', 'BASE_NONE')
return ('FT_OID', 'BASE_NONE')
def GetTTag(self, ectx):
return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')