2 * $Id: semcheck.c,v 1.7 2001/12/18 19:09:06 gram Exp $
4 * Ethereal - Network traffic analyzer
5 * By Gerald Combs <gerald@ethereal.com>
6 * Copyright 2001 Gerald Combs
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.
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.
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.
29 #include "dfilter-int.h"
30 #include "syntax-tree.h"
31 #include "sttype-range.h"
32 #include "sttype-test.h"
34 #include "exceptions.h"
38 semcheck(dfwork_t *dfw, stnode_t *st_node);
40 typedef gboolean (*FtypeCanFunc)(enum ftenum);
42 /* Compares to ftenum_t's and decides if they're
43 * compatible or not (if they're the same basic type) */
45 compatible_ftypes(ftenum_t a, ftenum_t b)
51 case FT_ABSOLUTE_TIME:
52 case FT_RELATIVE_TIME:
62 return (b == FT_ETHER || b == FT_BYTES);
101 g_assert_not_reached();
104 g_assert_not_reached();
108 /* Creates a FT_UINT32 fvalue with a given value. */
110 mk_uint32_fvalue(guint32 val)
114 fv = fvalue_new(FT_UINT32);
115 fvalue_set_integer(fv, val);
121 /* Try to make an fvalue from a string using a value_string or true_false_string.
122 * This works only for ftypes that are integers. Returns the created fvalue_t*
123 * or NULL if impossible. */
125 mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
127 static true_false_string default_tf = { "True", "False" };
128 true_false_string *tf = &default_tf;
132 switch(hfinfo->type) {
136 case FT_ABSOLUTE_TIME:
137 case FT_RELATIVE_TIME:
162 g_assert_not_reached();
165 /* Reset the dfilter error message, since *something* interesting
166 * will happen, and the error message will be more interesting than
167 * any error message I happen to have now. */
168 dfilter_error_msg = NULL;
170 /* TRUE/FALSE *always* exist for FT_BOOLEAN. */
171 if (hfinfo->type == FT_BOOLEAN) {
172 if (hfinfo->strings) {
173 tf = hfinfo->strings;
176 if (strcasecmp(s, tf->true_string) == 0) {
177 return mk_uint32_fvalue(TRUE);
179 else if (strcasecmp(s, tf->false_string) == 0) {
180 return mk_uint32_fvalue(FALSE);
183 dfilter_fail("\"%s\" cannot be found among the possible values for %s.",
189 /* Do val_strings exist? */
190 if (!hfinfo->strings) {
191 dfilter_fail("%s cannot accept strings as values.",
196 vals = hfinfo->strings;
197 while (vals->strptr != NULL) {
198 if (strcasecmp(s, vals->strptr) == 0) {
199 return mk_uint32_fvalue(vals->value);
203 dfilter_fail("\"%s\" cannot be found among the possible values for %s.",
210 is_bytes_type(enum ftenum type)
221 case FT_ABSOLUTE_TIME:
222 case FT_RELATIVE_TIME:
242 g_assert_not_reached();
245 g_assert_not_reached();
250 check_relation_LHS_FIELD(dfwork_t *dfw, FtypeCanFunc can_func, stnode_t *st_node,
251 stnode_t *st_arg1, stnode_t *st_arg2)
254 sttype_id_t type1, type2;
255 header_field_info *hfinfo1, *hfinfo2;
256 ftenum_t ftype1, ftype2;
261 type1 = stnode_type_id(st_arg1);
262 type2 = stnode_type_id(st_arg2);
264 hfinfo1 = stnode_data(st_arg1);
265 ftype1 = hfinfo1->type;
267 if (!can_func(ftype1)) {
268 dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
269 hfinfo1->abbrev, ftype_pretty_name(ftype1));
274 if (type2 == STTYPE_FIELD) {
275 hfinfo2 = stnode_data(st_arg2);
276 ftype2 = hfinfo2->type;
278 if (!compatible_ftypes(ftype1, ftype2)) {
279 dfilter_fail("%s and %s are not of compatible types.",
280 hfinfo1->abbrev, hfinfo2->abbrev);
283 /* Do this check even though you'd think that if
284 * they're compatible, then can_func() would pass. */
285 if (!can_func(ftype2)) {
286 dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
287 hfinfo2->abbrev, ftype_pretty_name(ftype2));
291 else if (type2 == STTYPE_STRING) {
292 s = stnode_data(st_arg2);
293 fvalue = fvalue_from_string(ftype1, s, dfilter_fail);
295 /* check value_string */
296 fvalue = mk_fvalue_from_val_string(hfinfo1, s);
302 new_st = stnode_new(STTYPE_FVALUE, fvalue);
303 sttype_test_set2_args(st_node, st_arg1, new_st);
304 stnode_free(st_arg2);
306 else if (type2 == STTYPE_RANGE) {
307 if (!is_bytes_type(ftype1)) {
308 if (!ftype_can_slice(ftype1)) {
309 dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
311 ftype_pretty_name(ftype1));
315 /* Convert entire field to bytes */
316 new_st = stnode_new(STTYPE_RANGE, NULL);
318 rn = drange_node_new();
319 drange_node_set_start_offset(rn, 0);
320 drange_node_set_to_the_end(rn);
321 /* st_arg1 is freed in this step */
322 sttype_range_set1(new_st, st_arg1, rn);
324 sttype_test_set2_args(st_node, new_st, st_arg2);
328 g_assert_not_reached();
333 check_relation_LHS_STRING(dfwork_t *dfw, FtypeCanFunc can_func, stnode_t *st_node,
334 stnode_t *st_arg1, stnode_t *st_arg2)
337 sttype_id_t type1, type2;
338 header_field_info *hfinfo2;
343 type1 = stnode_type_id(st_arg1);
344 type2 = stnode_type_id(st_arg2);
346 if (type2 == STTYPE_FIELD) {
347 hfinfo2 = stnode_data(st_arg2);
348 ftype2 = hfinfo2->type;
350 s = stnode_data(st_arg1);
351 fvalue = fvalue_from_string(ftype2, s, dfilter_fail);
353 /* check value_string */
354 fvalue = mk_fvalue_from_val_string(hfinfo2, s);
360 new_st = stnode_new(STTYPE_FVALUE, fvalue);
361 sttype_test_set2_args(st_node, new_st, st_arg2);
362 stnode_free(st_arg1);
364 else if (type2 == STTYPE_STRING) {
365 /* Well now that's silly... */
366 dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
367 stnode_data(st_arg1),
368 stnode_data(st_arg2));
371 else if (type2 == STTYPE_RANGE) {
372 s = stnode_data(st_arg1);
373 fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
377 new_st = stnode_new(STTYPE_FVALUE, fvalue);
378 sttype_test_set2_args(st_node, new_st, st_arg2);
379 stnode_free(st_arg1);
382 g_assert_not_reached();
387 check_relation_LHS_RANGE(dfwork_t *dfw, FtypeCanFunc can_func, stnode_t *st_node,
388 stnode_t *st_arg1, stnode_t *st_arg2)
391 sttype_id_t type1, type2;
392 header_field_info *hfinfo1, *hfinfo2;
393 ftenum_t ftype1, ftype2;
398 type1 = stnode_type_id(st_arg1);
399 type2 = stnode_type_id(st_arg2);
400 hfinfo1 = sttype_range_hfinfo(st_arg1);
401 ftype1 = hfinfo1->type;
403 if (!ftype_can_slice(ftype1)) {
404 dfilter_fail("\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
405 hfinfo1->abbrev, ftype_pretty_name(ftype1));
410 if (type2 == STTYPE_FIELD) {
411 hfinfo2 = sttype_range_hfinfo(st_arg2);
412 ftype2 = hfinfo2->type;
414 if (!is_bytes_type(ftype2)) {
415 if (!ftype_can_slice(ftype2)) {
416 dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
418 ftype_pretty_name(ftype2));
422 /* Convert entire field to bytes */
423 new_st = stnode_new(STTYPE_RANGE, NULL);
425 rn = drange_node_new();
426 drange_node_set_start_offset(rn, 0);
427 drange_node_set_to_the_end(rn);
428 /* st_arg2 is freed in this step */
429 sttype_range_set1(new_st, st_arg2, rn);
431 sttype_test_set2_args(st_node, st_arg1, new_st);
434 else if (type2 == STTYPE_STRING) {
435 s = stnode_data(st_arg2);
436 fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
440 new_st = stnode_new(STTYPE_FVALUE, fvalue);
441 sttype_test_set2_args(st_node, st_arg1, new_st);
442 stnode_free(st_arg2);
444 else if (type2 == STTYPE_RANGE) {
445 /* XXX - check lengths of both ranges */
448 g_assert_not_reached();
454 check_relation(dfwork_t *dfw, FtypeCanFunc can_func, stnode_t *st_node,
455 stnode_t *st_arg1, stnode_t *st_arg2)
457 switch (stnode_type_id(st_arg1)) {
459 check_relation_LHS_FIELD(dfw, can_func, st_node, st_arg1, st_arg2);
462 check_relation_LHS_STRING(dfw, can_func, st_node, st_arg1, st_arg2);
465 check_relation_LHS_RANGE(dfw, can_func, st_node, st_arg1, st_arg2);
468 case STTYPE_UNINITIALIZED:
472 case STTYPE_NUM_TYPES:
473 g_assert_not_reached();
478 check_test(dfwork_t *dfw, stnode_t *st_node)
481 stnode_t *st_arg1, *st_arg2;
483 sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2);
486 case TEST_OP_UNINITIALIZED:
487 g_assert_not_reached();
495 semcheck(dfw, st_arg1);
500 semcheck(dfw, st_arg1);
501 semcheck(dfw, st_arg2);
505 check_relation(dfw, ftype_can_eq, st_node, st_arg1, st_arg2);
508 check_relation(dfw, ftype_can_ne, st_node, st_arg1, st_arg2);
511 check_relation(dfw, ftype_can_gt, st_node, st_arg1, st_arg2);
514 check_relation(dfw, ftype_can_ge, st_node, st_arg1, st_arg2);
517 check_relation(dfw, ftype_can_lt, st_node, st_arg1, st_arg2);
520 check_relation(dfw, ftype_can_le, st_node, st_arg1, st_arg2);
527 semcheck(dfwork_t *dfw, stnode_t *st_node)
531 name = stnode_type_name(st_node);
533 switch (stnode_type_id(st_node)) {
535 check_test(dfw, st_node);
538 g_assert_not_reached();
544 dfw_semcheck(dfwork_t *dfw)
547 semcheck(dfw, dfw->st_root);