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 <stdlib.h>
12 #include <errno.h>
13 #include "ftypes-int.h"
14 #include <epan/addr_resolv.h>
15 #include <epan/strutil.h>
16 #include <epan/to_str.h>
17
18 #include <wsutil/pint.h>
19
20 static void
int_fvalue_new(fvalue_t * fv)21 int_fvalue_new(fvalue_t *fv)
22 {
23 fv->value.uinteger = 0;
24 }
25
26 static void
set_uinteger(fvalue_t * fv,guint32 value)27 set_uinteger(fvalue_t *fv, guint32 value)
28 {
29 fv->value.uinteger = value;
30 }
31
32 static void
set_sinteger(fvalue_t * fv,gint32 value)33 set_sinteger(fvalue_t *fv, gint32 value)
34 {
35 fv->value.sinteger = value;
36 }
37
38
39 static guint32
get_uinteger(fvalue_t * fv)40 get_uinteger(fvalue_t *fv)
41 {
42 return fv->value.uinteger;
43 }
44
45 static gint32
get_sinteger(fvalue_t * fv)46 get_sinteger(fvalue_t *fv)
47 {
48 return fv->value.sinteger;
49 }
50
51 static gboolean
parse_charconst(const char * s,unsigned long * valuep,gchar ** err_msg)52 parse_charconst(const char *s, unsigned long *valuep, gchar **err_msg)
53 {
54 const char *cp;
55 unsigned long value;
56
57 cp = s + 1; /* skip the leading ' */
58 if (*cp == '\\') {
59 /*
60 * C escape sequence.
61 * An escape sequence is an octal number \NNN,
62 * an hex number \xNN, or one of \' \" \? \\ \a \b \f \n \r
63 * \t \v that stands for the byte value of the equivalent
64 * C-escape in ASCII encoding.
65 */
66 cp++;
67 switch (*cp) {
68
69 case '\0':
70 if (err_msg != NULL)
71 *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s);
72 return FALSE;
73
74 case 'a':
75 value = '\a';
76 break;
77
78 case 'b':
79 value = '\b';
80 break;
81
82 case 'f':
83 value = '\f';
84 break;
85
86 case 'n':
87 value = '\n';
88 break;
89
90 case 'r':
91 value = '\r';
92 break;
93
94 case 't':
95 value = '\t';
96 break;
97
98 case 'v':
99 value = '\v';
100 break;
101
102 case '\'':
103 value = '\'';
104 break;
105
106 case '\\':
107 value = '\\';
108 break;
109
110 case '"':
111 value = '"';
112 break;
113
114 case 'x':
115 cp++;
116 if (*cp >= '0' && *cp <= '9')
117 value = *cp - '0';
118 else if (*cp >= 'A' && *cp <= 'F')
119 value = 10 + (*cp - 'A');
120 else if (*cp >= 'a' && *cp <= 'f')
121 value = 10 + (*cp - 'a');
122 else {
123 if (err_msg != NULL)
124 *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s);
125 return FALSE;
126 }
127 cp++;
128 if (*cp != '\'') {
129 value <<= 4;
130 if (*cp >= '0' && *cp <= '9')
131 value |= *cp - '0';
132 else if (*cp >= 'A' && *cp <= 'F')
133 value |= 10 + (*cp - 'A');
134 else if (*cp >= 'a' && *cp <= 'f')
135 value |= 10 + (*cp - 'a');
136 else {
137 if (err_msg != NULL)
138 *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s);
139 return FALSE;
140 }
141 }
142 break;
143
144 default:
145 /* Octal */
146 if (*cp >= '0' && *cp <= '7')
147 value = *cp - '0';
148 else {
149 if (err_msg != NULL)
150 *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s);
151 return FALSE;
152 }
153 if (*(cp + 1) != '\'') {
154 cp++;
155 value <<= 3;
156 if (*cp >= '0' && *cp <= '7')
157 value |= *cp - '0';
158 else {
159 if (err_msg != NULL)
160 *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s);
161 return FALSE;
162 }
163 if (*(cp + 1) != '\'') {
164 cp++;
165 value <<= 3;
166 if (*cp >= '0' && *cp <= '7')
167 value |= *cp - '0';
168 else {
169 if (err_msg != NULL)
170 *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s);
171 return FALSE;
172 }
173 }
174 }
175 if (value > 0xFF) {
176 if (err_msg != NULL)
177 *err_msg = g_strdup_printf("\"%s\" is too large to be a valid character constant.", s);
178 return FALSE;
179 }
180 }
181 } else {
182 value = *cp;
183 if (!g_ascii_isprint(value)) {
184 if (err_msg != NULL)
185 *err_msg = g_strdup_printf("Non-printable character '\\x%02lx' in character constant.", value);
186 return FALSE;
187 }
188 }
189 cp++;
190 if ((*cp != '\'') || (*(cp + 1) != '\0')){
191 if (err_msg != NULL)
192 *err_msg = g_strdup_printf("\"%s\" is too long to be a valid character constant.", s);
193 return FALSE;
194 }
195
196 *valuep = value;
197 return TRUE;
198 }
199
200 static gboolean
uint_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value _U_,gchar ** err_msg,guint32 max)201 uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg,
202 guint32 max)
203 {
204 unsigned long value;
205 char *endptr;
206
207 if (s[0] == '\'') {
208 /*
209 * Represented as a C-style character constant.
210 */
211 if (!parse_charconst(s, &value, err_msg))
212 return FALSE;
213 } else {
214 /*
215 * Try to parse it as a number.
216 */
217 if (strchr (s, '-') && strtol(s, NULL, 0) < 0) {
218 /*
219 * Probably a negative integer, but will be
220 * "converted in the obvious manner" by strtoul().
221 */
222 if (err_msg != NULL)
223 *err_msg = g_strdup_printf("\"%s\" too small for this field, minimum 0.", s);
224 return FALSE;
225 }
226
227 errno = 0;
228 value = strtoul(s, &endptr, 0);
229
230 if (errno == EINVAL || endptr == s || *endptr != '\0') {
231 /* This isn't a valid number. */
232 if (err_msg != NULL)
233 *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s);
234 return FALSE;
235 }
236 if (errno == ERANGE) {
237 if (err_msg != NULL) {
238 if (value == ULONG_MAX) {
239 *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.",
240 s);
241 }
242 else {
243 /*
244 * XXX - can "strtoul()" set errno to
245 * ERANGE without returning ULONG_MAX?
246 */
247 *err_msg = g_strdup_printf("\"%s\" is not an integer.", s);
248 }
249 }
250 return FALSE;
251 }
252 }
253
254 if (value > max) {
255 if (err_msg != NULL)
256 *err_msg = g_strdup_printf("\"%s\" too big for this field, maximum %u.", s, max);
257 return FALSE;
258 }
259
260 fv->value.uinteger = (guint32)value;
261 return TRUE;
262 }
263
264 static gboolean
uint32_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)265 uint32_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
266 {
267 return uint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXUINT32);
268 }
269
270 static gboolean
uint24_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)271 uint24_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
272 {
273 return uint_from_unparsed (fv, s, allow_partial_value, err_msg, 0xFFFFFF);
274 }
275
276 static gboolean
uint16_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)277 uint16_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
278 {
279 return uint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXUINT16);
280 }
281
282 static gboolean
uint8_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)283 uint8_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
284 {
285 return uint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXUINT8);
286 }
287
288 static gboolean
sint_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value _U_,gchar ** err_msg,gint32 max,gint32 min)289 sint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg,
290 gint32 max, gint32 min)
291 {
292 long value;
293 unsigned long charvalue;
294 char *endptr;
295
296 if (s[0] == '\'') {
297 /*
298 * Represented as a C-style character constant.
299 */
300 if (!parse_charconst(s, &charvalue, err_msg))
301 return FALSE;
302
303 /*
304 * The FT_CHAR type is defined to be signed, regardless
305 * of whether char is signed or unsigned, so cast the value
306 * to "signed char".
307 */
308 value = (signed char)charvalue;
309 } else {
310 /*
311 * Try to parse it as a number.
312 */
313 if (!strchr (s, '-') && strtoul(s, NULL, 0) > G_MAXINT32) {
314 /*
315 * Probably a positive integer > G_MAXINT32, but
316 * will be "converted in the obvious manner" by
317 * strtol().
318 */
319 if (err_msg != NULL)
320 *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s);
321 return FALSE;
322 }
323
324 errno = 0;
325 value = strtol(s, &endptr, 0);
326
327 if (errno == EINVAL || endptr == s || *endptr != '\0') {
328 /* This isn't a valid number. */
329 if (err_msg != NULL)
330 *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s);
331 return FALSE;
332 }
333 if (errno == ERANGE) {
334 if (err_msg != NULL) {
335 if (value == LONG_MAX) {
336 *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s);
337 }
338 else if (value == LONG_MIN) {
339 *err_msg = g_strdup_printf("\"%s\" causes an integer underflow.", s);
340 }
341 else {
342 /*
343 * XXX - can "strtol()" set errno to
344 * ERANGE without returning ULONG_MAX?
345 */
346 *err_msg = g_strdup_printf("\"%s\" is not an integer.", s);
347 }
348 }
349 return FALSE;
350 }
351 }
352
353 if (value > max) {
354 if (err_msg != NULL)
355 *err_msg = g_strdup_printf("\"%s\" too big for this field, maximum %d.",
356 s, max);
357 return FALSE;
358 } else if (value < min) {
359 if (err_msg != NULL)
360 *err_msg = g_strdup_printf("\"%s\" too small for this field, minimum %d.",
361 s, min);
362 return FALSE;
363 }
364
365 fv->value.sinteger = (gint32)value;
366 return TRUE;
367 }
368
369 static gboolean
sint32_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)370 sint32_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
371 {
372 return sint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXINT32, G_MININT32);
373 }
374
375 static gboolean
sint24_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)376 sint24_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
377 {
378 return sint_from_unparsed (fv, s, allow_partial_value, err_msg, 0x7FFFFF, -0x800000);
379 }
380
381 static gboolean
sint16_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)382 sint16_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
383 {
384 return sint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXINT16, G_MININT16);
385 }
386
387 static gboolean
sint8_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)388 sint8_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
389 {
390 return sint_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXINT8, G_MININT8);
391 }
392
393 static int
integer_repr_len(fvalue_t * fv _U_,ftrepr_t rtype _U_,int field_display _U_)394 integer_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_, int field_display _U_)
395 {
396 return 11; /* enough for 2^31-1, in decimal */
397 }
398
399 static void
integer_to_repr(fvalue_t * fv,ftrepr_t rtype _U_,int field_display _U_,char * buf,unsigned int size)400 integer_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display _U_, char *buf, unsigned int size)
401 {
402 guint32 val;
403
404 if (fv->value.sinteger < 0) {
405 *buf++ = '-';
406 val = -fv->value.sinteger;
407 } else
408 val = fv->value.sinteger;
409
410 guint32_to_str_buf(val, buf, size);
411 }
412
413 static int
uinteger_repr_len(fvalue_t * fv _U_,ftrepr_t rtype _U_,int field_display _U_)414 uinteger_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_, int field_display _U_)
415 {
416 return 10; /* enough for 2^32-1, in decimal or 0xXXXXXXXX */
417 }
418
419 static int
char_repr_len(fvalue_t * fv _U_,ftrepr_t rtype _U_,int field_display _U_)420 char_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_, int field_display _U_)
421 {
422 return 7; /* enough for '\OOO' or '\xXX' */
423 }
424
425 static void
uinteger_to_repr(fvalue_t * fv,ftrepr_t rtype _U_,int field_display,char * buf,unsigned int size)426 uinteger_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display, char *buf, unsigned int size)
427 {
428 if (((field_display & 0xff) == BASE_HEX) || ((field_display & 0xff) == BASE_HEX_DEC))
429 {
430 /* This format perfectly fits into 11 bytes. */
431 *buf++ = '0';
432 *buf++ = 'x';
433
434 switch (fv->ftype->ftype) {
435
436 case FT_UINT8:
437 buf = guint8_to_hex(buf, fv->value.uinteger);
438 break;
439
440 case FT_UINT16:
441 buf = word_to_hex(buf, fv->value.uinteger);
442 break;
443
444 case FT_UINT24:
445 buf = guint8_to_hex(buf, (fv->value.uinteger & 0x00ff0000) >> 16);
446 buf = word_to_hex(buf, (fv->value.uinteger & 0x0000ffff));
447 break;
448
449 default:
450 buf = dword_to_hex(buf, fv->value.uinteger);
451 break;
452 }
453
454 *buf++ = '\0';
455 }
456 else
457 {
458 guint32_to_str_buf(fv->value.uinteger, buf, size);
459 }
460 }
461
462 static void
char_to_repr(fvalue_t * fv,ftrepr_t rtype _U_,int field_display,char * buf,unsigned int size _U_)463 char_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display, char *buf, unsigned int size _U_)
464 {
465 /*
466 * The longest possible strings are "'\OOO'" and "'\xXX'", which
467 * take 7 bytes, including the terminating '\0'.
468 */
469 *buf++ = '\'';
470 if (g_ascii_isprint(fv->value.uinteger)) {
471 /* This perfectly fits into 4 or 5 bytes. */
472 if (fv->value.uinteger == '\\' || fv->value.uinteger == '\'')
473 *buf++ = '\\';
474 *buf++ = (char)fv->value.uinteger;
475 } else {
476 *buf++ = '\\';
477 switch (fv->value.uinteger) {
478
479 case '\0':
480 *buf++ = '0';
481 break;
482
483 case '\a':
484 *buf++ = 'a';
485 break;
486
487 case '\b':
488 *buf++ = 'b';
489 break;
490
491 case '\f':
492 *buf++ = 'f';
493 break;
494
495 case '\n':
496 *buf++ = 'n';
497 break;
498
499 case '\r':
500 *buf++ = 'r';
501 break;
502
503 case '\t':
504 *buf++ = 't';
505 break;
506
507 case '\v':
508 *buf++ = 'v';
509 break;
510
511 default:
512 if (field_display == BASE_HEX) {
513 *buf++ = 'x';
514 buf = guint8_to_hex(buf, fv->value.uinteger);
515 }
516 else
517 {
518 *buf++ = ((fv->value.uinteger >> 6) & 0x7) + '0';
519 *buf++ = ((fv->value.uinteger >> 3) & 0x7) + '0';
520 *buf++ = ((fv->value.uinteger >> 0) & 0x7) + '0';
521 }
522 break;
523 }
524 }
525 *buf++ = '\'';
526 *buf++ = '\0';
527 }
528
529 static gboolean
ipxnet_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value _U_,gchar ** err_msg)530 ipxnet_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
531 {
532 /*
533 * Don't request an error message if bytes_from_unparsed fails;
534 * if it does, we'll report an error specific to this address
535 * type.
536 */
537 if (uint32_from_unparsed(fv, s, TRUE, NULL)) {
538 return TRUE;
539 }
540
541 /* XXX - Try resolving as an IPX host name and parse that? */
542
543 if (err_msg != NULL)
544 *err_msg = g_strdup_printf("\"%s\" is not a valid IPX network address.", s);
545 return FALSE;
546 }
547
548 static int
ipxnet_repr_len(fvalue_t * fv _U_,ftrepr_t rtype _U_,int field_display _U_)549 ipxnet_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_, int field_display _U_)
550 {
551 return 2+8; /* 0xXXXXXXXX */
552 }
553
554 static void
ipxnet_to_repr(fvalue_t * fv,ftrepr_t rtype,int field_display _U_,char * buf,unsigned int size)555 ipxnet_to_repr(fvalue_t *fv, ftrepr_t rtype, int field_display _U_, char *buf, unsigned int size)
556 {
557 uinteger_to_repr(fv, rtype, BASE_HEX, buf, size);
558 }
559
560 static gboolean
cmp_eq(const fvalue_t * a,const fvalue_t * b)561 cmp_eq(const fvalue_t *a, const fvalue_t *b)
562 {
563 return a->value.uinteger == b->value.uinteger;
564 }
565
566 static gboolean
cmp_ne(const fvalue_t * a,const fvalue_t * b)567 cmp_ne(const fvalue_t *a, const fvalue_t *b)
568 {
569 return a->value.uinteger != b->value.uinteger;
570 }
571
572 static gboolean
u_cmp_gt(const fvalue_t * a,const fvalue_t * b)573 u_cmp_gt(const fvalue_t *a, const fvalue_t *b)
574 {
575 return a->value.uinteger > b->value.uinteger;
576 }
577
578 static gboolean
u_cmp_ge(const fvalue_t * a,const fvalue_t * b)579 u_cmp_ge(const fvalue_t *a, const fvalue_t *b)
580 {
581 return a->value.uinteger >= b->value.uinteger;
582 }
583
584 static gboolean
u_cmp_lt(const fvalue_t * a,const fvalue_t * b)585 u_cmp_lt(const fvalue_t *a, const fvalue_t *b)
586 {
587 return a->value.uinteger < b->value.uinteger;
588 }
589
590 static gboolean
u_cmp_le(const fvalue_t * a,const fvalue_t * b)591 u_cmp_le(const fvalue_t *a, const fvalue_t *b)
592 {
593 return a->value.uinteger <= b->value.uinteger;
594 }
595
596 static gboolean
s_cmp_gt(const fvalue_t * a,const fvalue_t * b)597 s_cmp_gt(const fvalue_t *a, const fvalue_t *b)
598 {
599 return a->value.sinteger > b->value.sinteger;
600 }
601
602 static gboolean
s_cmp_ge(const fvalue_t * a,const fvalue_t * b)603 s_cmp_ge(const fvalue_t *a, const fvalue_t *b)
604 {
605 return a->value.sinteger >= b->value.sinteger;
606 }
607
608 static gboolean
s_cmp_lt(const fvalue_t * a,const fvalue_t * b)609 s_cmp_lt(const fvalue_t *a, const fvalue_t *b)
610 {
611 return a->value.sinteger < b->value.sinteger;
612 }
613
614 static gboolean
s_cmp_le(const fvalue_t * a,const fvalue_t * b)615 s_cmp_le(const fvalue_t *a, const fvalue_t *b)
616 {
617 return a->value.sinteger <= b->value.sinteger;
618 }
619
620 static gboolean
cmp_bitwise_and(const fvalue_t * a,const fvalue_t * b)621 cmp_bitwise_and(const fvalue_t *a, const fvalue_t *b)
622 {
623 return ((a->value.uinteger & b->value.uinteger) != 0);
624 }
625
626 static void
int64_fvalue_new(fvalue_t * fv)627 int64_fvalue_new(fvalue_t *fv)
628 {
629 fv->value.sinteger64 = 0;
630 }
631
632 static void
set_uinteger64(fvalue_t * fv,guint64 value)633 set_uinteger64(fvalue_t *fv, guint64 value)
634 {
635 fv->value.uinteger64 = value;
636 }
637
638 static void
set_sinteger64(fvalue_t * fv,gint64 value)639 set_sinteger64(fvalue_t *fv, gint64 value)
640 {
641 fv->value.sinteger64 = value;
642 }
643
644 static guint64
get_uinteger64(fvalue_t * fv)645 get_uinteger64(fvalue_t *fv)
646 {
647 return fv->value.uinteger64;
648 }
649
650 static gint64
get_sinteger64(fvalue_t * fv)651 get_sinteger64(fvalue_t *fv)
652 {
653 return fv->value.sinteger64;
654 }
655
656 static gboolean
_uint64_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value _U_,gchar ** err_msg,guint64 max)657 _uint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg,
658 guint64 max)
659 {
660 guint64 value;
661 char *endptr;
662
663 if (strchr (s, '-') && g_ascii_strtoll(s, NULL, 0) < 0) {
664 /*
665 * Probably a negative integer, but will be
666 * "converted in the obvious manner" by g_ascii_strtoull().
667 */
668 if (err_msg != NULL)
669 *err_msg = g_strdup_printf("\"%s\" causes an integer underflow.", s);
670 return FALSE;
671 }
672
673 errno = 0;
674 value = g_ascii_strtoull(s, &endptr, 0);
675
676 if (errno == EINVAL || endptr == s || *endptr != '\0') {
677 /* This isn't a valid number. */
678 if (err_msg != NULL)
679 *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s);
680 return FALSE;
681 }
682 if (errno == ERANGE) {
683 if (err_msg != NULL) {
684 if (value == G_MAXUINT64) {
685 *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s);
686 }
687 else {
688 /*
689 * XXX - can "strtoul()" set errno to
690 * ERANGE without returning ULONG_MAX?
691 */
692 *err_msg = g_strdup_printf("\"%s\" is not an integer.", s);
693 }
694 }
695 return FALSE;
696 }
697
698 if (value > max) {
699 if (err_msg != NULL)
700 *err_msg = g_strdup_printf("\"%s\" too big for this field, maximum %" G_GINT64_MODIFIER "u.", s, max);
701 return FALSE;
702 }
703
704 fv->value.uinteger64 = value;
705 return TRUE;
706 }
707
708 static gboolean
uint64_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)709 uint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
710 {
711 return _uint64_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXUINT64);
712 }
713
714 static gboolean
uint56_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)715 uint56_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
716 {
717 return _uint64_from_unparsed (fv, s, allow_partial_value, err_msg, G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFF));
718 }
719
720 static gboolean
uint48_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)721 uint48_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
722 {
723 return _uint64_from_unparsed (fv, s, allow_partial_value, err_msg, G_GUINT64_CONSTANT(0xFFFFFFFFFFFF));
724 }
725
726 static gboolean
uint40_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)727 uint40_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
728 {
729 return _uint64_from_unparsed (fv, s, allow_partial_value, err_msg, G_GUINT64_CONSTANT(0xFFFFFFFFFF));
730 }
731
732 static gboolean
_sint64_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value _U_,gchar ** err_msg,gint64 max,gint64 min)733 _sint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg,
734 gint64 max, gint64 min)
735 {
736 gint64 value;
737 char *endptr;
738
739 if (!strchr (s, '-') && g_ascii_strtoull(s, NULL, 0) > G_MAXINT64) {
740 /*
741 * Probably a positive integer > G_MAXINT64, but will be
742 * "converted in the obvious manner" by g_ascii_strtoll().
743 */
744 if (err_msg != NULL)
745 *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s);
746 return FALSE;
747 }
748
749 errno = 0;
750 value = g_ascii_strtoll(s, &endptr, 0);
751
752 if (errno == EINVAL || endptr == s || *endptr != '\0') {
753 /* This isn't a valid number. */
754 if (err_msg != NULL)
755 *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s);
756 return FALSE;
757 }
758 if (errno == ERANGE) {
759 if (err_msg != NULL) {
760 if (value == G_MAXINT64) {
761 *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s);
762 }
763 else if (value == G_MININT64) {
764 *err_msg = g_strdup_printf("\"%s\" causes an integer underflow.", s);
765 }
766 else {
767 /*
768 * XXX - can "strtol()" set errno to
769 * ERANGE without returning LONG_MAX?
770 */
771 *err_msg = g_strdup_printf("\"%s\" is not an integer.", s);
772 }
773 }
774 return FALSE;
775 }
776
777 if (value > max) {
778 if (err_msg != NULL)
779 *err_msg = g_strdup_printf("\"%s\" too big for this field, maximum %" G_GINT64_MODIFIER "u.", s, max);
780 return FALSE;
781 } else if (value < min) {
782 if (err_msg != NULL)
783 *err_msg = g_strdup_printf("\"%s\" too small for this field, maximum %" G_GINT64_MODIFIER "u.", s, max);
784 return FALSE;
785 }
786
787 fv->value.sinteger64 = (guint64)value;
788 return TRUE;
789 }
790
791 static gboolean
sint64_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)792 sint64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
793 {
794 return _sint64_from_unparsed (fv, s, allow_partial_value, err_msg, G_MAXINT64, G_MININT64);
795 }
796
797 static gboolean
sint56_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)798 sint56_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
799 {
800 return _sint64_from_unparsed (fv, s, allow_partial_value, err_msg, G_GINT64_CONSTANT(0x7FFFFFFFFFFFFF), G_GINT64_CONSTANT(-0x80000000000000));
801 }
802
803 static gboolean
sint48_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)804 sint48_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
805 {
806 return _sint64_from_unparsed (fv, s, allow_partial_value, err_msg, G_GINT64_CONSTANT(0x7FFFFFFFFFFF), G_GINT64_CONSTANT(-0x800000000000));
807 }
808
809 static gboolean
sint40_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value,gchar ** err_msg)810 sint40_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value, gchar **err_msg)
811 {
812 return _sint64_from_unparsed (fv, s, allow_partial_value, err_msg, G_GINT64_CONSTANT(0x7FFFFFFFFF), G_GINT64_CONSTANT(-0x8000000000));
813 }
814
815 static int
integer64_repr_len(fvalue_t * fv _U_,ftrepr_t rtype _U_,int field_display _U_)816 integer64_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_, int field_display _U_)
817 {
818 return 20; /* enough for -2^63-1, in decimal */
819 }
820
821 static void
integer64_to_repr(fvalue_t * fv,ftrepr_t rtype _U_,int field_display _U_,char * buf,unsigned int size)822 integer64_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display _U_, char *buf, unsigned int size)
823 {
824 guint64 val;
825
826 if (fv->value.sinteger64 < 0) {
827 *buf++ = '-';
828 val = -fv->value.sinteger64;
829 } else
830 val = fv->value.sinteger64;
831
832 guint64_to_str_buf(val, buf, size);
833 }
834
835 static int
uinteger64_repr_len(fvalue_t * fv _U_,ftrepr_t rtype _U_,int field_display _U_)836 uinteger64_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_, int field_display _U_)
837 {
838 return 20; /* enough for 2^64-1, in decimal or 0xXXXXXXXXXXXXXXXX */
839 }
840
841 static void
uinteger64_to_repr(fvalue_t * fv,ftrepr_t rtype _U_,int field_display,char * buf,unsigned int size)842 uinteger64_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display, char *buf, unsigned int size)
843 {
844 if ((field_display == BASE_HEX) || (field_display == BASE_HEX_DEC))
845 {
846 /* This format perfectly fits into 19 bytes. */
847 *buf++ = '0';
848 *buf++ = 'x';
849
850 buf = qword_to_hex(buf, fv->value.uinteger64);
851 *buf++ = '\0';
852 }
853 else
854 {
855 guint64_to_str_buf(fv->value.uinteger64, buf, size);
856 }
857 }
858
859 static gboolean
cmp_eq64(const fvalue_t * a,const fvalue_t * b)860 cmp_eq64(const fvalue_t *a, const fvalue_t *b)
861 {
862 return a->value.uinteger64 == b->value.uinteger64;
863 }
864
865 static gboolean
cmp_ne64(const fvalue_t * a,const fvalue_t * b)866 cmp_ne64(const fvalue_t *a, const fvalue_t *b)
867 {
868 return a->value.uinteger64 != b->value.uinteger64;
869 }
870
871 static gboolean
u_cmp_gt64(const fvalue_t * a,const fvalue_t * b)872 u_cmp_gt64(const fvalue_t *a, const fvalue_t *b)
873 {
874 return a->value.uinteger64 > b->value.uinteger64;
875 }
876
877 static gboolean
u_cmp_ge64(const fvalue_t * a,const fvalue_t * b)878 u_cmp_ge64(const fvalue_t *a, const fvalue_t *b)
879 {
880 return a->value.uinteger64 >= b->value.uinteger64;
881 }
882
883 static gboolean
u_cmp_lt64(const fvalue_t * a,const fvalue_t * b)884 u_cmp_lt64(const fvalue_t *a, const fvalue_t *b)
885 {
886 return a->value.uinteger64 < b->value.uinteger64;
887 }
888
889 static gboolean
u_cmp_le64(const fvalue_t * a,const fvalue_t * b)890 u_cmp_le64(const fvalue_t *a, const fvalue_t *b)
891 {
892 return a->value.uinteger64 <= b->value.uinteger64;
893 }
894
895 static gboolean
s_cmp_gt64(const fvalue_t * a,const fvalue_t * b)896 s_cmp_gt64(const fvalue_t *a, const fvalue_t *b)
897 {
898 return (gint64)a->value.sinteger64 > (gint64)b->value.sinteger64;
899 }
900
901 static gboolean
s_cmp_ge64(const fvalue_t * a,const fvalue_t * b)902 s_cmp_ge64(const fvalue_t *a, const fvalue_t *b)
903 {
904 return (gint64)a->value.sinteger64 >= (gint64)b->value.sinteger64;
905 }
906
907 static gboolean
s_cmp_lt64(const fvalue_t * a,const fvalue_t * b)908 s_cmp_lt64(const fvalue_t *a, const fvalue_t *b)
909 {
910 return (gint64)a->value.sinteger64 < (gint64)b->value.sinteger64;
911 }
912
913 static gboolean
s_cmp_le64(const fvalue_t * a,const fvalue_t * b)914 s_cmp_le64(const fvalue_t *a, const fvalue_t *b)
915 {
916 return (gint64)a->value.sinteger64 <= (gint64)b->value.sinteger64;
917 }
918
919 static gboolean
cmp_bitwise_and64(const fvalue_t * a,const fvalue_t * b)920 cmp_bitwise_and64(const fvalue_t *a, const fvalue_t *b)
921 {
922 return ((a->value.uinteger64 & b->value.uinteger64) != 0);
923 }
924
925 /* BOOLEAN-specific */
926
927 static void
boolean_fvalue_new(fvalue_t * fv)928 boolean_fvalue_new(fvalue_t *fv)
929 {
930 fv->value.uinteger64 = TRUE;
931 }
932
933 static int
boolean_repr_len(fvalue_t * fv _U_,ftrepr_t rtype _U_,int field_display _U_)934 boolean_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_, int field_display _U_)
935 {
936 return 1;
937 }
938
939 static void
boolean_to_repr(fvalue_t * fv,ftrepr_t rtype _U_,int field_display _U_,char * buf,unsigned int size _U_)940 boolean_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display _U_, char *buf, unsigned int size _U_)
941 {
942 *buf++ = (fv->value.uinteger64) ? '1' : '0';
943 *buf = '\0';
944 }
945
946 /* Checks for equality with zero or non-zero */
947 static gboolean
bool_eq(const fvalue_t * a,const fvalue_t * b)948 bool_eq(const fvalue_t *a, const fvalue_t *b)
949 {
950 if (a->value.uinteger64) {
951 if (b->value.uinteger64) {
952 return TRUE;
953 }
954 else {
955 return FALSE;
956 }
957 }
958 else {
959 if (b->value.uinteger64) {
960 return FALSE;
961 }
962 else {
963 return TRUE;
964 }
965 }
966 }
967
968 /* Checks for inequality with zero or non-zero */
969 static gboolean
bool_ne(const fvalue_t * a,const fvalue_t * b)970 bool_ne(const fvalue_t *a, const fvalue_t *b)
971 {
972 return (!bool_eq(a,b));
973 }
974
975 /* EUI64-specific */
976 static gboolean
eui64_from_unparsed(fvalue_t * fv,const char * s,gboolean allow_partial_value _U_,gchar ** err_msg)977 eui64_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
978 {
979 GByteArray *bytes;
980 gboolean res;
981 union {
982 guint64 value;
983 guint8 bytes[8];
984 } eui64;
985
986 /*
987 * Don't request an error message if uint64_from_unparsed fails;
988 * if it does, we'll try parsing it as a sequence of bytes, and
989 * report an error if *that* fails.
990 */
991 if (uint64_from_unparsed(fv, s, TRUE, NULL)) {
992 return TRUE;
993 }
994
995 bytes = g_byte_array_new();
996 res = hex_str_to_bytes(s, bytes, TRUE);
997 if (!res || bytes->len != 8) {
998 if (err_msg != NULL)
999 *err_msg = g_strdup_printf("\"%s\" is not a valid EUI-64 address.", s);
1000 g_byte_array_free(bytes, TRUE);
1001 return FALSE;
1002 }
1003
1004 memcpy(eui64.bytes, bytes->data, 8);
1005 g_byte_array_free(bytes, TRUE);
1006 fv->value.integer64 = GUINT64_FROM_BE(eui64.value);
1007 return TRUE;
1008 }
1009
1010 static int
eui64_repr_len(fvalue_t * fv _U_,ftrepr_t rtype _U_,int field_display _U_)1011 eui64_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_, int field_display _U_)
1012 {
1013 return EUI64_STR_LEN; /* XX:XX:XX:XX:XX:XX:XX:XX */
1014 }
1015
1016 static void
eui64_to_repr(fvalue_t * fv,ftrepr_t rtype _U_,int field_display _U_,char * buf,unsigned int size)1017 eui64_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display _U_, char *buf, unsigned int size)
1018 {
1019 union {
1020 guint64 value;
1021 guint8 bytes[8];
1022 } eui64;
1023
1024 /* Copy and convert the address from host to network byte order. */
1025 eui64.value = GUINT64_TO_BE(fv->value.integer64);
1026
1027 g_snprintf(buf, size, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1028 eui64.bytes[0], eui64.bytes[1], eui64.bytes[2], eui64.bytes[3],
1029 eui64.bytes[4], eui64.bytes[5], eui64.bytes[6], eui64.bytes[7]);
1030 }
1031
1032 void
ftype_register_integers(void)1033 ftype_register_integers(void)
1034 {
1035 static ftype_t char_type = {
1036 FT_CHAR, /* ftype */
1037 "FT_CHAR", /* name */
1038 "Character, 1 byte", /* pretty name */
1039 1, /* wire_size */
1040 int_fvalue_new, /* new_value */
1041 NULL, /* free_value */
1042 uint8_from_unparsed, /* val_from_unparsed */
1043 NULL, /* val_from_string */
1044 char_to_repr, /* val_to_string_repr */
1045 char_repr_len, /* len_string_repr */
1046
1047 { .set_value_uinteger = set_uinteger }, /* union set_value */
1048 { .get_value_uinteger = get_uinteger }, /* union get_value */
1049
1050 cmp_eq,
1051 cmp_ne,
1052 u_cmp_gt,
1053 u_cmp_ge,
1054 u_cmp_lt,
1055 u_cmp_le,
1056 cmp_bitwise_and,
1057 NULL, /* cmp_contains */
1058 NULL, /* cmp_matches */
1059
1060 NULL, /* len */
1061 NULL, /* slice */
1062 };
1063 static ftype_t uint8_type = {
1064 FT_UINT8, /* ftype */
1065 "FT_UINT8", /* name */
1066 "Unsigned integer, 1 byte", /* pretty name */
1067 1, /* wire_size */
1068 int_fvalue_new, /* new_value */
1069 NULL, /* free_value */
1070 uint8_from_unparsed, /* val_from_unparsed */
1071 NULL, /* val_from_string */
1072 uinteger_to_repr, /* val_to_string_repr */
1073 uinteger_repr_len, /* len_string_repr */
1074
1075 { .set_value_uinteger = set_uinteger }, /* union set_value */
1076 { .get_value_uinteger = get_uinteger }, /* union get_value */
1077
1078 cmp_eq,
1079 cmp_ne,
1080 u_cmp_gt,
1081 u_cmp_ge,
1082 u_cmp_lt,
1083 u_cmp_le,
1084 cmp_bitwise_and,
1085 NULL, /* cmp_contains */
1086 NULL, /* cmp_matches */
1087
1088 NULL, /* len */
1089 NULL, /* slice */
1090 };
1091 static ftype_t uint16_type = {
1092 FT_UINT16, /* ftype */
1093 "FT_UINT16", /* name */
1094 "Unsigned integer, 2 bytes", /* pretty_name */
1095 2, /* wire_size */
1096 int_fvalue_new, /* new_value */
1097 NULL, /* free_value */
1098 uint16_from_unparsed, /* val_from_unparsed */
1099 NULL, /* val_from_string */
1100 uinteger_to_repr, /* val_to_string_repr */
1101 uinteger_repr_len, /* len_string_repr */
1102
1103 { .set_value_uinteger = set_uinteger }, /* union set_value */
1104 { .get_value_uinteger = get_uinteger }, /* union get_value */
1105
1106 cmp_eq,
1107 cmp_ne,
1108 u_cmp_gt,
1109 u_cmp_ge,
1110 u_cmp_lt,
1111 u_cmp_le,
1112 cmp_bitwise_and,
1113 NULL, /* cmp_contains */
1114 NULL, /* cmp_matches */
1115
1116 NULL, /* len */
1117 NULL, /* slice */
1118 };
1119 static ftype_t uint24_type = {
1120 FT_UINT24, /* ftype */
1121 "FT_UINT24", /* name */
1122 "Unsigned integer, 3 bytes", /* pretty_name */
1123 3, /* wire_size */
1124 int_fvalue_new, /* new_value */
1125 NULL, /* free_value */
1126 uint24_from_unparsed, /* val_from_unparsed */
1127 NULL, /* val_from_string */
1128 uinteger_to_repr, /* val_to_string_repr */
1129 uinteger_repr_len, /* len_string_repr */
1130
1131 { .set_value_uinteger = set_uinteger }, /* union set_value */
1132 { .get_value_uinteger = get_uinteger }, /* union get_value */
1133
1134 cmp_eq,
1135 cmp_ne,
1136 u_cmp_gt,
1137 u_cmp_ge,
1138 u_cmp_lt,
1139 u_cmp_le,
1140 cmp_bitwise_and,
1141 NULL, /* cmp_contains */
1142 NULL, /* cmp_matches */
1143
1144 NULL, /* len */
1145 NULL, /* slice */
1146 };
1147 static ftype_t uint32_type = {
1148 FT_UINT32, /* ftype */
1149 "FT_UINT32", /* name */
1150 "Unsigned integer, 4 bytes", /* pretty_name */
1151 4, /* wire_size */
1152 int_fvalue_new, /* new_value */
1153 NULL, /* free_value */
1154 uint32_from_unparsed, /* val_from_unparsed */
1155 NULL, /* val_from_string */
1156 uinteger_to_repr, /* val_to_string_repr */
1157 uinteger_repr_len, /* len_string_repr */
1158
1159 { .set_value_uinteger = set_uinteger }, /* union set_value */
1160 { .get_value_uinteger = get_uinteger }, /* union get_value */
1161
1162 cmp_eq,
1163 cmp_ne,
1164 u_cmp_gt,
1165 u_cmp_ge,
1166 u_cmp_lt,
1167 u_cmp_le,
1168 cmp_bitwise_and,
1169 NULL, /* cmp_contains */
1170 NULL, /* cmp_matches */
1171
1172 NULL, /* len */
1173 NULL, /* slice */
1174 };
1175 static ftype_t uint40_type = {
1176 FT_UINT40, /* ftype */
1177 "FT_UINT40", /* name */
1178 "Unsigned integer, 5 bytes", /* pretty_name */
1179 5, /* wire_size */
1180 int64_fvalue_new, /* new_value */
1181 NULL, /* free_value */
1182 uint40_from_unparsed, /* val_from_unparsed */
1183 NULL, /* val_from_string */
1184 uinteger64_to_repr, /* val_to_string_repr */
1185 uinteger64_repr_len, /* len_string_repr */
1186
1187 { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */
1188 { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */
1189
1190 cmp_eq64,
1191 cmp_ne64,
1192 u_cmp_gt64,
1193 u_cmp_ge64,
1194 u_cmp_lt64,
1195 u_cmp_le64,
1196 cmp_bitwise_and64,
1197 NULL, /* cmp_contains */
1198 NULL, /* cmp_matches */
1199
1200 NULL,
1201 NULL,
1202 };
1203 static ftype_t uint48_type = {
1204 FT_UINT48, /* ftype */
1205 "FT_UINT48", /* name */
1206 "Unsigned integer, 6 bytes", /* pretty_name */
1207 6, /* wire_size */
1208 int64_fvalue_new, /* new_value */
1209 NULL, /* free_value */
1210 uint48_from_unparsed, /* val_from_unparsed */
1211 NULL, /* val_from_string */
1212 uinteger64_to_repr, /* val_to_string_repr */
1213 uinteger64_repr_len, /* len_string_repr */
1214
1215 { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */
1216 { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */
1217
1218 cmp_eq64,
1219 cmp_ne64,
1220 u_cmp_gt64,
1221 u_cmp_ge64,
1222 u_cmp_lt64,
1223 u_cmp_le64,
1224 cmp_bitwise_and64,
1225 NULL, /* cmp_contains */
1226 NULL, /* cmp_matches */
1227
1228 NULL,
1229 NULL,
1230 };
1231 static ftype_t uint56_type = {
1232 FT_UINT56, /* ftype */
1233 "FT_UINT56", /* name */
1234 "Unsigned integer, 7 bytes", /* pretty_name */
1235 7, /* wire_size */
1236 int64_fvalue_new, /* new_value */
1237 NULL, /* free_value */
1238 uint56_from_unparsed, /* val_from_unparsed */
1239 NULL, /* val_from_string */
1240 uinteger64_to_repr, /* val_to_string_repr */
1241 uinteger64_repr_len, /* len_string_repr */
1242
1243 { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */
1244 { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */
1245
1246 cmp_eq64,
1247 cmp_ne64,
1248 u_cmp_gt64,
1249 u_cmp_ge64,
1250 u_cmp_lt64,
1251 u_cmp_le64,
1252 cmp_bitwise_and64,
1253 NULL, /* cmp_contains */
1254 NULL, /* cmp_matches */
1255
1256 NULL,
1257 NULL,
1258 };
1259 static ftype_t uint64_type = {
1260 FT_UINT64, /* ftype */
1261 "FT_UINT64", /* name */
1262 "Unsigned integer, 8 bytes", /* pretty_name */
1263 8, /* wire_size */
1264 int64_fvalue_new, /* new_value */
1265 NULL, /* free_value */
1266 uint64_from_unparsed, /* val_from_unparsed */
1267 NULL, /* val_from_string */
1268 uinteger64_to_repr, /* val_to_string_repr */
1269 uinteger64_repr_len, /* len_string_repr */
1270
1271 { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */
1272 { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */
1273
1274 cmp_eq64,
1275 cmp_ne64,
1276 u_cmp_gt64,
1277 u_cmp_ge64,
1278 u_cmp_lt64,
1279 u_cmp_le64,
1280 cmp_bitwise_and64,
1281 NULL, /* cmp_contains */
1282 NULL, /* cmp_matches */
1283
1284 NULL,
1285 NULL,
1286 };
1287 static ftype_t int8_type = {
1288 FT_INT8, /* ftype */
1289 "FT_INT8", /* name */
1290 "Signed integer, 1 byte", /* pretty_name */
1291 1, /* wire_size */
1292 int_fvalue_new, /* new_value */
1293 NULL, /* free_value */
1294 sint8_from_unparsed, /* val_from_unparsed */
1295 NULL, /* val_from_string */
1296 integer_to_repr, /* val_to_string_repr */
1297 integer_repr_len, /* len_string_repr */
1298
1299 { .set_value_sinteger = set_sinteger }, /* union set_value */
1300 { .get_value_sinteger = get_sinteger }, /* union get_value */
1301
1302 cmp_eq,
1303 cmp_ne,
1304 s_cmp_gt,
1305 s_cmp_ge,
1306 s_cmp_lt,
1307 s_cmp_le,
1308 cmp_bitwise_and,
1309 NULL, /* cmp_contains */
1310 NULL, /* cmp_matches */
1311
1312 NULL, /* len */
1313 NULL, /* slice */
1314 };
1315 static ftype_t int16_type = {
1316 FT_INT16, /* ftype */
1317 "FT_INT16", /* name */
1318 "Signed integer, 2 bytes", /* pretty_name */
1319 2, /* wire_size */
1320 int_fvalue_new, /* new_value */
1321 NULL, /* free_value */
1322 sint16_from_unparsed, /* val_from_unparsed */
1323 NULL, /* val_from_string */
1324 integer_to_repr, /* val_to_string_repr */
1325 integer_repr_len, /* len_string_repr */
1326
1327 { .set_value_sinteger = set_sinteger }, /* union set_value */
1328 { .get_value_sinteger = get_sinteger }, /* union get_value */
1329
1330 cmp_eq,
1331 cmp_ne,
1332 s_cmp_gt,
1333 s_cmp_ge,
1334 s_cmp_lt,
1335 s_cmp_le,
1336 cmp_bitwise_and,
1337 NULL, /* cmp_contains */
1338 NULL, /* cmp_matches */
1339
1340 NULL, /* len */
1341 NULL, /* slice */
1342 };
1343 static ftype_t int24_type = {
1344 FT_INT24, /* ftype */
1345 "FT_INT24", /* name */
1346 "Signed integer, 3 bytes", /* pretty_name */
1347 3, /* wire_size */
1348 int_fvalue_new, /* new_value */
1349 NULL, /* free_value */
1350 sint24_from_unparsed, /* val_from_unparsed */
1351 NULL, /* val_from_string */
1352 integer_to_repr, /* val_to_string_repr */
1353 integer_repr_len, /* len_string_repr */
1354
1355 { .set_value_sinteger = set_sinteger }, /* union set_value */
1356 { .get_value_sinteger = get_sinteger }, /* union get_value */
1357
1358 cmp_eq,
1359 cmp_ne,
1360 s_cmp_gt,
1361 s_cmp_ge,
1362 s_cmp_lt,
1363 s_cmp_le,
1364 cmp_bitwise_and,
1365 NULL, /* cmp_contains */
1366 NULL, /* cmp_matches */
1367
1368 NULL, /* len */
1369 NULL, /* slice */
1370 };
1371 static ftype_t int32_type = {
1372 FT_INT32, /* ftype */
1373 "FT_INT32", /* name */
1374 "Signed integer, 4 bytes", /* pretty_name */
1375 4, /* wire_size */
1376 int_fvalue_new, /* new_value */
1377 NULL, /* free_value */
1378 sint32_from_unparsed, /* val_from_unparsed */
1379 NULL, /* val_from_string */
1380 integer_to_repr, /* val_to_string_repr */
1381 integer_repr_len, /* len_string_repr */
1382
1383 { .set_value_sinteger = set_sinteger }, /* union set_value */
1384 { .get_value_sinteger = get_sinteger }, /* union get_value */
1385
1386 cmp_eq,
1387 cmp_ne,
1388 s_cmp_gt,
1389 s_cmp_ge,
1390 s_cmp_lt,
1391 s_cmp_le,
1392 cmp_bitwise_and,
1393 NULL, /* cmp_contains */
1394 NULL, /* cmp_matches */
1395
1396 NULL, /* len */
1397 NULL, /* slice */
1398 };
1399 static ftype_t int40_type = {
1400 FT_INT40, /* ftype */
1401 "FT_INT40", /* name */
1402 "Signed integer, 5 bytes", /* pretty_name */
1403 5, /* wire_size */
1404 int64_fvalue_new, /* new_value */
1405 NULL, /* free_value */
1406 sint40_from_unparsed, /* val_from_unparsed */
1407 NULL, /* val_from_string */
1408 integer64_to_repr, /* val_to_string_repr */
1409 integer64_repr_len, /* len_string_repr */
1410
1411 { .set_value_sinteger64 = set_sinteger64 }, /* union set_value */
1412 { .get_value_sinteger64 = get_sinteger64 }, /* union get_value */
1413
1414 cmp_eq64,
1415 cmp_ne64,
1416 s_cmp_gt64,
1417 s_cmp_ge64,
1418 s_cmp_lt64,
1419 s_cmp_le64,
1420 cmp_bitwise_and64,
1421 NULL, /* cmp_contains */
1422 NULL, /* cmp_matches */
1423
1424 NULL,
1425 NULL,
1426 };
1427 static ftype_t int48_type = {
1428 FT_INT48, /* ftype */
1429 "FT_INT48", /* name */
1430 "Signed integer, 6 bytes", /* pretty_name */
1431 6, /* wire_size */
1432 int64_fvalue_new, /* new_value */
1433 NULL, /* free_value */
1434 sint48_from_unparsed, /* val_from_unparsed */
1435 NULL, /* val_from_string */
1436 integer64_to_repr, /* val_to_string_repr */
1437 integer64_repr_len, /* len_string_repr */
1438
1439 { .set_value_sinteger64 = set_sinteger64 }, /* union set_value */
1440 { .get_value_sinteger64 = get_sinteger64 }, /* union get_value */
1441
1442 cmp_eq64,
1443 cmp_ne64,
1444 s_cmp_gt64,
1445 s_cmp_ge64,
1446 s_cmp_lt64,
1447 s_cmp_le64,
1448 cmp_bitwise_and64,
1449 NULL, /* cmp_contains */
1450 NULL, /* cmp_matches */
1451
1452 NULL,
1453 NULL,
1454 };
1455 static ftype_t int56_type = {
1456 FT_INT56, /* ftype */
1457 "FT_INT56", /* name */
1458 "Signed integer, 7 bytes", /* pretty_name */
1459 7, /* wire_size */
1460 int64_fvalue_new, /* new_value */
1461 NULL, /* free_value */
1462 sint56_from_unparsed, /* val_from_unparsed */
1463 NULL, /* val_from_string */
1464 integer64_to_repr, /* val_to_string_repr */
1465 integer64_repr_len, /* len_string_repr */
1466
1467 { .set_value_sinteger64 = set_sinteger64 }, /* union set_value */
1468 { .get_value_sinteger64 = get_sinteger64 }, /* union get_value */
1469
1470 cmp_eq64,
1471 cmp_ne64,
1472 s_cmp_gt64,
1473 s_cmp_ge64,
1474 s_cmp_lt64,
1475 s_cmp_le64,
1476 cmp_bitwise_and64,
1477 NULL, /* cmp_contains */
1478 NULL, /* cmp_matches */
1479
1480 NULL,
1481 NULL,
1482 };
1483 static ftype_t int64_type = {
1484 FT_INT64, /* ftype */
1485 "FT_INT64", /* name */
1486 "Signed integer, 8 bytes", /* pretty_name */
1487 8, /* wire_size */
1488 int64_fvalue_new, /* new_value */
1489 NULL, /* free_value */
1490 sint64_from_unparsed, /* val_from_unparsed */
1491 NULL, /* val_from_string */
1492 integer64_to_repr, /* val_to_string_repr */
1493 integer64_repr_len, /* len_string_repr */
1494
1495 { .set_value_sinteger64 = set_sinteger64 }, /* union set_value */
1496 { .get_value_sinteger64 = get_sinteger64 }, /* union get_value */
1497
1498 cmp_eq64,
1499 cmp_ne64,
1500 s_cmp_gt64,
1501 s_cmp_ge64,
1502 s_cmp_lt64,
1503 s_cmp_le64,
1504 cmp_bitwise_and64,
1505 NULL, /* cmp_contains */
1506 NULL, /* cmp_matches */
1507
1508 NULL,
1509 NULL,
1510 };
1511 static ftype_t boolean_type = {
1512 FT_BOOLEAN, /* ftype */
1513 "FT_BOOLEAN", /* name */
1514 "Boolean", /* pretty_name */
1515 0, /* wire_size */
1516 boolean_fvalue_new, /* new_value */
1517 NULL, /* free_value */
1518 uint64_from_unparsed, /* val_from_unparsed */
1519 NULL, /* val_from_string */
1520 boolean_to_repr, /* val_to_string_repr */
1521 boolean_repr_len, /* len_string_repr */
1522
1523 { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */
1524 { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */
1525
1526 bool_eq, /* cmp_eq */
1527 bool_ne, /* cmp_ne */
1528 NULL, /* cmp_gt */
1529 NULL, /* cmp_ge */
1530 NULL, /* cmp_lt */
1531 NULL, /* cmp_le */
1532 NULL, /* cmp_bitwise_and */
1533 NULL, /* cmp_contains */
1534 NULL, /* cmp_matches */
1535
1536 NULL, /* len */
1537 NULL, /* slice */
1538 };
1539
1540 static ftype_t ipxnet_type = {
1541 FT_IPXNET, /* ftype */
1542 "FT_IPXNET", /* name */
1543 "IPX network number", /* pretty_name */
1544 4, /* wire_size */
1545 int_fvalue_new, /* new_value */
1546 NULL, /* free_value */
1547 ipxnet_from_unparsed, /* val_from_unparsed */
1548 NULL, /* val_from_string */
1549 ipxnet_to_repr, /* val_to_string_repr */
1550 ipxnet_repr_len, /* len_string_repr */
1551
1552 { .set_value_uinteger = set_uinteger }, /* union set_value */
1553 { .get_value_uinteger = get_uinteger }, /* union get_value */
1554
1555 cmp_eq,
1556 cmp_ne,
1557 u_cmp_gt,
1558 u_cmp_ge,
1559 u_cmp_lt,
1560 u_cmp_le,
1561 cmp_bitwise_and,
1562 NULL, /* cmp_contains */
1563 NULL, /* cmp_matches */
1564
1565 NULL, /* len */
1566 NULL, /* slice */
1567 };
1568
1569 static ftype_t framenum_type = {
1570 FT_FRAMENUM, /* ftype */
1571 "FT_FRAMENUM", /* name */
1572 "Frame number", /* pretty_name */
1573 4, /* wire_size */
1574 int_fvalue_new, /* new_value */
1575 NULL, /* free_value */
1576 uint32_from_unparsed, /* val_from_unparsed */
1577 NULL, /* val_from_string */
1578 uinteger_to_repr, /* val_to_string_repr */
1579 uinteger_repr_len, /* len_string_repr */
1580
1581 { .set_value_uinteger = set_uinteger }, /* union set_value */
1582 { .get_value_uinteger = get_uinteger }, /* union get_value */
1583
1584 cmp_eq,
1585 cmp_ne,
1586 u_cmp_gt,
1587 u_cmp_ge,
1588 u_cmp_lt,
1589 u_cmp_le,
1590 NULL, /* cmp_bitwise_and */
1591 NULL, /* cmp_contains */
1592 NULL, /* cmp_matches */
1593
1594 NULL, /* len */
1595 NULL, /* slice */
1596 };
1597
1598 static ftype_t eui64_type = {
1599 FT_EUI64, /* ftype */
1600 "FT_EUI64", /* name */
1601 "EUI64 address", /* pretty_name */
1602 FT_EUI64_LEN, /* wire_size */
1603 int64_fvalue_new, /* new_value */
1604 NULL, /* free_value */
1605 eui64_from_unparsed, /* val_from_unparsed */
1606 NULL, /* val_from_string */
1607 eui64_to_repr, /* val_to_string_repr */
1608 eui64_repr_len, /* len_string_repr */
1609
1610 { .set_value_uinteger64 = set_uinteger64 }, /* union set_value */
1611 { .get_value_uinteger64 = get_uinteger64 }, /* union get_value */
1612
1613 cmp_eq64,
1614 cmp_ne64,
1615 u_cmp_gt64,
1616 u_cmp_ge64,
1617 u_cmp_lt64,
1618 u_cmp_le64,
1619 cmp_bitwise_and64,
1620 NULL, /* cmp_contains */
1621 NULL, /* cmp_matches */
1622
1623 NULL,
1624 NULL,
1625 };
1626
1627 ftype_register(FT_CHAR, &char_type);
1628 ftype_register(FT_UINT8, &uint8_type);
1629 ftype_register(FT_UINT16, &uint16_type);
1630 ftype_register(FT_UINT24, &uint24_type);
1631 ftype_register(FT_UINT32, &uint32_type);
1632 ftype_register(FT_UINT40, &uint40_type);
1633 ftype_register(FT_UINT48, &uint48_type);
1634 ftype_register(FT_UINT56, &uint56_type);
1635 ftype_register(FT_UINT64, &uint64_type);
1636 ftype_register(FT_INT8, &int8_type);
1637 ftype_register(FT_INT16, &int16_type);
1638 ftype_register(FT_INT24, &int24_type);
1639 ftype_register(FT_INT32, &int32_type);
1640 ftype_register(FT_INT40, &int40_type);
1641 ftype_register(FT_INT48, &int48_type);
1642 ftype_register(FT_INT56, &int56_type);
1643 ftype_register(FT_INT64, &int64_type);
1644 ftype_register(FT_BOOLEAN, &boolean_type);
1645 ftype_register(FT_IPXNET, &ipxnet_type);
1646 ftype_register(FT_FRAMENUM, &framenum_type);
1647 ftype_register(FT_EUI64, &eui64_type);
1648 }
1649
1650 /*
1651 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1652 *
1653 * Local variables:
1654 * c-basic-offset: 8
1655 * tab-width: 8
1656 * indent-tabs-mode: t
1657 * End:
1658 *
1659 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1660 * :indentSize=8:tabSize=8:noTabs=false:
1661 */
1662