1 /*
2 * Wireshark - Network traffic analyzer
3 * By Gerald Combs <gerald@wireshark.org>
4 * Copyright 2001 Gerald Combs
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9 #include "config.h"
10
11 #include <ftypes-int.h>
12 #include <glib.h>
13
14 #include "ftypes.h"
15 #include <wsutil/ws_assert.h>
16
17 /* Keep track of ftype_t's via their ftenum number */
18 static ftype_t* type_list[FT_NUM_TYPES];
19
20 /* Initialize the ftype module. */
21 void
ftypes_initialize(void)22 ftypes_initialize(void)
23 {
24 ftype_register_bytes();
25 ftype_register_double();
26 ftype_register_ieee_11073_float();
27 ftype_register_integers();
28 ftype_register_ipv4();
29 ftype_register_ipv6();
30 ftype_register_guid();
31 ftype_register_none();
32 ftype_register_string();
33 ftype_register_time();
34 ftype_register_tvbuff();
35 }
36
37 /* Each ftype_t is registered via this function */
38 void
ftype_register(enum ftenum ftype,ftype_t * ft)39 ftype_register(enum ftenum ftype, ftype_t *ft)
40 {
41 /* Check input */
42 ws_assert(ftype < FT_NUM_TYPES);
43 ws_assert(ftype == ft->ftype);
44
45 /* Don't re-register. */
46 ws_assert(type_list[ftype] == NULL);
47
48 type_list[ftype] = ft;
49 }
50
51 /* Given an ftenum number, return an ftype_t* */
52 #define FTYPE_LOOKUP(ftype, result) \
53 /* Check input */ \
54 ws_assert(ftype < FT_NUM_TYPES); \
55 result = type_list[ftype];
56
57
58
59 /* from README.dissector:
60 Note that the formats used must all belong to the same list as defined below:
61 - FT_INT8, FT_INT16, FT_INT24 and FT_INT32
62 - FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, FT_IPXNET and FT_FRAMENUM
63 - FT_UINT64 and FT_EUI64
64 - FT_STRING, FT_STRINGZ and FT_UINT_STRING
65 - FT_FLOAT and FT_DOUBLE
66 - FT_BYTES, FT_UINT_BYTES, FT_AX25, FT_ETHER, FT_VINES, FT_OID and FT_REL_OID
67 - FT_ABSOLUTE_TIME and FT_RELATIVE_TIME
68 */
69 static enum ftenum
same_ftype(const enum ftenum ftype)70 same_ftype(const enum ftenum ftype)
71 {
72 switch (ftype) {
73 case FT_INT8:
74 case FT_INT16:
75 case FT_INT24:
76 case FT_INT32:
77 return FT_INT32;
78
79 case FT_UINT8:
80 case FT_UINT16:
81 case FT_UINT24:
82 case FT_UINT32:
83 return FT_UINT32;
84
85 case FT_INT40:
86 case FT_INT48:
87 case FT_INT56:
88 case FT_INT64:
89 return FT_INT64;
90
91 case FT_UINT40:
92 case FT_UINT48:
93 case FT_UINT56:
94 case FT_UINT64:
95 return FT_UINT64;
96
97 case FT_STRING:
98 case FT_STRINGZ:
99 case FT_UINT_STRING:
100 return FT_STRING;
101
102 case FT_FLOAT:
103 case FT_DOUBLE:
104 return FT_DOUBLE;
105
106 case FT_BYTES:
107 case FT_UINT_BYTES:
108 return FT_BYTES;
109
110 case FT_OID:
111 case FT_REL_OID:
112 return FT_OID;
113
114 /* XXX: the folowing are unique for now */
115 case FT_IPv4:
116 case FT_IPv6:
117
118 /* everything else is unique */
119 default:
120 return ftype;
121 }
122 }
123
124 /* given two types, are they similar - for example can two
125 * duplicate fields be registered of these two types. */
126 gboolean
ftype_similar_types(const enum ftenum ftype_a,const enum ftenum ftype_b)127 ftype_similar_types(const enum ftenum ftype_a, const enum ftenum ftype_b)
128 {
129 return (same_ftype(ftype_a) == same_ftype(ftype_b));
130 }
131
132 /* Returns a string representing the name of the type. Useful
133 * for glossary production. */
134 const char*
ftype_name(enum ftenum ftype)135 ftype_name(enum ftenum ftype)
136 {
137 ftype_t *ft;
138
139 FTYPE_LOOKUP(ftype, ft);
140 return ft->name;
141 }
142
143 const char*
ftype_pretty_name(enum ftenum ftype)144 ftype_pretty_name(enum ftenum ftype)
145 {
146 ftype_t *ft;
147
148 FTYPE_LOOKUP(ftype, ft);
149 return ft->pretty_name;
150 }
151
152 int
ftype_length(enum ftenum ftype)153 ftype_length(enum ftenum ftype)
154 {
155 ftype_t *ft;
156
157 FTYPE_LOOKUP(ftype, ft);
158 return ft->wire_size;
159 }
160
161 gboolean
ftype_can_slice(enum ftenum ftype)162 ftype_can_slice(enum ftenum ftype)
163 {
164 ftype_t *ft;
165
166 FTYPE_LOOKUP(ftype, ft);
167 return ft->slice ? TRUE : FALSE;
168 }
169
170 gboolean
ftype_can_eq(enum ftenum ftype)171 ftype_can_eq(enum ftenum ftype)
172 {
173 ftype_t *ft;
174
175 FTYPE_LOOKUP(ftype, ft);
176 return ft->cmp_eq ? TRUE : FALSE;
177 }
178
179 gboolean
ftype_can_ne(enum ftenum ftype)180 ftype_can_ne(enum ftenum ftype)
181 {
182 ftype_t *ft;
183
184 FTYPE_LOOKUP(ftype, ft);
185 return ft->cmp_ne ? TRUE : FALSE;
186 }
187
188 gboolean
ftype_can_gt(enum ftenum ftype)189 ftype_can_gt(enum ftenum ftype)
190 {
191 ftype_t *ft;
192
193 FTYPE_LOOKUP(ftype, ft);
194 return ft->cmp_gt ? TRUE : FALSE;
195 }
196
197 gboolean
ftype_can_ge(enum ftenum ftype)198 ftype_can_ge(enum ftenum ftype)
199 {
200 ftype_t *ft;
201
202 FTYPE_LOOKUP(ftype, ft);
203 return ft->cmp_ge ? TRUE : FALSE;
204 }
205
206 gboolean
ftype_can_lt(enum ftenum ftype)207 ftype_can_lt(enum ftenum ftype)
208 {
209 ftype_t *ft;
210
211 FTYPE_LOOKUP(ftype, ft);
212 return ft->cmp_lt ? TRUE : FALSE;
213 }
214
215 gboolean
ftype_can_le(enum ftenum ftype)216 ftype_can_le(enum ftenum ftype)
217 {
218 ftype_t *ft;
219
220 FTYPE_LOOKUP(ftype, ft);
221 return ft->cmp_le ? TRUE : FALSE;
222 }
223
224 gboolean
ftype_can_bitwise_and(enum ftenum ftype)225 ftype_can_bitwise_and(enum ftenum ftype)
226 {
227 ftype_t *ft;
228
229 FTYPE_LOOKUP(ftype, ft);
230 return ft->cmp_bitwise_and ? TRUE : FALSE;
231 }
232
233 gboolean
ftype_can_contains(enum ftenum ftype)234 ftype_can_contains(enum ftenum ftype)
235 {
236 ftype_t *ft;
237
238 FTYPE_LOOKUP(ftype, ft);
239 return ft->cmp_contains ? TRUE : FALSE;
240 }
241
242 gboolean
ftype_can_matches(enum ftenum ftype)243 ftype_can_matches(enum ftenum ftype)
244 {
245 ftype_t *ft;
246
247 FTYPE_LOOKUP(ftype, ft);
248 return ft->cmp_matches ? TRUE : FALSE;
249 }
250
251 /* ---------------------------------------------------------- */
252
253 /* Allocate and initialize an fvalue_t, given an ftype */
254 fvalue_t*
fvalue_new(ftenum_t ftype)255 fvalue_new(ftenum_t ftype)
256 {
257 fvalue_t *fv;
258 ftype_t *ft;
259 FvalueNewFunc new_value;
260
261 fv = g_slice_new(fvalue_t);
262
263 FTYPE_LOOKUP(ftype, ft);
264 fv->ftype = ft;
265
266 new_value = ft->new_value;
267 if (new_value) {
268 new_value(fv);
269 }
270
271 return fv;
272 }
273
274 void
fvalue_init(fvalue_t * fv,ftenum_t ftype)275 fvalue_init(fvalue_t *fv, ftenum_t ftype)
276 {
277 ftype_t *ft;
278 FvalueNewFunc new_value;
279
280 FTYPE_LOOKUP(ftype, ft);
281 fv->ftype = ft;
282
283 new_value = ft->new_value;
284 if (new_value) {
285 new_value(fv);
286 }
287 }
288
289 fvalue_t*
fvalue_from_unparsed(ftenum_t ftype,const char * s,gboolean allow_partial_value,gchar ** err_msg)290 fvalue_from_unparsed(ftenum_t ftype, const char *s, gboolean allow_partial_value, gchar **err_msg)
291 {
292 fvalue_t *fv;
293
294 fv = fvalue_new(ftype);
295 if (fv->ftype->val_from_unparsed) {
296 if (fv->ftype->val_from_unparsed(fv, s, allow_partial_value, err_msg)) {
297 /* Success */
298 if (err_msg != NULL)
299 *err_msg = NULL;
300 return fv;
301 }
302 }
303 else {
304 if (err_msg != NULL) {
305 *err_msg = g_strdup_printf("\"%s\" cannot be converted to %s.",
306 s, ftype_pretty_name(ftype));
307 }
308 }
309 FVALUE_FREE(fv);
310 return NULL;
311 }
312
313 fvalue_t*
fvalue_from_string(ftenum_t ftype,const char * s,gchar ** err_msg)314 fvalue_from_string(ftenum_t ftype, const char *s, gchar **err_msg)
315 {
316 fvalue_t *fv;
317
318 fv = fvalue_new(ftype);
319 if (fv->ftype->val_from_string) {
320 if (fv->ftype->val_from_string(fv, s, err_msg)) {
321 /* Success */
322 if (err_msg != NULL)
323 *err_msg = NULL;
324 return fv;
325 }
326 }
327 else {
328 if (err_msg != NULL) {
329 *err_msg = g_strdup_printf("\"%s\" cannot be converted to %s.",
330 s, ftype_pretty_name(ftype));
331 }
332 }
333 FVALUE_FREE(fv);
334 return NULL;
335 }
336
337 ftenum_t
fvalue_type_ftenum(fvalue_t * fv)338 fvalue_type_ftenum(fvalue_t *fv)
339 {
340 return fv->ftype->ftype;
341 }
342
343 const char*
fvalue_type_name(fvalue_t * fv)344 fvalue_type_name(fvalue_t *fv)
345 {
346 return fv->ftype->name;
347 }
348
349
350 guint
fvalue_length(fvalue_t * fv)351 fvalue_length(fvalue_t *fv)
352 {
353 if (fv->ftype->len)
354 return fv->ftype->len(fv);
355 else
356 return fv->ftype->wire_size;
357 }
358
359 int
fvalue_string_repr_len(fvalue_t * fv,ftrepr_t rtype,int field_display)360 fvalue_string_repr_len(fvalue_t *fv, ftrepr_t rtype, int field_display)
361 {
362 ws_assert(fv->ftype->len_string_repr);
363 return fv->ftype->len_string_repr(fv, rtype, field_display);
364 }
365
366 char *
fvalue_to_string_repr(wmem_allocator_t * scope,fvalue_t * fv,ftrepr_t rtype,int field_display)367 fvalue_to_string_repr(wmem_allocator_t *scope, fvalue_t *fv, ftrepr_t rtype, int field_display)
368 {
369 char *buf;
370 int len;
371 if (fv->ftype->val_to_string_repr == NULL) {
372 /* no value-to-string-representation function, so the value cannot be represented */
373 return NULL;
374 }
375
376 if ((len = fvalue_string_repr_len(fv, rtype, field_display)) >= 0) {
377 buf = (char *)wmem_alloc0(scope, len + 1);
378 } else {
379 /* the value cannot be represented in the given representation type (rtype) */
380 return NULL;
381 }
382
383 fv->ftype->val_to_string_repr(fv, rtype, field_display, buf, (unsigned int)len+1);
384 return buf;
385 }
386
387 typedef struct {
388 fvalue_t *fv;
389 GByteArray *bytes;
390 gboolean slice_failure;
391 } slice_data_t;
392
393 static void
slice_func(gpointer data,gpointer user_data)394 slice_func(gpointer data, gpointer user_data)
395 {
396 drange_node *drnode = (drange_node *)data;
397 slice_data_t *slice_data = (slice_data_t *)user_data;
398 gint start_offset;
399 gint length = 0;
400 gint end_offset = 0;
401 guint field_length;
402 fvalue_t *fv;
403 drange_node_end_t ending;
404
405 if (slice_data->slice_failure) {
406 return;
407 }
408
409 start_offset = drange_node_get_start_offset(drnode);
410 ending = drange_node_get_ending(drnode);
411
412 fv = slice_data->fv;
413 field_length = fvalue_length(fv);
414
415 /* Check for negative start */
416 if (start_offset < 0) {
417 start_offset = field_length + start_offset;
418 if (start_offset < 0) {
419 slice_data->slice_failure = TRUE;
420 return;
421 }
422 }
423
424 /* Check the end type and set the length */
425
426 if (ending == DRANGE_NODE_END_T_TO_THE_END) {
427 length = field_length - start_offset;
428 if (length <= 0) {
429 slice_data->slice_failure = TRUE;
430 return;
431 }
432 }
433 else if (ending == DRANGE_NODE_END_T_LENGTH) {
434 length = drange_node_get_length(drnode);
435 if (start_offset + length > (int) field_length) {
436 slice_data->slice_failure = TRUE;
437 return;
438 }
439 }
440 else if (ending == DRANGE_NODE_END_T_OFFSET) {
441 end_offset = drange_node_get_end_offset(drnode);
442 if (end_offset < 0) {
443 end_offset = field_length + end_offset;
444 if (end_offset < start_offset) {
445 slice_data->slice_failure = TRUE;
446 return;
447 }
448 } else if (end_offset >= (int) field_length) {
449 slice_data->slice_failure = TRUE;
450 return;
451 }
452 length = end_offset - start_offset + 1;
453 }
454 else {
455 ws_assert_not_reached();
456 }
457
458 ws_assert(start_offset >=0 && length > 0);
459 fv->ftype->slice(fv, slice_data->bytes, start_offset, length);
460 }
461
462
463 /* Returns a new FT_BYTES fvalue_t* if possible, otherwise NULL */
464 fvalue_t*
fvalue_slice(fvalue_t * fv,drange_t * d_range)465 fvalue_slice(fvalue_t *fv, drange_t *d_range)
466 {
467 slice_data_t slice_data;
468 fvalue_t *new_fv;
469
470 slice_data.fv = fv;
471 slice_data.bytes = g_byte_array_new();
472 slice_data.slice_failure = FALSE;
473
474 /* XXX - We could make some optimizations here based on
475 * drange_has_total_length() and
476 * drange_get_max_offset().
477 */
478
479 drange_foreach_drange_node(d_range, slice_func, &slice_data);
480
481 new_fv = fvalue_new(FT_BYTES);
482 fvalue_set_byte_array(new_fv, slice_data.bytes);
483 return new_fv;
484 }
485
486
487 void
fvalue_set_byte_array(fvalue_t * fv,GByteArray * value)488 fvalue_set_byte_array(fvalue_t *fv, GByteArray *value)
489 {
490 ws_assert(fv->ftype->ftype == FT_BYTES ||
491 fv->ftype->ftype == FT_UINT_BYTES ||
492 fv->ftype->ftype == FT_OID ||
493 fv->ftype->ftype == FT_REL_OID ||
494 fv->ftype->ftype == FT_SYSTEM_ID);
495 ws_assert(fv->ftype->set_value.set_value_byte_array);
496 fv->ftype->set_value.set_value_byte_array(fv, value);
497 }
498
499 void
fvalue_set_bytes(fvalue_t * fv,const guint8 * value)500 fvalue_set_bytes(fvalue_t *fv, const guint8 *value)
501 {
502 ws_assert(fv->ftype->ftype == FT_AX25 ||
503 fv->ftype->ftype == FT_VINES ||
504 fv->ftype->ftype == FT_ETHER ||
505 fv->ftype->ftype == FT_FCWWN ||
506 fv->ftype->ftype == FT_IPv6);
507 ws_assert(fv->ftype->set_value.set_value_bytes);
508 fv->ftype->set_value.set_value_bytes(fv, value);
509 }
510
511 void
fvalue_set_guid(fvalue_t * fv,const e_guid_t * value)512 fvalue_set_guid(fvalue_t *fv, const e_guid_t *value)
513 {
514 ws_assert(fv->ftype->ftype == FT_GUID);
515 ws_assert(fv->ftype->set_value.set_value_guid);
516 fv->ftype->set_value.set_value_guid(fv, value);
517 }
518
519 void
fvalue_set_time(fvalue_t * fv,const nstime_t * value)520 fvalue_set_time(fvalue_t *fv, const nstime_t *value)
521 {
522 ws_assert(IS_FT_TIME(fv->ftype->ftype));
523 ws_assert(fv->ftype->set_value.set_value_time);
524 fv->ftype->set_value.set_value_time(fv, value);
525 }
526
527 void
fvalue_set_string(fvalue_t * fv,const gchar * value)528 fvalue_set_string(fvalue_t *fv, const gchar *value)
529 {
530 ws_assert(IS_FT_STRING(fv->ftype->ftype) ||
531 fv->ftype->ftype == FT_UINT_STRING);
532 ws_assert(fv->ftype->set_value.set_value_string);
533 fv->ftype->set_value.set_value_string(fv, value);
534 }
535
536 void
fvalue_set_protocol(fvalue_t * fv,tvbuff_t * value,const gchar * name)537 fvalue_set_protocol(fvalue_t *fv, tvbuff_t *value, const gchar *name)
538 {
539 ws_assert(fv->ftype->ftype == FT_PROTOCOL);
540 ws_assert(fv->ftype->set_value.set_value_protocol);
541 fv->ftype->set_value.set_value_protocol(fv, value, name);
542 }
543
544 void
fvalue_set_uinteger(fvalue_t * fv,guint32 value)545 fvalue_set_uinteger(fvalue_t *fv, guint32 value)
546 {
547 ws_assert(fv->ftype->ftype == FT_IEEE_11073_SFLOAT ||
548 fv->ftype->ftype == FT_IEEE_11073_FLOAT ||
549 fv->ftype->ftype == FT_CHAR ||
550 fv->ftype->ftype == FT_UINT8 ||
551 fv->ftype->ftype == FT_UINT16 ||
552 fv->ftype->ftype == FT_UINT24 ||
553 fv->ftype->ftype == FT_UINT32 ||
554 fv->ftype->ftype == FT_IPXNET ||
555 fv->ftype->ftype == FT_FRAMENUM ||
556 fv->ftype->ftype == FT_IPv4);
557 ws_assert(fv->ftype->set_value.set_value_uinteger);
558 fv->ftype->set_value.set_value_uinteger(fv, value);
559 }
560
561 void
fvalue_set_sinteger(fvalue_t * fv,gint32 value)562 fvalue_set_sinteger(fvalue_t *fv, gint32 value)
563 {
564 ws_assert(fv->ftype->ftype == FT_INT8 ||
565 fv->ftype->ftype == FT_INT16 ||
566 fv->ftype->ftype == FT_INT24 ||
567 fv->ftype->ftype == FT_INT32);
568 ws_assert(fv->ftype->set_value.set_value_sinteger);
569 fv->ftype->set_value.set_value_sinteger(fv, value);
570 }
571
572 void
fvalue_set_uinteger64(fvalue_t * fv,guint64 value)573 fvalue_set_uinteger64(fvalue_t *fv, guint64 value)
574 {
575 ws_assert(fv->ftype->ftype == FT_UINT40 ||
576 fv->ftype->ftype == FT_UINT48 ||
577 fv->ftype->ftype == FT_UINT56 ||
578 fv->ftype->ftype == FT_UINT64 ||
579 fv->ftype->ftype == FT_BOOLEAN ||
580 fv->ftype->ftype == FT_EUI64);
581 ws_assert(fv->ftype->set_value.set_value_uinteger64);
582 fv->ftype->set_value.set_value_uinteger64(fv, value);
583 }
584
585 void
fvalue_set_sinteger64(fvalue_t * fv,gint64 value)586 fvalue_set_sinteger64(fvalue_t *fv, gint64 value)
587 {
588 ws_assert(fv->ftype->ftype == FT_INT40 ||
589 fv->ftype->ftype == FT_INT48 ||
590 fv->ftype->ftype == FT_INT56 ||
591 fv->ftype->ftype == FT_INT64);
592 ws_assert(fv->ftype->set_value.set_value_sinteger64);
593 fv->ftype->set_value.set_value_sinteger64(fv, value);
594 }
595
596 void
fvalue_set_floating(fvalue_t * fv,gdouble value)597 fvalue_set_floating(fvalue_t *fv, gdouble value)
598 {
599 ws_assert(fv->ftype->ftype == FT_FLOAT ||
600 fv->ftype->ftype == FT_DOUBLE);
601 ws_assert(fv->ftype->set_value.set_value_floating);
602 fv->ftype->set_value.set_value_floating(fv, value);
603 }
604
605
606 gpointer
fvalue_get(fvalue_t * fv)607 fvalue_get(fvalue_t *fv)
608 {
609 ws_assert(fv->ftype->ftype == FT_BYTES ||
610 fv->ftype->ftype == FT_UINT_BYTES ||
611 fv->ftype->ftype == FT_AX25 ||
612 fv->ftype->ftype == FT_VINES ||
613 fv->ftype->ftype == FT_ETHER ||
614 fv->ftype->ftype == FT_OID ||
615 fv->ftype->ftype == FT_REL_OID ||
616 fv->ftype->ftype == FT_SYSTEM_ID ||
617 fv->ftype->ftype == FT_FCWWN ||
618 fv->ftype->ftype == FT_GUID ||
619 fv->ftype->ftype == FT_IPv6 ||
620 fv->ftype->ftype == FT_PROTOCOL ||
621 IS_FT_STRING(fv->ftype->ftype) ||
622 fv->ftype->ftype == FT_UINT_STRING ||
623 IS_FT_TIME(fv->ftype->ftype));
624 ws_assert(fv->ftype->get_value.get_value_ptr);
625 return fv->ftype->get_value.get_value_ptr(fv);
626 }
627
628 guint32
fvalue_get_uinteger(fvalue_t * fv)629 fvalue_get_uinteger(fvalue_t *fv)
630 {
631 ws_assert(fv->ftype->ftype == FT_IEEE_11073_SFLOAT ||
632 fv->ftype->ftype == FT_IEEE_11073_FLOAT ||
633 fv->ftype->ftype == FT_CHAR ||
634 fv->ftype->ftype == FT_UINT8 ||
635 fv->ftype->ftype == FT_UINT16 ||
636 fv->ftype->ftype == FT_UINT24 ||
637 fv->ftype->ftype == FT_UINT32 ||
638 fv->ftype->ftype == FT_IPXNET ||
639 fv->ftype->ftype == FT_FRAMENUM ||
640 fv->ftype->ftype == FT_IPv4);
641 ws_assert(fv->ftype->get_value.get_value_uinteger);
642 return fv->ftype->get_value.get_value_uinteger(fv);
643 }
644
645 gint32
fvalue_get_sinteger(fvalue_t * fv)646 fvalue_get_sinteger(fvalue_t *fv)
647 {
648 ws_assert(fv->ftype->ftype == FT_INT8 ||
649 fv->ftype->ftype == FT_INT16 ||
650 fv->ftype->ftype == FT_INT24 ||
651 fv->ftype->ftype == FT_INT32);
652 ws_assert(fv->ftype->get_value.get_value_sinteger);
653 return fv->ftype->get_value.get_value_sinteger(fv);
654 }
655
656 guint64
fvalue_get_uinteger64(fvalue_t * fv)657 fvalue_get_uinteger64(fvalue_t *fv)
658 {
659 ws_assert(fv->ftype->ftype == FT_UINT40 ||
660 fv->ftype->ftype == FT_UINT48 ||
661 fv->ftype->ftype == FT_UINT56 ||
662 fv->ftype->ftype == FT_UINT64 ||
663 fv->ftype->ftype == FT_BOOLEAN ||
664 fv->ftype->ftype == FT_EUI64);
665 ws_assert(fv->ftype->get_value.get_value_uinteger64);
666 return fv->ftype->get_value.get_value_uinteger64(fv);
667 }
668
669 gint64
fvalue_get_sinteger64(fvalue_t * fv)670 fvalue_get_sinteger64(fvalue_t *fv)
671 {
672 ws_assert(fv->ftype->ftype == FT_INT40 ||
673 fv->ftype->ftype == FT_INT48 ||
674 fv->ftype->ftype == FT_INT56 ||
675 fv->ftype->ftype == FT_INT64);
676 ws_assert(fv->ftype->get_value.get_value_sinteger64);
677 return fv->ftype->get_value.get_value_sinteger64(fv);
678 }
679
680 double
fvalue_get_floating(fvalue_t * fv)681 fvalue_get_floating(fvalue_t *fv)
682 {
683 ws_assert(fv->ftype->ftype == FT_FLOAT ||
684 fv->ftype->ftype == FT_DOUBLE);
685 ws_assert(fv->ftype->get_value.get_value_floating);
686 return fv->ftype->get_value.get_value_floating(fv);
687 }
688
689 gboolean
fvalue_eq(const fvalue_t * a,const fvalue_t * b)690 fvalue_eq(const fvalue_t *a, const fvalue_t *b)
691 {
692 /* XXX - check compatibility of a and b */
693 ws_assert(a->ftype->cmp_eq);
694 return a->ftype->cmp_eq(a, b);
695 }
696
697 gboolean
fvalue_ne(const fvalue_t * a,const fvalue_t * b)698 fvalue_ne(const fvalue_t *a, const fvalue_t *b)
699 {
700 /* XXX - check compatibility of a and b */
701 ws_assert(a->ftype->cmp_ne);
702 return a->ftype->cmp_ne(a, b);
703 }
704
705 gboolean
fvalue_gt(const fvalue_t * a,const fvalue_t * b)706 fvalue_gt(const fvalue_t *a, const fvalue_t *b)
707 {
708 /* XXX - check compatibility of a and b */
709 ws_assert(a->ftype->cmp_gt);
710 return a->ftype->cmp_gt(a, b);
711 }
712
713 gboolean
fvalue_ge(const fvalue_t * a,const fvalue_t * b)714 fvalue_ge(const fvalue_t *a, const fvalue_t *b)
715 {
716 /* XXX - check compatibility of a and b */
717 ws_assert(a->ftype->cmp_ge);
718 return a->ftype->cmp_ge(a, b);
719 }
720
721 gboolean
fvalue_lt(const fvalue_t * a,const fvalue_t * b)722 fvalue_lt(const fvalue_t *a, const fvalue_t *b)
723 {
724 /* XXX - check compatibility of a and b */
725 ws_assert(a->ftype->cmp_lt);
726 return a->ftype->cmp_lt(a, b);
727 }
728
729 gboolean
fvalue_le(const fvalue_t * a,const fvalue_t * b)730 fvalue_le(const fvalue_t *a, const fvalue_t *b)
731 {
732 /* XXX - check compatibility of a and b */
733 ws_assert(a->ftype->cmp_le);
734 return a->ftype->cmp_le(a, b);
735 }
736
737 gboolean
fvalue_bitwise_and(const fvalue_t * a,const fvalue_t * b)738 fvalue_bitwise_and(const fvalue_t *a, const fvalue_t *b)
739 {
740 /* XXX - check compatibility of a and b */
741 ws_assert(a->ftype->cmp_bitwise_and);
742 return a->ftype->cmp_bitwise_and(a, b);
743 }
744
745 gboolean
fvalue_contains(const fvalue_t * a,const fvalue_t * b)746 fvalue_contains(const fvalue_t *a, const fvalue_t *b)
747 {
748 /* XXX - check compatibility of a and b */
749 ws_assert(a->ftype->cmp_contains);
750 return a->ftype->cmp_contains(a, b);
751 }
752
753 gboolean
fvalue_matches(const fvalue_t * a,const GRegex * b)754 fvalue_matches(const fvalue_t *a, const GRegex *b)
755 {
756 /* XXX - check compatibility of a and b */
757 ws_assert(a->ftype->cmp_matches);
758 return a->ftype->cmp_matches(a, b);
759 }
760
761 /*
762 * Editor modelines - https://www.wireshark.org/tools/modelines.html
763 *
764 * Local variables:
765 * c-basic-offset: 8
766 * tab-width: 8
767 * indent-tabs-mode: t
768 * End:
769 *
770 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
771 * :indentSize=8:tabSize=8:noTabs=false:
772 */
773