2 * Wireshark - Network traffic analyzer
3 * By Gerald Combs <gerald@wireshark.org>
4 * Copyright 2001 Gerald Combs
6 * SPDX-License-Identifier: GPL-2.0-or-later
11 #include "ftypes-int.h"
13 #include <wsutil/ws_assert.h>
15 /* Keep track of ftype_t's via their ftenum number */
16 const ftype_t
* type_list
[FT_ENUM_SIZE
+ 1];
18 /* Initialize the ftype module. */
20 ftypes_initialize(void)
22 ftype_register_bytes();
23 ftype_register_double();
24 ftype_register_ieee_11073_float();
25 ftype_register_integers();
26 ftype_register_ipv4();
27 ftype_register_ipv6();
28 ftype_register_guid();
29 ftype_register_none();
30 ftype_register_string();
31 ftype_register_time();
32 ftype_register_tvbuff();
36 ftypes_register_pseudofields(void)
38 static int proto_ftypes
;
40 proto_ftypes
= proto_register_protocol(
41 "Wireshark Field/Fundamental Types",
45 ftype_register_pseudofields_bytes(proto_ftypes
);
46 ftype_register_pseudofields_double(proto_ftypes
);
47 ftype_register_pseudofields_ieee_11073_float(proto_ftypes
);
48 ftype_register_pseudofields_integer(proto_ftypes
);
49 ftype_register_pseudofields_ipv4(proto_ftypes
);
50 ftype_register_pseudofields_ipv6(proto_ftypes
);
51 ftype_register_pseudofields_guid(proto_ftypes
);
52 ftype_register_pseudofields_none(proto_ftypes
);
53 ftype_register_pseudofields_string(proto_ftypes
);
54 ftype_register_pseudofields_time(proto_ftypes
);
55 ftype_register_pseudofields_tvbuff(proto_ftypes
);
57 proto_set_cant_toggle(proto_ftypes
);
60 /* Each ftype_t is registered via this function */
62 ftype_register(enum ftenum ftype
, const ftype_t
*ft
)
65 ws_assert(ftype
< FT_NUM_TYPES
);
66 ws_assert(ftype
== ft
->ftype
);
68 /* Don't re-register. */
69 ws_assert(type_list
[ftype
] == NULL
);
71 type_list
[ftype
] = ft
;
75 /* from README.dissector:
76 Note that the formats used must all belong to the same list as defined below:
77 - FT_INT8, FT_INT16, FT_INT24 and FT_INT32
78 - FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, FT_IPXNET and FT_FRAMENUM
79 - FT_UINT64 and FT_EUI64
80 - FT_STRING, FT_STRINGZ and FT_UINT_STRING
81 - FT_FLOAT and FT_DOUBLE
82 - FT_BYTES, FT_UINT_BYTES, FT_AX25, FT_ETHER, FT_VINES, FT_OID and FT_REL_OID
83 - FT_ABSOLUTE_TIME and FT_RELATIVE_TIME
86 same_ftype(const enum ftenum ftype
)
130 /* XXX: the following are unique for now */
134 /* everything else is unique */
140 /* given two types, are they similar - for example can two
141 * duplicate fields be registered of these two types. */
143 ftype_similar_types(const enum ftenum ftype_a
, const enum ftenum ftype_b
)
145 return (same_ftype(ftype_a
) == same_ftype(ftype_b
));
148 /* Returns a string representing the name of the type. Useful
149 * for glossary production. */
151 ftype_name(enum ftenum ftype
)
154 const char *s
= "(null)";
156 FTYPE_LOOKUP(ftype
, ft
);
158 case FT_NONE
: s
= "FT_NONE"; break;
159 case FT_PROTOCOL
: s
= "FT_PROTOCOL"; break;
160 case FT_BOOLEAN
: s
= "FT_BOOLEAN"; break;
161 case FT_CHAR
: s
= "FT_CHAR"; break;
162 case FT_UINT8
: s
= "FT_UINT8"; break;
163 case FT_UINT16
: s
= "FT_UINT16"; break;
164 case FT_UINT24
: s
= "FT_UINT24"; break;
165 case FT_UINT32
: s
= "FT_UINT32"; break;
166 case FT_UINT40
: s
= "FT_UINT40"; break;
167 case FT_UINT48
: s
= "FT_UINT48"; break;
168 case FT_UINT56
: s
= "FT_UINT56"; break;
169 case FT_UINT64
: s
= "FT_UINT64"; break;
170 case FT_INT8
: s
= "FT_INT8"; break;
171 case FT_INT16
: s
= "FT_INT16"; break;
172 case FT_INT24
: s
= "FT_INT24"; break;
173 case FT_INT32
: s
= "FT_INT32"; break;
174 case FT_INT40
: s
= "FT_INT40"; break;
175 case FT_INT48
: s
= "FT_INT48"; break;
176 case FT_INT56
: s
= "FT_INT56"; break;
177 case FT_INT64
: s
= "FT_INT64"; break;
178 case FT_IEEE_11073_SFLOAT
: s
= "FT_IEEE_11073_SFLOAT"; break;
179 case FT_IEEE_11073_FLOAT
: s
= "FT_IEEE_11073_FLOAT"; break;
180 case FT_FLOAT
: s
= "FT_FLOAT"; break;
181 case FT_DOUBLE
: s
= "FT_DOUBLE"; break;
182 case FT_ABSOLUTE_TIME
: s
= "FT_ABSOLUTE_TIME"; break;
183 case FT_RELATIVE_TIME
: s
= "FT_RELATIVE_TIME"; break;
184 case FT_STRING
: s
= "FT_STRING"; break;
185 case FT_STRINGZ
: s
= "FT_STRINGZ"; break;
186 case FT_UINT_STRING
: s
= "FT_UINT_STRING"; break;
187 case FT_ETHER
: s
= "FT_ETHER"; break;
188 case FT_BYTES
: s
= "FT_BYTES"; break;
189 case FT_UINT_BYTES
: s
= "FT_UINT_BYTES"; break;
190 case FT_IPv4
: s
= "FT_IPv4"; break;
191 case FT_IPv6
: s
= "FT_IPv6"; break;
192 case FT_IPXNET
: s
= "FT_IPXNET"; break;
193 case FT_FRAMENUM
: s
= "FT_FRAMENUM"; break;
194 case FT_GUID
: s
= "FT_GUID"; break;
195 case FT_OID
: s
= "FT_OID"; break;
196 case FT_EUI64
: s
= "FT_EUI64"; break;
197 case FT_AX25
: s
= "FT_AX25"; break;
198 case FT_VINES
: s
= "FT_VINES"; break;
199 case FT_REL_OID
: s
= "FT_REL_OID"; break;
200 case FT_SYSTEM_ID
: s
= "FT_SYSTEM_ID"; break;
201 case FT_STRINGZPAD
: s
= "FT_STRINGZPAD"; break;
202 case FT_FCWWN
: s
= "FT_FCWWN"; break;
203 case FT_STRINGZTRUNC
: s
= "FT_STRINGZTRUNC"; break;
204 case FT_NUM_TYPES
: s
= "FT_NUM_TYPES"; break;
205 case FT_SCALAR
: s
= "FT_SCALAR"; break;
211 ftype_pretty_name(enum ftenum ftype
)
214 const char *s
= "(null)";
216 FTYPE_LOOKUP(ftype
, ft
);
218 case FT_NONE
: s
= "Label"; break;
219 case FT_PROTOCOL
: s
= "Protocol"; break;
220 case FT_BOOLEAN
: s
= "Boolean"; break;
221 case FT_CHAR
: s
= "Character (8 bits)"; break;
222 case FT_UINT8
: s
= "Unsigned integer (8 bits)"; break;
223 case FT_UINT16
: s
= "Unsigned integer (16 bits)"; break;
224 case FT_UINT24
: s
= "Unsigned integer (24 bits)"; break;
225 case FT_UINT32
: s
= "Unsigned integer (32 bits)"; break;
226 case FT_UINT40
: s
= "Unsigned integer (40 bits)"; break;
227 case FT_UINT48
: s
= "Unsigned integer (48 bits)"; break;
228 case FT_UINT56
: s
= "Unsigned integer (56 bits)"; break;
229 case FT_UINT64
: s
= "Unsigned integer (64 bits)"; break;
230 case FT_INT8
: s
= "Signed integer (8 bits)"; break;
231 case FT_INT16
: s
= "Signed integer (16 bits)"; break;
232 case FT_INT24
: s
= "Signed integer (24 bits)"; break;
233 case FT_INT32
: s
= "Signed integer (32 bits)"; break;
234 case FT_INT40
: s
= "Signed integer (40 bits)"; break;
235 case FT_INT48
: s
= "Signed integer (48 bits)"; break;
236 case FT_INT56
: s
= "Signed integer (56 bits)"; break;
237 case FT_INT64
: s
= "Signed integer (64 bits)"; break;
238 case FT_IEEE_11073_SFLOAT
: s
= "IEEE-11073 floating point (16-bit)"; break;
239 case FT_IEEE_11073_FLOAT
: s
= "IEEE-11073 Floating point (32-bit)"; break;
240 case FT_FLOAT
: s
= "Floating point (single-precision)"; break;
241 case FT_DOUBLE
: s
= "Floating point (double-precision)"; break;
242 case FT_ABSOLUTE_TIME
: s
= "Date and time"; break;
243 case FT_RELATIVE_TIME
: s
= "Time offset"; break;
244 case FT_STRING
: s
= "Character string"; break;
245 case FT_STRINGZ
: s
= "Character string"; break;
246 case FT_UINT_STRING
: s
= "Character string"; break;
247 case FT_ETHER
: s
= "Ethernet or other MAC address"; break;
248 case FT_BYTES
: s
= "Byte sequence"; break;
249 case FT_UINT_BYTES
: s
= "Byte sequence"; break;
250 case FT_IPv4
: s
= "IPv4 address"; break;
251 case FT_IPv6
: s
= "IPv6 address"; break;
252 case FT_IPXNET
: s
= "IPX network number"; break;
253 case FT_FRAMENUM
: s
= "Frame number"; break;
254 case FT_GUID
: s
= "Globally Unique Identifier"; break;
255 case FT_OID
: s
= "ASN.1 object identifier"; break;
256 case FT_EUI64
: s
= "EUI64 address"; break;
257 case FT_AX25
: s
= "AX.25 address"; break;
258 case FT_VINES
: s
= "VINES address"; break;
259 case FT_REL_OID
: s
= "ASN.1 relative object identifier"; break;
260 case FT_SYSTEM_ID
: s
= "OSI System-ID"; break;
261 case FT_STRINGZPAD
: s
= "Character string"; break;
262 case FT_FCWWN
: s
= "Fibre Channel WWN"; break;
263 case FT_STRINGZTRUNC
: s
= "Character string"; break;
264 case FT_NUM_TYPES
: s
= "(num types)"; break;
265 case FT_SCALAR
: s
= "Scalar"; break;
271 ftype_wire_size(enum ftenum ftype
)
275 FTYPE_LOOKUP(ftype
, ft
);
276 return ft
->wire_size
;
280 ftype_can_length(enum ftenum ftype
)
284 FTYPE_LOOKUP(ftype
, ft
);
285 return ft
->len
? true : false;
289 ftype_can_slice(enum ftenum ftype
)
293 FTYPE_LOOKUP(ftype
, ft
);
294 return ft
->slice
? true : false;
298 ftype_can_eq(enum ftenum ftype
)
302 FTYPE_LOOKUP(ftype
, ft
);
303 return ft
->compare
!= NULL
;
307 ftype_can_cmp(enum ftenum ftype
)
311 FTYPE_LOOKUP(ftype
, ft
);
312 return ft
->compare
!= NULL
;
316 ftype_can_bitwise_and(enum ftenum ftype
)
320 FTYPE_LOOKUP(ftype
, ft
);
321 return ft
->bitwise_and
? true : false;
325 ftype_can_unary_minus(enum ftenum ftype
)
329 FTYPE_LOOKUP(ftype
, ft
);
330 return ft
->unary_minus
!= NULL
;
334 ftype_can_add(enum ftenum ftype
)
338 FTYPE_LOOKUP(ftype
, ft
);
339 return ft
->add
!= NULL
;
343 ftype_can_subtract(enum ftenum ftype
)
347 FTYPE_LOOKUP(ftype
, ft
);
348 return ft
->subtract
!= NULL
;
352 ftype_can_multiply(enum ftenum ftype
)
356 FTYPE_LOOKUP(ftype
, ft
);
357 return ft
->multiply
!= NULL
;
361 ftype_can_divide(enum ftenum ftype
)
365 FTYPE_LOOKUP(ftype
, ft
);
366 return ft
->divide
!= NULL
;
370 ftype_can_modulo(enum ftenum ftype
)
374 FTYPE_LOOKUP(ftype
, ft
);
375 return ft
->modulo
!= NULL
;
379 ftype_can_contains(enum ftenum ftype
)
383 FTYPE_LOOKUP(ftype
, ft
);
384 return ft
->contains
? true : false;
388 ftype_can_matches(enum ftenum ftype
)
392 FTYPE_LOOKUP(ftype
, ft
);
393 return ft
->matches
? true : false;
397 ftype_can_is_zero(enum ftenum ftype
)
401 FTYPE_LOOKUP(ftype
, ft
);
402 return ft
->is_zero
? true : false;
406 ftype_can_is_negative(enum ftenum ftype
)
410 FTYPE_LOOKUP(ftype
, ft
);
411 return ft
->is_negative
? true : false;
415 ftype_can_val_to_sinteger(enum ftenum ftype
)
419 FTYPE_LOOKUP(ftype
, ft
);
420 /* We first convert to 64 bit and then check for overflow. */
421 return ft
->val_to_sinteger64
? true : false;
425 ftype_can_val_to_uinteger(enum ftenum ftype
)
429 FTYPE_LOOKUP(ftype
, ft
);
430 /* We first convert to 64 bit and then check for overflow. */
431 return ft
->val_to_uinteger64
? true : false;
435 ftype_can_val_to_sinteger64(enum ftenum ftype
)
439 FTYPE_LOOKUP(ftype
, ft
);
440 return ft
->val_to_sinteger64
? true : false;
444 ftype_can_val_to_uinteger64(enum ftenum ftype
)
448 FTYPE_LOOKUP(ftype
, ft
);
449 return ft
->val_to_uinteger64
? true : false;
452 /* ---------------------------------------------------------- */
454 /* Allocate and initialize an fvalue_t, given an ftype */
456 fvalue_new(ftenum_t ftype
)
460 FvalueNewFunc new_value
;
462 fv
= g_slice_new(fvalue_t
);
464 FTYPE_LOOKUP(ftype
, ft
);
467 new_value
= ft
->new_value
;
476 fvalue_dup(const fvalue_t
*fv_orig
)
479 FvalueCopyFunc copy_value
;
481 fv_new
= g_slice_new(fvalue_t
);
482 fv_new
->ftype
= fv_orig
->ftype
;
483 copy_value
= fv_new
->ftype
->copy_value
;
484 if (copy_value
!= NULL
) {
486 copy_value(fv_new
, fv_orig
);
490 memcpy(&fv_new
->value
, &fv_orig
->value
, sizeof(fv_orig
->value
));
497 fvalue_init(fvalue_t
*fv
, ftenum_t ftype
)
500 FvalueNewFunc new_value
;
502 FTYPE_LOOKUP(ftype
, ft
);
505 new_value
= ft
->new_value
;
512 fvalue_cleanup(fvalue_t
*fv
)
514 if (!fv
->ftype
->free_value
)
516 fv
->ftype
->free_value(fv
);
520 fvalue_free(fvalue_t
*fv
)
523 g_slice_free(fvalue_t
, fv
);
527 fvalue_from_literal(ftenum_t ftype
, const char *s
, bool allow_partial_value
, char **err_msg
)
532 fv
= fvalue_new(ftype
);
533 if (fv
->ftype
->val_from_literal
) {
534 ok
= fv
->ftype
->val_from_literal(fv
, s
, allow_partial_value
, err_msg
);
543 if (err_msg
!= NULL
) {
544 *err_msg
= ws_strdup_printf("\"%s\" cannot be converted to %s.",
545 s
, ftype_pretty_name(ftype
));
553 fvalue_from_string(ftenum_t ftype
, const char *str
, size_t len
, char **err_msg
)
557 fv
= fvalue_new(ftype
);
558 if (fv
->ftype
->val_from_string
) {
559 if (fv
->ftype
->val_from_string(fv
, str
, len
, err_msg
)) {
567 if (err_msg
!= NULL
) {
568 *err_msg
= ws_strdup_printf("%s cannot be converted from a string (\"%s\").",
569 ftype_pretty_name(ftype
), str
);
577 fvalue_from_charconst(ftenum_t ftype
, unsigned long num
, char **err_msg
)
581 fv
= fvalue_new(ftype
);
582 if (fv
->ftype
->val_from_charconst
) {
583 if (fv
->ftype
->val_from_charconst(fv
, num
, err_msg
)) {
591 if (err_msg
!= NULL
) {
592 if (num
<= 0x7f && g_ascii_isprint(num
)) {
593 *err_msg
= ws_strdup_printf("Character constant '%c' (0x%lx) cannot be converted to %s.",
594 (int)num
, num
, ftype_pretty_name(ftype
));
597 *err_msg
= ws_strdup_printf("Character constant 0x%lx cannot be converted to %s.",
598 num
, ftype_pretty_name(ftype
));
607 fvalue_from_sinteger64(ftenum_t ftype
, const char *s
, int64_t num
, char **err_msg
)
611 fv
= fvalue_new(ftype
);
612 if (fv
->ftype
->val_from_sinteger64
) {
613 if (fv
->ftype
->val_from_sinteger64(fv
, s
, num
, err_msg
)) {
621 if (err_msg
!= NULL
) {
622 *err_msg
= ws_strdup_printf("Integer %"PRId64
" cannot be converted to %s.",
623 num
, ftype_pretty_name(ftype
));
631 fvalue_from_uinteger64(ftenum_t ftype
, const char *s
, uint64_t num
, char **err_msg
)
635 fv
= fvalue_new(ftype
);
636 if (fv
->ftype
->val_from_uinteger64
) {
637 if (fv
->ftype
->val_from_uinteger64(fv
, s
, num
, err_msg
)) {
645 if (err_msg
!= NULL
) {
646 *err_msg
= ws_strdup_printf("Unsigned integer 0x%"PRIu64
" cannot be converted to %s.",
647 num
, ftype_pretty_name(ftype
));
655 fvalue_from_floating(ftenum_t ftype
, const char *s
, double num
, char **err_msg
)
659 fv
= fvalue_new(ftype
);
660 if (fv
->ftype
->val_from_double
) {
661 if (fv
->ftype
->val_from_double(fv
, s
, num
, err_msg
)) {
669 if (err_msg
!= NULL
) {
670 *err_msg
= ws_strdup_printf("Double %g cannot be converted to %s.",
671 num
, ftype_pretty_name(ftype
));
679 fvalue_type_ftenum(const fvalue_t
*fv
)
681 return fv
->ftype
->ftype
;
685 fvalue_type_name(const fvalue_t
*fv
)
687 return ftype_name(fv
->ftype
->ftype
);
692 fvalue_length2(fvalue_t
*fv
)
694 if (!fv
->ftype
->len
) {
695 ws_critical("fv->ftype->len is NULL");
698 return fv
->ftype
->len(fv
);
702 fvalue_to_string_repr(wmem_allocator_t
*scope
, const fvalue_t
*fv
, ftrepr_t rtype
, int field_display
)
704 if (fv
->ftype
->val_to_string_repr
== NULL
) {
705 /* no value-to-string-representation function, so the value cannot be represented */
709 return fv
->ftype
->val_to_string_repr(scope
, fv
, rtype
, field_display
);
713 fvalue_to_uinteger(const fvalue_t
*fv
, uint32_t *repr
)
716 enum ft_result res
= fv
->ftype
->val_to_uinteger64(fv
, &val
);
719 if (val
> UINT32_MAX
)
722 *repr
= (uint32_t)val
;
727 fvalue_to_sinteger(const fvalue_t
*fv
, int32_t *repr
)
730 enum ft_result res
= fv
->ftype
->val_to_sinteger64(fv
, &val
);
736 *repr
= (int32_t)val
;
741 fvalue_to_uinteger64(const fvalue_t
*fv
, uint64_t *repr
)
743 ws_assert(fv
->ftype
->val_to_uinteger64
);
744 return fv
->ftype
->val_to_uinteger64(fv
, repr
);
748 fvalue_to_sinteger64(const fvalue_t
*fv
, int64_t *repr
)
750 ws_assert(fv
->ftype
->val_to_sinteger64
);
751 return fv
->ftype
->val_to_sinteger64(fv
, repr
);
755 fvalue_to_double(const fvalue_t
*fv
, double *repr
)
757 ws_assert(fv
->ftype
->val_to_double
);
758 return fv
->ftype
->val_to_double(fv
, repr
);
768 compute_drnode(size_t field_length
, drange_node
*drnode
, size_t *offset_ptr
, size_t *length_ptr
)
770 ssize_t start_offset
;
772 ssize_t end_offset
= 0;
773 drange_node_end_t ending
;
775 start_offset
= drange_node_get_start_offset(drnode
);
776 ending
= drange_node_get_ending(drnode
);
778 /* Check for negative start */
779 if (start_offset
< 0) {
780 start_offset
= field_length
+ start_offset
;
781 if (start_offset
< 0) {
786 /* Check the end type and set the length */
788 if (ending
== DRANGE_NODE_END_T_TO_THE_END
) {
789 length
= field_length
- start_offset
;
794 else if (ending
== DRANGE_NODE_END_T_LENGTH
) {
795 length
= drange_node_get_length(drnode
);
796 if (start_offset
+ length
> (int) field_length
) {
800 else if (ending
== DRANGE_NODE_END_T_OFFSET
) {
801 end_offset
= drange_node_get_end_offset(drnode
);
802 if (end_offset
< 0) {
803 end_offset
= field_length
+ end_offset
;
804 if (end_offset
< start_offset
) {
807 } else if (end_offset
>= (int) field_length
) {
810 length
= end_offset
- start_offset
+ 1;
813 ws_assert_not_reached();
816 *offset_ptr
= start_offset
;
817 *length_ptr
= length
;
822 slice_func(void * data
, void * user_data
)
824 drange_node
*drnode
= (drange_node
*)data
;
825 slice_data_t
*slice_data
= (slice_data_t
*)user_data
;
830 if (slice_data
->slice_failure
) {
835 if (!compute_drnode((unsigned)fvalue_length2(fv
), drnode
, &start_offset
, &length
)) {
836 slice_data
->slice_failure
= true;
840 ws_assert(length
> 0);
841 fv
->ftype
->slice(fv
, slice_data
->ptr
, (unsigned)start_offset
, (unsigned)length
);
845 slice_string(fvalue_t
*fv
, drange_t
*d_range
)
847 slice_data_t slice_data
;
851 slice_data
.ptr
= wmem_strbuf_create(NULL
);
852 slice_data
.slice_failure
= false;
854 /* XXX - We could make some optimizations here based on
855 * drange_has_total_length() and
856 * drange_get_max_offset().
859 drange_foreach_drange_node(d_range
, slice_func
, &slice_data
);
861 new_fv
= fvalue_new(FT_STRING
);
862 fvalue_set_strbuf(new_fv
, slice_data
.ptr
);
867 slice_bytes(fvalue_t
*fv
, drange_t
*d_range
)
869 slice_data_t slice_data
;
873 slice_data
.ptr
= g_byte_array_new();
874 slice_data
.slice_failure
= false;
876 /* XXX - We could make some optimizations here based on
877 * drange_has_total_length() and
878 * drange_get_max_offset().
881 drange_foreach_drange_node(d_range
, slice_func
, &slice_data
);
883 new_fv
= fvalue_new(FT_BYTES
);
884 fvalue_set_byte_array(new_fv
, slice_data
.ptr
);
888 /* Returns a new slice fvalue_t* if possible, otherwise NULL */
890 fvalue_slice(fvalue_t
*fv
, drange_t
*d_range
)
892 if (FT_IS_STRING(fvalue_type_ftenum(fv
))) {
893 return slice_string(fv
, d_range
);
895 return slice_bytes(fv
, d_range
);
899 fvalue_set_bytes(fvalue_t
*fv
, GBytes
*value
)
901 ws_assert(fv
->ftype
->ftype
== FT_BYTES
||
902 fv
->ftype
->ftype
== FT_UINT_BYTES
||
903 fv
->ftype
->ftype
== FT_OID
||
904 fv
->ftype
->ftype
== FT_REL_OID
||
905 fv
->ftype
->ftype
== FT_SYSTEM_ID
||
906 fv
->ftype
->ftype
== FT_VINES
||
907 fv
->ftype
->ftype
== FT_ETHER
||
908 fv
->ftype
->ftype
== FT_FCWWN
);
909 ws_assert(fv
->ftype
->set_value
.set_value_bytes
);
910 fv
->ftype
->set_value
.set_value_bytes(fv
, value
);
914 fvalue_set_byte_array(fvalue_t
*fv
, GByteArray
*value
)
916 GBytes
*bytes
= g_byte_array_free_to_bytes(value
);
917 fvalue_set_bytes(fv
, bytes
);
918 g_bytes_unref(bytes
);
922 fvalue_set_bytes_data(fvalue_t
*fv
, const void *data
, size_t size
)
924 GBytes
*bytes
= g_bytes_new(data
, size
);
925 fvalue_set_bytes(fv
, bytes
);
926 g_bytes_unref(bytes
);
930 fvalue_set_fcwwn(fvalue_t
*fv
, const uint8_t *value
)
932 GBytes
*bytes
= g_bytes_new(value
, FT_FCWWN_LEN
);
933 fvalue_set_bytes(fv
, bytes
);
934 g_bytes_unref(bytes
);
938 fvalue_set_ax25(fvalue_t
*fv
, const uint8_t *value
)
940 wmem_strbuf_t
*buf
= wmem_strbuf_new(NULL
, NULL
);
941 for (size_t i
= 0; i
< FT_AX25_ADDR_LEN
- 1; i
++) {
942 if (value
[i
] != 0x40) {
943 /* ignore space-padding */
944 wmem_strbuf_append_c(buf
, value
[i
] >> 1);
947 /* Ignore C-bit and reserved bits, and end of address bits. */
948 uint8_t ssid
= (value
[FT_AX25_ADDR_LEN
- 1] >> 1) & 0x0f;
950 wmem_strbuf_append_printf(buf
, "-%u", ssid
);
952 fvalue_set_strbuf(fv
, buf
);
956 fvalue_set_vines(fvalue_t
*fv
, const uint8_t *value
)
958 GBytes
*bytes
= g_bytes_new(value
, FT_VINES_ADDR_LEN
);
959 fvalue_set_bytes(fv
, bytes
);
960 g_bytes_unref(bytes
);
964 fvalue_set_ether(fvalue_t
*fv
, const uint8_t *value
)
966 GBytes
*bytes
= g_bytes_new(value
, FT_ETHER_LEN
);
967 fvalue_set_bytes(fv
, bytes
);
968 g_bytes_unref(bytes
);
972 fvalue_set_guid(fvalue_t
*fv
, const e_guid_t
*value
)
974 ws_assert(fv
->ftype
->ftype
== FT_GUID
);
975 ws_assert(fv
->ftype
->set_value
.set_value_guid
);
976 fv
->ftype
->set_value
.set_value_guid(fv
, value
);
980 fvalue_set_time(fvalue_t
*fv
, const nstime_t
*value
)
982 ws_assert(FT_IS_TIME(fv
->ftype
->ftype
));
983 ws_assert(fv
->ftype
->set_value
.set_value_time
);
984 fv
->ftype
->set_value
.set_value_time(fv
, value
);
988 fvalue_set_string(fvalue_t
*fv
, const char *value
)
990 wmem_strbuf_t
*buf
= wmem_strbuf_new(NULL
, value
);
991 fvalue_set_strbuf(fv
, buf
);
995 fvalue_set_strbuf(fvalue_t
*fv
, wmem_strbuf_t
*value
)
997 if (value
->allocator
!= NULL
) {
998 /* XXX Can this condition be relaxed? */
999 ws_critical("Fvalue strbuf allocator must be NULL");
1001 ws_assert(FT_IS_STRING(fv
->ftype
->ftype
));
1002 ws_assert(fv
->ftype
->set_value
.set_value_strbuf
);
1003 fv
->ftype
->set_value
.set_value_strbuf(fv
, value
);
1007 fvalue_set_protocol(fvalue_t
*fv
, tvbuff_t
*value
, const char *name
, int length
)
1009 ws_assert(fv
->ftype
->ftype
== FT_PROTOCOL
);
1010 ws_assert(fv
->ftype
->set_value
.set_value_protocol
);
1011 fv
->ftype
->set_value
.set_value_protocol(fv
, value
, name
, length
);
1015 fvalue_set_protocol_length(fvalue_t
*fv
, int length
)
1017 ws_assert(fv
->ftype
->ftype
== FT_PROTOCOL
);
1018 protocol_value_t
*proto
= &fv
->value
.protocol
;
1019 proto
->length
= length
;
1023 fvalue_set_uinteger(fvalue_t
*fv
, uint32_t value
)
1025 ws_assert(fv
->ftype
->ftype
== FT_IEEE_11073_SFLOAT
||
1026 fv
->ftype
->ftype
== FT_IEEE_11073_FLOAT
||
1027 fv
->ftype
->ftype
== FT_CHAR
||
1028 fv
->ftype
->ftype
== FT_UINT8
||
1029 fv
->ftype
->ftype
== FT_UINT16
||
1030 fv
->ftype
->ftype
== FT_UINT24
||
1031 fv
->ftype
->ftype
== FT_UINT32
||
1032 fv
->ftype
->ftype
== FT_IPXNET
||
1033 fv
->ftype
->ftype
== FT_FRAMENUM
);
1034 ws_assert(fv
->ftype
->set_value
.set_value_uinteger
);
1035 fv
->ftype
->set_value
.set_value_uinteger(fv
, value
);
1039 fvalue_set_sinteger(fvalue_t
*fv
, int32_t value
)
1041 ws_assert(fv
->ftype
->ftype
== FT_INT8
||
1042 fv
->ftype
->ftype
== FT_INT16
||
1043 fv
->ftype
->ftype
== FT_INT24
||
1044 fv
->ftype
->ftype
== FT_INT32
);
1045 ws_assert(fv
->ftype
->set_value
.set_value_sinteger
);
1046 fv
->ftype
->set_value
.set_value_sinteger(fv
, value
);
1050 fvalue_set_uinteger64(fvalue_t
*fv
, uint64_t value
)
1052 ws_assert(fv
->ftype
->ftype
== FT_UINT40
||
1053 fv
->ftype
->ftype
== FT_UINT48
||
1054 fv
->ftype
->ftype
== FT_UINT56
||
1055 fv
->ftype
->ftype
== FT_UINT64
||
1056 fv
->ftype
->ftype
== FT_BOOLEAN
||
1057 fv
->ftype
->ftype
== FT_EUI64
);
1058 ws_assert(fv
->ftype
->set_value
.set_value_uinteger64
);
1059 fv
->ftype
->set_value
.set_value_uinteger64(fv
, value
);
1063 fvalue_set_sinteger64(fvalue_t
*fv
, int64_t value
)
1065 ws_assert(fv
->ftype
->ftype
== FT_INT40
||
1066 fv
->ftype
->ftype
== FT_INT48
||
1067 fv
->ftype
->ftype
== FT_INT56
||
1068 fv
->ftype
->ftype
== FT_INT64
);
1069 ws_assert(fv
->ftype
->set_value
.set_value_sinteger64
);
1070 fv
->ftype
->set_value
.set_value_sinteger64(fv
, value
);
1074 fvalue_set_floating(fvalue_t
*fv
, double value
)
1076 ws_assert(fv
->ftype
->ftype
== FT_FLOAT
||
1077 fv
->ftype
->ftype
== FT_DOUBLE
);
1078 ws_assert(fv
->ftype
->set_value
.set_value_floating
);
1079 fv
->ftype
->set_value
.set_value_floating(fv
, value
);
1083 fvalue_set_ipv4(fvalue_t
*fv
, const ipv4_addr_and_mask
*value
)
1085 ws_assert(fv
->ftype
->ftype
== FT_IPv4
);
1086 ws_assert(fv
->ftype
->set_value
.set_value_ipv4
);
1087 fv
->ftype
->set_value
.set_value_ipv4(fv
, value
);
1091 fvalue_set_ipv6(fvalue_t
*fv
, const ipv6_addr_and_prefix
*value
)
1093 ws_assert(fv
->ftype
->ftype
== FT_IPv6
);
1094 ws_assert(fv
->ftype
->set_value
.set_value_ipv6
);
1095 fv
->ftype
->set_value
.set_value_ipv6(fv
, value
);
1099 fvalue_get_bytes(fvalue_t
*fv
)
1101 ws_assert(fv
->ftype
->ftype
== FT_BYTES
||
1102 fv
->ftype
->ftype
== FT_UINT_BYTES
||
1103 fv
->ftype
->ftype
== FT_VINES
||
1104 fv
->ftype
->ftype
== FT_ETHER
||
1105 fv
->ftype
->ftype
== FT_OID
||
1106 fv
->ftype
->ftype
== FT_REL_OID
||
1107 fv
->ftype
->ftype
== FT_SYSTEM_ID
||
1108 fv
->ftype
->ftype
== FT_FCWWN
||
1109 fv
->ftype
->ftype
== FT_IPv6
);
1110 ws_assert(fv
->ftype
->get_value
.get_value_bytes
);
1111 return fv
->ftype
->get_value
.get_value_bytes(fv
);
1115 fvalue_get_bytes_size(fvalue_t
*fv
)
1117 GBytes
*bytes
= fvalue_get_bytes(fv
);
1118 size_t size
= g_bytes_get_size(bytes
);
1119 g_bytes_unref(bytes
);
1124 fvalue_get_bytes_data(fvalue_t
*fv
)
1126 GBytes
*bytes
= fvalue_get_bytes(fv
);
1127 const void *data
= g_bytes_get_data(bytes
, NULL
);
1128 g_bytes_unref(bytes
);
1133 fvalue_get_guid(fvalue_t
*fv
)
1135 ws_assert(fv
->ftype
->ftype
== FT_GUID
);
1136 ws_assert(fv
->ftype
->get_value
.get_value_guid
);
1137 return fv
->ftype
->get_value
.get_value_guid(fv
);
1141 fvalue_get_time(fvalue_t
*fv
)
1143 ws_assert(FT_IS_TIME(fv
->ftype
->ftype
));
1144 ws_assert(fv
->ftype
->get_value
.get_value_time
);
1145 return fv
->ftype
->get_value
.get_value_time(fv
);
1149 fvalue_get_string(fvalue_t
*fv
)
1151 return wmem_strbuf_get_str(fvalue_get_strbuf(fv
));
1154 const wmem_strbuf_t
*
1155 fvalue_get_strbuf(fvalue_t
*fv
)
1157 ws_assert(FT_IS_STRING(fv
->ftype
->ftype
));
1158 ws_assert(fv
->ftype
->get_value
.get_value_strbuf
);
1159 return fv
->ftype
->get_value
.get_value_strbuf(fv
);
1163 fvalue_get_protocol(fvalue_t
*fv
)
1165 ws_assert(fv
->ftype
->ftype
== FT_PROTOCOL
);
1166 ws_assert(fv
->ftype
->get_value
.get_value_protocol
);
1167 return fv
->ftype
->get_value
.get_value_protocol(fv
);
1171 fvalue_get_uinteger(fvalue_t
*fv
)
1173 ws_assert(fv
->ftype
->ftype
== FT_IEEE_11073_SFLOAT
||
1174 fv
->ftype
->ftype
== FT_IEEE_11073_FLOAT
||
1175 fv
->ftype
->ftype
== FT_CHAR
||
1176 fv
->ftype
->ftype
== FT_UINT8
||
1177 fv
->ftype
->ftype
== FT_UINT16
||
1178 fv
->ftype
->ftype
== FT_UINT24
||
1179 fv
->ftype
->ftype
== FT_UINT32
||
1180 fv
->ftype
->ftype
== FT_IPXNET
||
1181 fv
->ftype
->ftype
== FT_FRAMENUM
);
1182 ws_assert(fv
->ftype
->get_value
.get_value_uinteger
);
1183 return fv
->ftype
->get_value
.get_value_uinteger(fv
);
1187 fvalue_get_sinteger(fvalue_t
*fv
)
1189 ws_assert(fv
->ftype
->ftype
== FT_INT8
||
1190 fv
->ftype
->ftype
== FT_INT16
||
1191 fv
->ftype
->ftype
== FT_INT24
||
1192 fv
->ftype
->ftype
== FT_INT32
);
1193 ws_assert(fv
->ftype
->get_value
.get_value_sinteger
);
1194 return fv
->ftype
->get_value
.get_value_sinteger(fv
);
1198 fvalue_get_uinteger64(fvalue_t
*fv
)
1200 ws_assert(fv
->ftype
->ftype
== FT_UINT40
||
1201 fv
->ftype
->ftype
== FT_UINT48
||
1202 fv
->ftype
->ftype
== FT_UINT56
||
1203 fv
->ftype
->ftype
== FT_UINT64
||
1204 fv
->ftype
->ftype
== FT_BOOLEAN
||
1205 fv
->ftype
->ftype
== FT_EUI64
);
1206 ws_assert(fv
->ftype
->get_value
.get_value_uinteger64
);
1207 return fv
->ftype
->get_value
.get_value_uinteger64(fv
);
1211 fvalue_get_sinteger64(fvalue_t
*fv
)
1213 ws_assert(fv
->ftype
->ftype
== FT_INT40
||
1214 fv
->ftype
->ftype
== FT_INT48
||
1215 fv
->ftype
->ftype
== FT_INT56
||
1216 fv
->ftype
->ftype
== FT_INT64
);
1217 ws_assert(fv
->ftype
->get_value
.get_value_sinteger64
);
1218 return fv
->ftype
->get_value
.get_value_sinteger64(fv
);
1222 fvalue_get_floating(fvalue_t
*fv
)
1224 ws_assert(fv
->ftype
->ftype
== FT_FLOAT
||
1225 fv
->ftype
->ftype
== FT_DOUBLE
);
1226 ws_assert(fv
->ftype
->get_value
.get_value_floating
);
1227 return fv
->ftype
->get_value
.get_value_floating(fv
);
1230 const ipv4_addr_and_mask
*
1231 fvalue_get_ipv4(fvalue_t
*fv
)
1233 ws_assert(fv
->ftype
->ftype
== FT_IPv4
);
1234 ws_assert(fv
->ftype
->get_value
.get_value_ipv4
);
1235 return fv
->ftype
->get_value
.get_value_ipv4(fv
);
1238 const ipv6_addr_and_prefix
*
1239 fvalue_get_ipv6(fvalue_t
*fv
)
1241 ws_assert(fv
->ftype
->ftype
== FT_IPv6
);
1242 ws_assert(fv
->ftype
->get_value
.get_value_ipv6
);
1243 return fv
->ftype
->get_value
.get_value_ipv6(fv
);
1247 fvalue_eq(const fvalue_t
*a
, const fvalue_t
*b
)
1252 ws_assert(a
->ftype
->compare
);
1253 res
= a
->ftype
->compare(a
, b
, &cmp
);
1256 return cmp
== 0 ? FT_TRUE
: FT_FALSE
;
1260 fvalue_ne(const fvalue_t
*a
, const fvalue_t
*b
)
1265 ws_assert(a
->ftype
->compare
);
1266 res
= a
->ftype
->compare(a
, b
, &cmp
);
1269 return cmp
!= 0 ? FT_TRUE
: FT_FALSE
;
1273 fvalue_gt(const fvalue_t
*a
, const fvalue_t
*b
)
1278 ws_assert(a
->ftype
->compare
);
1279 res
= a
->ftype
->compare(a
, b
, &cmp
);
1282 return cmp
> 0 ? FT_TRUE
: FT_FALSE
;
1286 fvalue_ge(const fvalue_t
*a
, const fvalue_t
*b
)
1291 ws_assert(a
->ftype
->compare
);
1292 res
= a
->ftype
->compare(a
, b
, &cmp
);
1295 return cmp
>= 0 ? FT_TRUE
: FT_FALSE
;
1299 fvalue_lt(const fvalue_t
*a
, const fvalue_t
*b
)
1304 ws_assert(a
->ftype
->compare
);
1305 res
= a
->ftype
->compare(a
, b
, &cmp
);
1308 return cmp
< 0 ? FT_TRUE
: FT_FALSE
;
1312 fvalue_le(const fvalue_t
*a
, const fvalue_t
*b
)
1317 ws_assert(a
->ftype
->compare
);
1318 res
= a
->ftype
->compare(a
, b
, &cmp
);
1321 return cmp
<= 0 ? FT_TRUE
: FT_FALSE
;
1325 fvalue_contains(const fvalue_t
*a
, const fvalue_t
*b
)
1330 ws_assert(a
->ftype
->contains
);
1331 res
= a
->ftype
->contains(a
, b
, &yes
);
1334 return yes
? FT_TRUE
: FT_FALSE
;
1338 fvalue_matches(const fvalue_t
*a
, const ws_regex_t
*re
)
1343 ws_assert(a
->ftype
->matches
);
1344 res
= a
->ftype
->matches(a
, re
, &yes
);
1347 return yes
? FT_TRUE
: FT_FALSE
;
1351 fvalue_is_zero(const fvalue_t
*a
)
1353 return a
->ftype
->is_zero(a
);
1357 fvalue_is_negative(const fvalue_t
*a
)
1359 return a
->ftype
->is_negative(a
);
1363 _fvalue_binop(FvalueBinaryOp op
, const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1367 result
= fvalue_new(a
->ftype
->ftype
);
1368 if (op(result
, a
, b
, err_msg
) != FT_OK
) {
1369 fvalue_free(result
);
1376 fvalue_bitwise_and(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1378 /* XXX - check compatibility of a and b */
1379 ws_assert(a
->ftype
->bitwise_and
);
1380 return _fvalue_binop(a
->ftype
->bitwise_and
, a
, b
, err_msg
);
1384 fvalue_add(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1386 /* XXX - check compatibility of a and b */
1387 ws_assert(a
->ftype
->add
);
1388 return _fvalue_binop(a
->ftype
->add
, a
, b
, err_msg
);
1392 fvalue_subtract(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1394 /* XXX - check compatibility of a and b */
1395 ws_assert(a
->ftype
->subtract
);
1396 return _fvalue_binop(a
->ftype
->subtract
, a
, b
, err_msg
);
1400 fvalue_multiply(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1402 /* XXX - check compatibility of a and b */
1403 ws_assert(a
->ftype
->multiply
);
1404 return _fvalue_binop(a
->ftype
->multiply
, a
, b
, err_msg
);
1408 fvalue_divide(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1410 /* XXX - check compatibility of a and b */
1411 ws_assert(a
->ftype
->divide
);
1412 return _fvalue_binop(a
->ftype
->divide
, a
, b
, err_msg
);
1416 fvalue_modulo(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1418 /* XXX - check compatibility of a and b */
1419 ws_assert(a
->ftype
->modulo
);
1420 return _fvalue_binop(a
->ftype
->modulo
, a
, b
, err_msg
);
1424 fvalue_unary_minus(const fvalue_t
*fv
, char **err_msg
)
1428 ws_assert(fv
->ftype
->unary_minus
);
1430 result
= fvalue_new(fv
->ftype
->ftype
);
1431 if (fv
->ftype
->unary_minus(result
, fv
, err_msg
) != FT_OK
) {
1432 fvalue_free(result
);
1439 fvalue_hash(const fvalue_t
*fv
)
1441 ws_assert(fv
->ftype
->hash
);
1442 return fv
->ftype
->hash(fv
);
1446 fvalue_equal(const fvalue_t
*a
, const fvalue_t
*b
)
1448 return fvalue_eq(a
, b
) == FT_TRUE
;
1452 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1457 * indent-tabs-mode: t
1460 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1461 * :indentSize=8:tabSize=8:noTabs=false: