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 #define WS_LOG_DOMAIN LOG_DOMAIN_DFILTER
12
13 #include <string.h>
14
15 #include "dfilter-int.h"
16 #include "semcheck.h"
17 #include "syntax-tree.h"
18 #include "sttype-range.h"
drange_node_new(void)19 #include "sttype-test.h"
20 #include "sttype-set.h"
21 #include "sttype-function.h"
22
23 #include <epan/exceptions.h>
24 #include <epan/packet.h>
25
26 #include <wsutil/ws_assert.h>
27 #include <wsutil/wslog.h>
28
29 #include <ftypes/ftypes-int.h>
30
31
32 static void
33 semcheck(dfwork_t *dfw, stnode_t *st_node);
34
35 static stnode_t*
36 check_param_entity(dfwork_t *dfw, stnode_t *st_node);
37
38 static void
39 check_function(dfwork_t *dfw, stnode_t *st_node);
40
41 typedef gboolean (*FtypeCanFunc)(enum ftenum);
42
43 /* Compares to ftenum_t's and decides if they're
44 * compatible or not (if they're the same basic type) */
45 static gboolean
46 compatible_ftypes(ftenum_t a, ftenum_t b)
47 {
48 switch (a) {
drange_node_free(drange_node * drnode)49 case FT_NONE:
50 case FT_PROTOCOL:
51 case FT_FLOAT: /* XXX - should be able to compare with INT */
52 case FT_DOUBLE: /* XXX - should be able to compare with INT */
53 case FT_ABSOLUTE_TIME:
54 case FT_RELATIVE_TIME:
55 case FT_IEEE_11073_SFLOAT:
56 case FT_IEEE_11073_FLOAT:
57 case FT_IPv4:
58 case FT_IPv6:
59 case FT_IPXNET:
60 case FT_INT40: /* XXX - should be able to compare with INT */
61 case FT_UINT40: /* XXX - should be able to compare with INT */
62 case FT_INT48: /* XXX - should be able to compare with INT */
63 case FT_UINT48: /* XXX - should be able to compare with INT */
64 case FT_INT56: /* XXX - should be able to compare with INT */
65 case FT_UINT56: /* XXX - should be able to compare with INT */
66 case FT_INT64: /* XXX - should be able to compare with INT */
67 case FT_UINT64: /* XXX - should be able to compare with INT */
68 case FT_EUI64: /* XXX - should be able to compare with INT */
69 return a == b;
drange_node_get_end_offset(drange_node * drnode)70
71 case FT_ETHER:
72 case FT_BYTES:
73 case FT_UINT_BYTES:
74 case FT_GUID:
75 case FT_OID:
76 case FT_AX25:
77 case FT_VINES:
78 case FT_FCWWN:
79 case FT_REL_OID:
80 case FT_SYSTEM_ID:
81
82 return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES || b == FT_GUID || b == FT_OID || b == FT_AX25 || b == FT_VINES || b == FT_FCWWN || b == FT_REL_OID || b == FT_SYSTEM_ID);
83
84 case FT_BOOLEAN:
drange_node_set_start_offset(drange_node * drnode,gint offset)85 case FT_FRAMENUM:
86 case FT_CHAR:
87 case FT_UINT8:
88 case FT_UINT16:
89 case FT_UINT24:
90 case FT_UINT32:
91 case FT_INT8:
92 case FT_INT16:
93 case FT_INT24:
94 case FT_INT32:
95 switch (b) {
96 case FT_BOOLEAN:
97 case FT_FRAMENUM:
98 case FT_CHAR:
99 case FT_UINT8:
100 case FT_UINT16:
101 case FT_UINT24:
102 case FT_UINT32:
103 case FT_INT8:
104 case FT_INT16:
105 case FT_INT24:
106 case FT_INT32:
107 return TRUE;
108 default:
109 return FALSE;
110 }
111
112 case FT_STRING:
drange_new(void)113 case FT_STRINGZ:
114 case FT_UINT_STRING:
115 case FT_STRINGZPAD:
116 case FT_STRINGZTRUNC:
117 switch (b) {
118 case FT_STRING:
119 case FT_STRINGZ:
120 case FT_UINT_STRING:
121 case FT_STRINGZPAD:
122 case FT_STRINGZTRUNC:
123 return TRUE;
124 default:
125 return FALSE;
126 }
127
128 case FT_NUM_TYPES:
129 ws_assert_not_reached();
130 }
131
132 ws_assert_not_reached();
133 return FALSE;
134 }
drange_new_from_list(GSList * list)135
136 /* Gets an fvalue from a string, and sets the error message on failure. */
137 static fvalue_t*
138 dfilter_fvalue_from_unparsed(dfwork_t *dfw, ftenum_t ftype, const char *s, gboolean allow_partial_value)
139 {
140 /*
141 * Don't set the error message if it's already set.
142 */
143 return fvalue_from_unparsed(ftype, s, allow_partial_value,
144 dfw->error_message == NULL ? &dfw->error_message : NULL);
145 }
146
147 /* Gets an fvalue from a string, and sets the error message on failure. */
148 static fvalue_t*
149 dfilter_fvalue_from_string(dfwork_t *dfw, ftenum_t ftype, const char *s)
150 {
151 return fvalue_from_string(ftype, s,
152 dfw->error_message == NULL ? &dfw->error_message : NULL);
153 }
154
155 /* Creates a FT_UINT32 fvalue with a given value. */
156 static fvalue_t*
157 mk_uint32_fvalue(guint32 val)
158 {
159 fvalue_t *fv;
160
161 fv = fvalue_new(FT_UINT32);
162 fvalue_set_uinteger(fv, val);
163
drange_free(drange_t * dr)164 return fv;
165 }
166
167 /* Creates a FT_UINT64 fvalue with a given value. */
168 static fvalue_t*
169 mk_uint64_fvalue(guint64 val)
170 {
171 fvalue_t *fv;
drange_node_free_list(GSList * list)172
173 fv = fvalue_new(FT_UINT64);
174 fvalue_set_uinteger64(fv, val);
175
176 return fv;
177 }
drange_has_total_length(drange_t * dr)178
179 /* Try to make an fvalue from a string using a value_string or true_false_string.
180 * This works only for ftypes that are integers. Returns the created fvalue_t*
181 * or NULL if impossible. */
182 static fvalue_t*
183 mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, char *s)
184 {
185 static const true_false_string default_tf = { "True", "False" };
186 const true_false_string *tf = &default_tf;
187
188 /* Early return? */
189 switch(hfinfo->type) {
190 case FT_NONE:
191 case FT_PROTOCOL:
192 case FT_FLOAT:
193 case FT_DOUBLE:
194 case FT_IEEE_11073_SFLOAT:
195 case FT_IEEE_11073_FLOAT:
196 case FT_ABSOLUTE_TIME:
197 case FT_RELATIVE_TIME:
198 case FT_IPv4:
199 case FT_IPv6:
200 case FT_IPXNET:
201 case FT_AX25:
202 case FT_VINES:
203 case FT_FCWWN:
204 case FT_ETHER:
205 case FT_BYTES:
206 case FT_UINT_BYTES:
207 case FT_STRING:
208 case FT_STRINGZ:
209 case FT_UINT_STRING:
210 case FT_STRINGZPAD:
211 case FT_STRINGZTRUNC:
212 case FT_EUI64:
213 case FT_GUID:
214 case FT_OID:
215 case FT_REL_OID:
216 case FT_SYSTEM_ID:
217 case FT_FRAMENUM: /* hfinfo->strings contains ft_framenum_type_t, not strings */
218 return NULL;
219
220 case FT_BOOLEAN:
221 case FT_CHAR:
222 case FT_UINT8:
223 case FT_UINT16:
224 case FT_UINT24:
225 case FT_UINT32:
226 case FT_UINT40:
227 case FT_UINT48:
228 case FT_UINT56:
229 case FT_UINT64:
230 case FT_INT8:
231 case FT_INT16:
232 case FT_INT24:
233 case FT_INT32:
234 case FT_INT40:
235 case FT_INT48:
236 case FT_INT56:
237 case FT_INT64:
238 break;
239
240 case FT_NUM_TYPES:
241 ws_assert_not_reached();
242 }
243
244 /* TRUE/FALSE *always* exist for FT_BOOLEAN. */
245 if (hfinfo->type == FT_BOOLEAN) {
246 if (hfinfo->strings) {
247 tf = (const true_false_string *)hfinfo->strings;
248 }
249
250 if (g_ascii_strcasecmp(s, tf->true_string) == 0) {
251 return mk_uint64_fvalue(TRUE);
252 }
253 else if (g_ascii_strcasecmp(s, tf->false_string) == 0) {
254 return mk_uint64_fvalue(FALSE);
255 }
256 else {
257 /*
258 * Prefer this error message to whatever error message
259 * has already been set.
260 */
261 g_free(dfw->error_message);
262 dfw->error_message = NULL;
263 dfilter_fail(dfw, "\"%s\" cannot be found among the possible values for %s.",
264 s, hfinfo->abbrev);
265 return NULL;
266 }
267 }
268
269 /* Do val_strings exist? */
270 if (!hfinfo->strings) {
271 dfilter_fail(dfw, "%s cannot accept strings as values.",
272 hfinfo->abbrev);
273 return NULL;
274 }
275
276 /* Reset the error message, since *something* interesting will happen,
277 * and the error message will be more interesting than any error message
278 * I happen to have now. */
279 g_free(dfw->error_message);
280 dfw->error_message = NULL;
281
282 if (hfinfo->display & BASE_RANGE_STRING) {
283 dfilter_fail(dfw, "\"%s\" cannot accept [range] strings as values.",
284 hfinfo->abbrev);
285 }
286 else if (hfinfo->display & BASE_VAL64_STRING) {
287 const val64_string *vals = (const val64_string *)hfinfo->strings;
288
289 while (vals->strptr != NULL) {
290 if (g_ascii_strcasecmp(s, vals->strptr) == 0) {
291 return mk_uint64_fvalue(vals->value);
292 }
293 vals++;
294 }
295 dfilter_fail(dfw, "\"%s\" cannot be found among the possible values for %s.",
296 s, hfinfo->abbrev);
297 }
298 else if (hfinfo->display == BASE_CUSTOM) {
299 /* If a user wants to match against a custom string, we would
300 * somehow have to have the integer value here to pass it in
301 * to the custom-display function. But we don't have an
302 * integer, we have the string they're trying to match.
303 * -><-
304 */
305 dfilter_fail(dfw, "\"%s\" cannot accept [custom] strings as values.",
306 hfinfo->abbrev);
307 }
308 else {
309 const value_string *vals = (const value_string *)hfinfo->strings;
310 if (hfinfo->display & BASE_EXT_STRING)
311 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *) vals);
312
313 while (vals->strptr != NULL) {
314 if (g_ascii_strcasecmp(s, vals->strptr) == 0) {
315 return mk_uint32_fvalue(vals->value);
316 }
317 vals++;
318 }
319 dfilter_fail(dfw, "\"%s\" cannot be found among the possible values for %s.",
320 s, hfinfo->abbrev);
321 }
322 return NULL;
323 }
324
325 static gboolean
326 is_bytes_type(enum ftenum type)
327 {
328 switch(type) {
329 case FT_AX25:
330 case FT_VINES:
331 case FT_FCWWN:
332 case FT_ETHER:
333 case FT_BYTES:
334 case FT_UINT_BYTES:
335 case FT_IPv6:
336 case FT_GUID:
337 case FT_OID:
338 case FT_REL_OID:
339 case FT_SYSTEM_ID:
340 return TRUE;
341
342 case FT_NONE:
343 case FT_PROTOCOL:
344 case FT_FLOAT:
345 case FT_DOUBLE:
346 case FT_IEEE_11073_SFLOAT:
347 case FT_IEEE_11073_FLOAT:
348 case FT_ABSOLUTE_TIME:
349 case FT_RELATIVE_TIME:
350 case FT_IPv4:
351 case FT_IPXNET:
352 case FT_STRING:
353 case FT_STRINGZ:
354 case FT_UINT_STRING:
355 case FT_STRINGZPAD:
356 case FT_STRINGZTRUNC:
357 case FT_BOOLEAN:
358 case FT_FRAMENUM:
359 case FT_CHAR:
360 case FT_UINT8:
361 case FT_UINT16:
362 case FT_UINT24:
363 case FT_UINT32:
364 case FT_UINT40:
365 case FT_UINT48:
366 case FT_UINT56:
367 case FT_UINT64:
368 case FT_INT8:
369 case FT_INT16:
370 case FT_INT24:
371 case FT_INT32:
372 case FT_INT40:
373 case FT_INT48:
374 case FT_INT56:
375 case FT_INT64:
376 case FT_EUI64:
377 return FALSE;
378
379 case FT_NUM_TYPES:
380 ws_assert_not_reached();
381 }
382
383 ws_assert_not_reached();
384 return FALSE;
385 }
386
387 /* Gets a GRegex from a string, and sets the error message on failure. */
388 static GRegex*
389 dfilter_g_regex_from_string(dfwork_t *dfw, const char *s)
390 {
391 GError *regex_error = NULL;
392 GRegexCompileFlags cflags = (GRegexCompileFlags)(G_REGEX_CASELESS | G_REGEX_OPTIMIZE);
393 GRegex *pcre;
394
395 /*
396 * As FT_BYTES and FT_PROTOCOL contain arbitrary binary data
397 * and FT_STRING is not guaranteed to contain valid UTF-8,
398 * we have to disable support for UTF-8 patterns and treat
399 * every pattern and subject as raw bytes.
400 *
401 * Should support for UTF-8 patterns be necessary, then we
402 * should compile a pattern without G_REGEX_RAW. Additionally,
403 * we MUST use g_utf8_validate() before calling g_regex_match_full()
404 * or risk crashes.
405 */
406 cflags = (GRegexCompileFlags)(cflags | G_REGEX_RAW);
407
408 ws_debug("Compile regex pattern: %s", s);
409
410 pcre = g_regex_new(
411 s, /* pattern */
412 cflags, /* Compile options */
413 (GRegexMatchFlags)0, /* Match options */
414 ®ex_error /* Compile / study errors */
415 );
416
417 if (regex_error) {
418 if (dfw->error_message == NULL)
419 dfw->error_message = g_strdup(regex_error->message);
420 g_error_free(regex_error);
421 if (pcre) {
422 g_regex_unref(pcre);
423 }
424 return NULL;
425 }
426 return pcre;
427 }
428
429 /* Check the semantics of an existence test. */
430 static void
431 check_exists(dfwork_t *dfw, stnode_t *st_arg1)
432 {
433 static guint i = 0;
434
435 ws_debug("4 check_exists() [%u]", i++);
436 log_stnode(st_arg1);
437
438 switch (stnode_type_id(st_arg1)) {
439 case STTYPE_FIELD:
440 /* This is OK */
441 break;
442 case STTYPE_STRING:
443 case STTYPE_CHARCONST:
444 case STTYPE_UNPARSED:
445 dfilter_fail(dfw, "\"%s\" is neither a field nor a protocol name.",
446 (char *)stnode_data(st_arg1));
447 THROW(TypeError);
448 break;
449
450 case STTYPE_RANGE:
451 /*
452 * XXX - why not? Shouldn't "eth[3:2]" mean
453 * "check whether the 'eth' field is present and
454 * has at least 2 bytes starting at an offset of
455 * 3"?
456 */
457 dfilter_fail(dfw, "You cannot test whether a range is present.");
458 THROW(TypeError);
459 break;
460
461 case STTYPE_FUNCTION:
462 /* XXX - Maybe we should change functions so they can return fields,
463 * in which case the 'exist' should be fine. */
464 dfilter_fail(dfw, "You cannot test whether a function is present.");
465 THROW(TypeError);
466 break;
467
468 case STTYPE_UNINITIALIZED:
469 case STTYPE_TEST:
470 case STTYPE_INTEGER:
471 case STTYPE_FVALUE:
472 case STTYPE_SET:
473 case STTYPE_PCRE:
474 case STTYPE_NUM_TYPES:
475 ws_assert_not_reached();
476 }
477 }
478
479 struct check_drange_sanity_args {
480 dfwork_t *dfw;
481 stnode_t *st;
482 gboolean err;
483 };
484
485 static void
486 check_drange_node_sanity(gpointer data, gpointer user_data)
487 {
488 drange_node* drnode = (drange_node*)data;
489 struct check_drange_sanity_args *args = (struct check_drange_sanity_args*)user_data;
490 gint start_offset, end_offset, length;
491 stnode_t *entity;
492 header_field_info *hfinfo;
493
494 switch (drange_node_get_ending(drnode)) {
495
496 case DRANGE_NODE_END_T_LENGTH:
497 length = drange_node_get_length(drnode);
498 if (length <= 0) {
499 if (!args->err) {
500 args->err = TRUE;
501 start_offset = drange_node_get_start_offset(drnode);
502 entity = sttype_range_entity(args->st);
503 if (entity && stnode_type_id(entity) == STTYPE_FIELD) {
504 hfinfo = (header_field_info *)stnode_data(entity);
505
506 dfilter_fail(args->dfw, "Range %d:%d specified for \"%s\" isn't valid, "
507 "as length %d isn't positive",
508 start_offset, length,
509 hfinfo->abbrev,
510 length);
511 } else
512 dfilter_fail(args->dfw, "Range %d:%d isn't valid, "
513 "as length %d isn't positive",
514 start_offset, length,
515 length);
516 }
517 }
518 break;
519
520 case DRANGE_NODE_END_T_OFFSET:
521 /*
522 * Make sure the start offset isn't beyond the end
523 * offset. This applies to negative offsets too.
524 */
525
526 /* XXX - [-ve - +ve] is probably pathological, but isn't
527 * disallowed.
528 * [+ve - -ve] is probably pathological too, and happens to be
529 * disallowed.
530 */
531 start_offset = drange_node_get_start_offset(drnode);
532 end_offset = drange_node_get_end_offset(drnode);
533 if (start_offset > end_offset) {
534 if (!args->err) {
535 args->err = TRUE;
536 entity = sttype_range_entity(args->st);
537 if (entity && stnode_type_id(entity) == STTYPE_FIELD) {
538 hfinfo = (header_field_info *)stnode_data(entity);
539
540 dfilter_fail(args->dfw, "Range %d-%d specified for \"%s\" isn't valid, "
541 "as %d is greater than %d",
542 start_offset, end_offset,
543 hfinfo->abbrev,
544 start_offset, end_offset);
545
546 } else
547 dfilter_fail(args->dfw, "Range %d-%d isn't valid, "
548 "as %d is greater than %d",
549 start_offset, end_offset,
550 start_offset, end_offset);
551 }
552 }
553 break;
554
555 case DRANGE_NODE_END_T_TO_THE_END:
556 break;
557
558 case DRANGE_NODE_END_T_UNINITIALIZED:
559 default:
560 ws_assert_not_reached();
561 }
562 }
563
564 static void
565 check_drange_sanity(dfwork_t *dfw, stnode_t *st)
566 {
567 stnode_t *entity1;
568 header_field_info *hfinfo1;
569 ftenum_t ftype1;
570 struct check_drange_sanity_args args;
571 char *s;
572
573 entity1 = sttype_range_entity(st);
574 if (entity1 && stnode_type_id(entity1) == STTYPE_FIELD) {
575 hfinfo1 = (header_field_info *)stnode_data(entity1);
576 ftype1 = hfinfo1->type;
577
578 if (!ftype_can_slice(ftype1)) {
579 dfilter_fail(dfw, "\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
580 hfinfo1->abbrev, ftype_pretty_name(ftype1));
581 THROW(TypeError);
582 }
583 } else if (entity1 && stnode_type_id(entity1) == STTYPE_FUNCTION) {
584 df_func_def_t *funcdef = sttype_function_funcdef(entity1);
585 ftype1 = funcdef->retval_ftype;
586
587 if (!ftype_can_slice(ftype1)) {
588 dfilter_fail(dfw, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
589 funcdef->name, ftype_pretty_name(ftype1));
590 THROW(TypeError);
591 }
592
593 check_function(dfw, entity1);
594 } else if (entity1 && stnode_type_id(entity1) == STTYPE_RANGE) {
595 /* Should this be rejected instead? */
596 check_drange_sanity(dfw, entity1);
597 } else if (entity1) {
598 s = stnode_tostr(entity1);
599 dfilter_fail(dfw, "Range is not supported for entity %s of type %s",
600 s, stnode_type_name(entity1));
601 g_free(s);
602 THROW(TypeError);
603 } else {
604 dfilter_fail(dfw, "Range is not supported, details: " G_STRLOC " entity: NULL");
605 THROW(TypeError);
606 }
607
608 args.dfw = dfw;
609 args.st = st;
610 args.err = FALSE;
611
612 drange_foreach_drange_node(sttype_range_drange(st),
613 check_drange_node_sanity, &args);
614
615 if (args.err) {
616 THROW(TypeError);
617 }
618 }
619
620 static stnode_t *
621 convert_to_bytes(stnode_t *arg)
622 {
623 stnode_t *new_st;
624 drange_node *rn;
625
626 new_st = stnode_new(STTYPE_RANGE, NULL, arg->token_value);
627
628 rn = drange_node_new();
629 drange_node_set_start_offset(rn, 0);
630 drange_node_set_to_the_end(rn);
631 /* new_st is owner of arg in this step */
632 sttype_range_set1(new_st, arg, rn);
633
634 return new_st;
635 }
636
637 static void
638 check_function(dfwork_t *dfw, stnode_t *st_node)
639 {
640 df_func_def_t *funcdef;
641 GSList *params;
642 guint iparam;
643 guint nparams;
644
645 funcdef = sttype_function_funcdef(st_node);
646 params = sttype_function_params(st_node);
647 nparams = g_slist_length(params);
648
649 if (nparams < funcdef->min_nargs) {
650 dfilter_fail(dfw, "Function %s needs at least %u arguments.",
651 funcdef->name, funcdef->min_nargs);
652 THROW(TypeError);
653 } else if (nparams > funcdef->max_nargs) {
654 dfilter_fail(dfw, "Function %s can only accept %u arguments.",
655 funcdef->name, funcdef->max_nargs);
656 THROW(TypeError);
657 }
658
659 iparam = 0;
660 while (params) {
661 params->data = check_param_entity(dfw, (stnode_t *)params->data);
662 funcdef->semcheck_param_function(dfw, iparam, (stnode_t *)params->data);
663 params = params->next;
664 iparam++;
665 }
666 }
667
668 /* Convert a character constant to a 1-byte BYTE_STRING containing the
669 * character. */
670 static fvalue_t *
671 dfilter_fvalue_from_charconst_string(dfwork_t *dfw, ftenum_t ftype, char *s, gboolean allow_partial_value)
672 {
673 fvalue_t *fvalue;
674
675 fvalue = dfilter_fvalue_from_unparsed(dfw, FT_CHAR, s, allow_partial_value);
676 if (fvalue) {
677 char *temp_string;
678 /* It's valid. Create a 1-byte BYTE_STRING from its value. */
679 temp_string = g_strdup_printf("%02x", fvalue->value.uinteger);
680 FVALUE_FREE(fvalue);
681 fvalue = dfilter_fvalue_from_unparsed(dfw, ftype, temp_string, allow_partial_value);
682 g_free(temp_string);
683 }
684 return (fvalue);
685 }
686
687 /* If the LHS of a relation test is a FIELD, run some checks
688 * and possibly some modifications of syntax tree nodes. */
689 static void
690 check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string,
691 FtypeCanFunc can_func, gboolean allow_partial_value,
692 stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
693 {
694 stnode_t *new_st;
695 sttype_id_t type2;
696 header_field_info *hfinfo1, *hfinfo2;
697 df_func_def_t *funcdef;
698 ftenum_t ftype1, ftype2;
699 fvalue_t *fvalue;
700 GRegex *pcre;
701 char *s;
702
703 type2 = stnode_type_id(st_arg2);
704
705 hfinfo1 = (header_field_info*)stnode_data(st_arg1);
706 ftype1 = hfinfo1->type;
707
708 if (stnode_type_id(st_node) == STTYPE_TEST) {
709 ws_debug("5 check_relation_LHS_FIELD(%s)", relation_string);
710 } else {
711 ws_debug("6 check_relation_LHS_FIELD(%s)", relation_string);
712 }
713
714 if (!can_func(ftype1)) {
715 dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
716 hfinfo1->abbrev, ftype_pretty_name(ftype1),
717 relation_string);
718 THROW(TypeError);
719 }
720
721 if (type2 == STTYPE_FIELD) {
722 hfinfo2 = (header_field_info*)stnode_data(st_arg2);
723 ftype2 = hfinfo2->type;
724
725 if (!compatible_ftypes(ftype1, ftype2)) {
726 dfilter_fail(dfw, "%s and %s are not of compatible types.",
727 hfinfo1->abbrev, hfinfo2->abbrev);
728 THROW(TypeError);
729 }
730 /* Do this check even though you'd think that if
731 * they're compatible, then can_func() would pass. */
732 if (!can_func(ftype2)) {
733 dfilter_fail(dfw, "%s (type=%s) cannot participate in specified comparison.",
734 hfinfo2->abbrev, ftype_pretty_name(ftype2));
735 THROW(TypeError);
736 }
737 }
738 else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED ||
739 type2 == STTYPE_CHARCONST) {
740 s = (char *)stnode_data(st_arg2);
741 if (strcmp(relation_string, "matches") == 0) {
742 /* Convert to a GRegex */
743 pcre = dfilter_g_regex_from_string(dfw, s);
744 if (!pcre) {
745 THROW(TypeError);
746 }
747 stnode_replace(st_arg2, STTYPE_PCRE, pcre);
748 } else {
749 /* Skip incompatible fields */
750 while (hfinfo1->same_name_prev_id != -1 &&
751 ((type2 == STTYPE_STRING && ftype1 != FT_STRING && ftype1!= FT_STRINGZ) ||
752 (type2 != STTYPE_STRING && (ftype1 == FT_STRING || ftype1== FT_STRINGZ)))) {
753 hfinfo1 = proto_registrar_get_nth(hfinfo1->same_name_prev_id);
754 ftype1 = hfinfo1->type;
755 }
756
757 if (type2 == STTYPE_STRING)
758 fvalue = dfilter_fvalue_from_string(dfw, ftype1, s);
759 else if (type2 == STTYPE_CHARCONST &&
760 strcmp(relation_string, "contains") == 0) {
761 /* The RHS should be the same type as the LHS,
762 * but a character is just a one-byte byte
763 * string. */
764 fvalue = dfilter_fvalue_from_charconst_string(dfw, ftype1, s, allow_partial_value);
765 } else
766 fvalue = dfilter_fvalue_from_unparsed(dfw, ftype1, s, allow_partial_value);
767
768 /*
769 * If this is a character constant, just report the
770 * error, don't try to treat it as a string from
771 * a value_string table.
772 */
773 if (!fvalue && type2 != STTYPE_CHARCONST) {
774 /* check value_string */
775 fvalue = mk_fvalue_from_val_string(dfw, hfinfo1, s);
776
777 /*
778 * Ignore previous errors if this can be mapped
779 * to an item from value_string.
780 */
781 if (fvalue && dfw->error_message) {
782 g_free(dfw->error_message);
783 dfw->error_message = NULL;
784 }
785 }
786 if (!fvalue) {
787 THROW(TypeError);
788 }
789 stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
790 }
791 }
792 else if (type2 == STTYPE_RANGE) {
793 check_drange_sanity(dfw, st_arg2);
794 if (!is_bytes_type(ftype1)) {
795 if (!ftype_can_slice(ftype1)) {
796 dfilter_fail(dfw, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
797 hfinfo1->abbrev,
798 ftype_pretty_name(ftype1));
799 THROW(TypeError);
800 }
801
802 /* Convert entire field to bytes */
803 new_st = convert_to_bytes(st_arg1);
804
805 sttype_test_set2_args(st_node, new_st, st_arg2);
806 }
807 }
808 else if (type2 == STTYPE_FUNCTION) {
809 funcdef = sttype_function_funcdef(st_arg2);
810 ftype2 = funcdef->retval_ftype;
811
812 if (!compatible_ftypes(ftype1, ftype2)) {
813 dfilter_fail(dfw, "%s (type=%s) and return value of %s() (type=%s) are not of compatible types.",
814 hfinfo1->abbrev, ftype_pretty_name(ftype1),
815 funcdef->name, ftype_pretty_name(ftype2));
816 THROW(TypeError);
817 }
818
819 if (!can_func(ftype2)) {
820 dfilter_fail(dfw, "return value of %s() (type=%s) cannot participate in specified comparison.",
821 funcdef->name, ftype_pretty_name(ftype2));
822 THROW(TypeError);
823 }
824
825 check_function(dfw, st_arg2);
826 }
827 else if (type2 == STTYPE_SET) {
828 GSList *nodelist;
829 /* A set should only ever appear on RHS of 'in' operation */
830 if (strcmp(relation_string, "in") != 0) {
831 ws_assert_not_reached();
832 }
833 /* Attempt to interpret one element of the set at a time. Each
834 * element is represented by two items in the list, the element
835 * value and NULL. Both will be replaced by a lower and upper
836 * value if the element is a range. */
837 nodelist = (GSList*)stnode_data(st_arg2);
838 while (nodelist) {
839 stnode_t *node = (stnode_t*)nodelist->data;
840 /* Don't let a range on the RHS affect the LHS field. */
841 if (stnode_type_id(node) == STTYPE_RANGE) {
842 dfilter_fail(dfw, "A range may not appear inside a set.");
843 THROW(TypeError);
844 break;
845 }
846
847 nodelist = g_slist_next(nodelist);
848 ws_assert(nodelist);
849 stnode_t *node_right = (stnode_t *)nodelist->data;
850 if (node_right) {
851 /* range type, check if comparison is possible. */
852 if (!ftype_can_ge(ftype1)) {
853 dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
854 hfinfo1->abbrev, ftype_pretty_name(ftype1),
855 ">=");
856 THROW(TypeError);
857 }
858 check_relation_LHS_FIELD(dfw, ">=", ftype_can_ge,
859 allow_partial_value, st_arg2, st_arg1, node);
860 check_relation_LHS_FIELD(dfw, "<=", ftype_can_le,
861 allow_partial_value, st_arg2, st_arg1, node_right);
862 } else {
863 check_relation_LHS_FIELD(dfw, "==", can_func,
864 allow_partial_value, st_arg2, st_arg1, node);
865 }
866 nodelist = g_slist_next(nodelist);
867 }
868 }
869 else {
870 ws_assert_not_reached();
871 }
872 }
873
874 static void
875 check_relation_LHS_STRING(dfwork_t *dfw, const char* relation_string,
876 FtypeCanFunc can_func, gboolean allow_partial_value _U_,
877 stnode_t *st_node _U_,
878 stnode_t *st_arg1, stnode_t *st_arg2)
879 {
880 sttype_id_t type2;
881 header_field_info *hfinfo2;
882 df_func_def_t *funcdef;
883 ftenum_t ftype2;
884 fvalue_t *fvalue;
885 char *s;
886
887 type2 = stnode_type_id(st_arg2);
888
889 ws_debug("5 check_relation_LHS_STRING()");
890
891 if (type2 == STTYPE_FIELD) {
892 hfinfo2 = (header_field_info*)stnode_data(st_arg2);
893 ftype2 = hfinfo2->type;
894
895 if (!can_func(ftype2)) {
896 dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
897 hfinfo2->abbrev, ftype_pretty_name(ftype2),
898 relation_string);
899 THROW(TypeError);
900 }
901
902 s = (char*)stnode_data(st_arg1);
903 fvalue = dfilter_fvalue_from_string(dfw, ftype2, s);
904 if (!fvalue) {
905 /* check value_string */
906 fvalue = mk_fvalue_from_val_string(dfw, hfinfo2, s);
907 if (!fvalue) {
908 THROW(TypeError);
909 }
910 }
911
912 stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
913 }
914 else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED ||
915 type2 == STTYPE_CHARCONST) {
916 /* Well now that's silly... */
917 dfilter_fail(dfw, "Neither \"%s\" nor \"%s\" are field or protocol names.",
918 (char *)stnode_data(st_arg1),
919 (char *)stnode_data(st_arg2));
920 THROW(TypeError);
921 }
922 else if (type2 == STTYPE_RANGE) {
923 check_drange_sanity(dfw, st_arg2);
924 s = (char*)stnode_data(st_arg1);
925 fvalue = dfilter_fvalue_from_string(dfw, FT_BYTES, s);
926 if (!fvalue) {
927 THROW(TypeError);
928 }
929 stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
930 }
931 else if (type2 == STTYPE_FUNCTION) {
932 funcdef = sttype_function_funcdef(st_arg2);
933 ftype2 = funcdef->retval_ftype;
934
935 if (!can_func(ftype2)) {
936 dfilter_fail(dfw, "Return value of function %s (type=%s) cannot participate in '%s' comparison.",
937 funcdef->name, ftype_pretty_name(ftype2),
938 relation_string);
939 THROW(TypeError);
940 }
941
942 s = (char*)stnode_data(st_arg1);
943 fvalue = dfilter_fvalue_from_string(dfw, ftype2, s);
944 if (!fvalue) {
945 THROW(TypeError);
946 }
947
948 check_function(dfw, st_arg2);
949
950 stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
951 }
952 else if (type2 == STTYPE_SET) {
953 dfilter_fail(dfw, "Only a field may be tested for membership in a set.");
954 THROW(TypeError);
955 }
956 else {
957 ws_assert_not_reached();
958 }
959 }
960
961 static void
962 check_relation_LHS_UNPARSED(dfwork_t *dfw, const char* relation_string,
963 FtypeCanFunc can_func, gboolean allow_partial_value,
964 stnode_t *st_node _U_,
965 stnode_t *st_arg1, stnode_t *st_arg2)
966 {
967 sttype_id_t type2;
968 header_field_info *hfinfo2;
969 df_func_def_t *funcdef;
970 ftenum_t ftype2;
971 fvalue_t *fvalue;
972 char *s;
973
974 type2 = stnode_type_id(st_arg2);
975
976 ws_debug("5 check_relation_LHS_UNPARSED()");
977
978 if (type2 == STTYPE_FIELD) {
979 hfinfo2 = (header_field_info*)stnode_data(st_arg2);
980 ftype2 = hfinfo2->type;
981
982 if (!can_func(ftype2)) {
983 dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
984 hfinfo2->abbrev, ftype_pretty_name(ftype2),
985 relation_string);
986 THROW(TypeError);
987 }
988
989 s = (char*)stnode_data(st_arg1);
990 fvalue = dfilter_fvalue_from_unparsed(dfw, ftype2, s, allow_partial_value);
991 if (!fvalue) {
992 /* check value_string */
993 fvalue = mk_fvalue_from_val_string(dfw, hfinfo2, s);
994 if (!fvalue) {
995 THROW(TypeError);
996 }
997 }
998
999 stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
1000 }
1001 else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED ||
1002 type2 == STTYPE_CHARCONST) {
1003 /* Well now that's silly... */
1004 dfilter_fail(dfw, "Neither \"%s\" nor \"%s\" are field or protocol names.",
1005 (char *)stnode_data(st_arg1),
1006 (char *)stnode_data(st_arg2));
1007 THROW(TypeError);
1008 }
1009 else if (type2 == STTYPE_RANGE) {
1010 check_drange_sanity(dfw, st_arg2);
1011 s = (char*)stnode_data(st_arg1);
1012 fvalue = dfilter_fvalue_from_unparsed(dfw, FT_BYTES, s, allow_partial_value);
1013 if (!fvalue) {
1014 THROW(TypeError);
1015 }
1016 stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
1017 }
1018 else if (type2 == STTYPE_FUNCTION) {
1019 funcdef = sttype_function_funcdef(st_arg2);
1020 ftype2 = funcdef->retval_ftype;
1021
1022 if (!can_func(ftype2)) {
1023 dfilter_fail(dfw, "return value of function %s() (type=%s) cannot participate in '%s' comparison.",
1024 funcdef->name, ftype_pretty_name(ftype2), relation_string);
1025 THROW(TypeError);
1026 }
1027
1028 s = (char*)stnode_data(st_arg1);
1029 fvalue = dfilter_fvalue_from_unparsed(dfw, ftype2, s, allow_partial_value);
1030
1031 if (!fvalue) {
1032 THROW(TypeError);
1033 }
1034
1035 check_function(dfw, st_arg2);
1036
1037 stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
1038 }
1039 else if (type2 == STTYPE_SET) {
1040 dfilter_fail(dfw, "Only a field may be tested for membership in a set.");
1041 THROW(TypeError);
1042 }
1043 else {
1044 ws_assert_not_reached();
1045 }
1046 }
1047
1048 static void
1049 check_relation_LHS_RANGE(dfwork_t *dfw, const char *relation_string,
1050 FtypeCanFunc can_func _U_,
1051 gboolean allow_partial_value,
1052 stnode_t *st_node,
1053 stnode_t *st_arg1, stnode_t *st_arg2)
1054 {
1055 stnode_t *new_st;
1056 sttype_id_t type2;
1057 header_field_info *hfinfo2;
1058 ftenum_t ftype2;
1059 fvalue_t *fvalue;
1060 GRegex *pcre;
1061 char *s;
1062
1063 ws_debug("5 check_relation_LHS_RANGE(%s)", relation_string);
1064
1065 check_drange_sanity(dfw, st_arg1);
1066
1067 type2 = stnode_type_id(st_arg2);
1068
1069 if (type2 == STTYPE_FIELD) {
1070 ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_FIELD)");
1071 hfinfo2 = (header_field_info*)stnode_data(st_arg2);
1072 ftype2 = hfinfo2->type;
1073
1074 if (!is_bytes_type(ftype2)) {
1075 if (!ftype_can_slice(ftype2)) {
1076 dfilter_fail(dfw, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
1077 hfinfo2->abbrev,
1078 ftype_pretty_name(ftype2));
1079 THROW(TypeError);
1080 }
1081
1082 /* Convert entire field to bytes */
1083 new_st = convert_to_bytes(st_arg2);
1084
1085 sttype_test_set2_args(st_node, st_arg1, new_st);
1086 }
1087 }
1088 else if (type2 == STTYPE_STRING) {
1089 ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_STRING)");
1090 s = (char*)stnode_data(st_arg2);
1091 if (strcmp(relation_string, "matches") == 0) {
1092 /* Convert to a GRegex * */
1093 pcre = dfilter_g_regex_from_string(dfw, s);
1094 if (!pcre) {
1095 THROW(TypeError);
1096 }
1097 stnode_replace(st_arg2, STTYPE_PCRE, pcre);
1098 } else {
1099 fvalue = dfilter_fvalue_from_string(dfw, FT_BYTES, s);
1100 if (!fvalue) {
1101 THROW(TypeError);
1102 }
1103 stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
1104 }
1105 }
1106 else if (type2 == STTYPE_UNPARSED) {
1107 ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED)");
1108 s = (char*)stnode_data(st_arg2);
1109 if (strcmp(relation_string, "matches") == 0) {
1110 /* Convert to a GRegex */
1111 pcre = dfilter_g_regex_from_string(dfw, s);
1112 if (!pcre) {
1113 THROW(TypeError);
1114 }
1115 stnode_replace(st_arg2, STTYPE_PCRE, pcre);
1116 } else {
1117 fvalue = dfilter_fvalue_from_unparsed(dfw, FT_BYTES, s, allow_partial_value);
1118 if (!fvalue) {
1119 THROW(TypeError);
1120 }
1121 stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
1122 }
1123 }
1124 else if (type2 == STTYPE_CHARCONST) {
1125 ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_CHARCONST)");
1126 s = (char*)stnode_data(st_arg2);
1127 if (strcmp(relation_string, "matches") == 0) {
1128 /* Convert to a GRegex */
1129 pcre = dfilter_g_regex_from_string(dfw, s);
1130 if (!pcre) {
1131 THROW(TypeError);
1132 }
1133 stnode_replace(st_arg2, STTYPE_PCRE, pcre);
1134 } else {
1135 /* The RHS should be FT_BYTES, but a character is just a
1136 * one-byte byte string. */
1137 fvalue = dfilter_fvalue_from_charconst_string(dfw, FT_BYTES, s, allow_partial_value);
1138 if (!fvalue) {
1139 THROW(TypeError);
1140 }
1141 stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
1142 }
1143 }
1144 else if (type2 == STTYPE_RANGE) {
1145 ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_RANGE)");
1146 check_drange_sanity(dfw, st_arg2);
1147 }
1148 else if (type2 == STTYPE_FUNCTION) {
1149 df_func_def_t *funcdef = sttype_function_funcdef(st_arg2);
1150 ftype2 = funcdef->retval_ftype;
1151
1152 if (!is_bytes_type(ftype2)) {
1153 if (!ftype_can_slice(ftype2)) {
1154 dfilter_fail(dfw, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
1155 funcdef->name,
1156 ftype_pretty_name(ftype2));
1157 THROW(TypeError);
1158 }
1159
1160 /* Convert function result to bytes */
1161 new_st = convert_to_bytes(st_arg2);
1162
1163 sttype_test_set2_args(st_node, st_arg1, new_st);
1164 }
1165
1166 check_function(dfw, st_arg2);
1167 }
1168 else if (type2 == STTYPE_SET) {
1169 dfilter_fail(dfw, "Only a field may be tested for membership in a set.");
1170 THROW(TypeError);
1171 }
1172 else {
1173 ws_assert_not_reached();
1174 }
1175 }
1176
1177 static stnode_t*
1178 check_param_entity(dfwork_t *dfw, stnode_t *st_node)
1179 {
1180 sttype_id_t e_type;
1181 stnode_t *new_st;
1182 fvalue_t *fvalue;
1183 char *s;
1184
1185 e_type = stnode_type_id(st_node);
1186 /* If there's an unparsed string, change it to an FT_STRING */
1187 if (e_type == STTYPE_UNPARSED || e_type == STTYPE_CHARCONST) {
1188 s = (char*)stnode_data(st_node);
1189 fvalue = dfilter_fvalue_from_unparsed(dfw, FT_STRING, s, FALSE);
1190 if (!fvalue) {
1191 THROW(TypeError);
1192 }
1193
1194 new_st = stnode_new(STTYPE_FVALUE, fvalue, st_node->token_value);
1195 stnode_free(st_node);
1196 return new_st;
1197 }
1198 return st_node;
1199 }
1200
1201
1202 /* If the LHS of a relation test is a FUNCTION, run some checks
1203 * and possibly some modifications of syntax tree nodes. */
1204 static void
1205 check_relation_LHS_FUNCTION(dfwork_t *dfw, const char *relation_string,
1206 FtypeCanFunc can_func,
1207 gboolean allow_partial_value,
1208 stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
1209 {
1210 stnode_t *new_st;
1211 sttype_id_t type2;
1212 header_field_info *hfinfo2;
1213 ftenum_t ftype1, ftype2;
1214 fvalue_t *fvalue;
1215 GRegex *pcre;
1216 char *s;
1217 df_func_def_t *funcdef;
1218 df_func_def_t *funcdef2;
1219 /* GSList *params; */
1220
1221 check_function(dfw, st_arg1);
1222 type2 = stnode_type_id(st_arg2);
1223
1224 funcdef = sttype_function_funcdef(st_arg1);
1225 ftype1 = funcdef->retval_ftype;
1226
1227 /* params = */sttype_function_params(st_arg1); /* XXX: is this done for the side-effect ? */
1228
1229 ws_debug("5 check_relation_LHS_FUNCTION(%s)", relation_string);
1230
1231 if (!can_func(ftype1)) {
1232 dfilter_fail(dfw, "Function %s (type=%s) cannot participate in '%s' comparison.",
1233 funcdef->name, ftype_pretty_name(ftype1),
1234 relation_string);
1235 THROW(TypeError);
1236 }
1237
1238 if (type2 == STTYPE_FIELD) {
1239 hfinfo2 = (header_field_info*)stnode_data(st_arg2);
1240 ftype2 = hfinfo2->type;
1241
1242 if (!compatible_ftypes(ftype1, ftype2)) {
1243 dfilter_fail(dfw, "Function %s and %s are not of compatible types.",
1244 funcdef->name, hfinfo2->abbrev);
1245 THROW(TypeError);
1246 }
1247 /* Do this check even though you'd think that if
1248 * they're compatible, then can_func() would pass. */
1249 if (!can_func(ftype2)) {
1250 dfilter_fail(dfw, "%s (type=%s) cannot participate in specified comparison.",
1251 hfinfo2->abbrev, ftype_pretty_name(ftype2));
1252 THROW(TypeError);
1253 }
1254 }
1255 else if (type2 == STTYPE_STRING) {
1256 s = (char*)stnode_data(st_arg2);
1257 if (strcmp(relation_string, "matches") == 0) {
1258 /* Convert to a GRegex */
1259 pcre = dfilter_g_regex_from_string(dfw, s);
1260 if (!pcre) {
1261 THROW(TypeError);
1262 }
1263 stnode_replace(st_arg2, STTYPE_PCRE, pcre);
1264 } else {
1265 fvalue = dfilter_fvalue_from_string(dfw, ftype1, s);
1266 if (!fvalue) {
1267 THROW(TypeError);
1268 }
1269 stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
1270 }
1271 }
1272 else if (type2 == STTYPE_UNPARSED || type2 == STTYPE_CHARCONST) {
1273 s = (char*)stnode_data(st_arg2);
1274 if (strcmp(relation_string, "matches") == 0) {
1275 /* Convert to a GRegex */
1276 pcre = dfilter_g_regex_from_string(dfw, s);
1277 if (!pcre) {
1278 THROW(TypeError);
1279 }
1280 stnode_replace(st_arg2, STTYPE_PCRE, pcre);
1281 } else {
1282 fvalue = dfilter_fvalue_from_unparsed(dfw, ftype1, s, allow_partial_value);
1283 if (!fvalue) {
1284 THROW(TypeError);
1285 }
1286 stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
1287 }
1288 }
1289 else if (type2 == STTYPE_RANGE) {
1290 check_drange_sanity(dfw, st_arg2);
1291 if (!is_bytes_type(ftype1)) {
1292 if (!ftype_can_slice(ftype1)) {
1293 dfilter_fail(dfw, "Function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
1294 funcdef->name,
1295 ftype_pretty_name(ftype1));
1296 THROW(TypeError);
1297 }
1298
1299 /* Convert function result to bytes */
1300 new_st = convert_to_bytes(st_arg1);
1301
1302 sttype_test_set2_args(st_node, new_st, st_arg2);
1303 }
1304 }
1305 else if (type2 == STTYPE_FUNCTION) {
1306 funcdef2 = sttype_function_funcdef(st_arg2);
1307 ftype2 = funcdef2->retval_ftype;
1308
1309 if (!compatible_ftypes(ftype1, ftype2)) {
1310 dfilter_fail(dfw, "Return values of function %s (type=%s) and function %s (type=%s) are not of compatible types.",
1311 funcdef->name, ftype_pretty_name(ftype1), funcdef2->name, ftype_pretty_name(ftype2));
1312 THROW(TypeError);
1313 }
1314
1315 /* Do this check even though you'd think that if
1316 * they're compatible, then can_func() would pass. */
1317 if (!can_func(ftype2)) {
1318 dfilter_fail(dfw, "Return value of %s (type=%s) cannot participate in specified comparison.",
1319 funcdef2->name, ftype_pretty_name(ftype2));
1320 THROW(TypeError);
1321 }
1322
1323 check_function(dfw, st_arg2);
1324 }
1325 else if (type2 == STTYPE_SET) {
1326 dfilter_fail(dfw, "Only a field may be tested for membership in a set.");
1327 THROW(TypeError);
1328 }
1329 else {
1330 ws_assert_not_reached();
1331 }
1332 }
1333
1334
1335 /* Check the semantics of any relational test. */
1336 static void
1337 check_relation(dfwork_t *dfw, const char *relation_string,
1338 gboolean allow_partial_value,
1339 FtypeCanFunc can_func, stnode_t *st_node,
1340 stnode_t *st_arg1, stnode_t *st_arg2)
1341 {
1342 static guint i = 0;
1343 header_field_info *hfinfo;
1344 char *s;
1345
1346 ws_debug("4 check_relation(\"%s\") [%u]", relation_string, i++);
1347 log_stnode(st_arg1);
1348 log_stnode(st_arg2);
1349
1350 /* Protocol can only be on LHS (for "contains" or "matches" operators).
1351 * Check to see if protocol is on RHS, and re-interpret it as UNPARSED
1352 * instead. The subsequent functions will parse it according to the
1353 * existing rules for unparsed unquoted strings.
1354 *
1355 * This catches the case where the user has written "fc" on the RHS,
1356 * probably intending a byte value rather than the fibre channel
1357 * protocol, or similar for a number of other possibilities
1358 * ("dc", "ff", "fefd"), and also catches the case where the user
1359 * has written a generic string on the RHS for a "contains" or
1360 * "matches" relation. (XXX: There's still a bit of a confusing mess;
1361 * byte arrays take precedent over generic strings when unquoted, so
1362 * "field contains data" matches "\x64 \x61 \x74 \x61" but
1363 * "field contains dc" matches "\xdc" and not "\x64 \x43", but that's
1364 * an underlying issue.)
1365 *
1366 * XXX: Is there a better way to do this in the lex scanner or grammar
1367 * parser step instead? Should the determination of whether something
1368 * is a field occur later than it does currently? This is kind of a
1369 * hack.
1370 */
1371
1372 if (stnode_type_id(st_arg2) == STTYPE_FIELD) {
1373 hfinfo = (header_field_info*)stnode_data(st_arg2);
1374 if (hfinfo->type == FT_PROTOCOL) {
1375 /* Discard const qualifier from hfinfo->abbrev
1376 * for sttnode_new, even though it duplicates the
1377 * string.
1378 */
1379 s = (char *)hfinfo->abbrev;
1380 /* Send it through as unparsed and all the other
1381 * functions will take care of it as if it didn't
1382 * match a protocol string.
1383 */
1384 stnode_replace(st_arg2, STTYPE_UNPARSED, s);
1385 }
1386 }
1387
1388 switch (stnode_type_id(st_arg1)) {
1389 case STTYPE_FIELD:
1390 check_relation_LHS_FIELD(dfw, relation_string, can_func,
1391 allow_partial_value, st_node, st_arg1, st_arg2);
1392 break;
1393 case STTYPE_STRING:
1394 check_relation_LHS_STRING(dfw, relation_string, can_func,
1395 allow_partial_value, st_node, st_arg1, st_arg2);
1396 break;
1397 case STTYPE_RANGE:
1398 check_relation_LHS_RANGE(dfw, relation_string, can_func,
1399 allow_partial_value, st_node, st_arg1, st_arg2);
1400 break;
1401 case STTYPE_UNPARSED:
1402 case STTYPE_CHARCONST:
1403 check_relation_LHS_UNPARSED(dfw, relation_string, can_func,
1404 allow_partial_value, st_node, st_arg1, st_arg2);
1405 break;
1406 case STTYPE_FUNCTION:
1407 check_relation_LHS_FUNCTION(dfw, relation_string, can_func,
1408 allow_partial_value, st_node, st_arg1, st_arg2);
1409 break;
1410
1411 case STTYPE_UNINITIALIZED:
1412 case STTYPE_TEST:
1413 case STTYPE_INTEGER:
1414 case STTYPE_FVALUE:
1415 case STTYPE_SET:
1416 default:
1417 ws_assert_not_reached();
1418 }
1419 }
1420
1421 /* Check the semantics of any type of TEST */
1422 static void
1423 check_test(dfwork_t *dfw, stnode_t *st_node)
1424 {
1425 test_op_t st_op, st_arg_op;
1426 stnode_t *st_arg1, *st_arg2;
1427 static guint i = 0;
1428
1429 ws_debug("3 check_test(stnode_t *st_node = %p) [%u]\n", st_node, i++);
1430 log_stnode(st_node);
1431
1432 sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2);
1433
1434 switch (st_op) {
1435 case TEST_OP_UNINITIALIZED:
1436 ws_assert_not_reached();
1437 break;
1438
1439 case TEST_OP_EXISTS:
1440 check_exists(dfw, st_arg1);
1441 break;
1442
1443 case TEST_OP_NOT:
1444 semcheck(dfw, st_arg1);
1445 break;
1446
1447 case TEST_OP_AND:
1448 case TEST_OP_OR:
1449 if (stnode_type_id(st_arg1) == STTYPE_TEST) {
1450 sttype_test_get(st_arg1, &st_arg_op, NULL, NULL);
1451 if (st_arg_op == TEST_OP_AND || st_arg_op == TEST_OP_OR) {
1452 if (st_op != st_arg_op && !stnode_inside_parens(st_arg1))
1453 add_deprecated_token(dfw, "suggest parentheses around '&&' within '||'");
1454 }
1455 }
1456
1457 if (stnode_type_id(st_arg2) == STTYPE_TEST) {
1458 sttype_test_get(st_arg2, &st_arg_op, NULL, NULL);
1459 if (st_arg_op == TEST_OP_AND || st_arg_op == TEST_OP_OR) {
1460 if (st_op != st_arg_op && !stnode_inside_parens(st_arg2))
1461 add_deprecated_token(dfw, "suggest parentheses around '&&' within '||'");
1462 }
1463 }
1464
1465 semcheck(dfw, st_arg1);
1466 semcheck(dfw, st_arg2);
1467 break;
1468
1469 case TEST_OP_ANY_EQ:
1470 check_relation(dfw, "==", FALSE, ftype_can_eq, st_node, st_arg1, st_arg2);
1471 break;
1472 case TEST_OP_ALL_NE:
1473 check_relation(dfw, "!=", FALSE, ftype_can_ne, st_node, st_arg1, st_arg2);
1474 break;
1475 case TEST_OP_ANY_NE:
1476 check_relation(dfw, "~=", FALSE, ftype_can_ne, st_node, st_arg1, st_arg2);
1477 break;
1478 case TEST_OP_GT:
1479 check_relation(dfw, ">", FALSE, ftype_can_gt, st_node, st_arg1, st_arg2);
1480 break;
1481 case TEST_OP_GE:
1482 check_relation(dfw, ">=", FALSE, ftype_can_ge, st_node, st_arg1, st_arg2);
1483 break;
1484 case TEST_OP_LT:
1485 check_relation(dfw, "<", FALSE, ftype_can_lt, st_node, st_arg1, st_arg2);
1486 break;
1487 case TEST_OP_LE:
1488 check_relation(dfw, "<=", FALSE, ftype_can_le, st_node, st_arg1, st_arg2);
1489 break;
1490 case TEST_OP_BITWISE_AND:
1491 check_relation(dfw, "&", FALSE, ftype_can_bitwise_and, st_node, st_arg1, st_arg2);
1492 break;
1493 case TEST_OP_CONTAINS:
1494 check_relation(dfw, "contains", TRUE, ftype_can_contains, st_node, st_arg1, st_arg2);
1495 break;
1496 case TEST_OP_MATCHES:
1497 check_relation(dfw, "matches", TRUE, ftype_can_matches, st_node, st_arg1, st_arg2);
1498 break;
1499 case TEST_OP_IN:
1500 /* Use the ftype_can_eq as the items in the set are evaluated using the
1501 * semantics of equality. */
1502 check_relation(dfw, "in", FALSE, ftype_can_eq, st_node, st_arg1, st_arg2);
1503 break;
1504
1505 default:
1506 ws_assert_not_reached();
1507 }
1508 }
1509
1510
1511 /* Check the entire syntax tree. */
1512 static void
1513 semcheck(dfwork_t *dfw, stnode_t *st_node)
1514 {
1515 static guint i = 0;
1516
1517 ws_debug("2 semcheck(stnode_t *st_node = %p) [%u]", st_node, i++);
1518
1519 /* The parser assures that the top-most syntax-tree
1520 * node will be a TEST node, no matter what. So assert that. */
1521 switch (stnode_type_id(st_node)) {
1522 case STTYPE_TEST:
1523 check_test(dfw, st_node);
1524 break;
1525 default:
1526 ws_assert_not_reached();
1527 }
1528 }
1529
1530
1531 /* Check the syntax tree for semantic errors, and convert
1532 * some of the nodes into the form they need to be in order to
1533 * later generate the DFVM bytecode. */
1534 gboolean
1535 dfw_semcheck(dfwork_t *dfw)
1536 {
1537 volatile gboolean ok_filter = TRUE;
1538 static guint i = 0;
1539
1540 ws_debug("1 dfw_semcheck(dfwork_t *dfw = %p) [%u]", dfw, i);
1541
1542 /* Instead of having to check for errors at every stage of
1543 * the semantic-checking, the semantic-checking code will
1544 * throw an exception if a problem is found. */
1545 TRY {
1546 semcheck(dfw, dfw->st_root);
1547 }
1548 CATCH(TypeError) {
1549 ok_filter = FALSE;
1550 }
1551 ENDTRY;
1552
1553 ws_debug("1 dfw_semcheck(dfwork_t *dfw = %p) [%u] - Returns %d",
1554 dfw, i++, ok_filter);
1555 return ok_filter;
1556 }
1557
1558 /*
1559 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1560 *
1561 * Local variables:
1562 * c-basic-offset: 8
1563 * tab-width: 8
1564 * indent-tabs-mode: t
1565 * End:
1566 *
1567 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1568 * :indentSize=8:tabSize=8:noTabs=false:
1569 */
1570