2 * $Id: semcheck.c,v 1.14 2002/11/28 01:46:14 guy 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 <epan/exceptions.h>
35 #include <epan/packet.h>
38 semcheck(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)
52 case FT_ABSOLUTE_TIME:
53 case FT_RELATIVE_TIME:
64 return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES);
103 g_assert_not_reached();
106 g_assert_not_reached();
110 /* Creates a FT_UINT32 fvalue with a given value. */
112 mk_uint32_fvalue(guint32 val)
116 fv = fvalue_new(FT_UINT32);
117 fvalue_set_integer(fv, val);
123 /* Try to make an fvalue from a string using a value_string or true_false_string.
124 * This works only for ftypes that are integers. Returns the created fvalue_t*
125 * or NULL if impossible. */
127 mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
129 static const true_false_string default_tf = { "True", "False" };
130 const true_false_string *tf = &default_tf;
131 const value_string *vals;
134 switch(hfinfo->type) {
139 case FT_ABSOLUTE_TIME:
140 case FT_RELATIVE_TIME:
166 g_assert_not_reached();
169 /* Reset the dfilter error message, since *something* interesting
170 * will happen, and the error message will be more interesting than
171 * any error message I happen to have now. */
172 dfilter_error_msg = NULL;
174 /* TRUE/FALSE *always* exist for FT_BOOLEAN. */
175 if (hfinfo->type == FT_BOOLEAN) {
176 if (hfinfo->strings) {
177 tf = hfinfo->strings;
180 if (strcasecmp(s, tf->true_string) == 0) {
181 return mk_uint32_fvalue(TRUE);
183 else if (strcasecmp(s, tf->false_string) == 0) {
184 return mk_uint32_fvalue(FALSE);
187 dfilter_fail("\"%s\" cannot be found among the possible values for %s.",
193 /* Do val_strings exist? */
194 if (!hfinfo->strings) {
195 dfilter_fail("%s cannot accept strings as values.",
200 vals = hfinfo->strings;
201 while (vals->strptr != NULL) {
202 if (strcasecmp(s, vals->strptr) == 0) {
203 return mk_uint32_fvalue(vals->value);
207 dfilter_fail("\"%s\" cannot be found among the possible values for %s.",
214 is_bytes_type(enum ftenum type)
227 case FT_ABSOLUTE_TIME:
228 case FT_RELATIVE_TIME:
248 g_assert_not_reached();
251 g_assert_not_reached();
256 check_relation_LHS_FIELD(FtypeCanFunc can_func, stnode_t *st_node,
257 stnode_t *st_arg1, stnode_t *st_arg2)
260 sttype_id_t type1, type2;
261 header_field_info *hfinfo1, *hfinfo2;
262 ftenum_t ftype1, ftype2;
267 type1 = stnode_type_id(st_arg1);
268 type2 = stnode_type_id(st_arg2);
270 hfinfo1 = stnode_data(st_arg1);
271 ftype1 = hfinfo1->type;
273 if (!can_func(ftype1)) {
274 dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
275 hfinfo1->abbrev, ftype_pretty_name(ftype1));
280 if (type2 == STTYPE_FIELD) {
281 hfinfo2 = stnode_data(st_arg2);
282 ftype2 = hfinfo2->type;
284 if (!compatible_ftypes(ftype1, ftype2)) {
285 dfilter_fail("%s and %s are not of compatible types.",
286 hfinfo1->abbrev, hfinfo2->abbrev);
289 /* Do this check even though you'd think that if
290 * they're compatible, then can_func() would pass. */
291 if (!can_func(ftype2)) {
292 dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
293 hfinfo2->abbrev, ftype_pretty_name(ftype2));
297 else if (type2 == STTYPE_STRING) {
298 s = stnode_data(st_arg2);
299 fvalue = fvalue_from_string(ftype1, s, dfilter_fail);
301 /* check value_string */
302 fvalue = mk_fvalue_from_val_string(hfinfo1, s);
308 new_st = stnode_new(STTYPE_FVALUE, fvalue);
309 sttype_test_set2_args(st_node, st_arg1, new_st);
310 stnode_free(st_arg2);
312 else if (type2 == STTYPE_RANGE) {
313 if (!is_bytes_type(ftype1)) {
314 if (!ftype_can_slice(ftype1)) {
315 dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
317 ftype_pretty_name(ftype1));
321 /* Convert entire field to bytes */
322 new_st = stnode_new(STTYPE_RANGE, NULL);
324 rn = drange_node_new();
325 drange_node_set_start_offset(rn, 0);
326 drange_node_set_to_the_end(rn);
327 /* st_arg1 is freed in this step */
328 sttype_range_set1(new_st, st_arg1, rn);
330 sttype_test_set2_args(st_node, new_st, st_arg2);
334 g_assert_not_reached();
339 check_relation_LHS_STRING(FtypeCanFunc can_func _U_, stnode_t *st_node,
340 stnode_t *st_arg1, stnode_t *st_arg2)
343 sttype_id_t type1, type2;
344 header_field_info *hfinfo2;
349 type1 = stnode_type_id(st_arg1);
350 type2 = stnode_type_id(st_arg2);
352 if (type2 == STTYPE_FIELD) {
353 hfinfo2 = stnode_data(st_arg2);
354 ftype2 = hfinfo2->type;
356 s = stnode_data(st_arg1);
357 fvalue = fvalue_from_string(ftype2, s, dfilter_fail);
359 /* check value_string */
360 fvalue = mk_fvalue_from_val_string(hfinfo2, s);
366 new_st = stnode_new(STTYPE_FVALUE, fvalue);
367 sttype_test_set2_args(st_node, new_st, st_arg2);
368 stnode_free(st_arg1);
370 else if (type2 == STTYPE_STRING) {
371 /* Well now that's silly... */
372 dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
373 stnode_data(st_arg1),
374 stnode_data(st_arg2));
377 else if (type2 == STTYPE_RANGE) {
378 s = stnode_data(st_arg1);
379 fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
383 new_st = stnode_new(STTYPE_FVALUE, fvalue);
384 sttype_test_set2_args(st_node, new_st, st_arg2);
385 stnode_free(st_arg1);
388 g_assert_not_reached();
393 check_relation_LHS_RANGE(FtypeCanFunc can_func _U_, stnode_t *st_node,
394 stnode_t *st_arg1, stnode_t *st_arg2)
397 sttype_id_t type1, type2;
398 header_field_info *hfinfo1, *hfinfo2;
399 ftenum_t ftype1, ftype2;
404 type1 = stnode_type_id(st_arg1);
405 type2 = stnode_type_id(st_arg2);
406 hfinfo1 = sttype_range_hfinfo(st_arg1);
407 ftype1 = hfinfo1->type;
409 if (!ftype_can_slice(ftype1)) {
410 dfilter_fail("\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
411 hfinfo1->abbrev, ftype_pretty_name(ftype1));
416 if (type2 == STTYPE_FIELD) {
417 hfinfo2 = sttype_range_hfinfo(st_arg2);
418 ftype2 = hfinfo2->type;
420 if (!is_bytes_type(ftype2)) {
421 if (!ftype_can_slice(ftype2)) {
422 dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
424 ftype_pretty_name(ftype2));
428 /* Convert entire field to bytes */
429 new_st = stnode_new(STTYPE_RANGE, NULL);
431 rn = drange_node_new();
432 drange_node_set_start_offset(rn, 0);
433 drange_node_set_to_the_end(rn);
434 /* st_arg2 is freed in this step */
435 sttype_range_set1(new_st, st_arg2, rn);
437 sttype_test_set2_args(st_node, st_arg1, new_st);
440 else if (type2 == STTYPE_STRING) {
441 s = stnode_data(st_arg2);
442 fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
446 new_st = stnode_new(STTYPE_FVALUE, fvalue);
447 sttype_test_set2_args(st_node, st_arg1, new_st);
448 stnode_free(st_arg2);
450 else if (type2 == STTYPE_RANGE) {
451 /* XXX - check lengths of both ranges */
454 g_assert_not_reached();
460 check_relation(FtypeCanFunc can_func, stnode_t *st_node,
461 stnode_t *st_arg1, stnode_t *st_arg2)
463 switch (stnode_type_id(st_arg1)) {
465 check_relation_LHS_FIELD(can_func, st_node, st_arg1, st_arg2);
468 check_relation_LHS_STRING(can_func, st_node, st_arg1, st_arg2);
471 check_relation_LHS_RANGE(can_func, st_node, st_arg1, st_arg2);
474 case STTYPE_UNINITIALIZED:
478 case STTYPE_NUM_TYPES:
479 g_assert_not_reached();
484 check_test(stnode_t *st_node)
487 stnode_t *st_arg1, *st_arg2;
489 sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2);
492 case TEST_OP_UNINITIALIZED:
493 g_assert_not_reached();
511 check_relation(ftype_can_eq, st_node, st_arg1, st_arg2);
514 check_relation(ftype_can_ne, st_node, st_arg1, st_arg2);
517 check_relation(ftype_can_gt, st_node, st_arg1, st_arg2);
520 check_relation(ftype_can_ge, st_node, st_arg1, st_arg2);
523 check_relation(ftype_can_lt, st_node, st_arg1, st_arg2);
526 check_relation(ftype_can_le, st_node, st_arg1, st_arg2);
533 semcheck(stnode_t *st_node)
537 name = stnode_type_name(st_node);
539 switch (stnode_type_id(st_node)) {
544 g_assert_not_reached();
550 dfw_semcheck(dfwork_t *dfw)
553 semcheck(dfw->st_root);