2 * Wireshark - Network traffic analyzer
3 * By Gerald Combs <gerald@wireshark.org>
4 * Copyright 2001 Gerald Combs
6 * SPDX-License-Identifier: GPL-2.0-or-later
10 #define WS_LOG_DOMAIN LOG_DOMAIN_DFILTER
14 #include <ftypes/ftypes.h>
15 #include <wsutil/array.h>
16 #include <wsutil/ws_assert.h>
19 debug_register(GSList
*reg
, uint32_t num
);
22 dfvm_opcode_tostr(dfvm_opcode_t code
)
25 case DFVM_NULL
: return "(DFVM_NULL)";
26 case DFVM_IF_TRUE_GOTO
: return "IF_TRUE_GOTO";
27 case DFVM_IF_FALSE_GOTO
: return "IF_FALSE_GOTO";
28 case DFVM_CHECK_EXISTS
: return "CHECK_EXISTS";
29 case DFVM_CHECK_EXISTS_R
: return "CHECK_EXISTS_R";
30 case DFVM_NOT
: return "NOT";
31 case DFVM_RETURN
: return "RETURN";
32 case DFVM_READ_TREE
: return "READ_TREE";
33 case DFVM_READ_TREE_R
: return "READ_TREE_R";
34 case DFVM_READ_REFERENCE
: return "READ_REFERENCE";
35 case DFVM_READ_REFERENCE_R
: return "READ_REFERENCE_R";
36 case DFVM_PUT_FVALUE
: return "PUT_FVALUE";
37 case DFVM_ALL_EQ
: return "ALL_EQ";
38 case DFVM_ANY_EQ
: return "ANY_EQ";
39 case DFVM_ALL_NE
: return "ALL_NE";
40 case DFVM_ANY_NE
: return "ANY_NE";
41 case DFVM_ALL_GT
: return "ALL_GT";
42 case DFVM_ANY_GT
: return "ANY_GT";
43 case DFVM_ALL_GE
: return "ALL_GE";
44 case DFVM_ANY_GE
: return "ANY_GE";
45 case DFVM_ALL_LT
: return "ALL_LT";
46 case DFVM_ANY_LT
: return "ANY_LT";
47 case DFVM_ALL_LE
: return "ALL_LE";
48 case DFVM_ANY_LE
: return "ANY_LE";
49 case DFVM_ALL_CONTAINS
: return "ALL_CONTAINS";
50 case DFVM_ANY_CONTAINS
: return "ANY_CONTAINS";
51 case DFVM_ALL_MATCHES
: return "ALL_MATCHES";
52 case DFVM_ANY_MATCHES
: return "ANY_MATCHES";
53 case DFVM_SET_ALL_IN
: return "SET_ALL_IN";
54 case DFVM_SET_ANY_IN
: return "SET_ANY_IN";
55 case DFVM_SET_ALL_NOT_IN
: return "SET_ALL_NOT_IN";
56 case DFVM_SET_ANY_NOT_IN
: return "SET_ANY_NOT_IN";
57 case DFVM_SET_ADD
: return "SET_ADD";
58 case DFVM_SET_ADD_RANGE
: return "SET_ADD_RANGE";
59 case DFVM_SET_CLEAR
: return "SET_CLEAR";
60 case DFVM_SLICE
: return "SLICE";
61 case DFVM_LENGTH
: return "LENGTH";
62 case DFVM_VALUE_STRING
: return "VALUE_STRING";
63 case DFVM_BITWISE_AND
: return "BITWISE_AND";
64 case DFVM_UNARY_MINUS
: return "UNARY_MINUS";
65 case DFVM_ADD
: return "ADD";
66 case DFVM_SUBTRACT
: return "SUBTRACT";
67 case DFVM_MULTIPLY
: return "MULTIPLY";
68 case DFVM_DIVIDE
: return "DIVIDE";
69 case DFVM_MODULO
: return "MODULO";
70 case DFVM_CALL_FUNCTION
: return "CALL_FUNCTION";
71 case DFVM_STACK_PUSH
: return "STACK_PUSH";
72 case DFVM_STACK_POP
: return "STACK_POP";
73 case DFVM_NOT_ALL_ZERO
: return "NOT_ALL_ZERO";
74 case DFVM_NO_OP
: return "NO_OP";
76 return "(fix-opcode-string)";
80 dfvm_value_free(dfvm_value_t
*v
)
84 g_ptr_array_unref(v
->value
.fvalue_p
);
87 drange_free(v
->value
.drange
);
90 ws_regex_free(v
->value
.pcre
);
105 dfvm_value_ref(dfvm_value_t
*v
)
114 dfvm_value_unref(dfvm_value_t
*v
)
118 if (v
->ref_count
> 0)
124 dfvm_insn_new(dfvm_opcode_t op
)
128 insn
= g_new(dfvm_insn_t
, 1);
137 dfvm_insn_replace_no_op(dfvm_insn_t
*insn
)
140 dfvm_value_unref(insn
->arg1
);
144 dfvm_value_unref(insn
->arg2
);
148 dfvm_value_unref(insn
->arg3
);
151 insn
->op
= DFVM_NO_OP
;
155 dfvm_insn_free(dfvm_insn_t
*insn
)
158 dfvm_value_unref(insn
->arg1
);
161 dfvm_value_unref(insn
->arg2
);
164 dfvm_value_unref(insn
->arg3
);
171 dfvm_value_new(dfvm_value_type_t type
)
175 v
= g_new(dfvm_value_t
, 1);
182 dfvm_value_new_fvalue(fvalue_t
*fv
)
184 dfvm_value_t
*v
= dfvm_value_new(FVALUE
);
185 v
->value
.fvalue_p
= g_ptr_array_new_full(1, (GDestroyNotify
)fvalue_free
);
186 g_ptr_array_add(v
->value
.fvalue_p
, fv
);
191 dfvm_value_new_hfinfo(header_field_info
*hfinfo
, bool raw
)
196 v
= dfvm_value_new(RAW_HFINFO
);
198 v
= dfvm_value_new(HFINFO
);
199 v
->value
.hfinfo
= hfinfo
;
204 dfvm_value_new_register(int reg
)
206 dfvm_value_t
*v
= dfvm_value_new(REGISTER
);
207 v
->value
.numeric
= reg
;
212 dfvm_value_new_drange(drange_t
*dr
)
214 dfvm_value_t
*v
= dfvm_value_new(DRANGE
);
215 v
->value
.drange
= dr
;
220 dfvm_value_new_funcdef(df_func_def_t
*funcdef
)
222 dfvm_value_t
*v
= dfvm_value_new(FUNCTION_DEF
);
223 v
->value
.funcdef
= funcdef
;
228 dfvm_value_new_pcre(ws_regex_t
*re
)
230 dfvm_value_t
*v
= dfvm_value_new(PCRE
);
236 dfvm_value_new_uint(unsigned num
)
238 dfvm_value_t
*v
= dfvm_value_new(INTEGER
);
239 v
->value
.numeric
= num
;
244 dfvm_value_tostr(dfvm_value_t
*v
)
253 s
= ws_strdup(v
->value
.hfinfo
->abbrev
);
256 s
= ws_strdup_printf("@%s", v
->value
.hfinfo
->abbrev
);
259 s
= fvalue_to_debug_repr(NULL
, dfvm_value_get_fvalue(v
));
262 s
= drange_tostr(v
->value
.drange
);
265 s
= ws_strdup(ws_regex_pattern(v
->value
.pcre
));
268 s
= ws_strdup_printf("R%"PRIu32
, v
->value
.numeric
);
271 s
= ws_strdup(v
->value
.funcdef
->name
);
274 s
= ws_strdup_printf("%"PRIu32
, v
->value
.numeric
);
277 s
= ws_strdup("EMPTY");
280 s
= ws_strdup_printf("INSN(%"PRIu32
")", v
->value
.numeric
);
287 value_type_tostr(dfvm_value_t
*v
, bool show_ftype
)
291 if (!v
|| !show_ftype
)
292 return ws_strdup("");
296 s
= ftype_name(v
->value
.hfinfo
->type
);
302 s
= fvalue_type_name(dfvm_value_get_fvalue(v
));
305 if (v
->value
.funcdef
->return_ftype
!= FT_NONE
)
306 s
= ftype_name(v
->value
.funcdef
->return_ftype
);
311 return ws_strdup("");
313 return ws_strdup_printf(" <%s>", s
);
317 dump_str_stack_push(GSList
*stack
, const char *arg
, const char *arg_type
)
319 stack
= g_slist_prepend(stack
, g_strdup(arg
));
320 stack
= g_slist_prepend(stack
, g_strdup(arg_type
));
325 dump_str_stack_pop(GSList
*stack
, uint32_t count
)
327 while (stack
&& count
-- > 0) {
328 /* For each argument count we need to pop two elements from the stack,
329 * the argument string itself and the argument type string.
330 * They always come in pairs. */
332 stack
= g_slist_delete_link(stack
, stack
);
334 stack
= g_slist_delete_link(stack
, stack
);
340 append_call_function(wmem_strbuf_t
*buf
, const char *func
, const char *func_type
,
341 uint32_t nargs
, GSList
*stack_print
)
346 const char *sep
= "";
348 wmem_strbuf_append_printf(buf
, "%s(", func
);
350 gs
= g_string_new(NULL
);
351 for (l
= stack_print
, idx
= 0; l
!= NULL
&& idx
< nargs
; idx
++, l
= l
->next
) {
352 /* Argument strings always come in pairs, string + type string. Type comes first
353 * (top to bottom). */
354 g_string_prepend(gs
, sep
);
355 g_string_prepend(gs
, l
->data
);
357 g_string_prepend(gs
, l
->data
);
360 wmem_strbuf_append(buf
, gs
->str
);
361 g_string_free(gs
, TRUE
);
363 wmem_strbuf_append_printf(buf
, ")%s", func_type
);
367 indent(wmem_strbuf_t
*buf
, size_t offset
, size_t start
)
369 size_t pos
= buf
->len
- start
;
372 wmem_strbuf_append_c_count(buf
, ' ', offset
- pos
);
374 #define indent1(buf, start) indent(buf, 24, start)
375 #define indent2(buf, start) indent(buf, 16, start)
378 append_to_register(wmem_strbuf_t
*buf
, const char *reg
)
380 wmem_strbuf_append_printf(buf
, " -> %s", reg
);
384 append_op_args(wmem_strbuf_t
*buf
, dfvm_insn_t
*insn
, GSList
**stack_print
,
387 dfvm_value_t
*arg1
, *arg2
, *arg3
;
388 char *arg1_str
, *arg2_str
, *arg3_str
;
389 char *arg1_str_type
, *arg2_str_type
, *arg3_str_type
;
395 arg1_str
= dfvm_value_tostr(arg1
);
396 arg2_str
= dfvm_value_tostr(arg2
);
397 arg3_str
= dfvm_value_tostr(arg3
);
398 arg1_str_type
= value_type_tostr(arg1
, flags
& DF_DUMP_SHOW_FTYPE
);
399 arg2_str_type
= value_type_tostr(arg2
, flags
& DF_DUMP_SHOW_FTYPE
);
400 arg3_str_type
= value_type_tostr(arg3
, flags
& DF_DUMP_SHOW_FTYPE
);
402 col_start
= buf
->len
;
405 case DFVM_CHECK_EXISTS
:
406 wmem_strbuf_append_printf(buf
, "%s%s",
407 arg1_str
, arg1_str_type
);
410 case DFVM_CHECK_EXISTS_R
:
411 wmem_strbuf_append_printf(buf
, "%s#[%s]%s",
412 arg1_str
, arg2_str
, arg1_str_type
);
416 wmem_strbuf_append_printf(buf
, "%s%s",
417 arg1_str
, arg1_str_type
);
418 indent2(buf
, col_start
);
419 append_to_register(buf
, arg2_str
);
422 case DFVM_READ_TREE_R
:
423 wmem_strbuf_append_printf(buf
, "%s#[%s]%s",
424 arg1_str
, arg3_str
, arg1_str_type
);
425 indent2(buf
, col_start
);
426 append_to_register(buf
, arg2_str
);
429 case DFVM_READ_REFERENCE
:
430 wmem_strbuf_append_printf(buf
, "${%s}%s",
431 arg1_str
, arg1_str_type
);
432 indent2(buf
, col_start
);
433 append_to_register(buf
, arg2_str
);
436 case DFVM_READ_REFERENCE_R
:
437 wmem_strbuf_append_printf(buf
, "${%s#[%s]}%s",
438 arg1_str
, arg3_str
, arg1_str_type
);
439 indent2(buf
, col_start
);
440 append_to_register(buf
, arg2_str
);
443 case DFVM_PUT_FVALUE
:
444 wmem_strbuf_append_printf(buf
, "%s%s",
445 arg1_str
, arg1_str_type
);
446 indent2(buf
, col_start
);
447 append_to_register(buf
, arg2_str
);
450 case DFVM_CALL_FUNCTION
:
451 append_call_function(buf
, arg1_str
, arg1_str_type
,
452 arg3
->value
.numeric
, *stack_print
);
453 indent2(buf
, col_start
);
454 append_to_register(buf
, arg2_str
);
457 case DFVM_STACK_PUSH
:
458 wmem_strbuf_append_printf(buf
, "%s%s", arg1_str
, arg1_str_type
);
459 *stack_print
= dump_str_stack_push(*stack_print
, arg1_str
, arg1_str_type
);
463 wmem_strbuf_append_printf(buf
, "[%s]", arg1_str
);
464 *stack_print
= dump_str_stack_pop(*stack_print
, arg1
->value
.numeric
);
468 wmem_strbuf_append_printf(buf
, "%s[%s]%s",
469 arg1_str
, arg3_str
, arg1_str_type
);
470 indent2(buf
, col_start
);
471 append_to_register(buf
, arg2_str
);
475 wmem_strbuf_append_printf(buf
, "%s%s",
476 arg1_str
, arg1_str_type
);
477 indent2(buf
, col_start
);
478 append_to_register(buf
, arg2_str
);
481 case DFVM_VALUE_STRING
:
482 wmem_strbuf_append_printf(buf
, "%s::VS(%s%s)",
483 arg1_str
, arg2_str
, arg2_str_type
);
484 indent2(buf
, col_start
);
485 append_to_register(buf
, arg3_str
);
489 wmem_strbuf_append_printf(buf
, "%s%s === %s%s",
490 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
494 wmem_strbuf_append_printf(buf
, "%s%s == %s%s",
495 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
499 wmem_strbuf_append_printf(buf
, "%s%s != %s%s",
500 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
504 wmem_strbuf_append_printf(buf
, "%s%s !== %s%s",
505 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
510 wmem_strbuf_append_printf(buf
, "%s%s > %s%s",
511 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
516 wmem_strbuf_append_printf(buf
, "%s%s >= %s%s",
517 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
522 wmem_strbuf_append_printf(buf
, "%s%s < %s%s",
523 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
528 wmem_strbuf_append_printf(buf
, "%s%s <= %s%s",
529 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
532 case DFVM_NOT_ALL_ZERO
:
533 wmem_strbuf_append_printf(buf
, "%s%s",
534 arg1_str
, arg1_str_type
);
537 case DFVM_ALL_CONTAINS
:
538 case DFVM_ANY_CONTAINS
:
539 wmem_strbuf_append_printf(buf
, "%s%s contains %s%s",
540 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
543 case DFVM_ALL_MATCHES
:
544 case DFVM_ANY_MATCHES
:
545 wmem_strbuf_append_printf(buf
, "%s%s matches %s%s",
546 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
549 case DFVM_SET_ALL_IN
:
550 case DFVM_SET_ANY_IN
:
551 case DFVM_SET_ALL_NOT_IN
:
552 case DFVM_SET_ANY_NOT_IN
:
553 wmem_strbuf_append_printf(buf
, "%s%s",
554 arg1_str
, arg1_str_type
);
558 wmem_strbuf_append_printf(buf
, "%s%s", arg1_str
, arg1_str_type
);
561 case DFVM_SET_ADD_RANGE
:
562 wmem_strbuf_append_printf(buf
, "%s%s .. %s%s",
563 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
566 case DFVM_BITWISE_AND
:
567 wmem_strbuf_append_printf(buf
, "%s%s & %s%s",
568 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
569 indent2(buf
, col_start
);
570 append_to_register(buf
, arg3_str
);
573 case DFVM_UNARY_MINUS
:
574 wmem_strbuf_append_printf(buf
, "-%s%s",
575 arg1_str
, arg1_str_type
);
576 indent2(buf
, col_start
);
577 append_to_register(buf
, arg2_str
);
581 wmem_strbuf_append_printf(buf
, "%s%s + %s%s",
582 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
583 indent2(buf
, col_start
);
584 append_to_register(buf
, arg3_str
);
588 wmem_strbuf_append_printf(buf
, "%s%s - %s%s",
589 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
590 indent2(buf
, col_start
);
591 append_to_register(buf
, arg3_str
);
595 wmem_strbuf_append_printf(buf
, "%s%s * %s%s",
596 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
597 indent2(buf
, col_start
);
598 append_to_register(buf
, arg3_str
);
602 wmem_strbuf_append_printf(buf
, "%s%s / %s%s",
603 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
604 indent2(buf
, col_start
);
605 append_to_register(buf
, arg3_str
);
609 wmem_strbuf_append_printf(buf
, "%s%s %% %s%s",
610 arg1_str
, arg1_str_type
, arg2_str
, arg2_str_type
);
611 indent2(buf
, col_start
);
612 append_to_register(buf
, arg3_str
);
615 case DFVM_IF_TRUE_GOTO
:
616 case DFVM_IF_FALSE_GOTO
:
617 wmem_strbuf_append_printf(buf
, "%u", arg1
->value
.numeric
);
622 wmem_strbuf_append_printf(buf
, "%s%s", arg1_str
, arg1_str_type
);
630 ASSERT_DFVM_OP_NOT_REACHED(insn
->op
);
636 g_free(arg1_str_type
);
637 g_free(arg2_str_type
);
638 g_free(arg3_str_type
);
642 append_references(wmem_strbuf_t
*buf
, GHashTable
*references
, bool raw
)
644 GHashTableIter ref_iter
;
649 g_hash_table_iter_init(&ref_iter
, references
);
650 while (g_hash_table_iter_next(&ref_iter
, &key
, &value
)) {
651 const char *abbrev
= ((header_field_info
*)key
)->abbrev
;
652 GPtrArray
*refs_array
= value
;
656 wmem_strbuf_append_printf(buf
, " ${@%s} = {", abbrev
);
658 wmem_strbuf_append_printf(buf
, " ${%s} = {", abbrev
);
659 for (i
= 0; i
< refs_array
->len
; i
++) {
661 wmem_strbuf_append(buf
, ", ");
663 ref
= refs_array
->pdata
[i
];
664 str
= fvalue_to_debug_repr(NULL
, ref
->value
);
665 wmem_strbuf_append_printf(buf
, "%s <%s>", str
, fvalue_type_name(ref
->value
));
668 wmem_strbuf_append(buf
, "}\n");
673 dfvm_dump_str(wmem_allocator_t
*alloc
, dfilter_t
*df
, uint16_t flags
)
678 GSList
*stack_print
= NULL
;
681 buf
= wmem_strbuf_new(alloc
, NULL
);
683 if (flags
& DF_DUMP_REFERENCES
) {
684 if (g_hash_table_size(df
->references
) > 0) {
685 wmem_strbuf_append(buf
, "References:\n");
686 append_references(buf
, df
->references
, false);
689 wmem_strbuf_append(buf
, "References: (none)\n");
691 wmem_strbuf_append_c(buf
, '\n');
694 if (flags
& DF_DUMP_REFERENCES
) {
695 if (g_hash_table_size(df
->raw_references
) > 0) {
696 wmem_strbuf_append(buf
, "Raw references:\n");
697 append_references(buf
, df
->raw_references
, true);
700 wmem_strbuf_append(buf
, "Raw references: (none)\n");
702 wmem_strbuf_append_c(buf
, '\n');
705 wmem_strbuf_append(buf
, "Instructions:");
707 length
= df
->insns
->len
;
708 for (id
= 0; id
< length
; id
++) {
709 insn
= g_ptr_array_index(df
->insns
, id
);
710 col_start
= buf
->len
;
711 wmem_strbuf_append_printf(buf
, "\n %04d %s", id
, dfvm_opcode_tostr(insn
->op
));
720 indent1(buf
, col_start
);
721 append_op_args(buf
, insn
, &stack_print
, flags
);
726 if (flags
& DF_DUMP_SHOW_FTYPE
) {
727 wmem_strbuf_append_printf(buf
, "\nReturn Type: <%s>", ftype_name(df
->ret_type
));
730 return wmem_strbuf_finalize(buf
);
734 dfvm_dump(FILE *f
, dfilter_t
*df
, uint16_t flags
)
736 char *str
= dfvm_dump_str(NULL
, df
, flags
);
739 wmem_free(NULL
, str
);
743 compare_finfo_layer(const void *_a
, const void *_b
)
745 const field_info
*a
= *(const field_info
**)_a
;
746 const field_info
*b
= *(const field_info
**)_b
;
747 return a
->proto_layer_num
- b
->proto_layer_num
;
751 drange_contains_layer(drange_t
*dr
, int num
, int length
)
754 GSList
*list
= dr
->range_list
;
759 lower
= rn
->start_offset
;
763 if (rn
->ending
== DRANGE_NODE_END_T_LENGTH
) {
764 upper
= lower
+ rn
->length
- 1;
766 else if (rn
->ending
== DRANGE_NODE_END_T_OFFSET
) {
767 upper
= rn
->end_offset
;
769 else if (rn
->ending
== DRANGE_NODE_END_T_TO_THE_END
) {
773 ws_assert_not_reached();
776 if (num
>= lower
&& num
<= upper
) { /* inclusive */
780 list
= g_slist_next(list
);
786 dfvm_get_raw_fvalue(const field_info
*fi
)
790 int length
, tvb_length
;
793 * XXX - a field can have a length that runs past
794 * the end of the tvbuff. Ideally, that should
795 * be fixed when adding an item to the protocol
796 * tree, but checking the length when doing
797 * that could be expensive. Until we fix that,
798 * we'll do the check here.
800 tvb_length
= tvb_captured_length_remaining(fi
->ds_tvb
, fi
->start
);
801 if (tvb_length
< 0) {
805 if (length
> tvb_length
)
808 bytes
= g_byte_array_new();
809 g_byte_array_append(bytes
, tvb_get_ptr(fi
->ds_tvb
, fi
->start
, length
), length
);
811 fv
= fvalue_new(FT_BYTES
);
812 fvalue_set_byte_array(fv
, bytes
);
817 filter_finfo_fvalues(df_cell_t
*rp
, GPtrArray
*finfos
, drange_t
*range
, bool raw
)
819 int length
; /* maximum proto layer number. The numbers are sequential. */
820 field_info
*last_finfo
, *finfo
;
823 bool cookie_matches
= false;
827 g_ptr_array_sort(finfos
, compare_finfo_layer
);
828 last_finfo
= finfos
->pdata
[finfos
->len
- 1];
829 length
= last_finfo
->proto_layer_num
;
831 for (unsigned i
= 0; i
< finfos
->len
; i
++) {
832 finfo
= finfos
->pdata
[i
];
833 layer
= finfo
->proto_layer_num
;
834 if (cookie
== layer
) {
835 if (cookie_matches
) {
838 fv
= dfvm_get_raw_fvalue(finfo
);
841 df_cell_append(rp
, fv
);
848 cookie_matches
= drange_contains_layer(range
, layer
, length
);
849 if (cookie_matches
) {
852 fv
= dfvm_get_raw_fvalue(finfo
);
855 df_cell_append(rp
, fv
);
865 read_tree_finfos(df_cell_t
*rp
, proto_tree
*tree
,
866 header_field_info
*hfinfo
, drange_t
*range
, bool raw
)
872 /* The caller should NOT free the GPtrArray. */
873 finfos
= proto_get_finfo_ptr_array(tree
, hfinfo
->id
);
874 if (finfos
== NULL
|| g_ptr_array_len(finfos
) == 0) {
878 return filter_finfo_fvalues(rp
, finfos
, range
, raw
) > 0;
881 for (unsigned i
= 0; i
< finfos
->len
; i
++) {
882 finfo
= g_ptr_array_index(finfos
, i
);
884 fv
= dfvm_get_raw_fvalue(finfo
);
887 df_cell_append(rp
, fv
);
892 /* Reads a field from the proto_tree and loads the fvalues into a register,
893 * if that field has not already been read. */
895 read_tree(dfilter_t
*df
, proto_tree
*tree
,
896 dfvm_value_t
*arg1
, dfvm_value_t
*arg2
,
899 drange_t
*range
= NULL
;
903 header_field_info
*hfinfo
= arg1
->value
.hfinfo
;
904 raw
= arg1
->type
== RAW_HFINFO
;
906 int reg
= arg2
->value
.numeric
;
909 range
= arg3
->value
.drange
;
912 rp
= &df
->registers
[reg
];
914 /* Already loaded in this run of the dfilter? */
915 if (!df_cell_is_null(rp
)) {
916 return !df_cell_is_empty(rp
);
920 df_cell_init(rp
, true);
923 // These values are referenced only, do not try to free it later.
924 df_cell_init(rp
, false);
928 read_tree_finfos(rp
, tree
, hfinfo
, range
, raw
);
929 hfinfo
= hfinfo
->same_name_next
;
932 return !df_cell_is_empty(rp
);
936 filter_refs_fvalues(df_cell_t
*rp
, GPtrArray
*refs_array
, drange_t
*range
)
938 int length
; /* maximum proto layer number. The numbers are sequential. */
939 df_reference_t
*last_ref
= NULL
;
941 bool cookie_matches
= false;
943 if (!refs_array
|| refs_array
->len
== 0) {
947 /* refs array is sorted. */
948 last_ref
= refs_array
->pdata
[refs_array
->len
- 1];
949 length
= last_ref
->proto_layer_num
;
951 for (unsigned i
= 0; i
< refs_array
->len
; i
++) {
952 df_reference_t
*ref
= refs_array
->pdata
[i
];
953 int layer
= ref
->proto_layer_num
;
956 df_cell_append(rp
, ref
->value
);
960 if (cookie
== layer
) {
961 if (cookie_matches
) {
962 df_cell_append(rp
, ref
->value
);
967 cookie_matches
= drange_contains_layer(range
, layer
, length
);
968 if (cookie_matches
) {
969 df_cell_append(rp
, ref
->value
);
976 read_reference(dfilter_t
*df
, dfvm_value_t
*arg1
, dfvm_value_t
*arg2
,
981 drange_t
*range
= NULL
;
984 header_field_info
*hfinfo
= arg1
->value
.hfinfo
;
985 raw
= arg1
->type
== RAW_HFINFO
;
987 int reg
= arg2
->value
.numeric
;
990 range
= arg3
->value
.drange
;
993 rp
= &df
->registers
[reg
];
995 /* Already loaded in this run of the dfilter? */
996 if (!df_cell_is_null(rp
)) {
997 return !df_cell_is_empty(rp
);
1000 refs
= g_hash_table_lookup(raw
? df
->raw_references
: df
->references
, hfinfo
);
1001 if (refs
== NULL
|| refs
->len
== 0) {
1005 // These values are referenced only, do not try to free it later.
1006 df_cell_init(rp
, false);
1007 filter_refs_fvalues(rp
, refs
, range
);
1016 typedef ft_bool_t (*DFVMCompareFunc
)(const fvalue_t
*, const fvalue_t
*);
1017 typedef ft_bool_t (*DFVMTestFunc
)(const fvalue_t
*);
1020 cmp_test_internal(enum match_how how
, DFVMCompareFunc match_func
,
1021 GPtrArray
*fv1
, GPtrArray
*fv2
)
1023 bool want_all
= (how
== MATCH_ALL
);
1024 bool want_any
= (how
== MATCH_ANY
);
1025 ft_bool_t have_match
;
1027 for (size_t idx1
= 0; idx1
< fv1
->len
; idx1
++) {
1028 for (size_t idx2
= 0; idx2
< fv2
->len
; idx2
++) {
1029 have_match
= match_func(fv1
->pdata
[idx1
], fv2
->pdata
[idx2
]);
1030 if (want_all
&& have_match
== FT_FALSE
) {
1033 else if (want_any
&& have_match
== FT_TRUE
) {
1038 /* want_all || !want_any */
1043 cmp_test_unary(enum match_how how
, DFVMTestFunc test_func
,
1044 const fvalue_t
**fv_ptr
, size_t fv_count
)
1046 bool want_all
= (how
== MATCH_ALL
);
1047 bool want_any
= (how
== MATCH_ANY
);
1048 ft_bool_t have_match
;
1050 for (size_t idx
= 0; idx
< fv_count
; idx
++) {
1051 have_match
= test_func(fv_ptr
[idx
]);
1052 if (want_all
&& have_match
== FT_FALSE
) {
1055 else if (want_any
&& have_match
== FT_TRUE
) {
1059 /* want_all || !want_any */
1064 all_test_unary(dfilter_t
*df
, DFVMTestFunc func
, dfvm_value_t
*arg1
)
1066 ws_assert(arg1
->type
== REGISTER
);
1067 df_cell_t
*rp
= &df
->registers
[arg1
->value
.numeric
];
1068 return cmp_test_unary(MATCH_ALL
, func
,
1069 (const fvalue_t
**)df_cell_array(rp
), df_cell_size(rp
));
1073 cmp_test(dfilter_t
*df
, DFVMCompareFunc cmp
,
1074 dfvm_value_t
*arg1
, dfvm_value_t
*arg2
,
1077 GPtrArray
*fv1
, *fv2
;
1079 if (arg1
->type
== REGISTER
) {
1080 fv1
= df_cell_ptr(&df
->registers
[arg1
->value
.numeric
]);
1082 else if (arg1
->type
== FVALUE
) {
1083 fv1
= arg1
->value
.fvalue_p
;
1086 ws_assert_not_reached();
1089 if (arg2
->type
== REGISTER
) {
1090 fv2
= df_cell_ptr(&df
->registers
[arg2
->value
.numeric
]);
1092 else if (arg2
->type
== FVALUE
) {
1093 fv2
= arg2
->value
.fvalue_p
;
1096 ws_assert_not_reached();
1099 return cmp_test_internal(how
, cmp
, fv1
, fv2
);
1102 /* cmp(A) <=> cmp(a1) OR cmp(a2) OR cmp(a3) OR ... */
1104 any_test(dfilter_t
*df
, DFVMCompareFunc cmp
,
1105 dfvm_value_t
*arg1
, dfvm_value_t
*arg2
)
1107 return cmp_test(df
, cmp
, arg1
, arg2
, MATCH_ANY
);
1110 /* cmp(A) <=> cmp(a1) AND cmp(a2) AND cmp(a3) AND ... */
1112 all_test(dfilter_t
*df
, DFVMCompareFunc cmp
,
1113 dfvm_value_t
*arg1
, dfvm_value_t
*arg2
)
1115 return cmp_test(df
, cmp
, arg1
, arg2
, MATCH_ALL
);
1119 any_matches(dfilter_t
*df
, dfvm_value_t
*arg1
, dfvm_value_t
*arg2
)
1121 df_cell_t
*rp
= &df
->registers
[arg1
->value
.numeric
];
1122 ws_regex_t
*re
= arg2
->value
.pcre
;
1124 const fvalue_t
**fv_ptr
= (const fvalue_t
**)df_cell_array(rp
);
1126 for (size_t idx
= 0; idx
< df_cell_size(rp
); idx
++) {
1127 if (fvalue_matches(fv_ptr
[idx
], re
) == FT_TRUE
) {
1135 all_matches(dfilter_t
*df
, dfvm_value_t
*arg1
, dfvm_value_t
*arg2
)
1137 df_cell_t
*rp
= &df
->registers
[arg1
->value
.numeric
];
1138 ws_regex_t
*re
= arg2
->value
.pcre
;
1140 const fvalue_t
**fv_ptr
= (const fvalue_t
**)df_cell_array(rp
);
1142 for (size_t idx
= 0; idx
< df_cell_size(rp
); idx
++) {
1143 if (fvalue_matches(fv_ptr
[idx
], re
) == FT_FALSE
) {
1151 test_in_internal(fvalue_t
*fv
, GPtrArray
*range
[2])
1153 GPtrArray
*low
= range
[0];
1154 GPtrArray
*high
= range
[1];
1155 bool low_ok
= false, high_ok
= false;
1159 for (unsigned i
= 0; i
< high
->len
; i
++) {
1160 if (fvalue_le(fv
, high
->pdata
[i
]) == FT_TRUE
) {
1169 for (unsigned i
= 0; i
< low
->len
; i
++) {
1170 if (fvalue_ge(fv
, low
->pdata
[i
]) == FT_TRUE
) {
1177 /* single element */
1178 for (unsigned i
= 0; i
< low
->len
; i
++) {
1179 if (fvalue_eq(fv
, low
->pdata
[i
]) == FT_TRUE
) {
1190 any_in(dfilter_t
*df
, dfvm_value_t
*arg1
)
1192 df_cell_t
*rp
= &df
->registers
[arg1
->value
.numeric
];
1197 /* If the read failed we jump over the membership test. */
1198 ws_assert(!df_cell_is_empty(rp
));
1199 value
= df_cell_ptr(rp
);
1201 for (size_t i
= 0; i
< value
->len
; i
++) {
1202 stack
= df
->set_stack
;
1205 if (test_in_internal(value
->pdata
[i
], stack
->data
)) {
1209 stack
= stack
->next
;
1219 all_in(dfilter_t
*df
, dfvm_value_t
*arg1
)
1221 df_cell_t
*rp
= &df
->registers
[arg1
->value
.numeric
];
1226 /* If the read failed we jump over the membership test. */
1227 ws_assert(!df_cell_is_empty(rp
));
1228 value
= df_cell_ptr(rp
);
1230 for (size_t i
= 0; i
< value
->len
; i
++) {
1231 stack
= df
->set_stack
;
1234 if (test_in_internal(value
->pdata
[i
], stack
->data
)) {
1238 stack
= stack
->next
;
1247 /* Clear registers that were populated during evaluation.
1248 * If we created the values, then these will be freed as well. */
1250 free_register_overhead(dfilter_t
* df
)
1252 for (unsigned i
= 0; i
< df
->num_registers
; i
++) {
1253 df_cell_clear(&df
->registers
[i
]);
1257 /* Takes the list of fvalue_t's in a register, uses fvalue_slice()
1258 * to make a new list of fvalue_t's (which are byte-slices),
1259 * and puts the new list into a new register. */
1261 mk_slice(dfilter_t
*df
, dfvm_value_t
*from_arg
, dfvm_value_t
*to_arg
,
1262 dfvm_value_t
*drange_arg
)
1264 df_cell_t
*from_rp
, *to_rp
;
1265 df_cell_iter_t from_iter
;
1269 to_rp
= &df
->registers
[to_arg
->value
.numeric
];
1270 df_cell_init(to_rp
, true);
1271 from_rp
= &df
->registers
[from_arg
->value
.numeric
];
1272 drange_t
*drange
= drange_arg
->value
.drange
;
1274 df_cell_iter_init(from_rp
, &from_iter
);
1275 while ((old_fv
= df_cell_iter_next(&from_iter
)) != NULL
) {
1276 new_fv
= fvalue_slice(old_fv
, drange
);
1277 /* Assert here because semcheck.c should have
1278 * already caught the cases in which a slice
1279 * cannot be made. */
1281 df_cell_append(to_rp
, new_fv
);
1286 mk_length(dfilter_t
*df
, dfvm_value_t
*from_arg
, dfvm_value_t
*to_arg
)
1288 df_cell_t
*from_rp
, *to_rp
;
1289 df_cell_iter_t from_iter
;
1293 to_rp
= &df
->registers
[to_arg
->value
.numeric
];
1294 df_cell_init(to_rp
, true);
1295 from_rp
= &df
->registers
[from_arg
->value
.numeric
];
1297 df_cell_iter_init(from_rp
, &from_iter
);
1298 while ((old_fv
= df_cell_iter_next(&from_iter
)) != NULL
) {
1299 new_fv
= fvalue_new(FT_UINT32
);
1300 fvalue_set_uinteger(new_fv
, (uint32_t)fvalue_length2(old_fv
));
1301 df_cell_append(to_rp
, new_fv
);
1306 try_value_string(const header_field_info
*hfinfo
, fvalue_t
*fv_num
, char *buf
)
1310 /* XXX - What about BASE_UNIT_STRING? Should we guarantee that we
1311 * don't get here for unit strings in semcheck.c (currently we
1312 * do for OP_MATCHES instead of disallowing it, which will result
1313 * in a legal filter that always compares false as this returns NULL.)
1315 if (fvalue_to_uinteger64(fv_num
, &val
) != FT_OK
)
1318 /* XXX We should find or create instead a suitable function in proto.h
1319 * to perform this mapping. hf_try_val[64]_to_str are similar, though
1320 * don't handle BASE_CUSTOM but do handle BASE_UNIT_STRING */
1322 if (hfinfo
->type
== FT_FRAMENUM
) {
1323 /* FT_FRAMENUM can be converted to an integer (and is compatible
1324 * with the integer types), but if it has an hfinfo->strings it
1325 * is not a value_string and will crash if treated as one.
1326 * Handle the corner case of a FT_FRAMENUM field registered with
1327 * the same abbreviation as a field with a value string.
1328 * (FT_PROTOCOL is caught above because it cannot be converted
1334 if (hfinfo
->display
& BASE_RANGE_STRING
) {
1335 return try_rval_to_str((uint32_t)val
, hfinfo
->strings
);
1337 else if (hfinfo
->display
& BASE_EXT_STRING
) {
1338 if (hfinfo
->display
& BASE_VAL64_STRING
) {
1339 return try_val64_to_str_ext(val
, (val64_string_ext
*)hfinfo
->strings
);
1341 return try_val_to_str_ext((uint32_t)val
, (value_string_ext
*)hfinfo
->strings
);
1344 else if (hfinfo
->display
& BASE_VAL64_STRING
) {
1345 return try_val64_to_str(val
, hfinfo
->strings
);
1347 else if (hfinfo
->display
== BASE_CUSTOM
) {
1348 if (FT_IS_INT32(hfinfo
->type
) || FT_IS_UINT32(hfinfo
->type
))
1349 ((custom_fmt_func_t
)hfinfo
->strings
)(buf
, (uint32_t)val
);
1350 else if (FT_IS_INT64(hfinfo
->type
) || FT_IS_UINT64(hfinfo
->type
))
1351 ((custom_fmt_func_64_t
)hfinfo
->strings
)(buf
, val
);
1353 ws_assert_not_reached();
1356 return try_val_to_str((uint32_t)val
, hfinfo
->strings
);
1358 ws_assert_not_reached();
1362 mk_value_string(dfilter_t
*df
, dfvm_value_t
*vs_arg
, dfvm_value_t
*from_arg
, dfvm_value_t
*to_arg
)
1364 df_cell_t
*from_rp
, *to_rp
;
1365 df_cell_iter_t from_iter
;
1366 const header_field_info
*hfinfo
;
1370 char label_buf
[ITEM_LABEL_LENGTH
];
1372 hfinfo
= vs_arg
->value
.hfinfo
;
1374 to_rp
= &df
->registers
[to_arg
->value
.numeric
];
1375 df_cell_init(to_rp
, true);
1376 from_rp
= &df
->registers
[from_arg
->value
.numeric
];
1378 df_cell_iter_init(from_rp
, &from_iter
);
1379 while ((old_fv
= df_cell_iter_next(&from_iter
)) != NULL
) {
1380 str
= try_value_string(hfinfo
, old_fv
, label_buf
);
1382 new_fv
= fvalue_new(FT_STRING
);
1383 fvalue_set_string(new_fv
, str
);
1384 df_cell_append(to_rp
, new_fv
);
1386 /* XXX - If there's no match we could have a NULL result
1387 * as now (and return false), or use a string like "Unknown"
1388 * the way columns do. We could fall back to a string
1389 * representation of the value if BASE_SPECIAL_VALS if set.
1393 return !df_cell_is_empty(to_rp
);
1397 call_function(dfilter_t
*df
, dfvm_value_t
*arg1
, dfvm_value_t
*arg2
,
1400 df_func_def_t
*funcdef
;
1402 df_cell_t
*rp_return
;
1406 funcdef
= arg1
->value
.funcdef
;
1407 rp_return
= &df
->registers
[arg2
->value
.numeric
];
1408 arg_count
= arg3
->value
.numeric
;
1410 // Functions create a new value, so own it.
1411 df_cell_init(rp_return
, true);
1413 accum
= funcdef
->function(df
->function_stack
, arg_count
, rp_return
);
1417 static void debug_op_error(const fvalue_t
*v1
, const fvalue_t
*v2
, const char *op
, const char *msg
)
1419 char *s1
= fvalue_to_debug_repr(NULL
, v1
);
1420 char *s2
= fvalue_to_debug_repr(NULL
, v2
);
1421 ws_noisy("Error: %s %s %s: %s", s1
, op
, s2
, msg
);
1426 /* Used for temporary debugging only, don't leave in production code (at
1427 * a minimum WS_DEBUG_HERE must be replaced by another log level). */
1429 debug_register(GSList
*reg
, uint32_t num
)
1435 buf
= wmem_strbuf_new(NULL
, NULL
);
1437 wmem_strbuf_append_printf(buf
, "Reg#%"PRIu32
" = { ", num
);
1438 for (l
= reg
; l
!= NULL
; l
= l
->next
) {
1439 s
= fvalue_to_debug_repr(NULL
, l
->data
);
1440 wmem_strbuf_append_printf(buf
, "%s <%s>", s
, fvalue_type_name(l
->data
));
1442 if (l
->next
!= NULL
) {
1443 wmem_strbuf_append(buf
, ", ");
1446 wmem_strbuf_append_c(buf
, '}');
1447 WS_DEBUG_HERE("%s", wmem_strbuf_get_str(buf
));
1448 wmem_strbuf_destroy(buf
);
1452 typedef fvalue_t
* (*DFVMBinaryFunc
)(const fvalue_t
*, const fvalue_t
*, char **);
1455 mk_binary_internal(DFVMBinaryFunc func
, GPtrArray
*fv1
, GPtrArray
*fv2
, df_cell_t
*retval
)
1458 char *err_msg
= NULL
;
1460 for (size_t i
= 0; i
< fv1
->len
; i
++) {
1461 for (size_t j
= 0; j
< fv2
->len
; j
++) {
1462 result
= func(fv1
->pdata
[i
], fv2
->pdata
[j
], &err_msg
);
1463 if (result
== NULL
) {
1464 debug_op_error(fv1
->pdata
[i
], fv2
->pdata
[i
], "&", err_msg
);
1469 df_cell_append(retval
, result
);
1476 mk_binary(dfilter_t
*df
, DFVMBinaryFunc func
,
1477 dfvm_value_t
*arg1
, dfvm_value_t
*arg2
, dfvm_value_t
*to_arg
)
1479 GPtrArray
*val1
, *val2
;
1482 if (arg1
->type
== REGISTER
) {
1483 val1
= df_cell_ptr(&df
->registers
[arg1
->value
.numeric
]);
1485 else if (arg1
->type
== FVALUE
) {
1486 val1
= arg1
->value
.fvalue_p
;
1489 ws_assert_not_reached();
1492 if (arg2
->type
== REGISTER
) {
1493 val2
= df_cell_ptr(&df
->registers
[arg2
->value
.numeric
]);
1495 else if (arg2
->type
== FVALUE
) {
1496 val2
= arg2
->value
.fvalue_p
;
1499 ws_assert_not_reached();
1502 to_rp
= &df
->registers
[to_arg
->value
.numeric
];
1503 df_cell_init(to_rp
, true);
1505 mk_binary_internal(func
, val1
, val2
, to_rp
);
1506 //debug_register(result, to_arg->value.numeric);
1510 mk_minus_internal(GPtrArray
*fv
, df_cell_t
*retval
)
1513 char *err_msg
= NULL
;
1515 for (size_t i
= 0; i
< fv
->len
; i
++) {
1516 result
= fvalue_unary_minus(fv
->pdata
[i
], &err_msg
);
1517 if (result
== NULL
) {
1518 ws_noisy("unary_minus: %s", err_msg
);
1523 df_cell_append(retval
, result
);
1529 mk_minus(dfilter_t
*df
, dfvm_value_t
*arg1
, dfvm_value_t
*to_arg
)
1534 if (arg1
->type
== REGISTER
) {
1535 val
= df_cell_ptr(&df
->registers
[arg1
->value
.numeric
]);
1537 else if (arg1
->type
== FVALUE
) {
1538 val
= arg1
->value
.fvalue_p
;
1541 ws_assert_not_reached();
1544 to_rp
= &df
->registers
[to_arg
->value
.numeric
];
1545 df_cell_init(to_rp
, true);
1547 mk_minus_internal(val
, to_rp
);
1551 put_fvalue(dfilter_t
*df
, dfvm_value_t
*arg1
, dfvm_value_t
*to_arg
)
1553 df_cell_t
*to_rp
= &df
->registers
[to_arg
->value
.numeric
];
1554 /* Memory is owned by the dfvm_value_t. */
1555 df_cell_init(to_rp
, false);
1556 df_cell_append(to_rp
, dfvm_value_get_fvalue(arg1
));
1560 stack_push(dfilter_t
*df
, dfvm_value_t
*arg1
)
1564 if (arg1
->type
== FVALUE
) {
1565 arg
= g_ptr_array_ref(arg1
->value
.fvalue_p
);
1567 else if (arg1
->type
== REGISTER
) {
1568 arg
= df_cell_ref(&df
->registers
[arg1
->value
.numeric
]);
1571 ws_assert_not_reached();
1573 df
->function_stack
= g_slist_prepend(df
->function_stack
, arg
);
1577 stack_pop(dfilter_t
*df
, dfvm_value_t
*arg1
)
1579 unsigned count
= arg1
->value
.numeric
;
1581 for (unsigned i
= 0; i
< count
; i
++) {
1582 /* Free top of stack data. */
1583 if (df
->function_stack
->data
) {
1584 g_ptr_array_unref(df
->function_stack
->data
);
1586 /* Remove top of stack. */
1587 df
->function_stack
= g_slist_delete_link(df
->function_stack
, df
->function_stack
);
1592 set_push(dfilter_t
*df
, dfvm_value_t
*arg1
, dfvm_value_t
*arg2
)
1596 /* We don´t need to use reference counting because the lifetime of each
1597 * arg is guaranteed to outlive the set stack. */
1599 range
= g_new0(GPtrArray
*, 2);
1601 if (arg1
->type
== FVALUE
) {
1602 range
[0] = arg1
->value
.fvalue_p
;
1604 else if (arg1
->type
== REGISTER
) {
1605 range
[0] = df_cell_ptr(&df
->registers
[arg1
->value
.numeric
]);
1608 ws_assert_not_reached();
1612 if (arg2
->type
== FVALUE
) {
1613 range
[1] = arg2
->value
.fvalue_p
;
1615 else if (arg2
->type
== REGISTER
) {
1616 range
[1] = df_cell_ptr(&df
->registers
[arg2
->value
.numeric
]);
1619 ws_assert_not_reached();
1623 df
->set_stack
= g_slist_prepend(df
->set_stack
, range
);
1627 set_clear(dfilter_t
*df
)
1629 g_slist_free_full(df
->set_stack
, g_free
);
1630 df
->set_stack
= NULL
;
1634 check_exists_finfos(proto_tree
*tree
, header_field_info
*hfinfo
, drange_t
*range
)
1638 finfos
= proto_get_finfo_ptr_array(tree
, hfinfo
->id
);
1639 if (finfos
== NULL
|| g_ptr_array_len(finfos
) == 0) {
1642 if (range
== NULL
) {
1645 return filter_finfo_fvalues(NULL
, finfos
, range
, false) > 0;
1649 check_exists(proto_tree
*tree
, dfvm_value_t
*arg1
, dfvm_value_t
*arg2
)
1651 header_field_info
*hfinfo
;
1652 drange_t
*range
= NULL
;
1654 hfinfo
= arg1
->value
.hfinfo
;
1656 range
= arg2
->value
.drange
;
1659 if (check_exists_finfos(tree
, hfinfo
, range
)) {
1662 hfinfo
= hfinfo
->same_name_next
;
1669 dfvm_apply_full(dfilter_t
*df
, proto_tree
*tree
, GPtrArray
**fvals
)
1676 dfvm_value_t
*arg3
= NULL
;
1680 length
= df
->insns
->len
;
1682 for (id
= 0; id
< length
; id
++) {
1685 insn
= g_ptr_array_index(df
->insns
, id
);
1691 case DFVM_CHECK_EXISTS
:
1692 accum
= check_exists(tree
, arg1
, NULL
);
1695 case DFVM_CHECK_EXISTS_R
:
1696 accum
= check_exists(tree
, arg1
, arg2
);
1699 case DFVM_READ_TREE
:
1700 accum
= read_tree(df
, tree
, arg1
, arg2
, NULL
);
1703 case DFVM_READ_TREE_R
:
1704 accum
= read_tree(df
, tree
, arg1
, arg2
, arg3
);
1707 case DFVM_READ_REFERENCE
:
1708 accum
= read_reference(df
, arg1
, arg2
, NULL
);
1711 case DFVM_READ_REFERENCE_R
:
1712 accum
= read_reference(df
, arg1
, arg2
, arg3
);
1715 case DFVM_PUT_FVALUE
:
1716 put_fvalue(df
, arg1
, arg2
);
1719 case DFVM_CALL_FUNCTION
:
1720 accum
= call_function(df
, arg1
, arg2
, arg3
);
1723 case DFVM_STACK_PUSH
:
1724 stack_push(df
, arg1
);
1727 case DFVM_STACK_POP
:
1728 stack_pop(df
, arg1
);
1732 mk_slice(df
, arg1
, arg2
, arg3
);
1736 mk_length(df
, arg1
, arg2
);
1739 case DFVM_VALUE_STRING
:
1740 accum
= mk_value_string(df
, arg1
, arg2
, arg3
);
1744 accum
= all_test(df
, fvalue_eq
, arg1
, arg2
);
1748 accum
= any_test(df
, fvalue_eq
, arg1
, arg2
);
1752 accum
= all_test(df
, fvalue_ne
, arg1
, arg2
);
1756 accum
= any_test(df
, fvalue_ne
, arg1
, arg2
);
1760 accum
= all_test(df
, fvalue_gt
, arg1
, arg2
);
1764 accum
= any_test(df
, fvalue_gt
, arg1
, arg2
);
1768 accum
= all_test(df
, fvalue_ge
, arg1
, arg2
);
1772 accum
= any_test(df
, fvalue_ge
, arg1
, arg2
);
1776 accum
= all_test(df
, fvalue_lt
, arg1
, arg2
);
1780 accum
= any_test(df
, fvalue_lt
, arg1
, arg2
);
1784 accum
= all_test(df
, fvalue_le
, arg1
, arg2
);
1788 accum
= any_test(df
, fvalue_le
, arg1
, arg2
);
1791 case DFVM_BITWISE_AND
:
1792 mk_binary(df
, fvalue_bitwise_and
, arg1
, arg2
, arg3
);
1796 mk_binary(df
, fvalue_add
, arg1
, arg2
, arg3
);
1800 mk_binary(df
, fvalue_subtract
, arg1
, arg2
, arg3
);
1804 mk_binary(df
, fvalue_multiply
, arg1
, arg2
, arg3
);
1808 mk_binary(df
, fvalue_divide
, arg1
, arg2
, arg3
);
1812 mk_binary(df
, fvalue_modulo
, arg1
, arg2
, arg3
);
1815 case DFVM_NOT_ALL_ZERO
:
1816 accum
= !all_test_unary(df
, fvalue_is_zero
, arg1
);
1819 case DFVM_ALL_CONTAINS
:
1820 accum
= all_test(df
, fvalue_contains
, arg1
, arg2
);
1823 case DFVM_ANY_CONTAINS
:
1824 accum
= any_test(df
, fvalue_contains
, arg1
, arg2
);
1827 case DFVM_ALL_MATCHES
:
1828 accum
= all_matches(df
, arg1
, arg2
);
1831 case DFVM_ANY_MATCHES
:
1832 accum
= any_matches(df
, arg1
, arg2
);
1836 set_push(df
, arg1
, NULL
);
1839 case DFVM_SET_ADD_RANGE
:
1840 set_push(df
, arg1
, arg2
);
1843 case DFVM_SET_ALL_IN
:
1844 accum
= all_in(df
, arg1
);
1847 case DFVM_SET_ANY_IN
:
1848 accum
= any_in(df
, arg1
);
1851 case DFVM_SET_ALL_NOT_IN
:
1852 accum
= !all_in(df
, arg1
);
1855 case DFVM_SET_ANY_NOT_IN
:
1856 accum
= !any_in(df
, arg1
);
1859 case DFVM_SET_CLEAR
:
1863 case DFVM_UNARY_MINUS
:
1864 mk_minus(df
, arg1
, arg2
);
1872 if (fvals
&& arg1
) {
1873 *fvals
= df_cell_ref(&df
->registers
[arg1
->value
.numeric
]);
1874 if (*fvals
== NULL
) {
1875 *fvals
= g_ptr_array_new();
1878 free_register_overhead(df
);
1884 case DFVM_IF_TRUE_GOTO
:
1886 id
= arg1
->value
.numeric
;
1891 case DFVM_IF_FALSE_GOTO
:
1893 id
= arg1
->value
.numeric
;
1899 ASSERT_DFVM_OP_NOT_REACHED(insn
->op
);
1903 ws_assert_not_reached();
1907 dfvm_apply(dfilter_t
*df
, proto_tree
*tree
)
1909 return dfvm_apply_full(df
, tree
, NULL
);
1913 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1918 * indent-tabs-mode: t
1921 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1922 * :indentSize=8:tabSize=8:noTabs=false: