epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / ftypes / ftypes.c
blob7427556de0a92fcf126fab59013c51a4dc56f256
1 /*
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
7 */
9 #include "config.h"
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. */
19 void
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();
35 void
36 ftypes_register_pseudofields(void)
38 static int proto_ftypes;
40 proto_ftypes = proto_register_protocol(
41 "Wireshark Field/Fundamental Types",
42 "Wireshark FTypes",
43 "_ws.ftypes");
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 */
61 void
62 ftype_register(enum ftenum ftype, const ftype_t *ft)
64 /* Check input */
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
85 static enum ftenum
86 same_ftype(const enum ftenum ftype)
88 switch (ftype) {
89 case FT_INT8:
90 case FT_INT16:
91 case FT_INT24:
92 case FT_INT32:
93 return FT_INT32;
95 case FT_UINT8:
96 case FT_UINT16:
97 case FT_UINT24:
98 case FT_UINT32:
99 return FT_UINT32;
101 case FT_INT40:
102 case FT_INT48:
103 case FT_INT56:
104 case FT_INT64:
105 return FT_INT64;
107 case FT_UINT40:
108 case FT_UINT48:
109 case FT_UINT56:
110 case FT_UINT64:
111 return FT_UINT64;
113 case FT_STRING:
114 case FT_STRINGZ:
115 case FT_UINT_STRING:
116 return FT_STRING;
118 case FT_FLOAT:
119 case FT_DOUBLE:
120 return FT_DOUBLE;
122 case FT_BYTES:
123 case FT_UINT_BYTES:
124 return FT_BYTES;
126 case FT_OID:
127 case FT_REL_OID:
128 return FT_OID;
130 /* XXX: the following are unique for now */
131 case FT_IPv4:
132 case FT_IPv6:
134 /* everything else is unique */
135 default:
136 return ftype;
140 /* given two types, are they similar - for example can two
141 * duplicate fields be registered of these two types. */
142 bool
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. */
150 const char*
151 ftype_name(enum ftenum ftype)
153 const ftype_t *ft;
154 const char *s = "(null)";
156 FTYPE_LOOKUP(ftype, ft);
157 switch (ft->ftype) {
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;
207 return s;
210 const char*
211 ftype_pretty_name(enum ftenum ftype)
213 const ftype_t *ft;
214 const char *s = "(null)";
216 FTYPE_LOOKUP(ftype, ft);
217 switch (ft->ftype) {
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;
267 return s;
271 ftype_wire_size(enum ftenum ftype)
273 const ftype_t *ft;
275 FTYPE_LOOKUP(ftype, ft);
276 return ft->wire_size;
279 bool
280 ftype_can_length(enum ftenum ftype)
282 const ftype_t *ft;
284 FTYPE_LOOKUP(ftype, ft);
285 return ft->len ? true : false;
288 bool
289 ftype_can_slice(enum ftenum ftype)
291 const ftype_t *ft;
293 FTYPE_LOOKUP(ftype, ft);
294 return ft->slice ? true : false;
297 bool
298 ftype_can_eq(enum ftenum ftype)
300 const ftype_t *ft;
302 FTYPE_LOOKUP(ftype, ft);
303 return ft->compare != NULL;
306 bool
307 ftype_can_cmp(enum ftenum ftype)
309 const ftype_t *ft;
311 FTYPE_LOOKUP(ftype, ft);
312 return ft->compare != NULL;
315 bool
316 ftype_can_bitwise_and(enum ftenum ftype)
318 const ftype_t *ft;
320 FTYPE_LOOKUP(ftype, ft);
321 return ft->bitwise_and ? true : false;
324 bool
325 ftype_can_unary_minus(enum ftenum ftype)
327 const ftype_t *ft;
329 FTYPE_LOOKUP(ftype, ft);
330 return ft->unary_minus != NULL;
333 bool
334 ftype_can_add(enum ftenum ftype)
336 const ftype_t *ft;
338 FTYPE_LOOKUP(ftype, ft);
339 return ft->add != NULL;
342 bool
343 ftype_can_subtract(enum ftenum ftype)
345 const ftype_t *ft;
347 FTYPE_LOOKUP(ftype, ft);
348 return ft->subtract != NULL;
351 bool
352 ftype_can_multiply(enum ftenum ftype)
354 const ftype_t *ft;
356 FTYPE_LOOKUP(ftype, ft);
357 return ft->multiply != NULL;
360 bool
361 ftype_can_divide(enum ftenum ftype)
363 const ftype_t *ft;
365 FTYPE_LOOKUP(ftype, ft);
366 return ft->divide != NULL;
369 bool
370 ftype_can_modulo(enum ftenum ftype)
372 const ftype_t *ft;
374 FTYPE_LOOKUP(ftype, ft);
375 return ft->modulo != NULL;
378 bool
379 ftype_can_contains(enum ftenum ftype)
381 const ftype_t *ft;
383 FTYPE_LOOKUP(ftype, ft);
384 return ft->contains ? true : false;
387 bool
388 ftype_can_matches(enum ftenum ftype)
390 const ftype_t *ft;
392 FTYPE_LOOKUP(ftype, ft);
393 return ft->matches ? true : false;
396 bool
397 ftype_can_is_zero(enum ftenum ftype)
399 const ftype_t *ft;
401 FTYPE_LOOKUP(ftype, ft);
402 return ft->is_zero ? true : false;
405 bool
406 ftype_can_is_negative(enum ftenum ftype)
408 const ftype_t *ft;
410 FTYPE_LOOKUP(ftype, ft);
411 return ft->is_negative ? true : false;
414 bool
415 ftype_can_val_to_sinteger(enum ftenum ftype)
417 const ftype_t *ft;
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;
424 bool
425 ftype_can_val_to_uinteger(enum ftenum ftype)
427 const ftype_t *ft;
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;
434 bool
435 ftype_can_val_to_sinteger64(enum ftenum ftype)
437 const ftype_t *ft;
439 FTYPE_LOOKUP(ftype, ft);
440 return ft->val_to_sinteger64 ? true : false;
443 bool
444 ftype_can_val_to_uinteger64(enum ftenum ftype)
446 const ftype_t *ft;
448 FTYPE_LOOKUP(ftype, ft);
449 return ft->val_to_uinteger64 ? true : false;
452 /* ---------------------------------------------------------- */
454 /* Allocate and initialize an fvalue_t, given an ftype */
455 fvalue_t*
456 fvalue_new(ftenum_t ftype)
458 fvalue_t *fv;
459 const ftype_t *ft;
460 FvalueNewFunc new_value;
462 fv = g_slice_new(fvalue_t);
464 FTYPE_LOOKUP(ftype, ft);
465 fv->ftype = ft;
467 new_value = ft->new_value;
468 if (new_value) {
469 new_value(fv);
472 return fv;
475 fvalue_t*
476 fvalue_dup(const fvalue_t *fv_orig)
478 fvalue_t *fv_new;
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) {
485 /* deep copy */
486 copy_value(fv_new, fv_orig);
488 else {
489 /* shallow copy */
490 memcpy(&fv_new->value, &fv_orig->value, sizeof(fv_orig->value));
493 return fv_new;
496 void
497 fvalue_init(fvalue_t *fv, ftenum_t ftype)
499 const ftype_t *ft;
500 FvalueNewFunc new_value;
502 FTYPE_LOOKUP(ftype, ft);
503 fv->ftype = ft;
505 new_value = ft->new_value;
506 if (new_value) {
507 new_value(fv);
511 void
512 fvalue_cleanup(fvalue_t *fv)
514 if (!fv->ftype->free_value)
515 return;
516 fv->ftype->free_value(fv);
519 void
520 fvalue_free(fvalue_t *fv)
522 fvalue_cleanup(fv);
523 g_slice_free(fvalue_t, fv);
526 fvalue_t*
527 fvalue_from_literal(ftenum_t ftype, const char *s, bool allow_partial_value, char **err_msg)
529 fvalue_t *fv;
530 bool ok = false;
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);
535 if (ok) {
536 /* Success */
537 if (err_msg != NULL)
538 *err_msg = NULL;
539 return fv;
542 else {
543 if (err_msg != NULL) {
544 *err_msg = ws_strdup_printf("\"%s\" cannot be converted to %s.",
545 s, ftype_pretty_name(ftype));
548 fvalue_free(fv);
549 return NULL;
552 fvalue_t*
553 fvalue_from_string(ftenum_t ftype, const char *str, size_t len, char **err_msg)
555 fvalue_t *fv;
557 fv = fvalue_new(ftype);
558 if (fv->ftype->val_from_string) {
559 if (fv->ftype->val_from_string(fv, str, len, err_msg)) {
560 /* Success */
561 if (err_msg != NULL)
562 *err_msg = NULL;
563 return fv;
566 else {
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);
572 fvalue_free(fv);
573 return NULL;
576 fvalue_t*
577 fvalue_from_charconst(ftenum_t ftype, unsigned long num, char **err_msg)
579 fvalue_t *fv;
581 fv = fvalue_new(ftype);
582 if (fv->ftype->val_from_charconst) {
583 if (fv->ftype->val_from_charconst(fv, num, err_msg)) {
584 /* Success */
585 if (err_msg != NULL)
586 *err_msg = NULL;
587 return fv;
590 else {
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));
596 else {
597 *err_msg = ws_strdup_printf("Character constant 0x%lx cannot be converted to %s.",
598 num, ftype_pretty_name(ftype));
602 fvalue_free(fv);
603 return NULL;
606 fvalue_t*
607 fvalue_from_sinteger64(ftenum_t ftype, const char *s, int64_t num, char **err_msg)
609 fvalue_t *fv;
611 fv = fvalue_new(ftype);
612 if (fv->ftype->val_from_sinteger64) {
613 if (fv->ftype->val_from_sinteger64(fv, s, num, err_msg)) {
614 /* Success */
615 if (err_msg != NULL)
616 *err_msg = NULL;
617 return fv;
620 else {
621 if (err_msg != NULL) {
622 *err_msg = ws_strdup_printf("Integer %"PRId64" cannot be converted to %s.",
623 num, ftype_pretty_name(ftype));
626 fvalue_free(fv);
627 return NULL;
630 fvalue_t*
631 fvalue_from_uinteger64(ftenum_t ftype, const char *s, uint64_t num, char **err_msg)
633 fvalue_t *fv;
635 fv = fvalue_new(ftype);
636 if (fv->ftype->val_from_uinteger64) {
637 if (fv->ftype->val_from_uinteger64(fv, s, num, err_msg)) {
638 /* Success */
639 if (err_msg != NULL)
640 *err_msg = NULL;
641 return fv;
644 else {
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));
650 fvalue_free(fv);
651 return NULL;
654 fvalue_t*
655 fvalue_from_floating(ftenum_t ftype, const char *s, double num, char **err_msg)
657 fvalue_t *fv;
659 fv = fvalue_new(ftype);
660 if (fv->ftype->val_from_double) {
661 if (fv->ftype->val_from_double(fv, s, num, err_msg)) {
662 /* Success */
663 if (err_msg != NULL)
664 *err_msg = NULL;
665 return fv;
668 else {
669 if (err_msg != NULL) {
670 *err_msg = ws_strdup_printf("Double %g cannot be converted to %s.",
671 num, ftype_pretty_name(ftype));
674 fvalue_free(fv);
675 return NULL;
678 ftenum_t
679 fvalue_type_ftenum(const fvalue_t *fv)
681 return fv->ftype->ftype;
684 const char*
685 fvalue_type_name(const fvalue_t *fv)
687 return ftype_name(fv->ftype->ftype);
691 size_t
692 fvalue_length2(fvalue_t *fv)
694 if (!fv->ftype->len) {
695 ws_critical("fv->ftype->len is NULL");
696 return 0;
698 return fv->ftype->len(fv);
701 char *
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 */
706 return NULL;
709 return fv->ftype->val_to_string_repr(scope, fv, rtype, field_display);
712 enum ft_result
713 fvalue_to_uinteger(const fvalue_t *fv, uint32_t *repr)
715 uint64_t val;
716 enum ft_result res = fv->ftype->val_to_uinteger64(fv, &val);
717 if (res != FT_OK)
718 return res;
719 if (val > UINT32_MAX)
720 return FT_OVERFLOW;
722 *repr = (uint32_t)val;
723 return FT_OK;
726 enum ft_result
727 fvalue_to_sinteger(const fvalue_t *fv, int32_t *repr)
729 int64_t val;
730 enum ft_result res = fv->ftype->val_to_sinteger64(fv, &val);
731 if (res != FT_OK)
732 return res;
733 if (val > INT32_MAX)
734 return FT_OVERFLOW;
736 *repr = (int32_t)val;
737 return FT_OK;
740 enum ft_result
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);
747 enum ft_result
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);
754 enum ft_result
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);
761 typedef struct {
762 fvalue_t *fv;
763 void *ptr;
764 bool slice_failure;
765 } slice_data_t;
767 static bool
768 compute_drnode(size_t field_length, drange_node *drnode, size_t *offset_ptr, size_t *length_ptr)
770 ssize_t start_offset;
771 ssize_t length = 0;
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) {
782 return false;
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;
790 if (length <= 0) {
791 return false;
794 else if (ending == DRANGE_NODE_END_T_LENGTH) {
795 length = drange_node_get_length(drnode);
796 if (start_offset + length > (int) field_length) {
797 return false;
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) {
805 return false;
807 } else if (end_offset >= (int) field_length) {
808 return false;
810 length = end_offset - start_offset + 1;
812 else {
813 ws_assert_not_reached();
816 *offset_ptr = start_offset;
817 *length_ptr = length;
818 return true;
821 static void
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;
826 size_t start_offset;
827 size_t length = 0;
828 fvalue_t *fv;
830 if (slice_data->slice_failure) {
831 return;
834 fv = slice_data->fv;
835 if (!compute_drnode((unsigned)fvalue_length2(fv), drnode, &start_offset, &length)) {
836 slice_data->slice_failure = true;
837 return;
840 ws_assert(length > 0);
841 fv->ftype->slice(fv, slice_data->ptr, (unsigned)start_offset, (unsigned)length);
844 static fvalue_t *
845 slice_string(fvalue_t *fv, drange_t *d_range)
847 slice_data_t slice_data;
848 fvalue_t *new_fv;
850 slice_data.fv = fv;
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);
863 return new_fv;
866 static fvalue_t *
867 slice_bytes(fvalue_t *fv, drange_t *d_range)
869 slice_data_t slice_data;
870 fvalue_t *new_fv;
872 slice_data.fv = fv;
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);
885 return new_fv;
888 /* Returns a new slice fvalue_t* if possible, otherwise NULL */
889 fvalue_t*
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);
898 void
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);
913 void
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);
921 void
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);
929 void
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);
937 void
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;
949 if (ssid != 0) {
950 wmem_strbuf_append_printf(buf, "-%u", ssid);
952 fvalue_set_strbuf(fv, buf);
955 void
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);
963 void
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);
971 void
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);
979 void
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);
987 void
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);
994 void
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);
1006 void
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);
1014 void
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;
1022 void
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);
1038 void
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);
1049 void
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);
1062 void
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);
1073 void
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);
1082 void
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);
1090 void
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);
1098 GBytes *
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);
1114 size_t
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);
1120 return size;
1123 const void *
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);
1129 return data;
1132 const e_guid_t *
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);
1140 const nstime_t *
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);
1148 const char *
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);
1162 tvbuff_t *
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);
1170 uint32_t
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);
1186 int32_t
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);
1197 uint64_t
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);
1210 int64_t
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);
1221 double
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);
1246 ft_bool_t
1247 fvalue_eq(const fvalue_t *a, const fvalue_t *b)
1249 int cmp;
1250 enum ft_result res;
1252 ws_assert(a->ftype->compare);
1253 res = a->ftype->compare(a, b, &cmp);
1254 if (res != FT_OK)
1255 return -res;
1256 return cmp == 0 ? FT_TRUE : FT_FALSE;
1259 ft_bool_t
1260 fvalue_ne(const fvalue_t *a, const fvalue_t *b)
1262 int cmp;
1263 enum ft_result res;
1265 ws_assert(a->ftype->compare);
1266 res = a->ftype->compare(a, b, &cmp);
1267 if (res != FT_OK)
1268 return -res;
1269 return cmp != 0 ? FT_TRUE : FT_FALSE;
1272 ft_bool_t
1273 fvalue_gt(const fvalue_t *a, const fvalue_t *b)
1275 int cmp;
1276 enum ft_result res;
1278 ws_assert(a->ftype->compare);
1279 res = a->ftype->compare(a, b, &cmp);
1280 if (res != FT_OK)
1281 return -res;
1282 return cmp > 0 ? FT_TRUE : FT_FALSE;
1285 ft_bool_t
1286 fvalue_ge(const fvalue_t *a, const fvalue_t *b)
1288 int cmp;
1289 enum ft_result res;
1291 ws_assert(a->ftype->compare);
1292 res = a->ftype->compare(a, b, &cmp);
1293 if (res != FT_OK)
1294 return -res;
1295 return cmp >= 0 ? FT_TRUE : FT_FALSE;
1298 ft_bool_t
1299 fvalue_lt(const fvalue_t *a, const fvalue_t *b)
1301 int cmp;
1302 enum ft_result res;
1304 ws_assert(a->ftype->compare);
1305 res = a->ftype->compare(a, b, &cmp);
1306 if (res != FT_OK)
1307 return -res;
1308 return cmp < 0 ? FT_TRUE : FT_FALSE;
1311 ft_bool_t
1312 fvalue_le(const fvalue_t *a, const fvalue_t *b)
1314 int cmp;
1315 enum ft_result res;
1317 ws_assert(a->ftype->compare);
1318 res = a->ftype->compare(a, b, &cmp);
1319 if (res != FT_OK)
1320 return -res;
1321 return cmp <= 0 ? FT_TRUE : FT_FALSE;
1324 ft_bool_t
1325 fvalue_contains(const fvalue_t *a, const fvalue_t *b)
1327 bool yes;
1328 enum ft_result res;
1330 ws_assert(a->ftype->contains);
1331 res = a->ftype->contains(a, b, &yes);
1332 if (res != FT_OK)
1333 return -res;
1334 return yes ? FT_TRUE : FT_FALSE;
1337 ft_bool_t
1338 fvalue_matches(const fvalue_t *a, const ws_regex_t *re)
1340 bool yes;
1341 enum ft_result res;
1343 ws_assert(a->ftype->matches);
1344 res = a->ftype->matches(a, re, &yes);
1345 if (res != FT_OK)
1346 return -res;
1347 return yes ? FT_TRUE : FT_FALSE;
1350 bool
1351 fvalue_is_zero(const fvalue_t *a)
1353 return a->ftype->is_zero(a);
1356 bool
1357 fvalue_is_negative(const fvalue_t *a)
1359 return a->ftype->is_negative(a);
1362 static fvalue_t *
1363 _fvalue_binop(FvalueBinaryOp op, const fvalue_t *a, const fvalue_t *b, char **err_msg)
1365 fvalue_t *result;
1367 result = fvalue_new(a->ftype->ftype);
1368 if (op(result, a, b, err_msg) != FT_OK) {
1369 fvalue_free(result);
1370 return NULL;
1372 return result;
1375 fvalue_t *
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);
1383 fvalue_t *
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);
1391 fvalue_t *
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);
1399 fvalue_t *
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);
1407 fvalue_t *
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);
1415 fvalue_t *
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);
1423 fvalue_t*
1424 fvalue_unary_minus(const fvalue_t *fv, char **err_msg)
1426 fvalue_t *result;
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);
1433 return NULL;
1435 return result;
1438 unsigned
1439 fvalue_hash(const fvalue_t *fv)
1441 ws_assert(fv->ftype->hash);
1442 return fv->ftype->hash(fv);
1445 bool
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
1454 * Local variables:
1455 * c-basic-offset: 8
1456 * tab-width: 8
1457 * indent-tabs-mode: t
1458 * End:
1460 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1461 * :indentSize=8:tabSize=8:noTabs=false: