2 * $Id: ftype-bytes.c,v 1.8 2001/11/22 03:07:07 hagbard Exp $
4 * Ethereal - Network traffic analyzer
5 * By Gerald Combs <gerald@ethereal.com>
6 * Copyright 2001 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 #include <ftypes-int.h>
31 #include "int-64bit.h"
38 bytes_fvalue_new(fvalue_t *fv)
40 fv->value.bytes = NULL;
44 bytes_fvalue_free(fvalue_t *fv)
46 if (fv->value.bytes) {
47 g_byte_array_free(fv->value.bytes, TRUE);
54 bytes_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
56 g_assert(already_copied);
57 fv->value.bytes = value;
61 common_fvalue_set(fvalue_t *fv, guint8* data, guint len)
63 fv->value.bytes = g_byte_array_new();
64 g_byte_array_append(fv->value.bytes, data, len);
68 ether_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
70 g_assert(!already_copied);
71 common_fvalue_set(fv, value, ETHER_LEN);
75 ipv6_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
77 g_assert(!already_copied);
78 common_fvalue_set(fv, value, IPv6_LEN);
82 u64_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
84 g_assert(!already_copied);
85 common_fvalue_set(fv, value, U64_LEN);
89 value_get(fvalue_t *fv)
91 return fv->value.bytes->data;
97 return (c == '-' || c == ':' || c == '.');
101 val_from_string(fvalue_t *fv, char *s, LogFunc log)
105 guchar *p, *q, *punct;
108 gboolean fail = FALSE;
110 bytes = g_byte_array_new();
115 if (*q && isxdigit(*p) && isxdigit(*q)) {
118 two_digits[2] = '\0';
121 * Two or more hex digits in a row.
122 * "strtoul()" will succeed, as it'll see at
123 * least one hex digit.
125 val = (guint8) strtoul(two_digits, NULL, 16);
126 g_byte_array_append(bytes, &val, 1);
130 * Make sure the character after
131 * the second hex digit is a byte
132 * separator, i.e. that we don't have
133 * more than two hex digits, or a
136 if (is_byte_sep(*punct)) {
150 else if (*q && isxdigit(*p) && is_byte_sep(*q)) {
155 * Only one hex digit.
156 * "strtoul()" will succeed, as it'll see that
159 val = (guint8) strtoul(one_digit, NULL, 16);
160 g_byte_array_append(bytes, &val, 1);
164 else if (!*q && isxdigit(*p)) {
169 * Only one hex digit.
170 * "strtoul()" will succeed, as it'll see that
173 val = (guint8) strtoul(one_digit, NULL, 16);
174 g_byte_array_append(bytes, &val, 1);
186 log("\"%s\" is not a valid byte string.", s);
187 g_byte_array_free(bytes, TRUE);
191 fv->value.bytes = bytes;
198 ether_from_string(fvalue_t *fv, char *s, LogFunc log)
203 * Don't log a message if this fails; we'll try looking it
204 * up as an Ethernet host name if it does, and if that fails,
205 * we'll log a message.
207 if (val_from_string(fv, s, NULL)) {
211 mac = get_ether_addr(s);
213 log("\"%s\" is not a valid hostname or Ethernet address.", s);
217 ether_fvalue_set(fv, mac, FALSE);
222 ipv6_from_string(fvalue_t *fv, char *s, LogFunc log)
226 if (!get_host_ipaddr6(s, (struct e_in6_addr*)buffer)) {
227 log("\"%s\" is not a valid hostname or IPv6 address.", s);
231 ipv6_fvalue_set(fv, buffer, FALSE);
236 u64_from_string(fvalue_t *fv, char *s, LogFunc log)
240 if (atou64(s, buffer) == NULL) {
241 log("\"%s\" is not a valid integer", s);
245 u64_fvalue_set(fv, buffer, FALSE);
250 i64_from_string(fvalue_t *fv, char *s, LogFunc log)
254 if (atoi64(s, buffer) == NULL) {
255 log("\"%s\" is not a valid integer", s);
259 u64_fvalue_set(fv, buffer, FALSE);
266 return fv->value.bytes->len;
270 slice(fvalue_t *fv, GByteArray *bytes, guint offset, guint length)
274 data = fv->value.bytes->data + offset;
276 g_byte_array_append(bytes, data, length);
281 cmp_eq(fvalue_t *fv_a, fvalue_t *fv_b)
283 GByteArray *a = fv_a->value.bytes;
284 GByteArray *b = fv_b->value.bytes;
286 if (a->len != b->len) {
290 return (memcmp(a->data, b->data, a->len) == 0);
295 cmp_ne(fvalue_t *fv_a, fvalue_t *fv_b)
297 GByteArray *a = fv_a->value.bytes;
298 GByteArray *b = fv_b->value.bytes;
300 if (a->len != b->len) {
304 return (memcmp(a->data, b->data, a->len) != 0);
309 cmp_gt(fvalue_t *fv_a, fvalue_t *fv_b)
311 GByteArray *a = fv_a->value.bytes;
312 GByteArray *b = fv_b->value.bytes;
314 if (a->len > b->len) {
318 if (a->len < b->len) {
322 return (memcmp(a->data, b->data, a->len) > 0);
326 cmp_ge(fvalue_t *fv_a, fvalue_t *fv_b)
328 GByteArray *a = fv_a->value.bytes;
329 GByteArray *b = fv_b->value.bytes;
331 if (a->len > b->len) {
335 if (a->len < b->len) {
339 return (memcmp(a->data, b->data, a->len) >= 0);
343 cmp_lt(fvalue_t *fv_a, fvalue_t *fv_b)
345 GByteArray *a = fv_a->value.bytes;
346 GByteArray *b = fv_b->value.bytes;
348 if (a->len < b->len) {
352 if (a->len > b->len) {
356 return (memcmp(a->data, b->data, a->len) < 0);
360 cmp_le(fvalue_t *fv_a, fvalue_t *fv_b)
362 GByteArray *a = fv_a->value.bytes;
363 GByteArray *b = fv_b->value.bytes;
365 if (a->len < b->len) {
369 if (a->len > b->len) {
373 return (memcmp(a->data, b->data, a->len) <= 0);
377 cmp_gt_i64(fvalue_t *fv_a, fvalue_t *fv_b)
379 GByteArray *a = fv_a->value.bytes;
380 GByteArray *b = fv_b->value.bytes;
382 if (a->len > b->len) {
386 if (a->len < b->len) {
390 if ((a->data[0] & 0x80) == 0) {
394 if (b->data[0] & 0x80) {
396 * "b" is negative, so a > b.
404 if ((b->data[0] & 0x80) == 0) {
406 * "b" is positive, so a < b.
413 * "a" and "b" have the same sign, so "memcmp()" should
414 * give the right answer.
416 return (memcmp(a->data, b->data, a->len) > 0);
420 cmp_ge_i64(fvalue_t *fv_a, fvalue_t *fv_b)
422 GByteArray *a = fv_a->value.bytes;
423 GByteArray *b = fv_b->value.bytes;
425 if (a->len > b->len) {
429 if (a->len < b->len) {
433 if ((a->data[0] & 0x80) == 0) {
437 if (b->data[0] & 0x80) {
439 * "b" is negative, so a > b.
447 if ((b->data[0] & 0x80) == 0) {
449 * "b" is positive, so a < b.
456 * "a" and "b" have the same sign, so "memcmp()" should
457 * give the right answer.
459 return (memcmp(a->data, b->data, a->len) >= 0);
463 cmp_lt_i64(fvalue_t *fv_a, fvalue_t *fv_b)
465 GByteArray *a = fv_a->value.bytes;
466 GByteArray *b = fv_b->value.bytes;
468 if (a->len < b->len) {
472 if (a->len > b->len) {
476 if (a->data[0] & 0x80) {
480 if ((b->data[0] & 0x80) == 0) {
482 * "b" is positive, so a < b.
490 if (b->data[0] & 0x80) {
492 * "b" is negative, so a > b.
499 * "a" and "b" have the same sign, so "memcmp()" should
500 * give the right answer.
502 return (memcmp(a->data, b->data, a->len) < 0);
506 cmp_le_i64(fvalue_t *fv_a, fvalue_t *fv_b)
508 GByteArray *a = fv_a->value.bytes;
509 GByteArray *b = fv_b->value.bytes;
511 if (a->len < b->len) {
515 if (a->len > b->len) {
519 if (a->data[0] & 0x80) {
523 if ((b->data[0] & 0x80) == 0) {
525 * "b" is positive, so a < b.
533 if (b->data[0] & 0x80) {
535 * "b" is negative, so a > b.
542 * "a" and "b" have the same sign, so "memcmp()" should
543 * give the right answer.
545 return (memcmp(a->data, b->data, a->len) <= 0);
549 ftype_register_bytes(void)
552 static ftype_t bytes_type = {
579 static ftype_t ether_type = {
581 "Ethernet or other MAC address",
606 static ftype_t ipv6_type = {
633 static ftype_t u64_type = {
635 "Unsigned 64-bit integer",
660 static ftype_t i64_type = {
662 "Signed 64-bit integer",
687 ftype_register(FT_BYTES, &bytes_type);
688 ftype_register(FT_ETHER, ðer_type);
689 ftype_register(FT_IPv6, &ipv6_type);
690 ftype_register(FT_UINT64, &u64_type);
691 ftype_register(FT_INT64, &i64_type);