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