new FT_GUID handling - big/little endian supported

svn path=/trunk/; revision=17566
This commit is contained in:
Tomas Kukosa 2006-03-10 11:58:22 +00:00
parent 281e4a7ebb
commit 923855bb20
14 changed files with 281 additions and 145 deletions

View File

@ -41,6 +41,7 @@ libftypes_la_SOURCES = \
ftype-double.c \
ftype-integer.c \
ftype-ipv4.c \
ftype-guid.c \
ftype-none.c \
ftype-pcre.c \
ftype-string.c \

View File

@ -22,6 +22,7 @@ OBJECTS = \
ftype-double.obj \
ftype-integer.obj \
ftype-ipv4.obj \
ftype-guid.obj \
ftype-none.obj \
ftype-pcre.obj \
ftype-string.obj \

View File

@ -39,7 +39,6 @@
#define ETHER_LEN 6
#define IPv6_LEN 16
#define GUID_LEN 16
static void
bytes_fvalue_new(fvalue_t *fv)
@ -76,18 +75,6 @@ bytes_repr_len(fvalue_t *fv, ftrepr_t rtype _U_)
return fv->value.bytes->len * 3 - 1;
}
static int
guid_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
{
return GUID_STR_LEN;
}
static void
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_)
{
@ -147,13 +134,6 @@ ipv6_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
common_fvalue_set(fv, value, IPv6_LEN);
}
static void
guid_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
{
g_assert(!already_copied);
common_fvalue_set(fv, value, GUID_LEN);
}
static void
oid_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
{
@ -278,69 +258,6 @@ ipv6_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
ip6_to_str_buf((struct e_in6_addr *)fv->value.bytes->data, buf);
}
static gboolean
get_guid(char *s, guint8 *buf)
{
size_t i, n;
char *p, two_digits[3];
static const char fmt[] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
n = strlen(s);
if (n != strlen(fmt))
return FALSE;
for (i=0; i<n; i++) {
if (fmt[i] == 'X') {
if (!isxdigit((guchar)s[i]))
return FALSE;
} else {
if (s[i] != fmt[i])
return FALSE;
}
}
for (p=s,i=0; i<GUID_LEN; i++) {
if (*p == '-') p++;
two_digits[0] = *(p++);
two_digits[1] = *(p++);
two_digits[2] = '\0';
buf[i] = (guint8)strtoul(two_digits, NULL, 16);
}
return TRUE;
}
static gboolean
guid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
{
guint8 buffer[GUID_LEN];
/*
* Don't log a message if this fails; we'll try looking it
* up as an GUID if it does, and if that fails,
* we'll log a message.
*/
if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
if (fv->value.bytes->len > GUID_LEN) {
logfunc("\"%s\" contains too many bytes to be a valid Globally Unique Identifier.",
s);
return FALSE;
}
else if (fv->value.bytes->len < GUID_LEN && !allow_partial_value) {
logfunc("\"%s\" contains too few bytes to be a valid Globally Unique Identifier.",
s);
return FALSE;
}
return TRUE;
}
if (!get_guid(s, buffer)) {
logfunc("\"%s\" is not a valid GUID.", s);
return FALSE;
}
guid_fvalue_set(fv, buffer, FALSE);
return TRUE;
}
static gboolean
oid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
{
@ -702,41 +619,6 @@ ftype_register_bytes(void)
slice,
};
static ftype_t guid_type = {
"GUID", /* name */
"Globally Unique Identifier", /* pretty_name */
GUID_LEN, /* wire_size */
bytes_fvalue_new, /* new_value */
bytes_fvalue_free, /* free_value */
guid_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
guid_to_repr, /* val_to_string_repr */
guid_repr_len, /* len_string_repr */
guid_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,
};
static ftype_t oid_type = {
"OID", /* name */
"OBJECT IDENTIFIER", /* pretty_name */
@ -776,6 +658,5 @@ ftype_register_bytes(void)
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);
}

167
epan/ftypes/ftype-guid.c Normal file
View File

@ -0,0 +1,167 @@
/*
* $Id$
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Copyright 2001 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <ftypes-int.h>
#include <epan/guid-utils.h>
#define GUID_LEN 16
static void
set_guid(fvalue_t *fv, e_guid_t *value)
{
fv->value.guid = *value;
}
static gpointer
value_get(fvalue_t *fv)
{
return &(fv->value.guid);
}
static gboolean
get_guid(char *s, e_guid_t *guid)
{
size_t i, n;
char *p, digits[9];
static const char fmt[] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
n = strlen(s);
if (n != strlen(fmt))
return FALSE;
for (i=0; i<n; i++) {
if (fmt[i] == 'X') {
if (!isxdigit((guchar)s[i]))
return FALSE;
} else {
if (s[i] != fmt[i])
return FALSE;
}
}
p = s;
strncpy(digits, p, 8);
digits[8] = '\0';
guid->data1 = strtoul(digits, NULL, 16);
p += 9;
strncpy(digits, p, 4);
digits[4] = '\0';
guid->data2 = (guint16)strtoul(digits, NULL, 16);
p += 5;
strncpy(digits, p, 4);
digits[4] = '\0';
guid->data3 = (guint16)strtoul(digits, NULL, 16);
p += 5;
for (i=0; i < sizeof(guid->data4); i++) {
if (*p == '-') p++;
digits[0] = *(p++);
digits[1] = *(p++);
digits[2] = '\0';
guid->data4[i] = (guint8)strtoul(digits, NULL, 16);
}
return TRUE;
}
static gboolean
guid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
{
e_guid_t guid;
if (!get_guid(s, &guid)) {
logfunc("\"%s\" is not a valid GUID.", s);
return FALSE;
}
set_guid(fv, &guid);
return TRUE;
}
static int
guid_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
{
return GUID_STR_LEN;
}
static void
guid_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
{
guid_to_str_buf(&fv->value.guid, buf, GUID_STR_LEN);
}
static gboolean
cmp_eq(fvalue_t *a, fvalue_t *b)
{
return memcmp(&a->value.guid, &b->value.guid, sizeof(e_guid_t)) == 0;
}
static gboolean
cmp_ne(fvalue_t *a, fvalue_t *b)
{
return memcmp(&a->value.guid, &b->value.guid, sizeof(e_guid_t)) != 0;
}
void
ftype_register_guid(void)
{
static ftype_t guid_type = {
"GUID", /* name */
"Globally Unique Identifier", /* pretty_name */
GUID_LEN, /* wire_size */
NULL, /* new_value */
NULL, /* free_value */
guid_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
guid_to_repr, /* val_to_string_repr */
guid_repr_len, /* len_string_repr */
set_guid, /* 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,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL, /* cmp_matches */
NULL,
NULL,
};
ftype_register(FT_GUID, &guid_type);
}

View File

@ -51,6 +51,7 @@ void ftype_register_bytes(void);
void ftype_register_double(void);
void ftype_register_integers(void);
void ftype_register_ipv4(void);
void ftype_register_guid(void);
void ftype_register_none(void);
void ftype_register_string(void);
void ftype_register_time(void);

View File

@ -44,6 +44,7 @@ ftypes_initialize(void)
ftype_register_double();
ftype_register_integers();
ftype_register_ipv4();
ftype_register_guid();
ftype_register_none();
ftype_register_string();
ftype_register_time();

View File

@ -138,6 +138,7 @@ ftype_can_matches(enum ftenum ftype);
/* ---------------- FVALUE ----------------- */
#include <epan/ipv4.h>
#include <epan/guid-utils.h>
#include <epan/tvbuff.h>
#include <epan/nstime.h>
@ -156,6 +157,7 @@ typedef struct _fvalue_t {
GByteArray *bytes;
GString *gstring;
ipv4_addr ipv4;
e_guid_t guid;
nstime_t time;
tvbuff_t *tvb;
#ifdef HAVE_LIBPCRE

38
epan/guid-utils.h Normal file
View File

@ -0,0 +1,38 @@
/* guid-utils.h
* Definitions for GUID handling
*
* $Id$
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
*
* Copyright 1998 Gerald Combs
*
* MobileIPv6 support added by Tomislav Borosa <tomislav.borosa@siemens.hr>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GUID_UTILS_H__
#define __GUID_UTILS_H__
typedef struct _e_guid_t {
guint32 data1;
guint16 data2;
guint16 data3;
guint8 data4[8];
} e_guid_t;
#endif /* __GUID_UTILS_H__ */

View File

@ -151,9 +151,9 @@ proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
static void
proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start);
static void
proto_tree_set_guid(field_info *fi, const guint8* value_ptr);
proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
static void
proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start);
proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian);
static void
proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
static void
@ -902,7 +902,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, int hfindex,
case FT_GUID:
DISSECTOR_ASSERT(length == 16);
proto_tree_set_guid_tvb(new_fi, tvb, start);
proto_tree_set_guid_tvb(new_fi, tvb, start, little_endian);
break;
case FT_OID:
@ -1637,7 +1637,7 @@ proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start)
/* Add a FT_GUID to a proto_tree */
proto_item *
proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
const guint8* value_ptr)
const e_guid_t *value_ptr)
{
proto_item *pi;
field_info *new_fi;
@ -1659,7 +1659,7 @@ proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gi
proto_item *
proto_tree_add_guid_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
const guint8* value_ptr)
const e_guid_t *value_ptr)
{
proto_item *pi;
@ -1674,7 +1674,7 @@ proto_tree_add_guid_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st
proto_item *
proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
gint start, gint length, const guint8* value_ptr,
gint start, gint length, const e_guid_t *value_ptr,
const char *format, ...)
{
proto_item *pi;
@ -1693,7 +1693,7 @@ proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
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, ...)
const e_guid_t *value_ptr, const char *format, ...)
{
proto_item *pi;
va_list ap;
@ -1711,16 +1711,19 @@ proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st
/* Set the FT_GUID value */
static void
proto_tree_set_guid(field_info *fi, const guint8* value_ptr)
proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
{
DISSECTOR_ASSERT(value_ptr != NULL);
fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
}
static void
proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start)
proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian)
{
proto_tree_set_guid(fi, tvb_get_ptr(tvb, start, 16));
e_guid_t guid;
tvb_get_guid(tvb, start, &guid, little_endian);
proto_tree_set_guid(fi, &guid);
}
/* Add a FT_OID to a proto_tree */
@ -3669,6 +3672,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
guint8 *bytes;
guint32 integer;
ipv4_addr *ipv4;
e_guid_t *guid;
guint32 n_addr; /* network-order IPv4 address */
const gchar *name;
int ret; /*tmp return value */
@ -3827,10 +3831,10 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
break;
case FT_GUID:
bytes = fvalue_get(&fi->value);
guid = fvalue_get(&fi->value);
ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s", hfinfo->name,
guid_to_str(bytes));
guid_to_str(guid));
if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;

View File

@ -817,13 +817,13 @@ proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint s
@return the newly created item */
extern proto_item *
proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, const guint8* value_ptr);
gint length, const e_guid_t *value_ptr);
/** Add a hidden FT_GUID 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_guid_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, const guint8* value_ptr);
gint length, const e_guid_t *value_ptr);
/** Add a formatted FT_GUID to a proto_tree, with the format generating
the string for the value and with the field name being included
@ -839,7 +839,7 @@ proto_tree_add_guid_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st
@return the newly created item */
extern proto_item *
proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
gint start, gint length, const guint8* value_ptr, const char *format,
gint start, gint length, const e_guid_t *value_ptr, const char *format,
...) GNUC_FORMAT_CHECK(printf,7,8);
/** Add a formatted FT_GUID to a proto_tree, with the format generating
@ -855,7 +855,7 @@ proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
@return the newly created item */
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);
gint length, const e_guid_t *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
@ -870,7 +870,7 @@ 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 */
@deprecated use proto_tree_add_oid() 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);

View File

@ -873,19 +873,17 @@ gchar* oid_to_str_buf(const guint8 *oid, gint oid_len, gchar *buf, int buf_len)
return buf;
}
gchar* guid_to_str(const guint8 *guid) {
gchar* guid_to_str(const e_guid_t *guid) {
gchar *buf;
buf=ep_alloc(GUID_STR_LEN);
return guid_to_str_buf(guid, buf, GUID_STR_LEN);
}
gchar* guid_to_str_buf(const guint8 *guid, gchar *buf, int buf_len) {
g_snprintf(buf, buf_len, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
guid[0], guid[1], guid[2], guid[3],
guid[4], guid[5],
guid[6], guid[7],
guid[8], guid[9], guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]);
gchar* guid_to_str_buf(const e_guid_t *guid, gchar *buf, int buf_len) {
g_snprintf(buf, buf_len, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
guid->data1, guid->data2, guid->data3,
guid->data4[0], guid->data4[1], guid->data4[2], guid->data4[3], guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
return buf;
}

View File

@ -76,8 +76,8 @@ extern gchar* rel_time_to_str(nstime_t*);
extern gchar* rel_time_to_secs_str(nstime_t*);
extern gchar* oid_to_str(const guint8*, gint);
extern gchar* oid_to_str_buf(const guint8*, gint, gchar*, int);
extern gchar* guid_to_str(const guint8*);
extern gchar* guid_to_str_buf(const guint8*, gchar*, int);
extern gchar* guid_to_str(const e_guid_t*);
extern gchar* guid_to_str_buf(const e_guid_t*, gchar*, int);
void tipc_addr_to_str_buf( const guint8 *data, gchar *buf, int buf_len);

View File

@ -1411,6 +1411,41 @@ tvb_get_ipv6(tvbuff_t *tvb, gint offset, struct e_in6_addr *addr)
memcpy(addr, ptr, sizeof *addr);
}
/* Fetch a GUID. */
void
tvb_get_ntohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
{
const guint8* ptr;
ensure_contiguous(tvb, offset, sizeof(*guid));
guid->data1 = tvb_get_ntohl(tvb, offset);
guid->data2 = tvb_get_ntohs(tvb, offset + 4);
guid->data3 = tvb_get_ntohs(tvb, offset + 6);
tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
}
void
tvb_get_letohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
{
const guint8* ptr;
ensure_contiguous(tvb, offset, sizeof(*guid));
guid->data1 = tvb_get_letohl(tvb, offset);
guid->data2 = tvb_get_letohs(tvb, offset + 4);
guid->data3 = tvb_get_letohs(tvb, offset + 6);
tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
}
void
tvb_get_guid(tvbuff_t *tvb, gint offset, e_guid_t *guid, gboolean little_endian)
{
if (little_endian) {
tvb_get_letohguid(tvb, offset, guid);
} else {
tvb_get_ntohguid(tvb, offset, guid);
}
}
/* Find first occurence of needle in tvbuff, starting at offset. Searches
* at most maxlength number of bytes; if maxlength is -1, searches to
* end of tvbuff.

View File

@ -37,6 +37,7 @@
#include <glib.h>
#include <epan/ipv6-utils.h>
#include <epan/guid-utils.h>
#include "exceptions.h"
/** @file
@ -330,6 +331,12 @@ extern guint32 tvb_get_ipv4(tvbuff_t*, gint offset);
/* Fetch an IPv6 address. */
extern void tvb_get_ipv6(tvbuff_t*, gint offset, struct e_in6_addr *addr);
/* Fetch a GUID. */
extern void tvb_get_ntohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid);
extern void tvb_get_letohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid);
extern void tvb_get_guid(tvbuff_t *tvb, gint offset, e_guid_t *guid, gboolean little_endian);
/** Returns target for convenience. Does not suffer from possible
* expense of tvb_get_ptr(), since this routine is smart enough
* to copy data in chunks if the request range actually exists in