strcasecmp(), strncasecmp(), g_strcasecmp(), and g_strncasecmp() delenda
[obnox/wireshark/wip.git] / epan / dfilter / semcheck.c
1 /*
2  * $Id$
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 2001 Gerald Combs
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <string.h>
28
29 #include "dfilter-int.h"
30 #include "semcheck.h"
31 #include "syntax-tree.h"
32 #include "sttype-range.h"
33 #include "sttype-test.h"
34 #include "sttype-function.h"
35
36 #include <epan/exceptions.h>
37 #include <epan/packet.h>
38
39 #ifdef NEED_G_ASCII_STRCASECMP_H
40 #include "g_ascii_strcasecmp.h"
41 #endif
42
43 /* Enable debug logging by defining AM_CFLAGS
44  * so that it contains "-DDEBUG_dfilter".
45  * Usage: DebugLog(("Error: string=%s\n", str)); */
46
47 #ifdef DEBUG_dfilter
48 #define DebugLog(x) \
49         printf("%s:%u: ", __FILE__, __LINE__); \
50         printf x; \
51         fflush(stdout)
52 #else
53 #define DebugLog(x) ;
54 #endif
55
56 static void
57 semcheck(stnode_t *st_node);
58
59 typedef gboolean (*FtypeCanFunc)(enum ftenum);
60
61 /* Compares to ftenum_t's and decides if they're
62  * compatible or not (if they're the same basic type) */
63 static gboolean
64 compatible_ftypes(ftenum_t a, ftenum_t b)
65 {
66         switch (a) {
67                 case FT_NONE:
68                 case FT_PROTOCOL:
69                 case FT_FLOAT:          /* XXX - should be able to compare with INT */
70                 case FT_DOUBLE:         /* XXX - should be able to compare with INT */
71                 case FT_ABSOLUTE_TIME:
72                 case FT_RELATIVE_TIME:
73                 case FT_IPv4:
74                 case FT_IPv6:
75                 case FT_IPXNET:
76                 case FT_INT64:          /* XXX - should be able to compare with INT */
77                 case FT_UINT64:         /* XXX - should be able to compare with INT */
78                         return a == b;
79
80                 case FT_ETHER:
81                 case FT_BYTES:
82                 case FT_UINT_BYTES:
83                 case FT_GUID:
84                 case FT_OID:
85                         return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES || b == FT_GUID || b == FT_OID);
86
87                 case FT_BOOLEAN:
88                 case FT_FRAMENUM:
89                 case FT_UINT8:
90                 case FT_UINT16:
91                 case FT_UINT24:
92                 case FT_UINT32:
93                 case FT_INT8:
94                 case FT_INT16:
95                 case FT_INT24:
96                 case FT_INT32:
97                         switch (b) {
98                                 case FT_BOOLEAN:
99                                 case FT_FRAMENUM:
100                                 case FT_UINT8:
101                                 case FT_UINT16:
102                                 case FT_UINT24:
103                                 case FT_UINT32:
104                                 case FT_INT8:
105                                 case FT_INT16:
106                                 case FT_INT24:
107                                 case FT_INT32:
108                                         return TRUE;
109                                 default:
110                                         return FALSE;
111                         }
112
113                 case FT_STRING:
114                 case FT_STRINGZ:
115                 case FT_EBCDIC:
116                 case FT_UINT_STRING:
117                         switch (b) {
118                                 case FT_STRING:
119                                 case FT_STRINGZ:
120                                 case FT_UINT_STRING:
121                                         return TRUE;
122                                 default:
123                                         return FALSE;
124                         }
125
126                 case FT_PCRE:
127                 case FT_NUM_TYPES:
128                         g_assert_not_reached();
129         }
130
131         g_assert_not_reached();
132         return FALSE;
133 }
134
135 /* Creates a FT_UINT32 fvalue with a given value. */
136 static fvalue_t*
137 mk_uint32_fvalue(guint32 val)
138 {
139         fvalue_t *fv;
140
141         fv = fvalue_new(FT_UINT32);
142         fvalue_set_uinteger(fv, val);
143
144         return fv;
145 }
146
147 /* Try to make an fvalue from a string using a value_string or true_false_string.
148  * This works only for ftypes that are integers. Returns the created fvalue_t*
149  * or NULL if impossible. */
150 static fvalue_t*
151 mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
152 {
153         static const true_false_string  default_tf = { "True", "False" };
154         const true_false_string         *tf = &default_tf;
155         const value_string              *vals;
156
157         /* Early return? */
158         switch(hfinfo->type) {
159                 case FT_NONE:
160                 case FT_PROTOCOL:
161                 case FT_FLOAT:
162                 case FT_DOUBLE:
163                 case FT_ABSOLUTE_TIME:
164                 case FT_RELATIVE_TIME:
165                 case FT_IPv4:
166                 case FT_IPv6:
167                 case FT_IPXNET:
168                 case FT_ETHER:
169                 case FT_BYTES:
170                 case FT_UINT_BYTES:
171                 case FT_STRING:
172                 case FT_STRINGZ:
173                 case FT_EBCDIC:
174                 case FT_UINT_STRING:
175                 case FT_UINT64:
176                 case FT_INT64:
177                 case FT_PCRE:
178                 case FT_GUID:
179                 case FT_OID:
180                         return FALSE;
181
182                 case FT_BOOLEAN:
183                 case FT_FRAMENUM:
184                 case FT_UINT8:
185                 case FT_UINT16:
186                 case FT_UINT24:
187                 case FT_UINT32:
188                 case FT_INT8:
189                 case FT_INT16:
190                 case FT_INT24:
191                 case FT_INT32:
192                         break;
193
194                 case FT_NUM_TYPES:
195                         g_assert_not_reached();
196         }
197
198         /* Reset the dfilter error message, since *something* interesting
199          * will happen, and the error message will be more interesting than
200          * any error message I happen to have now. */
201         dfilter_error_msg = NULL;
202
203         /* TRUE/FALSE *always* exist for FT_BOOLEAN. */
204         if (hfinfo->type == FT_BOOLEAN) {
205                 if (hfinfo->strings) {
206                         tf = hfinfo->strings;
207                 }
208
209                 if (g_ascii_strcasecmp(s, tf->true_string) == 0) {
210                         return mk_uint32_fvalue(TRUE);
211                 }
212                 else if (g_ascii_strcasecmp(s, tf->false_string) == 0) {
213                         return mk_uint32_fvalue(FALSE);
214                 }
215                 else {
216                         dfilter_fail("\"%s\" cannot be found among the possible values for %s.",
217                                 s, hfinfo->abbrev);
218                         return NULL;
219                 }
220         }
221
222         /* Do val_strings exist? */
223         if (!hfinfo->strings) {
224                 dfilter_fail("%s cannot accept strings as values.",
225                                 hfinfo->abbrev);
226                 return FALSE;
227         }
228
229         vals = hfinfo->strings;
230         while (vals->strptr != NULL) {
231                 if (g_ascii_strcasecmp(s, vals->strptr) == 0) {
232                         return mk_uint32_fvalue(vals->value);
233                 }
234                 vals++;
235         }
236         dfilter_fail("\"%s\" cannot be found among the possible values for %s.",
237                         s, hfinfo->abbrev);
238         return FALSE;
239 }
240
241 static gboolean
242 is_bytes_type(enum ftenum type)
243 {
244         switch(type) {
245                 case FT_ETHER:
246                 case FT_BYTES:
247                 case FT_UINT_BYTES:
248                 case FT_IPv6:
249                 case FT_GUID:
250                 case FT_OID:
251                         return TRUE;
252
253                 case FT_NONE:
254                 case FT_PROTOCOL:
255                 case FT_FLOAT:
256                 case FT_DOUBLE:
257                 case FT_ABSOLUTE_TIME:
258                 case FT_RELATIVE_TIME:
259                 case FT_IPv4:
260                 case FT_IPXNET:
261                 case FT_STRING:
262                 case FT_STRINGZ:
263                 case FT_EBCDIC:
264                 case FT_UINT_STRING:
265                 case FT_BOOLEAN:
266                 case FT_FRAMENUM:
267                 case FT_UINT8:
268                 case FT_UINT16:
269                 case FT_UINT24:
270                 case FT_UINT32:
271                 case FT_UINT64:
272                 case FT_INT8:
273                 case FT_INT16:
274                 case FT_INT24:
275                 case FT_INT32:
276                 case FT_INT64:
277                 case FT_PCRE:
278                         return FALSE;
279
280                 case FT_NUM_TYPES:
281                         g_assert_not_reached();
282         }
283
284         g_assert_not_reached();
285         return FALSE;
286 }
287
288 /* Check the semantics of an existence test. */
289 static void
290 check_exists(stnode_t *st_arg1)
291 {
292 #ifdef DEBUG_dfilter
293         static guint i = 0;
294 #endif
295
296         DebugLog(("   4 check_exists() [%u]\n", i++));
297         switch (stnode_type_id(st_arg1)) {
298                 case STTYPE_FIELD:
299                         /* This is OK */
300                         break;
301                 case STTYPE_STRING:
302                 case STTYPE_UNPARSED:
303                         dfilter_fail("\"%s\" is neither a field nor a protocol name.",
304                                         stnode_data(st_arg1));
305                         THROW(TypeError);
306                         break;
307
308                 case STTYPE_RANGE:
309                         /*
310                          * XXX - why not?  Shouldn't "eth[3:2]" mean
311                          * "check whether the 'eth' field is present and
312                          * has at least 2 bytes starting at an offset of
313                          * 3"?
314                          */
315                         dfilter_fail("You cannot test whether a range is present.");
316                         THROW(TypeError);
317                         break;
318
319                 case STTYPE_FUNCTION:
320             /* XXX - Maybe we should change functions so they can return fields,
321              * in which case the 'exist' should be fine. */
322                         dfilter_fail("You cannot test whether a function is present.");
323                         THROW(TypeError);
324                         break;
325
326                 case STTYPE_UNINITIALIZED:
327                 case STTYPE_TEST:
328                 case STTYPE_INTEGER:
329                 case STTYPE_FVALUE:
330                 case STTYPE_NUM_TYPES:
331                         g_assert_not_reached();
332         }
333 }
334
335 struct check_drange_sanity_args {
336         stnode_t                *st;
337         gboolean                err;
338 };
339
340 /* Q: Where are sttype_range_drange() and sttype_range_hfinfo() defined?
341  *
342  * A: Those functions are defined by macros in epan/dfilter/sttype-range.h
343  *
344  *    The macro which creates them, STTYPE_ACCESSOR, is defined in
345  *    epan/dfilter/syntax-tree.h.
346  *
347  * From http://www.ethereal.com/lists/ethereal-dev/200308/msg00070.html
348  */
349
350 static void
351 check_drange_node_sanity(gpointer data, gpointer user_data)
352 {
353         drange_node*            drnode = data;
354         struct check_drange_sanity_args *args = user_data;
355         gint                    start_offset, end_offset, length;
356         header_field_info       *hfinfo;
357
358         switch (drange_node_get_ending(drnode)) {
359
360         case LENGTH:
361                 length = drange_node_get_length(drnode);
362                 if (length <= 0) {
363                         if (!args->err) {
364                                 args->err = TRUE;
365                                 start_offset = drange_node_get_start_offset(drnode);
366                                 hfinfo = sttype_range_hfinfo(args->st);
367                                 dfilter_fail("Range %d:%d specified for \"%s\" isn't valid, "
368                                         "as length %d isn't positive",
369                                         start_offset, length,
370                                         hfinfo->abbrev,
371                                         length);
372                         }
373                 }
374                 break;
375
376         case OFFSET:
377                 /*
378                  * Make sure the start offset isn't beyond the end
379                  * offset.  This applies to negative offsets too.
380                  */
381
382                 /* XXX - [-ve - +ve] is probably pathological, but isn't
383                  * disallowed.
384                  * [+ve - -ve] is probably pathological too, and happens to be
385                  * disallowed.
386                  */
387                 start_offset = drange_node_get_start_offset(drnode);
388                 end_offset = drange_node_get_end_offset(drnode);
389                 if (start_offset > end_offset) {
390                         if (!args->err) {
391                                 args->err = TRUE;
392                                 hfinfo = sttype_range_hfinfo(args->st);
393                                 dfilter_fail("Range %d-%d specified for \"%s\" isn't valid, "
394                                         "as %d is greater than %d",
395                                         start_offset, end_offset,
396                                         hfinfo->abbrev,
397                                         start_offset, end_offset);
398                         }
399                 }
400                 break;
401
402         case TO_THE_END:
403                 break;
404
405         case UNINITIALIZED:
406         default:
407                 g_assert_not_reached();
408         }
409 }
410
411 static void
412 check_drange_sanity(stnode_t *st)
413 {
414         struct check_drange_sanity_args args;
415
416         args.st = st;
417         args.err = FALSE;
418
419         drange_foreach_drange_node(sttype_range_drange(st),
420             check_drange_node_sanity, &args);
421
422         if (args.err) {
423                 THROW(TypeError);
424         }
425 }
426
427 /* If the LHS of a relation test is a FIELD, run some checks
428  * and possibly some modifications of syntax tree nodes. */
429 static void
430 check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func,
431                 gboolean allow_partial_value,
432                 stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
433 {
434         stnode_t                *new_st;
435         sttype_id_t             type1, type2;
436         header_field_info       *hfinfo1, *hfinfo2;
437         ftenum_t                ftype1, ftype2;
438         fvalue_t                *fvalue;
439         char                    *s;
440         drange_node             *rn;
441
442         type1 = stnode_type_id(st_arg1);
443         type2 = stnode_type_id(st_arg2);
444
445         hfinfo1 = stnode_data(st_arg1);
446         ftype1 = hfinfo1->type;
447
448         DebugLog(("    5 check_relation_LHS_FIELD(%s)\n", relation_string));
449
450         if (!can_func(ftype1)) {
451                 dfilter_fail("%s (type=%s) cannot participate in '%s' comparison.",
452                                 hfinfo1->abbrev, ftype_pretty_name(ftype1),
453                                 relation_string);
454                 THROW(TypeError);
455         }
456
457         if (type2 == STTYPE_FIELD) {
458                 hfinfo2 = stnode_data(st_arg2);
459                 ftype2 = hfinfo2->type;
460
461                 if (!compatible_ftypes(ftype1, ftype2)) {
462                         dfilter_fail("%s and %s are not of compatible types.",
463                                         hfinfo1->abbrev, hfinfo2->abbrev);
464                         THROW(TypeError);
465                 }
466                 /* Do this check even though you'd think that if
467                  * they're compatible, then can_func() would pass. */
468                 if (!can_func(ftype2)) {
469                         dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
470                                         hfinfo2->abbrev, ftype_pretty_name(ftype2));
471                         THROW(TypeError);
472                 }
473         }
474         else if (type2 == STTYPE_STRING) {
475                 s = stnode_data(st_arg2);
476                 if (strcmp(relation_string, "matches") == 0) {
477                         /* Convert to a FT_PCRE */
478                         fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail);
479                 } else {
480                         fvalue = fvalue_from_string(ftype1, s, dfilter_fail);
481                         if (!fvalue) {
482                                 /* check value_string */
483                                 fvalue = mk_fvalue_from_val_string(hfinfo1, s);
484                         }
485                 }
486                 if (!fvalue) {
487                         THROW(TypeError);
488                 }
489
490                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
491                 sttype_test_set2_args(st_node, st_arg1, new_st);
492                 stnode_free(st_arg2);
493         }
494         else if (type2 == STTYPE_UNPARSED) {
495                 s = stnode_data(st_arg2);
496                 if (strcmp(relation_string, "matches") == 0) {
497                         /* Convert to a FT_PCRE */
498                         fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail);
499                 } else {
500                         fvalue = fvalue_from_unparsed(ftype1, s, allow_partial_value, dfilter_fail);
501                         if (!fvalue) {
502                                 /* check value_string */
503                                 fvalue = mk_fvalue_from_val_string(hfinfo1, s);
504                         }
505                 }
506                 if (!fvalue) {
507                         THROW(TypeError);
508                 }
509
510                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
511                 sttype_test_set2_args(st_node, st_arg1, new_st);
512                 stnode_free(st_arg2);
513         }
514         else if (type2 == STTYPE_RANGE) {
515                 check_drange_sanity(st_arg2);
516                 if (!is_bytes_type(ftype1)) {
517                         if (!ftype_can_slice(ftype1)) {
518                                 dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
519                                                 hfinfo1->abbrev,
520                                                 ftype_pretty_name(ftype1));
521                                 THROW(TypeError);
522                         }
523
524                         /* Convert entire field to bytes */
525                         new_st = stnode_new(STTYPE_RANGE, NULL);
526
527                         rn = drange_node_new();
528                         drange_node_set_start_offset(rn, 0);
529                         drange_node_set_to_the_end(rn);
530                         /* st_arg1 is freed in this step */
531                         sttype_range_set1(new_st, st_arg1, rn);
532
533                         sttype_test_set2_args(st_node, new_st, st_arg2);
534                 }
535         }
536         else {
537                 g_assert_not_reached();
538         }
539 }
540
541 static void
542 check_relation_LHS_STRING(const char* relation_string,
543                 FtypeCanFunc can_func _U_, gboolean allow_partial_value _U_,
544                 stnode_t *st_node,
545                 stnode_t *st_arg1, stnode_t *st_arg2)
546 {
547         stnode_t                *new_st;
548         sttype_id_t             type1, type2;
549         header_field_info       *hfinfo2;
550         ftenum_t                ftype2;
551         fvalue_t                *fvalue;
552         char                    *s;
553
554         type1 = stnode_type_id(st_arg1);
555         type2 = stnode_type_id(st_arg2);
556
557         DebugLog(("    5 check_relation_LHS_STRING()\n"));
558
559         if (type2 == STTYPE_FIELD) {
560                 hfinfo2 = stnode_data(st_arg2);
561                 ftype2 = hfinfo2->type;
562
563                 if (!can_func(ftype2)) {
564                         dfilter_fail("%s (type=%s) cannot participate in '%s' comparison.",
565                                         hfinfo2->abbrev, ftype_pretty_name(ftype2),
566                                         relation_string);
567                         THROW(TypeError);
568                 }
569
570                 s = stnode_data(st_arg1);
571                 fvalue = fvalue_from_string(ftype2, s, dfilter_fail);
572                 if (!fvalue) {
573                         /* check value_string */
574                         fvalue = mk_fvalue_from_val_string(hfinfo2, s);
575                         if (!fvalue) {
576                                 THROW(TypeError);
577                         }
578                 }
579
580                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
581                 sttype_test_set2_args(st_node, new_st, st_arg2);
582                 stnode_free(st_arg1);
583         }
584         else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) {
585                 /* Well now that's silly... */
586                 dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
587                                 stnode_data(st_arg1),
588                                 stnode_data(st_arg2));
589                 THROW(TypeError);
590         }
591         else if (type2 == STTYPE_RANGE) {
592                 check_drange_sanity(st_arg2);
593                 s = stnode_data(st_arg1);
594                 fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
595                 if (!fvalue) {
596                         THROW(TypeError);
597                 }
598                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
599                 sttype_test_set2_args(st_node, new_st, st_arg2);
600                 stnode_free(st_arg1);
601         }
602         else {
603                 g_assert_not_reached();
604         }
605 }
606
607 static void
608 check_relation_LHS_UNPARSED(const char* relation_string,
609                 FtypeCanFunc can_func, gboolean allow_partial_value,
610                 stnode_t *st_node,
611                 stnode_t *st_arg1, stnode_t *st_arg2)
612 {
613         stnode_t                *new_st;
614         sttype_id_t             type1, type2;
615         header_field_info       *hfinfo2;
616         ftenum_t                ftype2;
617         fvalue_t                *fvalue;
618         char                    *s;
619
620         type1 = stnode_type_id(st_arg1);
621         type2 = stnode_type_id(st_arg2);
622
623         DebugLog(("    5 check_relation_LHS_UNPARSED()\n"));
624
625         if (type2 == STTYPE_FIELD) {
626                 hfinfo2 = stnode_data(st_arg2);
627                 ftype2 = hfinfo2->type;
628
629                 if (!can_func(ftype2)) {
630                         dfilter_fail("%s (type=%s) cannot participate in '%s' comparison.",
631                                         hfinfo2->abbrev, ftype_pretty_name(ftype2),
632                                         relation_string);
633                         THROW(TypeError);
634                 }
635
636                 s = stnode_data(st_arg1);
637                 fvalue = fvalue_from_unparsed(ftype2, s, allow_partial_value, dfilter_fail);
638                 if (!fvalue) {
639                         /* check value_string */
640                         fvalue = mk_fvalue_from_val_string(hfinfo2, s);
641                         if (!fvalue) {
642                                 THROW(TypeError);
643                         }
644                 }
645
646                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
647                 sttype_test_set2_args(st_node, new_st, st_arg2);
648                 stnode_free(st_arg1);
649         }
650         else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) {
651                 /* Well now that's silly... */
652                 dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
653                                 stnode_data(st_arg1),
654                                 stnode_data(st_arg2));
655                 THROW(TypeError);
656         }
657         else if (type2 == STTYPE_RANGE) {
658                 check_drange_sanity(st_arg2);
659                 s = stnode_data(st_arg1);
660                 fvalue = fvalue_from_unparsed(FT_BYTES, s, allow_partial_value, dfilter_fail);
661                 if (!fvalue) {
662                         THROW(TypeError);
663                 }
664                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
665                 sttype_test_set2_args(st_node, new_st, st_arg2);
666                 stnode_free(st_arg1);
667         }
668         else {
669                 g_assert_not_reached();
670         }
671 }
672
673 static void
674 check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
675                 gboolean allow_partial_value,
676                 stnode_t *st_node,
677                 stnode_t *st_arg1, stnode_t *st_arg2)
678 {
679         stnode_t                *new_st;
680         sttype_id_t             type1, type2;
681         header_field_info       *hfinfo1, *hfinfo2;
682         ftenum_t                ftype1, ftype2;
683         fvalue_t                *fvalue;
684         char                    *s;
685         drange_node             *rn;
686
687         type1 = stnode_type_id(st_arg1);
688         type2 = stnode_type_id(st_arg2);
689         hfinfo1 = sttype_range_hfinfo(st_arg1);
690         ftype1 = hfinfo1->type;
691
692         DebugLog(("    5 check_relation_LHS_RANGE(%s)\n", relation_string));
693
694         if (!ftype_can_slice(ftype1)) {
695                 dfilter_fail("\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
696                                 hfinfo1->abbrev, ftype_pretty_name(ftype1));
697                 THROW(TypeError);
698         }
699
700         check_drange_sanity(st_arg1);
701
702         if (type2 == STTYPE_FIELD) {
703                 DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_FIELD)\n"));
704                 hfinfo2 = stnode_data(st_arg2);
705                 ftype2 = hfinfo2->type;
706
707                 if (!is_bytes_type(ftype2)) {
708                         if (!ftype_can_slice(ftype2)) {
709                                 dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
710                                                 hfinfo2->abbrev,
711                                                 ftype_pretty_name(ftype2));
712                                 THROW(TypeError);
713                         }
714
715                         /* Convert entire field to bytes */
716                         new_st = stnode_new(STTYPE_RANGE, NULL);
717
718                         rn = drange_node_new();
719                         drange_node_set_start_offset(rn, 0);
720                         drange_node_set_to_the_end(rn);
721                         /* st_arg2 is freed in this step */
722                         sttype_range_set1(new_st, st_arg2, rn);
723
724                         sttype_test_set2_args(st_node, st_arg1, new_st);
725                 }
726         }
727         else if (type2 == STTYPE_STRING) {
728                 DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_STRING)\n"));
729                 s = stnode_data(st_arg2);
730                 if (strcmp(relation_string, "matches") == 0) {
731                         /* Convert to a FT_PCRE */
732                         fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail);
733                 } else {
734                         fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
735                 }
736                 if (!fvalue) {
737                         DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_STRING): Could not convert from string!\n"));
738                         THROW(TypeError);
739                 }
740                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
741                 sttype_test_set2_args(st_node, st_arg1, new_st);
742                 stnode_free(st_arg2);
743         }
744         else if (type2 == STTYPE_UNPARSED) {
745                 DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED)\n"));
746                 s = stnode_data(st_arg2);
747                 if (strcmp(relation_string, "matches") == 0) {
748                         /* Convert to a FT_PCRE */
749                         fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail);
750                 } else {
751                         fvalue = fvalue_from_unparsed(FT_BYTES, s, allow_partial_value, dfilter_fail);
752                 }
753                 if (!fvalue) {
754                         DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED): Could not convert from string!\n"));
755                         THROW(TypeError);
756                 }
757                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
758                 sttype_test_set2_args(st_node, st_arg1, new_st);
759                 stnode_free(st_arg2);
760         }
761         else if (type2 == STTYPE_RANGE) {
762                 DebugLog(("    5 check_relation_LHS_RANGE(type2 = STTYPE_RANGE)\n"));
763                 check_drange_sanity(st_arg2);
764         }
765         else {
766                 g_assert_not_reached();
767         }
768 }
769
770 static stnode_t*
771 check_param_entity(stnode_t *st_node)
772 {
773         sttype_id_t             e_type;
774         stnode_t                *new_st;
775         fvalue_t                *fvalue;
776     char *s;
777
778         e_type = stnode_type_id(st_node);
779     /* If there's an unparsed string, change it to an FT_STRING */
780     if (e_type == STTYPE_UNPARSED) {
781                 s = stnode_data(st_node);
782         fvalue = fvalue_from_unparsed(FT_STRING, s, FALSE, dfilter_fail);
783                 if (!fvalue) {
784                         THROW(TypeError);
785                 }
786
787                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
788                 stnode_free(st_node);
789         return new_st;
790     }
791
792     return st_node;
793 }
794
795
796 /* If the LHS of a relation test is a FUNCTION, run some checks
797  * and possibly some modifications of syntax tree nodes. */
798 static void
799 check_relation_LHS_FUNCTION(const char *relation_string, FtypeCanFunc can_func,
800                 gboolean allow_partial_value,
801                 stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2)
802 {
803         stnode_t                *new_st;
804         sttype_id_t             type2;
805         header_field_info       *hfinfo2;
806         ftenum_t                ftype1, ftype2;
807         fvalue_t                *fvalue;
808         char                    *s;
809     int             param_i;
810         drange_node             *rn;
811     df_func_def_t   *funcdef;
812     guint             num_params;
813     GSList          *params;
814
815         type2 = stnode_type_id(st_arg2);
816
817     funcdef = sttype_function_funcdef(st_arg1);
818         ftype1 = funcdef->retval_ftype;
819
820     params = sttype_function_params(st_arg1);
821     num_params = g_slist_length(params);
822     if (num_params < funcdef->min_nargs) {
823         dfilter_fail("Function %s needs at least %u arguments.",
824                 funcdef->name, funcdef->min_nargs);
825         THROW(TypeError);
826     }
827     else if (num_params > funcdef->max_nargs) {
828         dfilter_fail("Function %s can only accept %u arguments.",
829                 funcdef->name, funcdef->max_nargs);
830         THROW(TypeError);
831     }
832
833     param_i = 0;
834     while (params) {
835         params->data = check_param_entity(params->data);
836         funcdef->semcheck_param_function(param_i, params->data);
837         params = params->next;
838     }
839
840         DebugLog(("    5 check_relation_LHS_FUNCTION(%s)\n", relation_string));
841
842         if (!can_func(ftype1)) {
843                 dfilter_fail("Function %s (type=%s) cannot participate in '%s' comparison.",
844                                 funcdef->name, ftype_pretty_name(ftype1),
845                                 relation_string);
846                 THROW(TypeError);
847         }
848
849         if (type2 == STTYPE_FIELD) {
850                 hfinfo2 = stnode_data(st_arg2);
851                 ftype2 = hfinfo2->type;
852
853                 if (!compatible_ftypes(ftype1, ftype2)) {
854                         dfilter_fail("Function %s and %s are not of compatible types.",
855                                         funcdef->name, hfinfo2->abbrev);
856                         THROW(TypeError);
857                 }
858                 /* Do this check even though you'd think that if
859                  * they're compatible, then can_func() would pass. */
860                 if (!can_func(ftype2)) {
861                         dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
862                                         hfinfo2->abbrev, ftype_pretty_name(ftype2));
863                         THROW(TypeError);
864                 }
865         }
866         else if (type2 == STTYPE_STRING) {
867                 s = stnode_data(st_arg2);
868                 if (strcmp(relation_string, "matches") == 0) {
869                         /* Convert to a FT_PCRE */
870                         fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail);
871                 } else {
872                         fvalue = fvalue_from_string(ftype1, s, dfilter_fail);
873                 }
874                 if (!fvalue) {
875                         THROW(TypeError);
876                 }
877
878                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
879                 sttype_test_set2_args(st_node, st_arg1, new_st);
880                 stnode_free(st_arg2);
881         }
882         else if (type2 == STTYPE_UNPARSED) {
883                 s = stnode_data(st_arg2);
884                 if (strcmp(relation_string, "matches") == 0) {
885                         /* Convert to a FT_PCRE */
886                         fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail);
887                 } else {
888                         fvalue = fvalue_from_unparsed(ftype1, s, allow_partial_value, dfilter_fail);
889                 }
890                 if (!fvalue) {
891                         THROW(TypeError);
892                 }
893
894                 new_st = stnode_new(STTYPE_FVALUE, fvalue);
895                 sttype_test_set2_args(st_node, st_arg1, new_st);
896                 stnode_free(st_arg2);
897         }
898         else if (type2 == STTYPE_RANGE) {
899                 check_drange_sanity(st_arg2);
900                 if (!is_bytes_type(ftype1)) {
901                         if (!ftype_can_slice(ftype1)) {
902                                 dfilter_fail("Function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
903                                                 funcdef->name,
904                                                 ftype_pretty_name(ftype1));
905                                 THROW(TypeError);
906                         }
907
908                         /* Convert entire field to bytes */
909                         new_st = stnode_new(STTYPE_RANGE, NULL);
910
911                         rn = drange_node_new();
912                         drange_node_set_start_offset(rn, 0);
913                         drange_node_set_to_the_end(rn);
914                         /* st_arg1 is freed in this step */
915                         sttype_range_set1(new_st, st_arg1, rn);
916
917                         sttype_test_set2_args(st_node, new_st, st_arg2);
918                 }
919         }
920         else {
921                 g_assert_not_reached();
922         }
923 }
924
925
926 /* Check the semantics of any relational test. */
927 static void
928 check_relation(const char *relation_string, gboolean allow_partial_value,
929                 FtypeCanFunc can_func, stnode_t *st_node,
930                 stnode_t *st_arg1, stnode_t *st_arg2)
931 {
932 #ifdef DEBUG_dfilter
933         static guint i = 0;
934 #endif
935 header_field_info   *hfinfo;
936
937         DebugLog(("   4 check_relation(\"%s\") [%u]\n", relation_string, i++));
938
939         /* Protocol can only be on LHS (for "contains" or "matches" operators).
940          * Check to see if protocol is on RHS.  This catches the case where the
941          * user has written "fc" on the RHS, probably intending a byte value
942          * rather than the fibre channel protocol.
943          */
944
945         if (stnode_type_id(st_arg2) == STTYPE_FIELD) {
946                 hfinfo = stnode_data(st_arg2);
947                 if (hfinfo->type == FT_PROTOCOL)
948                         dfilter_fail("Protocol (\"%s\") cannot appear on right-hand side of comparison.", hfinfo->abbrev);
949                         THROW(TypeError);
950         }
951
952         switch (stnode_type_id(st_arg1)) {
953                 case STTYPE_FIELD:
954                         check_relation_LHS_FIELD(relation_string, can_func,
955                                         allow_partial_value, st_node, st_arg1, st_arg2);
956                         break;
957                 case STTYPE_STRING:
958                         check_relation_LHS_STRING(relation_string, can_func,
959                                         allow_partial_value, st_node, st_arg1, st_arg2);
960                         break;
961                 case STTYPE_RANGE:
962                         check_relation_LHS_RANGE(relation_string, can_func,
963                                         allow_partial_value, st_node, st_arg1, st_arg2);
964                         break;
965                 case STTYPE_UNPARSED:
966                         check_relation_LHS_UNPARSED(relation_string, can_func,
967                                         allow_partial_value, st_node, st_arg1, st_arg2);
968                         break;
969                 case STTYPE_FUNCTION:
970                         check_relation_LHS_FUNCTION(relation_string, can_func,
971                                         allow_partial_value, st_node, st_arg1, st_arg2);
972                         break;
973
974                 case STTYPE_UNINITIALIZED:
975                 case STTYPE_TEST:
976                 case STTYPE_INTEGER:
977                 case STTYPE_FVALUE:
978         default:
979                         g_assert_not_reached();
980         }
981 }
982
983 /* Check the semantics of any type of TEST */
984 static void
985 check_test(stnode_t *st_node)
986 {
987         test_op_t               st_op;
988         stnode_t                *st_arg1, *st_arg2;
989 #ifdef DEBUG_dfilter
990         static guint i = 0;
991 #endif
992
993         DebugLog(("  3 check_test(stnode_t *st_node = %p) [%u]\n", st_node, i));
994
995         sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2);
996
997         switch (st_op) {
998                 case TEST_OP_UNINITIALIZED:
999                         g_assert_not_reached();
1000                         break;
1001
1002                 case TEST_OP_EXISTS:
1003                         check_exists(st_arg1);
1004                         break;
1005
1006                 case TEST_OP_NOT:
1007                         semcheck(st_arg1);
1008                         break;
1009
1010                 case TEST_OP_AND:
1011                 case TEST_OP_OR:
1012                         semcheck(st_arg1);
1013                         semcheck(st_arg2);
1014                         break;
1015
1016                 case TEST_OP_EQ:
1017                         check_relation("==", FALSE, ftype_can_eq, st_node, st_arg1, st_arg2);
1018                         break;
1019                 case TEST_OP_NE:
1020                         check_relation("!=", FALSE, ftype_can_ne, st_node, st_arg1, st_arg2);
1021                         break;
1022                 case TEST_OP_GT:
1023                         check_relation(">", FALSE, ftype_can_gt, st_node, st_arg1, st_arg2);
1024                         break;
1025                 case TEST_OP_GE:
1026                         check_relation(">=", FALSE, ftype_can_ge, st_node, st_arg1, st_arg2);
1027                         break;
1028                 case TEST_OP_LT:
1029                         check_relation("<", FALSE, ftype_can_lt, st_node, st_arg1, st_arg2);
1030                         break;
1031                 case TEST_OP_LE:
1032                         check_relation("<=", FALSE, ftype_can_le, st_node, st_arg1, st_arg2);
1033                         break;
1034                 case TEST_OP_BITWISE_AND:
1035                         check_relation("&", FALSE, ftype_can_bitwise_and, st_node, st_arg1, st_arg2);
1036                         break;
1037                 case TEST_OP_CONTAINS:
1038                         check_relation("contains", TRUE, ftype_can_contains, st_node, st_arg1, st_arg2);
1039                         break;
1040                 case TEST_OP_MATCHES:
1041 #ifdef HAVE_LIBPCRE
1042                         check_relation("matches", TRUE, ftype_can_matches, st_node, st_arg1, st_arg2);
1043 #else
1044                         dfilter_fail("This Wireshark version does not support the \"matches\" operation.");
1045                         THROW(TypeError);
1046 #endif
1047                         break;
1048
1049                 default:
1050                         g_assert_not_reached();
1051         }
1052         DebugLog(("  3 check_test(stnode_t *st_node = %p) [%u] - End\n", st_node, i++));
1053 }
1054
1055
1056 /* Check the entire syntax tree. */
1057 static void
1058 semcheck(stnode_t *st_node)
1059 {
1060 #ifdef DEBUG_dfilter
1061         static guint i = 0;
1062 #endif
1063         DebugLog((" 2 semcheck(stnode_t *st_node = %p) [%u]\n", st_node, i++));
1064         /* The parser assures that the top-most syntax-tree
1065          * node will be a TEST node, no matter what. So assert that. */
1066         switch (stnode_type_id(st_node)) {
1067                 case STTYPE_TEST:
1068                         check_test(st_node);
1069                         break;
1070                 default:
1071                         g_assert_not_reached();
1072         }
1073 }
1074
1075
1076 /* Check the syntax tree for semantic errors, and convert
1077  * some of the nodes into the form they need to be in order to
1078  * later generate the DFVM bytecode. */
1079 gboolean
1080 dfw_semcheck(dfwork_t *dfw)
1081 {
1082         volatile gboolean ok_filter = TRUE;
1083 #ifdef DEBUG_dfilter
1084         static guint i = 0;
1085 #endif
1086         
1087         DebugLog(("1 dfw_semcheck(dfwork_t *dfw = %p) [%u]\n", dfw, i));
1088         /* Instead of having to check for errors at every stage of
1089          * the semantic-checking, the semantic-checking code will
1090          * throw an exception if a problem is found. */
1091         TRY {
1092                 semcheck(dfw->st_root);
1093         }
1094         CATCH(TypeError) {
1095                 ok_filter = FALSE;
1096         }
1097         ENDTRY;
1098
1099         DebugLog(("1 dfw_semcheck(dfwork_t *dfw = %p) [%u] - Returns %d\n",
1100                                 dfw, i++,ok_filter));
1101         return ok_filter;
1102 }