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.
29 #include "ftypes-int.h"
30 #include <epan/addr_resolv.h>
32 #ifdef NEED_G_ASCII_STRTOULL_H
33 #include "g_ascii_strtoull.h"
37 * GLib 1.2[.x] doesn't define G_MAXUINT32 or G_MAXUINT64; if they're
38 * not defined, we define them as the maximum 32-bit and 32-bit
42 #define G_MAXUINT32 ((guint32)0xFFFFFFFFU)
45 #define G_MAXUINT64 ((guint64)G_GINT64_CONSTANT(0xFFFFFFFFFFFFFFFFU))
49 int_fvalue_new(fvalue_t *fv)
51 fv->value.integer = 0;
55 set_integer(fvalue_t *fv, guint32 value)
57 fv->value.integer = value;
61 get_integer(fvalue_t *fv)
63 return fv->value.integer;
67 val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
73 value = strtoul(s, &endptr, 0);
75 if (errno == EINVAL || endptr == s || *endptr != '\0') {
76 /* This isn't a valid number. */
78 logfunc("\"%s\" is not a valid number.", s);
81 if (errno == ERANGE) {
82 if (logfunc != NULL) {
83 if (value == ULONG_MAX) {
84 logfunc("\"%s\" causes an integer overflow.",
89 * XXX - can "strtoul()" set errno to
90 * ERANGE without returning ULONG_MAX?
92 logfunc("\"%s\" is not an integer.", s);
97 if (value > G_MAXUINT32) {
99 * Fits in an unsigned long, but not in a guint32
100 * (an unsigned long might be 64 bits).
103 logfunc("\"%s\" causes an integer overflow.", s);
107 fv->value.integer = value;
112 integer_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
114 return 11; /* enough for 12^31-1, in decimal */
118 integer_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
120 sprintf(buf, "%d", fv->value.integer);
124 uinteger_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
126 return 10; /* enough for 2^32-1, in decimal */
130 uinteger_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
132 sprintf(buf, "%u", fv->value.integer);
136 ipxnet_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
142 * Don't log a message if this fails; we'll try looking it
143 * up as an IPX network name if it does, and if that fails,
144 * we'll log a message.
146 if (val_from_unparsed(fv, s, TRUE, NULL)) {
150 val = get_ipxnet_addr(s, &known);
152 fv->value.integer = val;
156 logfunc("\"%s\" is not a valid IPX network name or address.", s);
161 ipxnet_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
163 return 2+8; /* 0xXXXXXXXX */
167 ipxnet_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
169 sprintf(buf, "0x%08x", fv->value.integer);
173 cmp_eq(fvalue_t *a, fvalue_t *b)
175 return a->value.integer == b->value.integer;
179 cmp_ne(fvalue_t *a, fvalue_t *b)
181 return a->value.integer != b->value.integer;
185 u_cmp_gt(fvalue_t *a, fvalue_t *b)
187 return (int)a->value.integer > (int)b->value.integer;
191 u_cmp_ge(fvalue_t *a, fvalue_t *b)
193 return (int)a->value.integer >= (int)b->value.integer;
197 u_cmp_lt(fvalue_t *a, fvalue_t *b)
199 return (int)a->value.integer < (int)b->value.integer;
203 u_cmp_le(fvalue_t *a, fvalue_t *b)
205 return (int)a->value.integer <= (int)b->value.integer;
209 s_cmp_gt(fvalue_t *a, fvalue_t *b)
211 return a->value.integer > b->value.integer;
215 s_cmp_ge(fvalue_t *a, fvalue_t *b)
217 return a->value.integer >= b->value.integer;
221 s_cmp_lt(fvalue_t *a, fvalue_t *b)
223 return a->value.integer < b->value.integer;
227 s_cmp_le(fvalue_t *a, fvalue_t *b)
229 return a->value.integer <= b->value.integer;
233 cmp_bitwise_and(fvalue_t *a, fvalue_t *b)
235 return ((a->value.integer & b->value.integer) != 0);
239 int64_fvalue_new(fvalue_t *fv)
241 fv->value.integer64 = 0;
245 set_integer64(fvalue_t *fv, guint64 value)
247 fv->value.integer64 = value;
251 get_integer64(fvalue_t *fv)
253 return fv->value.integer64;
257 val64_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
263 value = g_ascii_strtoull(s, &endptr, 0);
265 if (errno == EINVAL || endptr == s || *endptr != '\0') {
266 /* This isn't a valid number. */
268 logfunc("\"%s\" is not a valid number.", s);
271 if (errno == ERANGE) {
272 if (logfunc != NULL) {
273 if (value == ULONG_MAX) {
274 logfunc("\"%s\" causes an integer overflow.",
279 * XXX - can "strtoul()" set errno to
280 * ERANGE without returning ULONG_MAX?
282 logfunc("\"%s\" is not an integer.", s);
287 if (value > G_MAXUINT64) {
289 * Fits in an unsigned long, but not in a guint64
290 * (unlikely, but not impossible).
293 logfunc("\"%s\" causes an integer overflow.", s);
297 fv->value.integer64 = value;
302 integer64_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
304 return 20; /* enough for -2^63-1, in decimal */
308 integer64_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
310 sprintf(buf, PRId64, fv->value.integer64);
314 uinteger64_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
316 return 20; /* enough for 2^64-1, in decimal */
320 uinteger64_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
322 sprintf(buf, PRIu64, fv->value.integer64);
326 cmp_eq64(fvalue_t *a, fvalue_t *b)
328 return a->value.integer64 == b->value.integer64;
332 cmp_ne64(fvalue_t *a, fvalue_t *b)
334 return a->value.integer64 != b->value.integer64;
338 u_cmp_gt64(fvalue_t *a, fvalue_t *b)
340 return (gint64)a->value.integer64 > (gint64)b->value.integer64;
344 u_cmp_ge64(fvalue_t *a, fvalue_t *b)
346 return (gint64)a->value.integer64 >= (gint64)b->value.integer64;
350 u_cmp_lt64(fvalue_t *a, fvalue_t *b)
352 return (gint64)a->value.integer64 < (gint64)b->value.integer64;
356 u_cmp_le64(fvalue_t *a, fvalue_t *b)
358 return (gint64)a->value.integer64 <= (gint64)b->value.integer64;
362 s_cmp_gt64(fvalue_t *a, fvalue_t *b)
364 return a->value.integer64 > b->value.integer64;
368 s_cmp_ge64(fvalue_t *a, fvalue_t *b)
370 return a->value.integer64 >= b->value.integer64;
374 s_cmp_lt64(fvalue_t *a, fvalue_t *b)
376 return a->value.integer64 < b->value.integer64;
380 s_cmp_le64(fvalue_t *a, fvalue_t *b)
382 return a->value.integer64 <= b->value.integer64;
386 cmp_bitwise_and64(fvalue_t *a, fvalue_t *b)
388 return ((a->value.integer64 & b->value.integer64) != 0);
391 /* BOOLEAN-specific */
394 boolean_fvalue_new(fvalue_t *fv)
396 fv->value.integer = TRUE;
400 boolean_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
406 boolean_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
408 sprintf(buf, "%s", fv->value.integer ? "1" : "0");
411 /* Checks for equality with zero or non-zero */
413 bool_eq(fvalue_t *a, fvalue_t *b)
415 if (a->value.integer) {
416 if (b->value.integer) {
424 if (b->value.integer) {
433 /* Checks for inequality with zero or non-zero */
435 bool_ne(fvalue_t *a, fvalue_t *b)
437 return (!bool_eq(a,b));
443 ftype_register_integers(void)
446 static ftype_t uint8_type = {
447 "FT_UINT8", /* name */
448 "unsigned, 1 byte", /* pretty name */
450 int_fvalue_new, /* new_value */
451 NULL, /* free_value */
452 val_from_unparsed, /* val_from_unparsed */
453 NULL, /* val_from_string */
454 uinteger_to_repr, /* val_to_string_repr */
455 uinteger_repr_len, /* len_string_repr */
457 NULL, /* set_value */
458 set_integer, /* set_value_integer */
459 NULL, /* set_value_integer64 */
460 NULL, /* set_value_floating */
462 NULL, /* get_value */
463 get_integer, /* get_value_integer */
464 NULL, /* get_value_integer64 */
465 NULL, /* get_value_floating */
474 NULL, /* cmp_contains */
475 NULL, /* cmp_matches */
480 static ftype_t uint16_type = {
481 "FT_UINT16", /* name */
482 "unsigned, 2 bytes", /* pretty_name */
484 int_fvalue_new, /* new_value */
485 NULL, /* free_value */
486 val_from_unparsed, /* val_from_unparsed */
487 NULL, /* val_from_string */
488 uinteger_to_repr, /* val_to_string_repr */
489 uinteger_repr_len, /* len_string_repr */
491 NULL, /* set_value */
492 set_integer, /* set_value_integer */
493 NULL, /* set_value_integer64 */
494 NULL, /* set_value_floating */
496 NULL, /* get_value */
497 get_integer, /* get_value_integer */
498 NULL, /* get_value_integer64 */
499 NULL, /* get_value_floating */
508 NULL, /* cmp_contains */
509 NULL, /* cmp_matches */
514 static ftype_t uint24_type = {
515 "FT_UINT24", /* name */
516 "unsigned, 3 bytes", /* pretty_name */
518 int_fvalue_new, /* new_value */
519 NULL, /* free_value */
520 val_from_unparsed, /* val_from_unparsed */
521 NULL, /* val_from_string */
522 uinteger_to_repr, /* val_to_string_repr */
523 uinteger_repr_len, /* len_string_repr */
525 NULL, /* set_value */
526 set_integer, /* set_value_integer */
527 NULL, /* set_value_integer64 */
528 NULL, /* set_value_floating */
530 NULL, /* get_value */
531 get_integer, /* get_value_integer */
532 NULL, /* get_value_integer64 */
533 NULL, /* get_value_floating */
542 NULL, /* cmp_contains */
543 NULL, /* cmp_matches */
548 static ftype_t uint32_type = {
549 "FT_UINT32", /* name */
550 "unsigned, 4 bytes", /* pretty_name */
552 int_fvalue_new, /* new_value */
553 NULL, /* free_value */
554 val_from_unparsed, /* val_from_unparsed */
555 NULL, /* val_from_string */
556 uinteger_to_repr, /* val_to_string_repr */
557 uinteger_repr_len, /* len_string_repr */
559 NULL, /* set_value */
560 set_integer, /* set_value_integer */
561 NULL, /* set_value_integer64 */
562 NULL, /* set_value_floating */
564 NULL, /* get_value */
565 get_integer, /* get_value_integer */
566 NULL, /* get_value_integer64 */
567 NULL, /* get_value_floating */
576 NULL, /* cmp_contains */
577 NULL, /* cmp_matches */
582 static ftype_t uint64_type = {
583 "FT_UINT64", /* name */
584 "unsigned, 8 bytes", /* pretty_name */
586 int64_fvalue_new, /* new_value */
587 NULL, /* free_value */
588 val64_from_unparsed, /* val_from_unparsed */
589 NULL, /* val_from_string */
590 uinteger64_to_repr, /* val_to_string_repr */
591 uinteger64_repr_len, /* len_string_repr */
593 NULL, /* set_value */
594 NULL, /* set_value_integer */
595 set_integer64, /* set_value_integer64 */
596 NULL, /* set_value_floating */
598 NULL, /* get_value */
599 NULL, /* get_value_integer */
600 get_integer64, /* get_value_integer64 */
601 NULL, /* get_value_floating */
610 NULL, /* cmp_contains */
611 NULL, /* cmp_matches */
616 static ftype_t int8_type = {
617 "FT_INT8", /* name */
618 "signed, 1 byte", /* pretty_name */
620 int_fvalue_new, /* new_value */
621 NULL, /* free_value */
622 val_from_unparsed, /* val_from_unparsed */
623 NULL, /* val_from_string */
624 integer_to_repr, /* val_to_string_repr */
625 integer_repr_len, /* len_string_repr */
627 NULL, /* set_value */
628 set_integer, /* set_value_integer */
629 NULL, /* set_value_integer64 */
630 NULL, /* set_value_floating */
632 NULL, /* get_value */
633 get_integer, /* get_value_integer */
634 NULL, /* get_value_integer64 */
635 NULL, /* get_value_floating */
644 NULL, /* cmp_contains */
645 NULL, /* cmp_matches */
650 static ftype_t int16_type = {
651 "FT_INT16", /* name */
652 "signed, 2 bytes", /* pretty_name */
654 int_fvalue_new, /* new_value */
655 NULL, /* free_value */
656 val_from_unparsed, /* val_from_unparsed */
657 NULL, /* val_from_string */
658 integer_to_repr, /* val_to_string_repr */
659 integer_repr_len, /* len_string_repr */
661 NULL, /* set_value */
662 set_integer, /* set_value_integer */
663 NULL, /* set_value_integer64 */
664 NULL, /* set_value_floating */
666 NULL, /* get_value */
667 get_integer, /* get_value_integer */
668 NULL, /* get_value_integer64 */
669 NULL, /* get_value_floating */
678 NULL, /* cmp_contains */
679 NULL, /* cmp_matches */
684 static ftype_t int24_type = {
685 "FT_INT24", /* name */
686 "signed, 3 bytes", /* pretty_name */
688 int_fvalue_new, /* new_value */
689 NULL, /* free_value */
690 val_from_unparsed, /* val_from_unparsed */
691 NULL, /* val_from_string */
692 integer_to_repr, /* val_to_string_repr */
693 integer_repr_len, /* len_string_repr */
695 NULL, /* set_value */
696 set_integer, /* set_value_integer */
697 NULL, /* set_value_integer64 */
698 NULL, /* set_value_floating */
700 NULL, /* get_value */
701 get_integer, /* get_value_integer */
702 NULL, /* get_value_integer64 */
703 NULL, /* get_value_floating */
712 NULL, /* cmp_contains */
713 NULL, /* cmp_matches */
718 static ftype_t int32_type = {
719 "FT_INT32", /* name */
720 "signed, 4 bytes", /* pretty_name */
722 int_fvalue_new, /* new_value */
723 NULL, /* free_value */
724 val_from_unparsed, /* val_from_unparsed */
725 NULL, /* val_from_string */
726 integer_to_repr, /* val_to_string_repr */
727 integer_repr_len, /* len_string_repr */
729 NULL, /* set_value */
730 set_integer, /* set_value_integer */
731 NULL, /* set_value_integer64 */
732 NULL, /* set_value_floating */
734 NULL, /* get_value */
735 get_integer, /* get_value_integer */
736 NULL, /* get_value_integer64 */
737 NULL, /* get_value_floating */
746 NULL, /* cmp_contains */
747 NULL, /* cmp_matches */
752 static ftype_t int64_type = {
753 "FT_INT64", /* name */
754 "signed, 8 bytes", /* pretty_name */
756 int64_fvalue_new, /* new_value */
757 NULL, /* free_value */
758 val64_from_unparsed, /* val_from_unparsed */
759 NULL, /* val_from_string */
760 integer64_to_repr, /* val_to_string_repr */
761 integer64_repr_len, /* len_string_repr */
763 NULL, /* set_value */
764 NULL, /* set_value_integer */
765 set_integer64, /* set_value_integer64 */
766 NULL, /* set_value_floating */
768 NULL, /* get_value */
769 NULL, /* get_value_integer */
770 get_integer64, /* get_value_integer64 */
771 NULL, /* get_value_floating */
780 NULL, /* cmp_contains */
781 NULL, /* cmp_matches */
786 static ftype_t boolean_type = {
787 "FT_BOOLEAN", /* name */
788 "Boolean", /* pretty_name */
790 boolean_fvalue_new, /* new_value */
791 NULL, /* free_value */
792 val_from_unparsed, /* val_from_unparsed */
793 NULL, /* val_from_string */
794 boolean_to_repr, /* val_to_string_repr */
795 boolean_repr_len, /* len_string_repr */
797 NULL, /* set_value */
798 set_integer, /* set_value_integer */
799 NULL, /* set_value_integer64 */
800 NULL, /* set_value_floating */
802 NULL, /* get_value */
803 get_integer, /* get_value_integer */
804 NULL, /* get_value_integer64 */
805 NULL, /* get_value_floating */
807 bool_eq, /* cmp_eq */
808 bool_ne, /* cmp_ne */
813 NULL, /* cmp_bitwise_and */
814 NULL, /* cmp_contains */
815 NULL, /* cmp_matches */
821 static ftype_t ipxnet_type = {
822 "FT_IPXNET", /* name */
823 "IPX network number", /* pretty_name */
825 int_fvalue_new, /* new_value */
826 NULL, /* free_value */
827 ipxnet_from_unparsed, /* val_from_unparsed */
828 NULL, /* val_from_string */
829 ipxnet_to_repr, /* val_to_string_repr */
830 ipxnet_repr_len, /* len_string_repr */
832 NULL, /* set_value */
833 set_integer, /* set_value_integer */
834 NULL, /* set_value_integer64 */
835 NULL, /* set_value_floating */
837 NULL, /* get_value */
838 get_integer, /* get_value_integer */
839 NULL, /* get_value_integer64 */
840 NULL, /* get_value_floating */
849 NULL, /* cmp_contains */
850 NULL, /* cmp_matches */
856 static ftype_t framenum_type = {
857 "FT_FRAMENUM", /* name */
858 "frame number", /* pretty_name */
860 int_fvalue_new, /* new_value */
861 NULL, /* free_value */
862 val_from_unparsed, /* val_from_unparsed */
863 NULL, /* val_from_string */
864 uinteger_to_repr, /* val_to_string_repr */
865 uinteger_repr_len, /* len_string_repr */
867 NULL, /* set_value */
868 set_integer, /* set_value_integer */
869 NULL, /* set_value_integer64 */
870 NULL, /* set_value_floating */
872 NULL, /* get_value */
873 get_integer, /* get_value_integer */
874 NULL, /* get_value_integer64 */
875 NULL, /* get_value_floating */
883 NULL, /* cmp_bitwise_and */
884 NULL, /* cmp_contains */
885 NULL, /* cmp_matches */
891 ftype_register(FT_UINT8, &uint8_type);
892 ftype_register(FT_UINT16, &uint16_type);
893 ftype_register(FT_UINT24, &uint24_type);
894 ftype_register(FT_UINT32, &uint32_type);
895 ftype_register(FT_UINT64, &uint64_type);
896 ftype_register(FT_INT8, &int8_type);
897 ftype_register(FT_INT16, &int16_type);
898 ftype_register(FT_INT24, &int24_type);
899 ftype_register(FT_INT32, &int32_type);
900 ftype_register(FT_INT64, &int64_type);
901 ftype_register(FT_BOOLEAN, &boolean_type);
902 ftype_register(FT_IPXNET, &ipxnet_type);
903 ftype_register(FT_FRAMENUM, &framenum_type);