/* Check the semantics of any type of TEST */ static void check_test(stnode_t *st_node) { test_op_t st_op; stnode_t *st_arg1, *st_arg2; #ifdef DEBUG_dfilter static guint i = 0; #endif DebugLog((" 3 check_test(stnode_t *st_node = %p) [%u]\n", st_node, i)); sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2); switch (st_op) { case TEST_OP_UNINITIALIZED: g_assert_not_reached(); break; case TEST_OP_EXISTS: check_exists(st_arg1); break; case TEST_OP_NOT: semcheck(st_arg1); break; case TEST_OP_AND: case TEST_OP_OR: semcheck(st_arg1); semcheck(st_arg2); break; case TEST_OP_EQ: check_relation("==", FALSE, ftype_can_eq, st_node, st_arg1, st_arg2); break; case TEST_OP_NE: check_relation("!=", FALSE, ftype_can_ne, st_node, st_arg1, st_arg2); break; case TEST_OP_GT: check_relation(">", FALSE, ftype_can_gt, st_node, st_arg1, st_arg2); break; case TEST_OP_GE: check_relation(">=", FALSE, ftype_can_ge, st_node, st_arg1, st_arg2); break; case TEST_OP_LT: check_relation("<", FALSE, ftype_can_lt, st_node, st_arg1, st_arg2); break; case TEST_OP_LE: check_relation("<=", FALSE, ftype_can_le, st_node, st_arg1, st_arg2); break; case TEST_OP_BITWISE_AND: check_relation("&", FALSE, ftype_can_bitwise_and, st_node, st_arg1, st_arg2); break; case TEST_OP_CONTAINS: check_relation("contains", TRUE, ftype_can_contains, st_node, st_arg1, st_arg2); break; case TEST_OP_MATCHES: #ifdef HAVE_LIBPCRE check_relation("matches", TRUE, ftype_can_matches, st_node, st_arg1, st_arg2); #else dfilter_fail("This Wireshark version does not support the \"matches\" operation."); THROW(TypeError); #endif break; default: g_assert_not_reached(); } DebugLog((" 3 check_test(stnode_t *st_node = %p) [%u] - End\n", st_node, i++)); }
static void gen_test(dfwork_t *dfw, stnode_t *st_node) { test_op_t st_op; stnode_t *st_arg1, *st_arg2; dfvm_value_t *val1; dfvm_insn_t *insn; header_field_info *hfinfo; sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2); switch (st_op) { case TEST_OP_UNINITIALIZED: g_assert_not_reached(); break; case TEST_OP_EXISTS: val1 = dfvm_value_new(HFINFO); hfinfo = (header_field_info*)stnode_data(st_arg1); /* Rewind to find the first field of this name. */ while (hfinfo->same_name_prev) { hfinfo = hfinfo->same_name_prev; } val1->value.hfinfo = hfinfo; insn = dfvm_insn_new(CHECK_EXISTS); insn->arg1 = val1; dfw_append_insn(dfw, insn); /* Record the FIELD_ID in hash of interesting fields. */ while (hfinfo) { g_hash_table_insert(dfw->interesting_fields, GINT_TO_POINTER(hfinfo->id), GUINT_TO_POINTER(TRUE)); hfinfo = hfinfo->same_name_next; } break; case TEST_OP_NOT: gencode(dfw, st_arg1); insn = dfvm_insn_new(NOT); dfw_append_insn(dfw, insn); break; case TEST_OP_AND: gencode(dfw, st_arg1); insn = dfvm_insn_new(IF_FALSE_GOTO); val1 = dfvm_value_new(INSN_NUMBER); insn->arg1 = val1; dfw_append_insn(dfw, insn); gencode(dfw, st_arg2); val1->value.numeric = dfw->next_insn_id; break; case TEST_OP_OR: gencode(dfw, st_arg1); insn = dfvm_insn_new(IF_TRUE_GOTO); val1 = dfvm_value_new(INSN_NUMBER); insn->arg1 = val1; dfw_append_insn(dfw, insn); gencode(dfw, st_arg2); val1->value.numeric = dfw->next_insn_id; break; case TEST_OP_EQ: gen_relation(dfw, ANY_EQ, st_arg1, st_arg2); break; case TEST_OP_NE: gen_relation(dfw, ANY_NE, st_arg1, st_arg2); break; case TEST_OP_GT: gen_relation(dfw, ANY_GT, st_arg1, st_arg2); break; case TEST_OP_GE: gen_relation(dfw, ANY_GE, st_arg1, st_arg2); break; case TEST_OP_LT: gen_relation(dfw, ANY_LT, st_arg1, st_arg2); break; case TEST_OP_LE: gen_relation(dfw, ANY_LE, st_arg1, st_arg2); break; case TEST_OP_BITWISE_AND: gen_relation(dfw, ANY_BITWISE_AND, st_arg1, st_arg2); break; case TEST_OP_CONTAINS: gen_relation(dfw, ANY_CONTAINS, st_arg1, st_arg2); break; case TEST_OP_MATCHES: gen_relation(dfw, ANY_MATCHES, st_arg1, st_arg2); break; } }
/* Check the semantics of any type of TEST */ static void check_test(stnode_t *st_node, GPtrArray *deprecated) { test_op_t st_op, st_arg_op; stnode_t *st_arg1, *st_arg2; #ifdef DEBUG_dfilter static guint i = 0; #endif DebugLog((" 3 check_test(stnode_t *st_node = %p) [%u]\n", st_node, i)); sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2); switch (st_op) { case TEST_OP_UNINITIALIZED: g_assert_not_reached(); break; case TEST_OP_EXISTS: check_exists(st_arg1); break; case TEST_OP_NOT: semcheck(st_arg1, deprecated); break; case TEST_OP_AND: case TEST_OP_OR: if (stnode_type_id(st_arg1) == STTYPE_TEST) { sttype_test_get(st_arg1, &st_arg_op, NULL, NULL); if (st_arg_op == TEST_OP_AND || st_arg_op == TEST_OP_OR) { if (st_op != st_arg_op && !st_arg1->inside_brackets) g_ptr_array_add(deprecated, g_strdup("suggest parentheses around '&&' within '||'")); } } if (stnode_type_id(st_arg2) == STTYPE_TEST) { sttype_test_get(st_arg2, &st_arg_op, NULL, NULL); if (st_arg_op == TEST_OP_AND || st_arg_op == TEST_OP_OR) { if (st_op != st_arg_op && !st_arg2->inside_brackets) g_ptr_array_add(deprecated, g_strdup("suggest parentheses around '&&' within '||'")); } } semcheck(st_arg1, deprecated); semcheck(st_arg2, deprecated); break; case TEST_OP_EQ: check_relation("==", FALSE, ftype_can_eq, st_node, st_arg1, st_arg2); break; case TEST_OP_NE: check_relation("!=", FALSE, ftype_can_ne, st_node, st_arg1, st_arg2); break; case TEST_OP_GT: check_relation(">", FALSE, ftype_can_gt, st_node, st_arg1, st_arg2); break; case TEST_OP_GE: check_relation(">=", FALSE, ftype_can_ge, st_node, st_arg1, st_arg2); break; case TEST_OP_LT: check_relation("<", FALSE, ftype_can_lt, st_node, st_arg1, st_arg2); break; case TEST_OP_LE: check_relation("<=", FALSE, ftype_can_le, st_node, st_arg1, st_arg2); break; case TEST_OP_BITWISE_AND: check_relation("&", FALSE, ftype_can_bitwise_and, st_node, st_arg1, st_arg2); break; case TEST_OP_CONTAINS: check_relation("contains", TRUE, ftype_can_contains, st_node, st_arg1, st_arg2); break; case TEST_OP_MATCHES: check_relation("matches", TRUE, ftype_can_matches, st_node, st_arg1, st_arg2); break; default: g_assert_not_reached(); } DebugLog((" 3 check_test(stnode_t *st_node = %p) [%u] - End\n", st_node, i++)); }