forked from osmocom/wireshark
new field type FT_OID for OBJECT IDENTIFIERs
svn path=/trunk/; revision=16652
This commit is contained in:
parent
a809b11b2b
commit
dcae7d303f
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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, ðer_type);
|
||||
ftype_register(FT_IPv6, &ipv6_type);
|
||||
ftype_register(FT_GUID, &guid_type);
|
||||
ftype_register(FT_OID, &oid_type);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
96
epan/proto.c
96
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 " == ".
|
||||
|
|
32
epan/proto.h
32
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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue