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, FT_CHAR, FT_UINT8, FT_UINT16,
78 FT_UINT24, FT_UINT32, FT_IPXNET, FT_FRAMENUM, FT_INT40, FT_INT48, FT_INT56
79 FT_INT64, FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64 and FT_EUI64
80 - FT_ABSOLUTE_TIME and FT_RELATIVE_TIME
81 - FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, and FT_AX25
82 - FT_FLOAT, FT_DOUBLE, FT_IEEE_11073_SFLOAT and FT_IEEE_11073_FLOAT
83 - FT_BYTES, FT_UINT_BYTES, FT_ETHER, FT_VINES and FT_FCWWN
84 - FT_OID, FT_REL_OID and FT_SYSTEM_ID
86 We thus divide the types into equivalence classes of compatible types.
87 The same field abbreviation can be used by more than one field, even of
88 different types, so long as the types are compatible.
90 This function returns the canonical representative of a type. It can
91 be used to check if two fields are compatible.
93 XXX - Currently epan/dfilter/semcheck.c has its own implementation of
97 same_ftype(const enum ftenum ftype
)
119 case FT_EUI64
: /* Really byte strings, but in ZigBee are stored in reverse order / Little-Endian so treated as integer */
126 case FT_STRINGZTRUNC
:
144 /* XXX - dfilter/semcheck.c treats this group as compatible with BYTES */
147 /* XXX: the following are unique for now */
150 case FT_IEEE_11073_SFLOAT
: /* XXX - should be able to compare with DOUBLE (#19011) */
151 case FT_IEEE_11073_FLOAT
: /* XXX - should be able to compare with DOUBLE */
153 /* everything else is unique */
154 /* XXX - README.dissector claims the time types are compatible. */
160 /* given two types, are they similar - for example can two
161 * duplicate fields be registered of these two types. */
163 ftype_similar_types(const enum ftenum ftype_a
, const enum ftenum ftype_b
)
165 return (same_ftype(ftype_a
) == same_ftype(ftype_b
));
168 /* Returns a string representing the name of the type. Useful
169 * for glossary production. */
171 ftype_name(enum ftenum ftype
)
174 const char *s
= "(null)";
176 FTYPE_LOOKUP(ftype
, ft
);
178 case FT_NONE
: s
= "FT_NONE"; break;
179 case FT_PROTOCOL
: s
= "FT_PROTOCOL"; break;
180 case FT_BOOLEAN
: s
= "FT_BOOLEAN"; break;
181 case FT_CHAR
: s
= "FT_CHAR"; break;
182 case FT_UINT8
: s
= "FT_UINT8"; break;
183 case FT_UINT16
: s
= "FT_UINT16"; break;
184 case FT_UINT24
: s
= "FT_UINT24"; break;
185 case FT_UINT32
: s
= "FT_UINT32"; break;
186 case FT_UINT40
: s
= "FT_UINT40"; break;
187 case FT_UINT48
: s
= "FT_UINT48"; break;
188 case FT_UINT56
: s
= "FT_UINT56"; break;
189 case FT_UINT64
: s
= "FT_UINT64"; break;
190 case FT_INT8
: s
= "FT_INT8"; break;
191 case FT_INT16
: s
= "FT_INT16"; break;
192 case FT_INT24
: s
= "FT_INT24"; break;
193 case FT_INT32
: s
= "FT_INT32"; break;
194 case FT_INT40
: s
= "FT_INT40"; break;
195 case FT_INT48
: s
= "FT_INT48"; break;
196 case FT_INT56
: s
= "FT_INT56"; break;
197 case FT_INT64
: s
= "FT_INT64"; break;
198 case FT_IEEE_11073_SFLOAT
: s
= "FT_IEEE_11073_SFLOAT"; break;
199 case FT_IEEE_11073_FLOAT
: s
= "FT_IEEE_11073_FLOAT"; break;
200 case FT_FLOAT
: s
= "FT_FLOAT"; break;
201 case FT_DOUBLE
: s
= "FT_DOUBLE"; break;
202 case FT_ABSOLUTE_TIME
: s
= "FT_ABSOLUTE_TIME"; break;
203 case FT_RELATIVE_TIME
: s
= "FT_RELATIVE_TIME"; break;
204 case FT_STRING
: s
= "FT_STRING"; break;
205 case FT_STRINGZ
: s
= "FT_STRINGZ"; break;
206 case FT_UINT_STRING
: s
= "FT_UINT_STRING"; break;
207 case FT_ETHER
: s
= "FT_ETHER"; break;
208 case FT_BYTES
: s
= "FT_BYTES"; break;
209 case FT_UINT_BYTES
: s
= "FT_UINT_BYTES"; break;
210 case FT_IPv4
: s
= "FT_IPv4"; break;
211 case FT_IPv6
: s
= "FT_IPv6"; break;
212 case FT_IPXNET
: s
= "FT_IPXNET"; break;
213 case FT_FRAMENUM
: s
= "FT_FRAMENUM"; break;
214 case FT_GUID
: s
= "FT_GUID"; break;
215 case FT_OID
: s
= "FT_OID"; break;
216 case FT_EUI64
: s
= "FT_EUI64"; break;
217 case FT_AX25
: s
= "FT_AX25"; break;
218 case FT_VINES
: s
= "FT_VINES"; break;
219 case FT_REL_OID
: s
= "FT_REL_OID"; break;
220 case FT_SYSTEM_ID
: s
= "FT_SYSTEM_ID"; break;
221 case FT_STRINGZPAD
: s
= "FT_STRINGZPAD"; break;
222 case FT_FCWWN
: s
= "FT_FCWWN"; break;
223 case FT_STRINGZTRUNC
: s
= "FT_STRINGZTRUNC"; break;
224 case FT_NUM_TYPES
: s
= "FT_NUM_TYPES"; break;
225 case FT_SCALAR
: s
= "FT_SCALAR"; break;
231 ftype_pretty_name(enum ftenum ftype
)
234 const char *s
= "(null)";
236 FTYPE_LOOKUP(ftype
, ft
);
238 case FT_NONE
: s
= "Label"; break;
239 case FT_PROTOCOL
: s
= "Protocol"; break;
240 case FT_BOOLEAN
: s
= "Boolean"; break;
241 case FT_CHAR
: s
= "Character (8 bits)"; break;
242 case FT_UINT8
: s
= "Unsigned integer (8 bits)"; break;
243 case FT_UINT16
: s
= "Unsigned integer (16 bits)"; break;
244 case FT_UINT24
: s
= "Unsigned integer (24 bits)"; break;
245 case FT_UINT32
: s
= "Unsigned integer (32 bits)"; break;
246 case FT_UINT40
: s
= "Unsigned integer (40 bits)"; break;
247 case FT_UINT48
: s
= "Unsigned integer (48 bits)"; break;
248 case FT_UINT56
: s
= "Unsigned integer (56 bits)"; break;
249 case FT_UINT64
: s
= "Unsigned integer (64 bits)"; break;
250 case FT_INT8
: s
= "Signed integer (8 bits)"; break;
251 case FT_INT16
: s
= "Signed integer (16 bits)"; break;
252 case FT_INT24
: s
= "Signed integer (24 bits)"; break;
253 case FT_INT32
: s
= "Signed integer (32 bits)"; break;
254 case FT_INT40
: s
= "Signed integer (40 bits)"; break;
255 case FT_INT48
: s
= "Signed integer (48 bits)"; break;
256 case FT_INT56
: s
= "Signed integer (56 bits)"; break;
257 case FT_INT64
: s
= "Signed integer (64 bits)"; break;
258 case FT_IEEE_11073_SFLOAT
: s
= "IEEE-11073 floating point (16-bit)"; break;
259 case FT_IEEE_11073_FLOAT
: s
= "IEEE-11073 Floating point (32-bit)"; break;
260 case FT_FLOAT
: s
= "Floating point (single-precision)"; break;
261 case FT_DOUBLE
: s
= "Floating point (double-precision)"; break;
262 case FT_ABSOLUTE_TIME
: s
= "Date and time"; break;
263 case FT_RELATIVE_TIME
: s
= "Time offset"; break;
264 case FT_STRING
: s
= "Character string"; break;
265 case FT_STRINGZ
: s
= "Character string"; break;
266 case FT_UINT_STRING
: s
= "Character string"; break;
267 case FT_ETHER
: s
= "Ethernet or other MAC address"; break;
268 case FT_BYTES
: s
= "Byte sequence"; break;
269 case FT_UINT_BYTES
: s
= "Byte sequence"; break;
270 case FT_IPv4
: s
= "IPv4 address"; break;
271 case FT_IPv6
: s
= "IPv6 address"; break;
272 case FT_IPXNET
: s
= "IPX network number"; break;
273 case FT_FRAMENUM
: s
= "Frame number"; break;
274 case FT_GUID
: s
= "Globally Unique Identifier"; break;
275 case FT_OID
: s
= "ASN.1 object identifier"; break;
276 case FT_EUI64
: s
= "EUI64 address"; break;
277 case FT_AX25
: s
= "AX.25 address"; break;
278 case FT_VINES
: s
= "VINES address"; break;
279 case FT_REL_OID
: s
= "ASN.1 relative object identifier"; break;
280 case FT_SYSTEM_ID
: s
= "OSI System-ID"; break;
281 case FT_STRINGZPAD
: s
= "Character string"; break;
282 case FT_FCWWN
: s
= "Fibre Channel WWN"; break;
283 case FT_STRINGZTRUNC
: s
= "Character string"; break;
284 case FT_NUM_TYPES
: s
= "(num types)"; break;
285 case FT_SCALAR
: s
= "Scalar"; break;
291 ftype_wire_size(enum ftenum ftype
)
295 FTYPE_LOOKUP(ftype
, ft
);
296 return ft
->wire_size
;
300 ftype_can_length(enum ftenum ftype
)
304 FTYPE_LOOKUP(ftype
, ft
);
305 return ft
->len
? true : false;
309 ftype_can_slice(enum ftenum ftype
)
313 FTYPE_LOOKUP(ftype
, ft
);
314 return ft
->slice
? true : false;
318 ftype_can_eq(enum ftenum ftype
)
322 FTYPE_LOOKUP(ftype
, ft
);
323 return ft
->compare
!= NULL
;
327 ftype_can_cmp(enum ftenum ftype
)
331 FTYPE_LOOKUP(ftype
, ft
);
332 return ft
->compare
!= NULL
;
336 ftype_can_bitwise_and(enum ftenum ftype
)
340 FTYPE_LOOKUP(ftype
, ft
);
341 return ft
->bitwise_and
? true : false;
345 ftype_can_unary_minus(enum ftenum ftype
)
349 FTYPE_LOOKUP(ftype
, ft
);
350 return ft
->unary_minus
!= NULL
;
354 ftype_can_add(enum ftenum ftype
)
358 FTYPE_LOOKUP(ftype
, ft
);
359 return ft
->add
!= NULL
;
363 ftype_can_subtract(enum ftenum ftype
)
367 FTYPE_LOOKUP(ftype
, ft
);
368 return ft
->subtract
!= NULL
;
372 ftype_can_multiply(enum ftenum ftype
)
376 FTYPE_LOOKUP(ftype
, ft
);
377 return ft
->multiply
!= NULL
;
381 ftype_can_divide(enum ftenum ftype
)
385 FTYPE_LOOKUP(ftype
, ft
);
386 return ft
->divide
!= NULL
;
390 ftype_can_modulo(enum ftenum ftype
)
394 FTYPE_LOOKUP(ftype
, ft
);
395 return ft
->modulo
!= NULL
;
399 ftype_can_contains(enum ftenum ftype
)
403 FTYPE_LOOKUP(ftype
, ft
);
404 return ft
->contains
? true : false;
408 ftype_can_matches(enum ftenum ftype
)
412 FTYPE_LOOKUP(ftype
, ft
);
413 return ft
->matches
? true : false;
417 ftype_can_is_zero(enum ftenum ftype
)
421 FTYPE_LOOKUP(ftype
, ft
);
422 return ft
->is_zero
? true : false;
426 ftype_can_is_negative(enum ftenum ftype
)
430 FTYPE_LOOKUP(ftype
, ft
);
431 return ft
->is_negative
? true : false;
435 ftype_can_val_to_sinteger(enum ftenum ftype
)
439 FTYPE_LOOKUP(ftype
, ft
);
440 /* We first convert to 64 bit and then check for overflow. */
441 return ft
->val_to_sinteger64
? true : false;
445 ftype_can_val_to_uinteger(enum ftenum ftype
)
449 FTYPE_LOOKUP(ftype
, ft
);
450 /* We first convert to 64 bit and then check for overflow. */
451 return ft
->val_to_uinteger64
? true : false;
455 ftype_can_val_to_sinteger64(enum ftenum ftype
)
459 FTYPE_LOOKUP(ftype
, ft
);
460 return ft
->val_to_sinteger64
? true : false;
464 ftype_can_val_to_uinteger64(enum ftenum ftype
)
468 FTYPE_LOOKUP(ftype
, ft
);
469 return ft
->val_to_uinteger64
? true : false;
473 ftype_can_val_to_double(enum ftenum ftype
)
477 FTYPE_LOOKUP(ftype
, ft
);
478 /* We first convert to 64 bit and then check for overflow. */
479 return ft
->val_to_double
? true : false;
482 /* ---------------------------------------------------------- */
484 /* Allocate and initialize an fvalue_t, given an ftype */
486 fvalue_new(ftenum_t ftype
)
490 FvalueNewFunc new_value
;
492 fv
= g_slice_new(fvalue_t
);
494 FTYPE_LOOKUP(ftype
, ft
);
497 new_value
= ft
->new_value
;
506 fvalue_dup(const fvalue_t
*fv_orig
)
509 FvalueCopyFunc copy_value
;
511 fv_new
= g_slice_new(fvalue_t
);
512 fv_new
->ftype
= fv_orig
->ftype
;
513 copy_value
= fv_new
->ftype
->copy_value
;
514 if (copy_value
!= NULL
) {
516 copy_value(fv_new
, fv_orig
);
520 memcpy(&fv_new
->value
, &fv_orig
->value
, sizeof(fv_orig
->value
));
527 fvalue_init(fvalue_t
*fv
, ftenum_t ftype
)
530 FvalueNewFunc new_value
;
532 FTYPE_LOOKUP(ftype
, ft
);
535 new_value
= ft
->new_value
;
542 fvalue_cleanup(fvalue_t
*fv
)
544 if (!fv
->ftype
->free_value
)
546 fv
->ftype
->free_value(fv
);
550 fvalue_free(fvalue_t
*fv
)
553 g_slice_free(fvalue_t
, fv
);
557 fvalue_from_literal(ftenum_t ftype
, const char *s
, bool allow_partial_value
, char **err_msg
)
562 fv
= fvalue_new(ftype
);
563 if (fv
->ftype
->val_from_literal
) {
564 ok
= fv
->ftype
->val_from_literal(fv
, s
, allow_partial_value
, err_msg
);
573 if (err_msg
!= NULL
&& *err_msg
== NULL
) {
574 *err_msg
= ws_strdup_printf("\"%s\" cannot be converted to %s.",
575 s
, ftype_pretty_name(ftype
));
583 fvalue_from_string(ftenum_t ftype
, const char *str
, size_t len
, char **err_msg
)
587 fv
= fvalue_new(ftype
);
588 if (fv
->ftype
->val_from_string
&& fv
->ftype
->val_from_string(fv
, str
, len
, err_msg
)) {
595 if (err_msg
!= NULL
&& *err_msg
== NULL
) {
596 *err_msg
= ws_strdup_printf("%s cannot be converted from a string (\"%s\").",
597 ftype_pretty_name(ftype
), str
);
605 fvalue_from_charconst(ftenum_t ftype
, unsigned long num
, char **err_msg
)
609 fv
= fvalue_new(ftype
);
610 if (fv
->ftype
->val_from_charconst
&& fv
->ftype
->val_from_charconst(fv
, num
, err_msg
)) {
617 if (err_msg
!= NULL
&& *err_msg
== NULL
) {
618 if (num
<= 0x7f && g_ascii_isprint(num
)) {
619 *err_msg
= ws_strdup_printf("Character constant '%c' (0x%lx) cannot be converted to %s.",
620 (int)num
, num
, ftype_pretty_name(ftype
));
623 *err_msg
= ws_strdup_printf("Character constant 0x%lx cannot be converted to %s.",
624 num
, ftype_pretty_name(ftype
));
633 fvalue_from_sinteger64(ftenum_t ftype
, const char *s
, int64_t num
, char **err_msg
)
637 fv
= fvalue_new(ftype
);
638 if (fv
->ftype
->val_from_sinteger64
&& fv
->ftype
->val_from_sinteger64(fv
, s
, num
, err_msg
)) {
645 if (err_msg
!= NULL
&& *err_msg
== NULL
) {
646 *err_msg
= ws_strdup_printf("Integer %"PRId64
" cannot be converted to %s.",
647 num
, ftype_pretty_name(ftype
));
655 fvalue_from_uinteger64(ftenum_t ftype
, const char *s
, uint64_t num
, char **err_msg
)
659 fv
= fvalue_new(ftype
);
660 if (fv
->ftype
->val_from_uinteger64
&& fv
->ftype
->val_from_uinteger64(fv
, s
, num
, err_msg
)) {
667 if (err_msg
!= NULL
&& *err_msg
== NULL
) {
668 *err_msg
= ws_strdup_printf("Unsigned integer 0x%"PRIu64
" cannot be converted to %s.",
669 num
, ftype_pretty_name(ftype
));
677 fvalue_from_floating(ftenum_t ftype
, const char *s
, double num
, char **err_msg
)
681 fv
= fvalue_new(ftype
);
682 if (fv
->ftype
->val_from_double
&& fv
->ftype
->val_from_double(fv
, s
, num
, err_msg
)) {
689 if (err_msg
!= NULL
&& *err_msg
== NULL
) {
690 *err_msg
= ws_strdup_printf("Double %g cannot be converted to %s.",
691 num
, ftype_pretty_name(ftype
));
699 fvalue_type_ftenum(const fvalue_t
*fv
)
701 return fv
->ftype
->ftype
;
705 fvalue_type_name(const fvalue_t
*fv
)
707 return ftype_name(fv
->ftype
->ftype
);
712 fvalue_length2(fvalue_t
*fv
)
714 if (!fv
->ftype
->len
) {
715 ws_critical("fv->ftype->len is NULL");
718 return fv
->ftype
->len(fv
);
722 fvalue_to_string_repr(wmem_allocator_t
*scope
, const fvalue_t
*fv
, ftrepr_t rtype
, int field_display
)
724 if (fv
->ftype
->val_to_string_repr
== NULL
) {
725 /* no value-to-string-representation function, so the value cannot be represented */
729 return fv
->ftype
->val_to_string_repr(scope
, fv
, rtype
, field_display
);
733 fvalue_to_uinteger(const fvalue_t
*fv
, uint32_t *repr
)
736 enum ft_result res
= fv
->ftype
->val_to_uinteger64(fv
, &val
);
739 if (val
> UINT32_MAX
)
742 *repr
= (uint32_t)val
;
747 fvalue_to_sinteger(const fvalue_t
*fv
, int32_t *repr
)
750 enum ft_result res
= fv
->ftype
->val_to_sinteger64(fv
, &val
);
758 *repr
= (int32_t)val
;
763 fvalue_to_uinteger64(const fvalue_t
*fv
, uint64_t *repr
)
765 if (!fv
->ftype
->val_to_uinteger64
) {
768 return fv
->ftype
->val_to_uinteger64(fv
, repr
);
772 fvalue_to_sinteger64(const fvalue_t
*fv
, int64_t *repr
)
774 if (!fv
->ftype
->val_to_sinteger64
) {
777 return fv
->ftype
->val_to_sinteger64(fv
, repr
);
781 fvalue_to_double(const fvalue_t
*fv
, double *repr
)
783 /* We should be able to test this earlier (e.g., in semantic check)
784 * but there are non-compatible fields that share the same abbrev
785 * so we have to check it on each fvalue.
787 if (!fv
->ftype
->val_to_double
) {
790 return fv
->ftype
->val_to_double(fv
, repr
);
800 compute_drnode(size_t field_length
, drange_node
*drnode
, size_t *offset_ptr
, size_t *length_ptr
)
802 ssize_t start_offset
;
804 ssize_t end_offset
= 0;
805 drange_node_end_t ending
;
807 start_offset
= drange_node_get_start_offset(drnode
);
808 ending
= drange_node_get_ending(drnode
);
810 /* Check for negative start */
811 if (start_offset
< 0) {
812 start_offset
= field_length
+ start_offset
;
813 if (start_offset
< 0) {
818 /* Check the end type and set the length */
820 if (ending
== DRANGE_NODE_END_T_TO_THE_END
) {
821 length
= field_length
- start_offset
;
826 else if (ending
== DRANGE_NODE_END_T_LENGTH
) {
827 length
= drange_node_get_length(drnode
);
828 if (start_offset
+ length
> (int) field_length
) {
832 else if (ending
== DRANGE_NODE_END_T_OFFSET
) {
833 end_offset
= drange_node_get_end_offset(drnode
);
834 if (end_offset
< 0) {
835 end_offset
= field_length
+ end_offset
;
836 if (end_offset
< start_offset
) {
839 } else if (end_offset
>= (int) field_length
) {
842 length
= end_offset
- start_offset
+ 1;
845 ws_assert_not_reached();
848 *offset_ptr
= start_offset
;
849 *length_ptr
= length
;
854 slice_func(void * data
, void * user_data
)
856 drange_node
*drnode
= (drange_node
*)data
;
857 slice_data_t
*slice_data
= (slice_data_t
*)user_data
;
862 if (slice_data
->slice_failure
) {
867 if (!compute_drnode((unsigned)fvalue_length2(fv
), drnode
, &start_offset
, &length
)) {
868 slice_data
->slice_failure
= true;
872 ws_assert(length
> 0);
873 fv
->ftype
->slice(fv
, slice_data
->ptr
, (unsigned)start_offset
, (unsigned)length
);
877 slice_string(fvalue_t
*fv
, drange_t
*d_range
)
879 slice_data_t slice_data
;
883 slice_data
.ptr
= wmem_strbuf_create(NULL
);
884 slice_data
.slice_failure
= false;
886 /* XXX - We could make some optimizations here based on
887 * drange_has_total_length() and
888 * drange_get_max_offset().
891 drange_foreach_drange_node(d_range
, slice_func
, &slice_data
);
893 new_fv
= fvalue_new(FT_STRING
);
894 fvalue_set_strbuf(new_fv
, slice_data
.ptr
);
899 slice_bytes(fvalue_t
*fv
, drange_t
*d_range
)
901 slice_data_t slice_data
;
905 slice_data
.ptr
= g_byte_array_new();
906 slice_data
.slice_failure
= false;
908 /* XXX - We could make some optimizations here based on
909 * drange_has_total_length() and
910 * drange_get_max_offset().
913 drange_foreach_drange_node(d_range
, slice_func
, &slice_data
);
915 new_fv
= fvalue_new(FT_BYTES
);
916 fvalue_set_byte_array(new_fv
, slice_data
.ptr
);
920 /* Returns a new slice fvalue_t* if possible, otherwise NULL */
922 fvalue_slice(fvalue_t
*fv
, drange_t
*d_range
)
924 if (FT_IS_STRING(fvalue_type_ftenum(fv
))) {
925 return slice_string(fv
, d_range
);
927 return slice_bytes(fv
, d_range
);
931 fvalue_set_bytes(fvalue_t
*fv
, GBytes
*value
)
933 ws_assert(fv
->ftype
->ftype
== FT_BYTES
||
934 fv
->ftype
->ftype
== FT_UINT_BYTES
||
935 fv
->ftype
->ftype
== FT_OID
||
936 fv
->ftype
->ftype
== FT_REL_OID
||
937 fv
->ftype
->ftype
== FT_SYSTEM_ID
||
938 fv
->ftype
->ftype
== FT_VINES
||
939 fv
->ftype
->ftype
== FT_ETHER
||
940 fv
->ftype
->ftype
== FT_FCWWN
);
941 ws_assert(fv
->ftype
->set_value
.set_value_bytes
);
942 fv
->ftype
->set_value
.set_value_bytes(fv
, value
);
946 fvalue_set_byte_array(fvalue_t
*fv
, GByteArray
*value
)
948 GBytes
*bytes
= g_byte_array_free_to_bytes(value
);
949 fvalue_set_bytes(fv
, bytes
);
950 g_bytes_unref(bytes
);
954 fvalue_set_bytes_data(fvalue_t
*fv
, const void *data
, size_t size
)
956 GBytes
*bytes
= g_bytes_new(data
, size
);
957 fvalue_set_bytes(fv
, bytes
);
958 g_bytes_unref(bytes
);
962 fvalue_set_fcwwn(fvalue_t
*fv
, const uint8_t *value
)
964 GBytes
*bytes
= g_bytes_new(value
, FT_FCWWN_LEN
);
965 fvalue_set_bytes(fv
, bytes
);
966 g_bytes_unref(bytes
);
970 fvalue_set_ax25(fvalue_t
*fv
, const uint8_t *value
)
972 wmem_strbuf_t
*buf
= wmem_strbuf_new(NULL
, NULL
);
973 for (size_t i
= 0; i
< FT_AX25_ADDR_LEN
- 1; i
++) {
974 if (value
[i
] != 0x40) {
975 /* ignore space-padding */
976 wmem_strbuf_append_c(buf
, value
[i
] >> 1);
979 /* Ignore C-bit and reserved bits, and end of address bits. */
980 uint8_t ssid
= (value
[FT_AX25_ADDR_LEN
- 1] >> 1) & 0x0f;
982 wmem_strbuf_append_printf(buf
, "-%u", ssid
);
984 fvalue_set_strbuf(fv
, buf
);
988 fvalue_set_vines(fvalue_t
*fv
, const uint8_t *value
)
990 GBytes
*bytes
= g_bytes_new(value
, FT_VINES_ADDR_LEN
);
991 fvalue_set_bytes(fv
, bytes
);
992 g_bytes_unref(bytes
);
996 fvalue_set_ether(fvalue_t
*fv
, const uint8_t *value
)
998 GBytes
*bytes
= g_bytes_new(value
, FT_ETHER_LEN
);
999 fvalue_set_bytes(fv
, bytes
);
1000 g_bytes_unref(bytes
);
1004 fvalue_set_guid(fvalue_t
*fv
, const e_guid_t
*value
)
1006 ws_assert(fv
->ftype
->ftype
== FT_GUID
);
1007 ws_assert(fv
->ftype
->set_value
.set_value_guid
);
1008 fv
->ftype
->set_value
.set_value_guid(fv
, value
);
1012 fvalue_set_time(fvalue_t
*fv
, const nstime_t
*value
)
1014 ws_assert(FT_IS_TIME(fv
->ftype
->ftype
));
1015 ws_assert(fv
->ftype
->set_value
.set_value_time
);
1016 fv
->ftype
->set_value
.set_value_time(fv
, value
);
1020 fvalue_set_string(fvalue_t
*fv
, const char *value
)
1022 wmem_strbuf_t
*buf
= wmem_strbuf_new(NULL
, value
);
1023 fvalue_set_strbuf(fv
, buf
);
1027 fvalue_set_strbuf(fvalue_t
*fv
, wmem_strbuf_t
*value
)
1029 if (value
->allocator
!= NULL
) {
1030 /* XXX Can this condition be relaxed? */
1031 ws_critical("Fvalue strbuf allocator must be NULL");
1033 ws_assert(FT_IS_STRING(fv
->ftype
->ftype
));
1034 ws_assert(fv
->ftype
->set_value
.set_value_strbuf
);
1035 fv
->ftype
->set_value
.set_value_strbuf(fv
, value
);
1039 fvalue_set_protocol(fvalue_t
*fv
, tvbuff_t
*value
, const char *name
, int length
)
1041 ws_assert(fv
->ftype
->ftype
== FT_PROTOCOL
);
1042 ws_assert(fv
->ftype
->set_value
.set_value_protocol
);
1043 fv
->ftype
->set_value
.set_value_protocol(fv
, value
, name
, length
);
1047 fvalue_set_protocol_length(fvalue_t
*fv
, int length
)
1049 ws_assert(fv
->ftype
->ftype
== FT_PROTOCOL
);
1050 protocol_value_t
*proto
= &fv
->value
.protocol
;
1051 proto
->length
= length
;
1055 fvalue_set_uinteger(fvalue_t
*fv
, uint32_t value
)
1057 ws_assert(fv
->ftype
->ftype
== FT_IEEE_11073_SFLOAT
||
1058 fv
->ftype
->ftype
== FT_IEEE_11073_FLOAT
||
1059 fv
->ftype
->ftype
== FT_CHAR
||
1060 fv
->ftype
->ftype
== FT_UINT8
||
1061 fv
->ftype
->ftype
== FT_UINT16
||
1062 fv
->ftype
->ftype
== FT_UINT24
||
1063 fv
->ftype
->ftype
== FT_UINT32
||
1064 fv
->ftype
->ftype
== FT_IPXNET
||
1065 fv
->ftype
->ftype
== FT_FRAMENUM
);
1066 ws_assert(fv
->ftype
->set_value
.set_value_uinteger
);
1067 fv
->ftype
->set_value
.set_value_uinteger(fv
, value
);
1071 fvalue_set_sinteger(fvalue_t
*fv
, int32_t value
)
1073 ws_assert(fv
->ftype
->ftype
== FT_INT8
||
1074 fv
->ftype
->ftype
== FT_INT16
||
1075 fv
->ftype
->ftype
== FT_INT24
||
1076 fv
->ftype
->ftype
== FT_INT32
);
1077 ws_assert(fv
->ftype
->set_value
.set_value_sinteger
);
1078 fv
->ftype
->set_value
.set_value_sinteger(fv
, value
);
1082 fvalue_set_uinteger64(fvalue_t
*fv
, uint64_t value
)
1084 ws_assert(fv
->ftype
->ftype
== FT_UINT40
||
1085 fv
->ftype
->ftype
== FT_UINT48
||
1086 fv
->ftype
->ftype
== FT_UINT56
||
1087 fv
->ftype
->ftype
== FT_UINT64
||
1088 fv
->ftype
->ftype
== FT_BOOLEAN
||
1089 fv
->ftype
->ftype
== FT_EUI64
);
1090 ws_assert(fv
->ftype
->set_value
.set_value_uinteger64
);
1091 fv
->ftype
->set_value
.set_value_uinteger64(fv
, value
);
1095 fvalue_set_sinteger64(fvalue_t
*fv
, int64_t value
)
1097 ws_assert(fv
->ftype
->ftype
== FT_INT40
||
1098 fv
->ftype
->ftype
== FT_INT48
||
1099 fv
->ftype
->ftype
== FT_INT56
||
1100 fv
->ftype
->ftype
== FT_INT64
);
1101 ws_assert(fv
->ftype
->set_value
.set_value_sinteger64
);
1102 fv
->ftype
->set_value
.set_value_sinteger64(fv
, value
);
1106 fvalue_set_floating(fvalue_t
*fv
, double value
)
1108 ws_assert(fv
->ftype
->ftype
== FT_FLOAT
||
1109 fv
->ftype
->ftype
== FT_DOUBLE
);
1110 ws_assert(fv
->ftype
->set_value
.set_value_floating
);
1111 fv
->ftype
->set_value
.set_value_floating(fv
, value
);
1115 fvalue_set_ipv4(fvalue_t
*fv
, const ipv4_addr_and_mask
*value
)
1117 ws_assert(fv
->ftype
->ftype
== FT_IPv4
);
1118 ws_assert(fv
->ftype
->set_value
.set_value_ipv4
);
1119 fv
->ftype
->set_value
.set_value_ipv4(fv
, value
);
1123 fvalue_set_ipv6(fvalue_t
*fv
, const ipv6_addr_and_prefix
*value
)
1125 ws_assert(fv
->ftype
->ftype
== FT_IPv6
);
1126 ws_assert(fv
->ftype
->set_value
.set_value_ipv6
);
1127 fv
->ftype
->set_value
.set_value_ipv6(fv
, value
);
1131 fvalue_get_bytes(fvalue_t
*fv
)
1133 ws_assert(fv
->ftype
->ftype
== FT_BYTES
||
1134 fv
->ftype
->ftype
== FT_UINT_BYTES
||
1135 fv
->ftype
->ftype
== FT_VINES
||
1136 fv
->ftype
->ftype
== FT_ETHER
||
1137 fv
->ftype
->ftype
== FT_OID
||
1138 fv
->ftype
->ftype
== FT_REL_OID
||
1139 fv
->ftype
->ftype
== FT_SYSTEM_ID
||
1140 fv
->ftype
->ftype
== FT_FCWWN
||
1141 fv
->ftype
->ftype
== FT_IPv6
);
1142 ws_assert(fv
->ftype
->get_value
.get_value_bytes
);
1143 return fv
->ftype
->get_value
.get_value_bytes(fv
);
1147 fvalue_get_bytes_size(fvalue_t
*fv
)
1149 GBytes
*bytes
= fvalue_get_bytes(fv
);
1150 size_t size
= g_bytes_get_size(bytes
);
1151 g_bytes_unref(bytes
);
1156 fvalue_get_bytes_data(fvalue_t
*fv
)
1158 GBytes
*bytes
= fvalue_get_bytes(fv
);
1159 const void *data
= g_bytes_get_data(bytes
, NULL
);
1160 g_bytes_unref(bytes
);
1165 fvalue_get_guid(fvalue_t
*fv
)
1167 ws_assert(fv
->ftype
->ftype
== FT_GUID
);
1168 ws_assert(fv
->ftype
->get_value
.get_value_guid
);
1169 return fv
->ftype
->get_value
.get_value_guid(fv
);
1173 fvalue_get_time(fvalue_t
*fv
)
1175 ws_assert(FT_IS_TIME(fv
->ftype
->ftype
));
1176 ws_assert(fv
->ftype
->get_value
.get_value_time
);
1177 return fv
->ftype
->get_value
.get_value_time(fv
);
1181 fvalue_get_string(fvalue_t
*fv
)
1183 return wmem_strbuf_get_str(fvalue_get_strbuf(fv
));
1186 const wmem_strbuf_t
*
1187 fvalue_get_strbuf(fvalue_t
*fv
)
1189 ws_assert(FT_IS_STRING(fv
->ftype
->ftype
));
1190 ws_assert(fv
->ftype
->get_value
.get_value_strbuf
);
1191 return fv
->ftype
->get_value
.get_value_strbuf(fv
);
1195 fvalue_get_protocol(fvalue_t
*fv
)
1197 ws_assert(fv
->ftype
->ftype
== FT_PROTOCOL
);
1198 ws_assert(fv
->ftype
->get_value
.get_value_protocol
);
1199 return fv
->ftype
->get_value
.get_value_protocol(fv
);
1203 fvalue_get_uinteger(fvalue_t
*fv
)
1205 ws_assert(fv
->ftype
->ftype
== FT_IEEE_11073_SFLOAT
||
1206 fv
->ftype
->ftype
== FT_IEEE_11073_FLOAT
||
1207 fv
->ftype
->ftype
== FT_CHAR
||
1208 fv
->ftype
->ftype
== FT_UINT8
||
1209 fv
->ftype
->ftype
== FT_UINT16
||
1210 fv
->ftype
->ftype
== FT_UINT24
||
1211 fv
->ftype
->ftype
== FT_UINT32
||
1212 fv
->ftype
->ftype
== FT_IPXNET
||
1213 fv
->ftype
->ftype
== FT_FRAMENUM
);
1214 ws_assert(fv
->ftype
->get_value
.get_value_uinteger
);
1215 return fv
->ftype
->get_value
.get_value_uinteger(fv
);
1219 fvalue_get_sinteger(fvalue_t
*fv
)
1221 ws_assert(fv
->ftype
->ftype
== FT_INT8
||
1222 fv
->ftype
->ftype
== FT_INT16
||
1223 fv
->ftype
->ftype
== FT_INT24
||
1224 fv
->ftype
->ftype
== FT_INT32
);
1225 ws_assert(fv
->ftype
->get_value
.get_value_sinteger
);
1226 return fv
->ftype
->get_value
.get_value_sinteger(fv
);
1230 fvalue_get_uinteger64(fvalue_t
*fv
)
1232 ws_assert(fv
->ftype
->ftype
== FT_UINT40
||
1233 fv
->ftype
->ftype
== FT_UINT48
||
1234 fv
->ftype
->ftype
== FT_UINT56
||
1235 fv
->ftype
->ftype
== FT_UINT64
||
1236 fv
->ftype
->ftype
== FT_BOOLEAN
||
1237 fv
->ftype
->ftype
== FT_EUI64
);
1238 ws_assert(fv
->ftype
->get_value
.get_value_uinteger64
);
1239 return fv
->ftype
->get_value
.get_value_uinteger64(fv
);
1243 fvalue_get_sinteger64(fvalue_t
*fv
)
1245 ws_assert(fv
->ftype
->ftype
== FT_INT40
||
1246 fv
->ftype
->ftype
== FT_INT48
||
1247 fv
->ftype
->ftype
== FT_INT56
||
1248 fv
->ftype
->ftype
== FT_INT64
);
1249 ws_assert(fv
->ftype
->get_value
.get_value_sinteger64
);
1250 return fv
->ftype
->get_value
.get_value_sinteger64(fv
);
1254 fvalue_get_floating(fvalue_t
*fv
)
1256 ws_assert(fv
->ftype
->ftype
== FT_FLOAT
||
1257 fv
->ftype
->ftype
== FT_DOUBLE
);
1258 ws_assert(fv
->ftype
->get_value
.get_value_floating
);
1259 return fv
->ftype
->get_value
.get_value_floating(fv
);
1262 const ipv4_addr_and_mask
*
1263 fvalue_get_ipv4(fvalue_t
*fv
)
1265 ws_assert(fv
->ftype
->ftype
== FT_IPv4
);
1266 ws_assert(fv
->ftype
->get_value
.get_value_ipv4
);
1267 return fv
->ftype
->get_value
.get_value_ipv4(fv
);
1270 const ipv6_addr_and_prefix
*
1271 fvalue_get_ipv6(fvalue_t
*fv
)
1273 ws_assert(fv
->ftype
->ftype
== FT_IPv6
);
1274 ws_assert(fv
->ftype
->get_value
.get_value_ipv6
);
1275 return fv
->ftype
->get_value
.get_value_ipv6(fv
);
1279 fvalue_eq(const fvalue_t
*a
, const fvalue_t
*b
)
1284 ws_assert(a
->ftype
->compare
);
1285 res
= a
->ftype
->compare(a
, b
, &cmp
);
1288 return cmp
== 0 ? FT_TRUE
: FT_FALSE
;
1292 fvalue_ne(const fvalue_t
*a
, const fvalue_t
*b
)
1297 ws_assert(a
->ftype
->compare
);
1298 res
= a
->ftype
->compare(a
, b
, &cmp
);
1301 return cmp
!= 0 ? FT_TRUE
: FT_FALSE
;
1305 fvalue_gt(const fvalue_t
*a
, const fvalue_t
*b
)
1310 ws_assert(a
->ftype
->compare
);
1311 res
= a
->ftype
->compare(a
, b
, &cmp
);
1314 return cmp
> 0 ? FT_TRUE
: FT_FALSE
;
1318 fvalue_ge(const fvalue_t
*a
, const fvalue_t
*b
)
1323 ws_assert(a
->ftype
->compare
);
1324 res
= a
->ftype
->compare(a
, b
, &cmp
);
1327 return cmp
>= 0 ? FT_TRUE
: FT_FALSE
;
1331 fvalue_lt(const fvalue_t
*a
, const fvalue_t
*b
)
1336 ws_assert(a
->ftype
->compare
);
1337 res
= a
->ftype
->compare(a
, b
, &cmp
);
1340 return cmp
< 0 ? FT_TRUE
: FT_FALSE
;
1344 fvalue_le(const fvalue_t
*a
, const fvalue_t
*b
)
1349 ws_assert(a
->ftype
->compare
);
1350 res
= a
->ftype
->compare(a
, b
, &cmp
);
1353 return cmp
<= 0 ? FT_TRUE
: FT_FALSE
;
1357 fvalue_contains(const fvalue_t
*a
, const fvalue_t
*b
)
1362 ws_assert(a
->ftype
->contains
);
1363 res
= a
->ftype
->contains(a
, b
, &yes
);
1366 return yes
? FT_TRUE
: FT_FALSE
;
1370 fvalue_matches(const fvalue_t
*a
, const ws_regex_t
*re
)
1375 ws_assert(a
->ftype
->matches
);
1376 res
= a
->ftype
->matches(a
, re
, &yes
);
1379 return yes
? FT_TRUE
: FT_FALSE
;
1383 fvalue_is_zero(const fvalue_t
*a
)
1385 return a
->ftype
->is_zero(a
) ? FT_TRUE
: FT_FALSE
;
1389 fvalue_is_negative(const fvalue_t
*a
)
1391 return a
->ftype
->is_negative(a
) ? FT_TRUE
: FT_FALSE
;
1395 _fvalue_binop(FvalueBinaryOp op
, const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1399 result
= fvalue_new(a
->ftype
->ftype
);
1400 if (op(result
, a
, b
, err_msg
) != FT_OK
) {
1401 fvalue_free(result
);
1408 fvalue_bitwise_and(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1410 /* XXX - check compatibility of a and b */
1411 ws_assert(a
->ftype
->bitwise_and
);
1412 return _fvalue_binop(a
->ftype
->bitwise_and
, a
, b
, err_msg
);
1416 fvalue_add(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1418 /* XXX - check compatibility of a and b */
1419 ws_assert(a
->ftype
->add
);
1420 return _fvalue_binop(a
->ftype
->add
, a
, b
, err_msg
);
1424 fvalue_subtract(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1426 /* XXX - check compatibility of a and b */
1427 ws_assert(a
->ftype
->subtract
);
1428 return _fvalue_binop(a
->ftype
->subtract
, a
, b
, err_msg
);
1432 fvalue_multiply(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1434 /* XXX - check compatibility of a and b */
1435 ws_assert(a
->ftype
->multiply
);
1436 return _fvalue_binop(a
->ftype
->multiply
, a
, b
, err_msg
);
1440 fvalue_divide(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1442 /* XXX - check compatibility of a and b */
1443 ws_assert(a
->ftype
->divide
);
1444 return _fvalue_binop(a
->ftype
->divide
, a
, b
, err_msg
);
1448 fvalue_modulo(const fvalue_t
*a
, const fvalue_t
*b
, char **err_msg
)
1450 /* XXX - check compatibility of a and b */
1451 ws_assert(a
->ftype
->modulo
);
1452 return _fvalue_binop(a
->ftype
->modulo
, a
, b
, err_msg
);
1456 fvalue_unary_minus(const fvalue_t
*fv
, char **err_msg
)
1460 ws_assert(fv
->ftype
->unary_minus
);
1462 result
= fvalue_new(fv
->ftype
->ftype
);
1463 if (fv
->ftype
->unary_minus(result
, fv
, err_msg
) != FT_OK
) {
1464 fvalue_free(result
);
1471 fvalue_hash(const fvalue_t
*fv
)
1473 ws_assert(fv
->ftype
->hash
);
1474 return fv
->ftype
->hash(fv
);
1478 fvalue_equal(const fvalue_t
*a
, const fvalue_t
*b
)
1480 return fvalue_eq(a
, b
) == FT_TRUE
;
1484 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1489 * indent-tabs-mode: t
1492 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1493 * :indentSize=8:tabSize=8:noTabs=false: