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
This commit is contained in:
Michael Mann 2013-10-06 02:31:10 +00:00
parent 625fbd5f9a
commit ee208c8dcc
22 changed files with 308 additions and 24 deletions

View File

@ -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_INT64, FT_FLOAT, FT_DOUBLE, FT_ABSOLUTE_TIME,
FT_RELATIVE_TIME, FT_STRING, FT_STRINGZ, FT_EUI64, FT_RELATIVE_TIME, FT_STRING, FT_STRINGZ, FT_EUI64,
FT_UINT_STRING, FT_ETHER, FT_BYTES, FT_UINT_BYTES, FT_IPv4, 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): 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, 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. address.
FT_GUID A Globally Unique Identifier FT_GUID A Globally Unique Identifier
FT_OID An ASN.1 Object Identifier FT_OID An ASN.1 Object Identifier
FT_REL_OID An ASN.1 Relative Object Identifier
FT_EUI64 A EUI-64 Address FT_EUI64 A EUI-64 Address
Some of these field types are still not handled in the display filter 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 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. 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, For FT_NONE, FT_BYTES, FT_ETHER, FT_IPv6, FT_IPXNET, FT_OID, FT_REL_OID
and 'protocol' fields the encoding is not relevant; the 'encoding' fields, and 'protocol' fields the encoding is not relevant; the 'encoding'
argument should be ENC_NA (Not Applicable). argument should be ENC_NA (Not Applicable).
For integral, floating-point, Boolean, FT_GUID, and FT_EUI64 fields, For integral, floating-point, Boolean, FT_GUID, and FT_EUI64 fields,

View File

@ -45,6 +45,7 @@ use Getopt::Std;
'FT_PCRE', 'Perl Compatible Regular Expression', 'FT_PCRE', 'Perl Compatible Regular Expression',
'FT_GUID', 'Globally Unique Identifier', 'FT_GUID', 'Globally Unique Identifier',
'FT_OID', 'Object Identifier', 'FT_OID', 'Object Identifier',
'FT_REL_OID', 'Relative Object Identifier',
); );
getopts('e'); getopts('e');

View File

@ -43,6 +43,7 @@
'FT_PCRE', 'Perl Compatible Regular Expression', 'FT_PCRE', 'Perl Compatible Regular Expression',
'FT_GUID', 'Globally Unique Identifier', 'FT_GUID', 'Globally Unique Identifier',
'FT_OID', 'Object Identifier', 'FT_OID', 'Object Identifier',
'FT_REL_OID', 'Relative Object Identifier',
); );
# Read all the data into memory # Read all the data into memory

View File

@ -83,8 +83,9 @@ compatible_ftypes(ftenum_t a, ftenum_t b)
case FT_OID: case FT_OID:
case FT_AX25: case FT_AX25:
case FT_VINES: 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_BOOLEAN:
case FT_FRAMENUM: case FT_FRAMENUM:
@ -189,6 +190,7 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
case FT_PCRE: case FT_PCRE:
case FT_GUID: case FT_GUID:
case FT_OID: case FT_OID:
case FT_REL_OID:
return NULL; return NULL;
case FT_BOOLEAN: case FT_BOOLEAN:
@ -296,6 +298,7 @@ is_bytes_type(enum ftenum type)
case FT_IPv6: case FT_IPv6:
case FT_GUID: case FT_GUID:
case FT_OID: case FT_OID:
case FT_REL_OID:
return TRUE; return TRUE;
case FT_NONE: case FT_NONE:

View File

@ -849,6 +849,9 @@ try_dissect_unknown_ber(packet_info *pinfo, tvbuff_t *tvb, volatile int offset,
case BER_UNI_TAG_OID: case BER_UNI_TAG_OID:
offset = dissect_ber_object_identifier_str(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OID, NULL); offset = dissect_ber_object_identifier_str(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OID, NULL);
break; 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: case BER_UNI_TAG_NumericString:
offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_NumericString, NULL); offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_NumericString, NULL);
break; break;
@ -3229,7 +3232,6 @@ dissect_ber_choice(asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int
#ifdef DEBUG_BER_CHOICE #ifdef DEBUG_BER_CHOICE
{ {
const char *name; const char *name;
header_field_info *hfinfo;
if (hf_id >= 0) { if (hf_id >= 0) {
hfinfo = proto_registrar_get_nth(hf_id); hfinfo = proto_registrar_get_nth(hf_id);
name = hfinfo->name; name = hfinfo->name;
@ -3356,7 +3358,6 @@ printf("CHOICE testing potential subdissector class[%p]:%d:(expected)%d tag:%d:
#ifdef DEBUG_BER_CHOICE #ifdef DEBUG_BER_CHOICE
{ {
const char *name; const char *name;
header_field_info *hfinfo;
if (hf_id >= 0) { if (hf_id >= 0) {
hfinfo = proto_registrar_get_nth(hf_id); hfinfo = proto_registrar_get_nth(hf_id);
name = hfinfo->name; name = hfinfo->name;
@ -3381,7 +3382,6 @@ printf("CHOICE dissect_ber_choice(%s) calling subdissector len:%d\n", name, tvb_
#ifdef DEBUG_BER_CHOICE #ifdef DEBUG_BER_CHOICE
{ {
const char *name; const char *name;
header_field_info *hfinfo;
if (hf_id >= 0) { if (hf_id >= 0) {
hfinfo = proto_registrar_get_nth(hf_id); hfinfo = proto_registrar_get_nth(hf_id);
name = hfinfo->name; name = hfinfo->name;
@ -3397,7 +3397,6 @@ printf("CHOICE dissect_ber_choice(%s) subdissector ate %d bytes\n", name, count)
#ifdef DEBUG_BER_CHOICE #ifdef DEBUG_BER_CHOICE
{ {
const char *name; const char *name;
header_field_info *hfinfo;
if (hf_id >= 0) { if (hf_id >= 0) {
hfinfo = proto_registrar_get_nth(hf_id); hfinfo = proto_registrar_get_nth(hf_id);
name = hfinfo->name; 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 #ifdef DEBUG_BER_CHOICE
{ {
const char *name; const char *name;
header_field_info *hfinfo;
if (hf_id >= 0) { if (hf_id >= 0) {
hfinfo = proto_registrar_get_nth(hf_id); hfinfo = proto_registrar_get_nth(hf_id);
name = hfinfo->name; name = hfinfo->name;
@ -3592,7 +3590,6 @@ printf("CHOICE testing potential subdissector class[%p]:%d:(expected)%d tag:%d:
#ifdef DEBUG_BER_CHOICE #ifdef DEBUG_BER_CHOICE
{ {
const char *name; const char *name;
header_field_info *hfinfo;
if (hf_id >= 0) { if (hf_id >= 0) {
hfinfo = proto_registrar_get_nth(hf_id); hfinfo = proto_registrar_get_nth(hf_id);
name = hfinfo->name; name = hfinfo->name;
@ -3614,7 +3611,6 @@ printf("CHOICE dissect_ber_old_choice(%s) calling subdissector len:%d\n", name,
#ifdef DEBUG_BER_CHOICE #ifdef DEBUG_BER_CHOICE
{ {
const char *name; const char *name;
header_field_info *hfinfo;
if (hf_id >= 0) { if (hf_id >= 0) {
hfinfo = proto_registrar_get_nth(hf_id); hfinfo = proto_registrar_get_nth(hf_id);
name = hfinfo->name; 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 #ifdef DEBUG_BER_CHOICE
{ {
const char *name; const char *name;
header_field_info *hfinfo;
if (hf_id >= 0) { if (hf_id >= 0) {
hfinfo = proto_registrar_get_nth(hf_id); hfinfo = proto_registrar_get_nth(hf_id);
name = hfinfo->name; name = hfinfo->name;
@ -3833,6 +3828,110 @@ dissect_ber_GeneralString(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int
return offset; 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. /* 8.19 Encoding of an object identifier value.
*/ */
int int
@ -3851,7 +3950,6 @@ dissect_ber_object_identifier(gboolean implicit_tag, asn1_ctx_t *actx, proto_tre
#ifdef DEBUG_BER #ifdef DEBUG_BER
{ {
const char *name;
header_field_info *hfinfo; header_field_info *hfinfo;
if (hf_id >= 0) { if (hf_id >= 0) {
hfinfo = proto_registrar_get_nth(hf_id); hfinfo = proto_registrar_get_nth(hf_id);

View File

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

View File

@ -77,6 +77,8 @@ bytes_repr_len(fvalue_t *fv, ftrepr_t rtype _U_)
* OID_REPR_LEN: * OID_REPR_LEN:
* *
* 5 for the first byte ([0-2].[0-39].) * 5 for the first byte ([0-2].[0-39].)
*
* REL_OID_REPR_LEN:
* for each extra byte if the sub-id is: * for each extra byte if the sub-id is:
* 1 byte it can be at most "127." (4 bytes we give it 4) * 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) * 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, * a 5 bytes encoded subid can already overflow the guint32 that holds a sub-id,
* making it a completely different issue! * 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 static int
oid_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_) 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)); 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 static void
bytes_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf) 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; 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 static guint
len(fvalue_t *fv) len(fvalue_t *fv)
{ {
@ -811,10 +863,49 @@ ftype_register_bytes(void)
slice, 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_BYTES, &bytes_type);
ftype_register(FT_UINT_BYTES, &uint_bytes_type); ftype_register(FT_UINT_BYTES, &uint_bytes_type);
ftype_register(FT_AX25, &ax25_type); ftype_register(FT_AX25, &ax25_type);
ftype_register(FT_VINES, &vines_type); ftype_register(FT_VINES, &vines_type);
ftype_register(FT_ETHER, &ether_type); ftype_register(FT_ETHER, &ether_type);
ftype_register(FT_OID, &oid_type); ftype_register(FT_OID, &oid_type);
ftype_register(FT_REL_OID, &rel_oid_type);
} }

View File

@ -69,6 +69,7 @@ enum ftenum {
FT_EUI64, FT_EUI64,
FT_AX25, FT_AX25,
FT_VINES, FT_VINES,
FT_REL_OID, /* RELATIVE-OID */
FT_NUM_TYPES /* last item number plus one */ FT_NUM_TYPES /* last item number plus one */
}; };

View File

@ -829,11 +829,16 @@ void oids_cleanup(void) {
} }
const char* oid_subid2string(guint32* subids, guint len) { 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* s = (char *)ep_alloc0(((len)*11)+1);
char* w = s; char* w = s;
if(!subids) if(!subids)
return "*** Empty OID ***"; return "*** Empty OID ***";
if (!is_absolute)
*w++ = '.';
do { do {
w += g_snprintf(w,12,"%u.",*subids++); 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) { 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; gint i;
guint n = 1; guint n = is_first ? 1 : 0;
gboolean is_first = TRUE;
guint32* subids; guint32* subids;
guint32* subid_overflow; 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 * 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 * the right thing to do in this situation, and at the very least it
* avoids uninitialized memory errors that would otherwise occur. */ * avoids uninitialized memory errors that would otherwise occur. */
if (n == 1) { if ((is_first && n == 0) || (!is_first && n == 1)) {
*subids = 0; *subids = 0;
return n; 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); 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 oid_subid2encoded(guint subids_len, guint32* subids, guint8** bytes_p) {
guint bytelen = 0; 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) { guint oid_string2encoded(const char *oid_str, guint8 **bytes) {
guint32* subids; guint32* subids;

View File

@ -142,14 +142,20 @@ guint oid_string2encoded(const gchar *oid_str, guint8** encoded_p);
WS_DLL_PUBLIC WS_DLL_PUBLIC
guint oid_encoded2subid(const guint8 *oid, gint len, guint32** subids_p); guint oid_encoded2subid(const guint8 *oid, gint len, guint32** subids_p);
WS_DLL_PUBLIC 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); 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* 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* 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 */ /* 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(guint len, guint32 *subids);
WS_DLL_PUBLIC const gchar *oid_resolved_from_encoded(const guint8 *oid, gint len); 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); WS_DLL_PUBLIC const gchar *oid_resolved_from_string(const gchar *oid_str);
/* these yield two formated strings one resolved and one numeric */ /* these yield two formated strings one resolved and one numeric */

View File

@ -1406,6 +1406,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
break; break;
case FT_OID: case FT_OID:
case FT_REL_OID:
proto_tree_set_oid_tvb(new_fi, tvb, start, length); proto_tree_set_oid_tvb(new_fi, tvb, start, length);
break; break;
@ -3876,6 +3877,17 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
size-offset_r); size-offset_r);
break; 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: case FT_OID:
bytes = (guint8 *)fvalue_get(&finfo->value); bytes = (guint8 *)fvalue_get(&finfo->value);
offset_r += protoo_strlcpy(result+offset_r, 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_INT24:
case FT_INT32: case FT_INT32:
case FT_OID: case FT_OID:
case FT_REL_OID:
/* for these types, "expr" is filled in the loop above */ /* for these types, "expr" is filled in the loop above */
break; break;
@ -4785,6 +4798,7 @@ static const value_string hf_types[] = {
{ FT_PCRE, "FT_PCR" }, { FT_PCRE, "FT_PCR" },
{ FT_GUID, "FT_GUID" }, { FT_GUID, "FT_GUID" },
{ FT_OID, "FT_OID" }, { FT_OID, "FT_OID" },
{ FT_REL_OID, "FT_REL_OID" },
{ 0, NULL } }; { 0, NULL } };
static const value_string hf_display[] = { 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))); oid_encoded2string(bytes, fvalue_length(&fi->value)));
} }
break; 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: case FT_EUI64:
integer64 = fvalue_get_integer64(&fi->value); integer64 = fvalue_get_integer64(&fi->value);
label_fill_descr(label_str, 0, hfinfo, label_fill_descr(label_str, 0, hfinfo,

View File

@ -617,6 +617,10 @@ byte_array_dup(GByteArray *ba) {
#define SUBID_BUF_LEN 5 #define SUBID_BUF_LEN 5
gboolean gboolean
oid_str_to_bytes(const char *oid_str, GByteArray *bytes) { 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; guint32 subid0, subid, sicnt, i;
const char *p, *dot; const char *p, *dot;
guint8 buf[SUBID_BUF_LEN]; guint8 buf[SUBID_BUF_LEN];
@ -629,7 +633,7 @@ oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
while (*p) { while (*p) {
if (!isdigit((guchar)*p) && (*p != '.')) return FALSE; if (!isdigit((guchar)*p) && (*p != '.')) return FALSE;
if (*p == '.') { if (*p == '.') {
if (p == oid_str) return FALSE; if (p == oid_str && is_absolute) return FALSE;
if (!*(p+1)) return FALSE; if (!*(p+1)) return FALSE;
if ((p-1) == dot) return FALSE; if ((p-1) == dot) return FALSE;
dot = p; dot = p;
@ -639,7 +643,8 @@ oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
if (!dot) return FALSE; if (!dot) return FALSE;
p = oid_str; p = oid_str;
sicnt = 0; sicnt = is_absolute ? 0 : 2;
if (!is_absolute) p++;
subid0 = 0; /* squelch GCC complaints */ subid0 = 0; /* squelch GCC complaints */
while (*p) { while (*p) {
subid = 0; subid = 0;

View File

@ -151,6 +151,17 @@ gboolean uri_str_to_bytes(const char *uri_str, GByteArray *bytes);
WS_DLL_PUBLIC WS_DLL_PUBLIC
const gchar* format_uri(const GByteArray *bytes, const gchar *reserved_chars); const gchar* format_uri(const GByteArray *bytes, const gchar *reserved_chars);
/** 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.
* @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. /** Turn a OID string representation (dot notation) into a byte array.
* *
* @param oid_str The OID string (dot notaion). * @param oid_str The OID string (dot notaion).

View File

@ -155,6 +155,7 @@ WSLUA_METAMETHOD FieldInfo__call(lua_State* L) {
case FT_UINT_BYTES: case FT_UINT_BYTES:
case FT_GUID: case FT_GUID:
case FT_PROTOCOL: case FT_PROTOCOL:
case FT_REL_OID:
case FT_OID: { case FT_OID: {
ByteArray ba = g_byte_array_new(); 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); g_byte_array_append(ba, (const guint8 *)tvb_memdup(wmem_packet_scope(),fi->ds_tvb,fi->start,fi->length),fi->length);

View File

@ -459,6 +459,7 @@ static const wslua_ft_types_t ftenums[] = {
{"ftypes.FRAMENUM", FT_FRAMENUM}, {"ftypes.FRAMENUM", FT_FRAMENUM},
{"ftypes.GUID", FT_GUID}, {"ftypes.GUID", FT_GUID},
{"ftypes.OID", FT_OID}, {"ftypes.OID", FT_OID},
{"ftypes.REL_OID", FT_REL_OID},
{NULL, FT_NONE} {NULL, FT_NONE}
}; };
@ -1185,6 +1186,7 @@ PROTOFIELD_OTHER(bytes,FT_BYTES)
PROTOFIELD_OTHER(ubytes,FT_UINT_BYTES) PROTOFIELD_OTHER(ubytes,FT_UINT_BYTES)
PROTOFIELD_OTHER(guid,FT_GUID) PROTOFIELD_OTHER(guid,FT_GUID)
PROTOFIELD_OTHER(oid,FT_OID) PROTOFIELD_OTHER(oid,FT_OID)
PROTOFIELD_OTHER(rel_oid,FT_REL_OID)
WSLUA_METAMETHOD ProtoField__tostring(lua_State* L) { WSLUA_METAMETHOD ProtoField__tostring(lua_State* L) {
/* Returns a string with info about a protofield (for debugging purposes) */ /* Returns a string with info about a protofield (for debugging purposes) */
@ -1246,6 +1248,7 @@ static const luaL_Reg ProtoField_methods[] = {
{"ubytes",ProtoField_ubytes}, {"ubytes",ProtoField_ubytes},
{"guid",ProtoField_guid}, {"guid",ProtoField_guid},
{"oid",ProtoField_oid}, {"oid",ProtoField_oid},
{"rel_oid",ProtoField_rel_oid},
{ NULL, NULL } { NULL, NULL }
}; };

View File

@ -225,6 +225,7 @@ static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
case FT_IPXNET: case FT_IPXNET:
case FT_GUID: case FT_GUID:
case FT_OID: case FT_OID:
case FT_REL_OID:
default: default:
luaL_error(L,"FT_ not yet supported"); luaL_error(L,"FT_ not yet supported");
return 0; return 0;

View File

@ -66,7 +66,8 @@ FT_IPXNET,
FT_FRAMENUM, FT_FRAMENUM,
FT_PCRE, FT_PCRE,
FT_GUID, FT_GUID,
FT_OID) = map(int, range(31)) FT_OID,
FT_REL_OID) = map(int, range(32))
# hf_register_info from usual dissectors # hf_register_info from usual dissectors
class register_info(object): class register_info(object):

View File

@ -1239,6 +1239,8 @@ static const char* ftenum_to_string(header_field_info *hfi)
return "FT_GUID"; return "FT_GUID";
case FT_OID: case FT_OID:
return "FT_OID"; return "FT_OID";
case FT_REL_OID:
return "FT_REL_OID";
case FT_NUM_TYPES: case FT_NUM_TYPES:
return "FT_NUM_TYPES"; return "FT_NUM_TYPES";
default: default:

View File

@ -5301,7 +5301,7 @@ class RelativeOIDType (Type):
return 'RELATIVE_OID' return 'RELATIVE_OID'
def eth_ftype(self, ectx): def eth_ftype(self, ectx):
return ('FT_BYTES', 'BASE_NONE') return ('FT_REL_OID', 'BASE_NONE')
def GetTTag(self, ectx): def GetTTag(self, ectx):
return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID') return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID')

View File

@ -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_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_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_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", my %EXPERT_SEVERITY = ('PI_COMMENT' => "PI_COMMENT",
'PI_CHAT' => "PI_CHAT", 'PI_CHAT' => "PI_CHAT",

View File

@ -76,7 +76,7 @@ my $searchReplaceEncNAHRef =
my @types_NA = 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 $searchReplaceEncNAHRef
); );
@ -179,6 +179,7 @@ my @types_ALL =
FT_PCRE FT_PCRE
FT_GUID FT_GUID
FT_OID FT_OID
FT_REL_OID
FT_EUI64 FT_EUI64
)], )],
{# valid encoding args {# valid encoding args

View File

@ -92,7 +92,7 @@ resolve_column (gint col, capture_file *cf)
/* Check if this is a valid field */ /* Check if this is a valid field */
if (hfi != NULL) { if (hfi != NULL) {
/* Check if we have an OID or a strings table with integer values */ /* 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->strings != NULL) &&
((hfi->type == FT_BOOLEAN) || (hfi->type == FT_FRAMENUM) || ((hfi->type == FT_BOOLEAN) || (hfi->type == FT_FRAMENUM) ||
IS_FT_INT(hfi->type) || IS_FT_UINT(hfi->type)))) { IS_FT_INT(hfi->type) || IS_FT_UINT(hfi->type)))) {