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