diff options
-rw-r--r-- | epan/dfilter/semcheck.c | 10 | ||||
-rw-r--r-- | epan/ftypes/ftype-bytes.c | 219 | ||||
-rw-r--r-- | epan/ftypes/ftypes.h | 8 | ||||
-rw-r--r-- | epan/proto.c | 41 | ||||
-rw-r--r-- | int-64bit.c | 193 | ||||
-rw-r--r-- | int-64bit.h | 31 | ||||
-rw-r--r-- | packet-diameter.c | 14 |
7 files changed, 479 insertions, 37 deletions
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index d63911f0dc..025d471baa 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -1,10 +1,9 @@ /* - * $Id: semcheck.c,v 1.5 2001/10/29 21:13:12 guy Exp $ + * $Id: semcheck.c,v 1.6 2001/11/02 10:09:49 guy Exp $ * * Ethereal - Network traffic analyzer - * By Gerald Combs <gerald@zing.org> + * 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 @@ -53,6 +52,7 @@ compatible_ftypes(ftenum_t a, ftenum_t b) case FT_IPv4: case FT_IPv6: case FT_IPXNET: + case FT_INT64: case FT_UINT64: return a == b; @@ -142,6 +142,8 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s) case FT_STRING: case FT_STRINGZ: case FT_UINT_STRING: + case FT_UINT64: + case FT_INT64: return FALSE; case FT_BOOLEAN: @@ -227,10 +229,12 @@ is_bytes_type(enum ftenum type) case FT_UINT16: case FT_UINT24: case FT_UINT32: + case FT_UINT64: case FT_INT8: case FT_INT16: case FT_INT24: case FT_INT32: + case FT_INT64: return FALSE; case FT_NUM_TYPES: diff --git a/epan/ftypes/ftype-bytes.c b/epan/ftypes/ftype-bytes.c index 66073e636b..ce43828130 100644 --- a/epan/ftypes/ftype-bytes.c +++ b/epan/ftypes/ftype-bytes.c @@ -1,10 +1,9 @@ /* - * $Id: ftype-bytes.c,v 1.6 2001/10/29 21:13:13 guy Exp $ + * $Id: ftype-bytes.c,v 1.7 2001/11/02 10:09:51 guy Exp $ * * Ethereal - Network traffic analyzer - * By Gerald Combs <gerald@zing.org> + * 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 @@ -247,6 +246,20 @@ u64_from_string(fvalue_t *fv, char *s, LogFunc log) return TRUE; } +static gboolean +i64_from_string(fvalue_t *fv, char *s, LogFunc log) +{ + guint8 buffer[8]; + + if (atoi64(s, buffer) == NULL) { + log("\"%s\" is not a valid integer", s); + return FALSE; + } + + u64_fvalue_set(fv, buffer, FALSE); + return TRUE; +} + static guint len(fvalue_t *fv) { @@ -360,6 +373,178 @@ cmp_le(fvalue_t *fv_a, fvalue_t *fv_b) return (memcmp(a->data, b->data, a->len) <= 0); } +static gboolean +cmp_gt_i64(fvalue_t *fv_a, fvalue_t *fv_b) +{ + GByteArray *a = fv_a->value.bytes; + GByteArray *b = fv_b->value.bytes; + + if (a->len > b->len) { + return TRUE; + } + + if (a->len < b->len) { + return FALSE; + } + + if ((a->data[0] & 0x80) == 0) { + /* + * "a" is positive. + */ + if (b->data[0] & 0x80) { + /* + * "b" is negative, so a > b. + */ + return TRUE; + } + } else { + /* + * "a" is negative. + */ + if ((b->data[0] & 0x80) == 0) { + /* + * "b" is positive, so a < b. + */ + return FALSE; + } + } + + /* + * "a" and "b" have the same sign, so "memcmp()" should + * give the right answer. + */ + return (memcmp(a->data, b->data, a->len) > 0); +} + +static gboolean +cmp_ge_i64(fvalue_t *fv_a, fvalue_t *fv_b) +{ + GByteArray *a = fv_a->value.bytes; + GByteArray *b = fv_b->value.bytes; + + if (a->len > b->len) { + return TRUE; + } + + if (a->len < b->len) { + return FALSE; + } + + if ((a->data[0] & 0x80) == 0) { + /* + * "a" is positive. + */ + if (b->data[0] & 0x80) { + /* + * "b" is negative, so a > b. + */ + return TRUE; + } + } else { + /* + * "a" is negative. + */ + if ((b->data[0] & 0x80) == 0) { + /* + * "b" is positive, so a < b. + */ + return FALSE; + } + } + + /* + * "a" and "b" have the same sign, so "memcmp()" should + * give the right answer. + */ + return (memcmp(a->data, b->data, a->len) >= 0); +} + +static gboolean +cmp_lt_i64(fvalue_t *fv_a, fvalue_t *fv_b) +{ + GByteArray *a = fv_a->value.bytes; + GByteArray *b = fv_b->value.bytes; + + if (a->len < b->len) { + return TRUE; + } + + if (a->len > b->len) { + return FALSE; + } + + if (a->data[0] & 0x80) { + /* + * "a" is negative. + */ + if ((b->data[0] & 0x80) == 0) { + /* + * "b" is positive, so a < b. + */ + return TRUE; + } + } else { + /* + * "a" is positive. + */ + if (b->data[0] & 0x80) { + /* + * "b" is negative, so a > b. + */ + return FALSE; + } + } + + /* + * "a" and "b" have the same sign, so "memcmp()" should + * give the right answer. + */ + return (memcmp(a->data, b->data, a->len) < 0); +} + +static gboolean +cmp_le_i64(fvalue_t *fv_a, fvalue_t *fv_b) +{ + GByteArray *a = fv_a->value.bytes; + GByteArray *b = fv_b->value.bytes; + + if (a->len < b->len) { + return TRUE; + } + + if (a->len > b->len) { + return FALSE; + } + + if (a->data[0] & 0x80) { + /* + * "a" is negative. + */ + if ((b->data[0] & 0x80) == 0) { + /* + * "b" is positive, so a < b. + */ + return TRUE; + } + } else { + /* + * "a" is positive. + */ + if (b->data[0] & 0x80) { + /* + * "b" is negative, so a > b. + */ + return FALSE; + } + } + + /* + * "a" and "b" have the same sign, so "memcmp()" should + * give the right answer. + */ + return (memcmp(a->data, b->data, a->len) <= 0); +} + void ftype_register_bytes(void) { @@ -472,8 +657,36 @@ ftype_register_bytes(void) slice, }; + static ftype_t i64_type = { + "FT_INT64", + "Signed 64-bit integer", + U64_LEN, + bytes_fvalue_new, + bytes_fvalue_free, + i64_from_string, + + u64_fvalue_set, + NULL, + NULL, + + value_get, + NULL, + NULL, + + cmp_eq, + cmp_ne, + cmp_gt_i64, + cmp_ge_i64, + cmp_lt_i64, + cmp_le_i64, + + len, + slice, + }; + ftype_register(FT_BYTES, &bytes_type); ftype_register(FT_ETHER, ðer_type); ftype_register(FT_IPv6, &ipv6_type); ftype_register(FT_UINT64, &u64_type); + ftype_register(FT_INT64, &i64_type); } diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h index 78f30ce7d8..0bf117944a 100644 --- a/epan/ftypes/ftypes.h +++ b/epan/ftypes/ftypes.h @@ -1,12 +1,11 @@ /* ftypes.h * Definitions for field types * - * $Id: ftypes.h,v 1.6 2001/10/29 21:13:13 guy Exp $ + * $Id: ftypes.h,v 1.7 2001/11/02 10:09:51 guy Exp $ * * Ethereal - Network traffic analyzer - * By Gerald Combs <gerald@zing.org> + * 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 @@ -42,8 +41,9 @@ enum ftenum { FT_UINT64, FT_INT8, FT_INT16, - FT_INT24, + FT_INT24, /* same as for UINT24 */ FT_INT32, + FT_INT64, FT_DOUBLE, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME, diff --git a/epan/proto.c b/epan/proto.c index 3811826ddb..298848ed45 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -1,7 +1,7 @@ /* proto.c * Routines for protocol tree * - * $Id: proto.c,v 1.38 2001/10/29 21:13:10 guy Exp $ + * $Id: proto.c,v 1.39 2001/11/02 10:09:48 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -54,6 +54,7 @@ proto_tree_free_node(GNode *node, gpointer data); static void fill_label_boolean(field_info *fi, gchar *label_str); static void fill_label_uint(field_info *fi, gchar *label_str); static void fill_label_uint64(field_info *fi, gchar *label_str); +static void fill_label_int64(field_info *fi, gchar *label_str); static void fill_label_enumerated_uint(field_info *fi, gchar *label_str); static void fill_label_enumerated_bitfield(field_info *fi, gchar *label_str); static void fill_label_numeric_bitfield(field_info *fi, gchar *label_str); @@ -491,6 +492,7 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb, get_uint_value(tvb, start, length, little_endian)); break; + case FT_INT64: case FT_UINT64: g_assert(length == 8); proto_tree_set_uint64_tvb(new_fi, tvb, start, little_endian); @@ -2006,6 +2008,10 @@ proto_item_fill_label(field_info *fi, gchar *label_str) } break; + case FT_INT64: + fill_label_int64(fi, label_str); + break; + case FT_DOUBLE: snprintf(label_str, ITEM_LABEL_LENGTH, "%s: %g", hfinfo->name, fvalue_get_floating(fi->value)); @@ -2096,6 +2102,30 @@ fill_label_uint64(field_info *fi, gchar *label_str) } static void +fill_label_int64(field_info *fi, gchar *label_str) +{ + unsigned char *bytes; + header_field_info *hfinfo = fi->hfinfo; + + bytes=fvalue_get(fi->value); + switch(hfinfo->display){ + case BASE_DEC: + snprintf(label_str, ITEM_LABEL_LENGTH, + "%s: %s", hfinfo->name, + i64toa(bytes)); + break; + case BASE_HEX: + snprintf(label_str, ITEM_LABEL_LENGTH, + "%s: %s", hfinfo->name, + u64toh(bytes)); + break; + default: + g_assert_not_reached(); + ; + } +} + +static void fill_label_boolean(field_info *fi, gchar *label_str) { char *p = label_str; @@ -2943,6 +2973,7 @@ proto_can_match_selected(field_info *finfo) case FT_INT16: case FT_INT24: case FT_INT32: + case FT_INT64: case FT_IPv4: case FT_IPXNET: case FT_IPv6: @@ -3013,6 +3044,14 @@ proto_alloc_dfilter_string(field_info *finfo, guint8 *pd) stringified); break; + case FT_INT64: + stringified = i64toa(fvalue_get(finfo->value)); + dfilter_len = abbrev_len + 4 + strlen(stringified) +1; + buf = g_malloc0(dfilter_len); + snprintf(buf, dfilter_len, "%s == %s", hfinfo->abbrev, + stringified); + break; + case FT_IPv4: dfilter_len = abbrev_len + 4 + 15 + 1; buf = g_malloc0(dfilter_len); diff --git a/int-64bit.c b/int-64bit.c index 4f11088a6b..2f07aef184 100644 --- a/int-64bit.c +++ b/int-64bit.c @@ -2,7 +2,7 @@ * Routines for handling of 64-bit integers * 2001 Ronnie Sahlberg * - * $Id: int-64bit.c,v 1.3 2001/10/30 08:39:02 guy Exp $ + * $Id: int-64bit.c,v 1.4 2001/11/02 10:09:47 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -118,13 +118,16 @@ static const signed char u64val[64][U64STRLEN] = It is much less important that the inverse: atou64 be efficient since it is only called when diplayfilters are entered. + + "neg" should be 1 if the number should have a "-" put in + front of it. */ -char * -u64toa(const unsigned char *u64ptr) +static char * +n64toa(const unsigned char *u64ptr, int neg) { unsigned char acc[U64STRLEN]; /* accumulator */ int i,j,k,pos; - static char str[U64STRLEN]; + static char str[U64STRLEN+1]; /* 1 extra for the sign */ /* clear out the accumulator */ for(i=0;i<U64STRLEN-1;i++){ @@ -168,21 +171,92 @@ u64toa(const unsigned char *u64ptr) } /* convert to a string */ - str[U64STRLEN-1]=0; + str[U64STRLEN-1+neg]=0; for(i=0;i<U64STRLEN-1;i++){ - str[U64STRLEN-2-i]='0'+acc[i]; + str[U64STRLEN-2-i+neg]='0'+acc[i]; } /* skip the initial zeros */ for(i=0;i<U64STRLEN-2;i++){ - if(str[i]>'0'){ + if(str[i+neg]>'0'){ break; } } + /* insert the sign */ + if (neg) + str[i] = '-'; + return str+i; } +/* + * Convert an unsigned 64-bit integer into a string, in decimal. + */ +char * +u64toa(const unsigned char *u64ptr) +{ + /* + * Just use "n64toa()". + */ + return n64toa(u64ptr, 0); +} + +/* + * Convert a signed 64-bit integer into a string, in decimal. + */ +char * +i64toa(const unsigned char *i64ptr) +{ + unsigned char neg[8]; + int i; + int carry; + int byte; + + /* + * The bytes of the integer go from msb to lsb, so the + * msb is "i64ptr[0]". + * + * The sign bit, therefore, is "i64ptr[0] & 0x80". + */ + if (i64ptr[0] & 0x80) { + /* + * It's negative - compute the absolute value, + * by taking the two's complement; take the + * one's complement of the low-order byte, add + * 1, take the one's complement of the next byte + * up, add the carry from the previous addition, + * etc. + * + * If it's the maximum negative value, which is + * 0x8000000000000000, this will turn it back + * into 0x8000000000000000, which "n64toa()" + * will handle correctly, reporting the absolute + * value of the maximum negative value; + * thus, we don't have to worry about it. + */ + carry = 1; + for (i = 7; i >= 0; i--) { + byte = ((unsigned char)~i64ptr[i]) + carry; + neg[i] = byte; + if (byte & 0x100) + carry = 1; + else + carry = 0; + } + + /* + * Use "n64toa()" on the negative, and tell it to insert + * a "-". + */ + return n64toa(neg, 1); + } else { + /* + * It's positive, so just use "n64toa()". + */ + return n64toa(i64ptr, 0); + } +} /* like memcmp but compares in reverse */ static int @@ -203,7 +277,9 @@ revcmp(const signed char *s1, const signed char *s2, int len) return 0; } - +/* + * Convert a string to an unsigned 64-bit integer. + */ unsigned char * atou64(const char *u64str, unsigned char *u64int) { @@ -267,6 +343,58 @@ atou64(const char *u64str, unsigned char *u64int) return u64int; } +/* + * Convert a string to a signed 64-bit integer. + */ +unsigned char * +atoi64(const char *i64str, unsigned char *i64int) +{ + int i; + int carry; + int byte; + + if(!i64str){ + return NULL; + } + + /* + * Does it begin with a minus sign? + */ + if (i64str[0] == '-') { + /* + * Yes - convert the rest of the string to a number... + */ + if (atou64(&i64str[1], i64int) == NULL) { + /* + * We failed. + */ + return NULL; + } + + /* + * ...and then take its negative. + */ + carry = 1; + for (i = 7; i >= 0; i--) { + byte = ((unsigned char)~i64int[i]) + carry; + i64int[i] = byte; + if (byte & 0x100) + carry = 1; + else + carry = 0; + } + return i64int; + } else { + /* + * No - just let "atou64()" handle it. + */ + return atou64(i64str, i64int); + } +} + +/* + * Convert an unsigned 64-bit integer to a string, in hex. + */ char * u64toh(const unsigned char *u64ptr) { @@ -305,6 +433,9 @@ ntoh(unsigned char h) return 0; } +/* + * Convert a hex string to an unsigned 64-bit integer. + */ unsigned char * htou64(const char *u64str, unsigned char *u64int) { @@ -370,15 +501,51 @@ htou64(const char *u64str, unsigned char *u64int) } #ifdef TEST_DEBUG +#include <stdio.h> + int main(void) { - char i[8] = {0,0,0,0,0x55,0x44,0x33,0x11}; + char i998877665544331[8] = + {0x0, 0x23, 0x7c, 0xbd, 0x4c, 0x49, 0xd5, 0x6f}; + char iminus9988776655443311[8] = + {0xff, 0xdc, 0x83, 0x42, 0xb3, 0xb6, 0x2a, 0x91}; + char i9223372036854775807[8] = + {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + char iminus1[8] = + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + char iminus9223372036854775808[8] = + {0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + char u9223372036854775808[8] = + {0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + char u18446744073709551615[8] = + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + char u0xaabbccdd00112233[8] = + {0xaa, 0xbb, 0xcc, 0xdd, 0x0, 0x11, 0x22, 0x33}; char t[8]; - printf("%s\n",u64toa(i)); - printf("%s\n",u64toa(atou64("55443311",t))); - printf("%s\n",u64toh(i)); - printf("%s\n",u64toh(htou64("0x55443311",t))); + printf("%s (9988776655443311)\n",i64toa(i998877665544331)); + printf("%s (-9988776655443311)\n",i64toa(iminus9988776655443311)); + printf("%s (9223372036854775807)\n",i64toa(i9223372036854775807)); + printf("%s (-1)\n",i64toa(iminus1)); + printf("%s (-9223372036854775808)\n",i64toa(iminus9223372036854775808)); + + printf("%s (9988776655443311)\n",u64toa(i998877665544331)); + printf("%s (9223372036854775807)\n",u64toa(i9223372036854775807)); + printf("%s (9223372036854775808)\n",u64toa(u9223372036854775808)); + printf("%s (18446744073709551615)\n",u64toa(u18446744073709551615)); + + printf("%s (0xaabbccdd00112233)\n",u64toh(u0xaabbccdd00112233)); + + printf("%s (55443311)\n",i64toa(atoi64("55443311",t))); + printf("%s (-55443311)\n",i64toa(atoi64("-55443311",t))); + printf("%s (9988776655443311)\n",i64toa(atoi64("9988776655443311",t))); + printf("%s (-9988776655443311)\n",i64toa(atoi64("-9988776655443311",t))); + printf("%s (9223372036854775807)\n",i64toa(atoi64("9223372036854775807",t))); + printf("%s (-1)\n",i64toa(atoi64("-1",t))); + printf("%s (-9223372036854775808)\n",i64toa(atoi64("-9223372036854775808",t))); + + printf("%s (55443311)\n",u64toa(atou64("55443311",t))); + printf("%s (0x55443311)\n",u64toh(htou64("0x55443311",t))); return 0; } #endif diff --git a/int-64bit.h b/int-64bit.h index b927a0e33f..448804ce8a 100644 --- a/int-64bit.h +++ b/int-64bit.h @@ -1,7 +1,7 @@ /* int-64bit.h * Handling of 64-bit integers * - * $Id: int-64bit.h,v 1.2 2001/10/29 21:53:58 guy Exp $ + * $Id: int-64bit.h,v 1.3 2001/11/02 10:09:47 guy Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,11 +26,36 @@ * arrays of 8 bytes in network byte order (bit-endian), and ASCII strings * giving integer values in decimal or hexadecimal. */ -char *u64toa(const unsigned char *u64ptr); + +/* + * Convert an unsigned 64-bit integer into a string, in decimal. + */ +extern char *u64toa(const unsigned char *u64ptr); + +/* + * Convert a signed 64-bit integer into a string, in decimal. + */ +extern char *i64toa(const unsigned char *i64ptr); + +/* + * Convert a string to an unsigned 64-bit integer. + */ unsigned char *atou64(const char *u64str, unsigned char *u64int); + +/* + * Convert a string to a signed 64-bit integer. + */ +unsigned char *atoi64(const char *i64str, unsigned char *i64int); + +/* + * Convert an unsigned 64-bit integer to a string, in hex. + */ char *u64toh(const unsigned char *u64ptr); -unsigned char *htou64(const char *u64str, unsigned char *u64int); +/* + * Convert a hex string to an unsigned 64-bit integer. + */ +unsigned char *htou64(const char *u64str, unsigned char *u64int); #endif diff --git a/packet-diameter.c b/packet-diameter.c index 4ee8100345..121b6b01ce 100644 --- a/packet-diameter.c +++ b/packet-diameter.c @@ -1,7 +1,7 @@ /* packet-diameter.c * Routines for Diameter packet disassembly * - * $Id: packet-diameter.c,v 1.28 2001/11/01 21:52:44 guy Exp $ + * $Id: packet-diameter.c,v 1.29 2001/11/02 10:09:47 guy Exp $ * * Copyright (c) 2001 by David Frascone <dave@frascone.com> * @@ -1465,15 +1465,9 @@ static void dissect_avps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *avp_tree break; case DIAMETER_INTEGER64: - { - gint64 data; - memcpy(&data, dataBuffer, 8); - /* data = ntohll(data); */ - proto_tree_add_int_format(avpi_tree, hf_diameter_avp_data_int64, - tvb, offset, avpDataLength, data, - "Value: 0x%016llx (%lld)", data, data ); - } + proto_tree_add_item(avpi_tree, hf_diameter_avp_data_int64, tvb, offset, 8, FALSE); break; + case DIAMETER_UNSIGNED64: proto_tree_add_item(avpi_tree, hf_diameter_avp_data_uint64, tvb, offset, 8, FALSE); break; @@ -1666,7 +1660,7 @@ proto_register_diameter(void) { "AVP Data","diameter.avp.data.uint64", FT_UINT64, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_diameter_avp_data_int64, - { "AVP Data","diameter.avp.data.int64", FT_INT32, BASE_DEC, + { "AVP Data","diameter.avp.data.int64", FT_INT64, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_diameter_avp_data_uint32, { "AVP Data","diameter.avp.data.uint32", FT_UINT32, BASE_DEC, |