Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dfilter / dfvm.c
blob23a6d6429931ef4ce3a90274e4b31aaf02a56193
1 /*
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
7 */
9 #include "config.h"
10 #define WS_LOG_DOMAIN LOG_DOMAIN_DFILTER
12 #include "dfvm.h"
14 #include <ftypes/ftypes.h>
15 #include <wsutil/array.h>
16 #include <wsutil/ws_assert.h>
18 static void
19 debug_register(GSList *reg, uint32_t num);
21 const char *
22 dfvm_opcode_tostr(dfvm_opcode_t code)
24 switch (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)";
79 static void
80 dfvm_value_free(dfvm_value_t *v)
82 switch (v->type) {
83 case FVALUE:
84 g_ptr_array_unref(v->value.fvalue_p);
85 break;
86 case DRANGE:
87 drange_free(v->value.drange);
88 break;
89 case PCRE:
90 ws_regex_free(v->value.pcre);
91 break;
92 case EMPTY:
93 case HFINFO:
94 case RAW_HFINFO:
95 case INSN_NUMBER:
96 case REGISTER:
97 case INTEGER:
98 case FUNCTION_DEF:
99 break;
101 g_free(v);
104 dfvm_value_t*
105 dfvm_value_ref(dfvm_value_t *v)
107 if (v == NULL)
108 return NULL;
109 v->ref_count++;
110 return v;
113 void
114 dfvm_value_unref(dfvm_value_t *v)
116 ws_assert(v);
117 v->ref_count--;
118 if (v->ref_count > 0)
119 return;
120 dfvm_value_free(v);
123 dfvm_insn_t*
124 dfvm_insn_new(dfvm_opcode_t op)
126 dfvm_insn_t *insn;
128 insn = g_new(dfvm_insn_t, 1);
129 insn->op = op;
130 insn->arg1 = NULL;
131 insn->arg2 = NULL;
132 insn->arg3 = NULL;
133 return insn;
136 void
137 dfvm_insn_replace_no_op(dfvm_insn_t *insn)
139 if (insn->arg1) {
140 dfvm_value_unref(insn->arg1);
141 insn->arg1 = NULL;
143 if (insn->arg2) {
144 dfvm_value_unref(insn->arg2);
145 insn->arg2 = NULL;
147 if (insn->arg3) {
148 dfvm_value_unref(insn->arg3);
149 insn->arg3 = NULL;
151 insn->op = DFVM_NO_OP;
154 void
155 dfvm_insn_free(dfvm_insn_t *insn)
157 if (insn->arg1) {
158 dfvm_value_unref(insn->arg1);
160 if (insn->arg2) {
161 dfvm_value_unref(insn->arg2);
163 if (insn->arg3) {
164 dfvm_value_unref(insn->arg3);
166 g_free(insn);
170 dfvm_value_t*
171 dfvm_value_new(dfvm_value_type_t type)
173 dfvm_value_t *v;
175 v = g_new(dfvm_value_t, 1);
176 v->type = type;
177 v->ref_count = 0;
178 return v;
181 dfvm_value_t*
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);
187 return v;
190 dfvm_value_t*
191 dfvm_value_new_hfinfo(header_field_info *hfinfo, bool raw)
193 dfvm_value_t *v;
195 if (raw)
196 v = dfvm_value_new(RAW_HFINFO);
197 else
198 v = dfvm_value_new(HFINFO);
199 v->value.hfinfo = hfinfo;
200 return v;
203 dfvm_value_t*
204 dfvm_value_new_register(int reg)
206 dfvm_value_t *v = dfvm_value_new(REGISTER);
207 v->value.numeric = reg;
208 return v;
211 dfvm_value_t*
212 dfvm_value_new_drange(drange_t *dr)
214 dfvm_value_t *v = dfvm_value_new(DRANGE);
215 v->value.drange = dr;
216 return v;
219 dfvm_value_t*
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;
224 return v;
227 dfvm_value_t*
228 dfvm_value_new_pcre(ws_regex_t *re)
230 dfvm_value_t *v = dfvm_value_new(PCRE);
231 v->value.pcre = re;
232 return v;
235 dfvm_value_t*
236 dfvm_value_new_uint(unsigned num)
238 dfvm_value_t *v = dfvm_value_new(INTEGER);
239 v->value.numeric = num;
240 return v;
243 static char *
244 dfvm_value_tostr(dfvm_value_t *v)
246 char *s = NULL;
248 if (!v)
249 return NULL;
251 switch (v->type) {
252 case HFINFO:
253 s = ws_strdup(v->value.hfinfo->abbrev);
254 break;
255 case RAW_HFINFO:
256 s = ws_strdup_printf("@%s", v->value.hfinfo->abbrev);
257 break;
258 case FVALUE:
259 s = fvalue_to_debug_repr(NULL, dfvm_value_get_fvalue(v));
260 break;
261 case DRANGE:
262 s = drange_tostr(v->value.drange);
263 break;
264 case PCRE:
265 s = ws_strdup(ws_regex_pattern(v->value.pcre));
266 break;
267 case REGISTER:
268 s = ws_strdup_printf("R%"PRIu32, v->value.numeric);
269 break;
270 case FUNCTION_DEF:
271 s = ws_strdup(v->value.funcdef->name);
272 break;
273 case INTEGER:
274 s = ws_strdup_printf("%"PRIu32, v->value.numeric);
275 break;
276 case EMPTY:
277 s = ws_strdup("EMPTY");
278 break;
279 case INSN_NUMBER:
280 s = ws_strdup_printf("INSN(%"PRIu32")", v->value.numeric);
281 break;
283 return s;
286 static char *
287 value_type_tostr(dfvm_value_t *v, bool show_ftype)
289 const char *s;
291 if (!v || !show_ftype)
292 return ws_strdup("");
294 switch (v->type) {
295 case HFINFO:
296 s = ftype_name(v->value.hfinfo->type);
297 break;
298 case RAW_HFINFO:
299 s = "FT_BYTES";
300 break;
301 case FVALUE:
302 s = fvalue_type_name(dfvm_value_get_fvalue(v));
303 break;
304 case FUNCTION_DEF:
305 if (v->value.funcdef->return_ftype != FT_NONE)
306 s = ftype_name(v->value.funcdef->return_ftype);
307 else
308 s = "***";
309 break;
310 default:
311 return ws_strdup("");
313 return ws_strdup_printf(" <%s>", s);
316 static GSList *
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));
321 return stack;
324 static GSList *
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. */
331 g_free(stack->data);
332 stack = g_slist_delete_link(stack, stack);
333 g_free(stack->data);
334 stack = g_slist_delete_link(stack, stack);
336 return stack;
339 static void
340 append_call_function(wmem_strbuf_t *buf, const char *func, const char *func_type,
341 uint32_t nargs, GSList *stack_print)
343 uint32_t idx;
344 GString *gs;
345 GSList *l;
346 const char *sep = "";
348 wmem_strbuf_append_printf(buf, "%s(", func);
349 if (nargs > 0) {
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);
356 l = l->next;
357 g_string_prepend(gs, l->data);
358 sep = ", ";
360 wmem_strbuf_append(buf, gs->str);
361 g_string_free(gs, TRUE);
363 wmem_strbuf_append_printf(buf, ")%s", func_type);
366 static void
367 indent(wmem_strbuf_t *buf, size_t offset, size_t start)
369 size_t pos = buf->len - start;
370 if (pos >= offset)
371 return;
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)
377 static void
378 append_to_register(wmem_strbuf_t *buf, const char *reg)
380 wmem_strbuf_append_printf(buf, " -> %s", reg);
383 static void
384 append_op_args(wmem_strbuf_t *buf, dfvm_insn_t *insn, GSList **stack_print,
385 uint16_t flags)
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;
390 size_t col_start;
392 arg1 = insn->arg1;
393 arg2 = insn->arg2;
394 arg3 = insn->arg3;
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;
404 switch (insn->op) {
405 case DFVM_CHECK_EXISTS:
406 wmem_strbuf_append_printf(buf, "%s%s",
407 arg1_str, arg1_str_type);
408 break;
410 case DFVM_CHECK_EXISTS_R:
411 wmem_strbuf_append_printf(buf, "%s#[%s]%s",
412 arg1_str, arg2_str, arg1_str_type);
413 break;
415 case DFVM_READ_TREE:
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);
420 break;
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);
427 break;
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);
434 break;
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);
441 break;
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);
448 break;
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);
455 break;
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);
460 break;
462 case DFVM_STACK_POP:
463 wmem_strbuf_append_printf(buf, "[%s]", arg1_str);
464 *stack_print = dump_str_stack_pop(*stack_print, arg1->value.numeric);
465 break;
467 case DFVM_SLICE:
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);
472 break;
474 case DFVM_LENGTH:
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);
479 break;
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);
486 break;
488 case DFVM_ALL_EQ:
489 wmem_strbuf_append_printf(buf, "%s%s === %s%s",
490 arg1_str, arg1_str_type, arg2_str, arg2_str_type);
491 break;
493 case DFVM_ANY_EQ:
494 wmem_strbuf_append_printf(buf, "%s%s == %s%s",
495 arg1_str, arg1_str_type, arg2_str, arg2_str_type);
496 break;
498 case DFVM_ALL_NE:
499 wmem_strbuf_append_printf(buf, "%s%s != %s%s",
500 arg1_str, arg1_str_type, arg2_str, arg2_str_type);
501 break;
503 case DFVM_ANY_NE:
504 wmem_strbuf_append_printf(buf, "%s%s !== %s%s",
505 arg1_str, arg1_str_type, arg2_str, arg2_str_type);
506 break;
508 case DFVM_ALL_GT:
509 case DFVM_ANY_GT:
510 wmem_strbuf_append_printf(buf, "%s%s > %s%s",
511 arg1_str, arg1_str_type, arg2_str, arg2_str_type);
512 break;
514 case DFVM_ALL_GE:
515 case DFVM_ANY_GE:
516 wmem_strbuf_append_printf(buf, "%s%s >= %s%s",
517 arg1_str, arg1_str_type, arg2_str, arg2_str_type);
518 break;
520 case DFVM_ALL_LT:
521 case DFVM_ANY_LT:
522 wmem_strbuf_append_printf(buf, "%s%s < %s%s",
523 arg1_str, arg1_str_type, arg2_str, arg2_str_type);
524 break;
526 case DFVM_ALL_LE:
527 case DFVM_ANY_LE:
528 wmem_strbuf_append_printf(buf, "%s%s <= %s%s",
529 arg1_str, arg1_str_type, arg2_str, arg2_str_type);
530 break;
532 case DFVM_NOT_ALL_ZERO:
533 wmem_strbuf_append_printf(buf, "%s%s",
534 arg1_str, arg1_str_type);
535 break;
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);
541 break;
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);
547 break;
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);
555 break;
557 case DFVM_SET_ADD:
558 wmem_strbuf_append_printf(buf, "%s%s", arg1_str, arg1_str_type);
559 break;
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);
564 break;
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);
571 break;
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);
578 break;
580 case DFVM_ADD:
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);
585 break;
587 case DFVM_SUBTRACT:
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);
592 break;
594 case DFVM_MULTIPLY:
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);
599 break;
601 case DFVM_DIVIDE:
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);
606 break;
608 case DFVM_MODULO:
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);
613 break;
615 case DFVM_IF_TRUE_GOTO:
616 case DFVM_IF_FALSE_GOTO:
617 wmem_strbuf_append_printf(buf, "%u", arg1->value.numeric);
618 break;
620 case DFVM_RETURN:
621 if (arg1_str) {
622 wmem_strbuf_append_printf(buf, "%s%s", arg1_str, arg1_str_type);
624 break;
626 case DFVM_NOT:
627 case DFVM_SET_CLEAR:
628 case DFVM_NULL:
629 case DFVM_NO_OP:
630 ASSERT_DFVM_OP_NOT_REACHED(insn->op);
633 g_free(arg1_str);
634 g_free(arg2_str);
635 g_free(arg3_str);
636 g_free(arg1_str_type);
637 g_free(arg2_str_type);
638 g_free(arg3_str_type);
641 static void
642 append_references(wmem_strbuf_t *buf, GHashTable *references, bool raw)
644 GHashTableIter ref_iter;
645 void *key, *value;
646 char *str;
647 unsigned i;
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;
653 df_reference_t *ref;
655 if (raw)
656 wmem_strbuf_append_printf(buf, " ${@%s} = {", abbrev);
657 else
658 wmem_strbuf_append_printf(buf, " ${%s} = {", abbrev);
659 for (i = 0; i < refs_array->len; i++) {
660 if (i != 0) {
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));
666 g_free(str);
668 wmem_strbuf_append(buf, "}\n");
672 char *
673 dfvm_dump_str(wmem_allocator_t *alloc, dfilter_t *df, uint16_t flags)
675 int id, length;
676 dfvm_insn_t *insn;
677 wmem_strbuf_t *buf;
678 GSList *stack_print = NULL;
679 size_t col_start;
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);
688 else {
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);
699 else {
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));
713 switch (insn->op) {
714 case DFVM_NOT:
715 case DFVM_SET_CLEAR:
716 case DFVM_NO_OP:
717 /* Nothing here */
718 break;
719 default:
720 indent1(buf, col_start);
721 append_op_args(buf, insn, &stack_print, flags);
722 break;
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);
733 void
734 dfvm_dump(FILE *f, dfilter_t *df, uint16_t flags)
736 char *str = dfvm_dump_str(NULL, df, flags);
737 fputs(str, f);
738 fputc('\n', f);
739 wmem_free(NULL, str);
742 static int
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;
750 static bool
751 drange_contains_layer(drange_t *dr, int num, int length)
753 drange_node *rn;
754 GSList *list = dr->range_list;
755 int lower, upper;
757 while (list) {
758 rn = list->data;
759 lower = rn->start_offset;
760 if (lower < 0) {
761 lower += length + 1;
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) {
770 upper = INT_MAX;
772 else {
773 ws_assert_not_reached();
776 if (num >= lower && num <= upper) { /* inclusive */
777 return true;
780 list = g_slist_next(list);
782 return false;
785 fvalue_t *
786 dfvm_get_raw_fvalue(const field_info *fi)
788 GByteArray *bytes;
789 fvalue_t *fv;
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) {
802 return NULL;
804 length = fi->length;
805 if (length > tvb_length)
806 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);
813 return fv;
816 static size_t
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;
821 fvalue_t *fv;
822 int cookie = -1;
823 bool cookie_matches = false;
824 int layer;
825 size_t count = 0;
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) {
836 if (rp != NULL) {
837 if (raw)
838 fv = dfvm_get_raw_fvalue(finfo);
839 else
840 fv = finfo->value;
841 df_cell_append(rp, fv);
843 count++;
846 else {
847 cookie = layer;
848 cookie_matches = drange_contains_layer(range, layer, length);
849 if (cookie_matches) {
850 if (rp != NULL) {
851 if (raw)
852 fv = dfvm_get_raw_fvalue(finfo);
853 else
854 fv = finfo->value;
855 df_cell_append(rp, fv);
857 count++;
861 return count;
864 static bool
865 read_tree_finfos(df_cell_t *rp, proto_tree *tree,
866 header_field_info *hfinfo, drange_t *range, bool raw)
868 GPtrArray *finfos;
869 field_info *finfo;
870 fvalue_t *fv;
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) {
875 return false;
877 if (range) {
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);
883 if (raw)
884 fv = dfvm_get_raw_fvalue(finfo);
885 else
886 fv = finfo->value;
887 df_cell_append(rp, fv);
889 return true;
892 /* Reads a field from the proto_tree and loads the fvalues into a register,
893 * if that field has not already been read. */
894 static bool
895 read_tree(dfilter_t *df, proto_tree *tree,
896 dfvm_value_t *arg1, dfvm_value_t *arg2,
897 dfvm_value_t *arg3)
899 drange_t *range = NULL;
900 bool raw;
901 df_cell_t *rp;
903 header_field_info *hfinfo = arg1->value.hfinfo;
904 raw = arg1->type == RAW_HFINFO;
906 int reg = arg2->value.numeric;
908 if (arg3) {
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);
919 if (raw) {
920 df_cell_init(rp, true);
922 else {
923 // These values are referenced only, do not try to free it later.
924 df_cell_init(rp, false);
927 while (hfinfo) {
928 read_tree_finfos(rp, tree, hfinfo, range, raw);
929 hfinfo = hfinfo->same_name_next;
932 return !df_cell_is_empty(rp);
935 static void
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;
940 int cookie = -1;
941 bool cookie_matches = false;
943 if (!refs_array || refs_array->len == 0) {
944 return;
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;
955 if (range == NULL) {
956 df_cell_append(rp, ref->value);
957 continue;
960 if (cookie == layer) {
961 if (cookie_matches) {
962 df_cell_append(rp, ref->value);
965 else {
966 cookie = layer;
967 cookie_matches = drange_contains_layer(range, layer, length);
968 if (cookie_matches) {
969 df_cell_append(rp, ref->value);
975 static bool
976 read_reference(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg2,
977 dfvm_value_t *arg3)
979 df_cell_t *rp;
980 GPtrArray *refs;
981 drange_t *range = NULL;
982 bool raw;
984 header_field_info *hfinfo = arg1->value.hfinfo;
985 raw = arg1->type == RAW_HFINFO;
987 int reg = arg2->value.numeric;
989 if (arg3) {
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) {
1002 return false;
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);
1008 return true;
1011 enum match_how {
1012 MATCH_ANY,
1013 MATCH_ALL
1016 typedef ft_bool_t (*DFVMCompareFunc)(const fvalue_t*, const fvalue_t*);
1017 typedef ft_bool_t (*DFVMTestFunc)(const fvalue_t*);
1019 static bool
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) {
1031 return false;
1033 else if (want_any && have_match == FT_TRUE) {
1034 return true;
1038 /* want_all || !want_any */
1039 return want_all;
1042 static bool
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) {
1053 return false;
1055 else if (want_any && have_match == FT_TRUE) {
1056 return true;
1059 /* want_all || !want_any */
1060 return want_all;
1063 static bool
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));
1072 static bool
1073 cmp_test(dfilter_t *df, DFVMCompareFunc cmp,
1074 dfvm_value_t *arg1, dfvm_value_t *arg2,
1075 enum match_how how)
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;
1085 else {
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;
1095 else {
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 ... */
1103 static inline bool
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 ... */
1111 static bool
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);
1118 static bool
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) {
1128 return true;
1131 return false;
1134 static bool
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) {
1144 return false;
1147 return true;
1150 static bool
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;
1157 if (high) {
1158 /* range */
1159 for (unsigned i = 0; i < high->len; i++) {
1160 if (fvalue_le(fv, high->pdata[i]) == FT_TRUE) {
1161 high_ok = true;
1162 break;
1165 if (!high_ok) {
1166 return false;
1168 ws_assert(low);
1169 for (unsigned i = 0; i < low->len; i++) {
1170 if (fvalue_ge(fv, low->pdata[i]) == FT_TRUE) {
1171 low_ok = true;
1172 break;
1176 else {
1177 /* single element */
1178 for (unsigned i = 0; i < low->len; i++) {
1179 if (fvalue_eq(fv, low->pdata[i]) == FT_TRUE) {
1180 low_ok = true;
1181 break;
1186 return low_ok;
1189 static bool
1190 any_in(dfilter_t *df, dfvm_value_t *arg1)
1192 df_cell_t *rp = &df->registers[arg1->value.numeric];
1193 GPtrArray *value;
1194 GSList *stack;
1195 bool ok;
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;
1203 ok = false;
1204 while (stack) {
1205 if (test_in_internal(value->pdata[i], stack->data)) {
1206 ok = true;
1207 break;
1209 stack = stack->next;
1211 if (ok) {
1212 return true;
1215 return false;
1218 static bool
1219 all_in(dfilter_t *df, dfvm_value_t *arg1)
1221 df_cell_t *rp = &df->registers[arg1->value.numeric];
1222 GPtrArray *value;
1223 GSList *stack;
1224 bool ok;
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;
1232 ok = false;
1233 while (stack) {
1234 if (test_in_internal(value->pdata[i], stack->data)) {
1235 ok = true;
1236 break;
1238 stack = stack->next;
1240 if (!ok) {
1241 return false;
1244 return true;
1247 /* Clear registers that were populated during evaluation.
1248 * If we created the values, then these will be freed as well. */
1249 static void
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. */
1260 static void
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;
1266 fvalue_t *old_fv;
1267 fvalue_t *new_fv;
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. */
1280 ws_assert(new_fv);
1281 df_cell_append(to_rp, new_fv);
1285 static void
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;
1290 fvalue_t *old_fv;
1291 fvalue_t *new_fv;
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);
1305 static const char *
1306 try_value_string(const header_field_info *hfinfo, fvalue_t *fv_num, char *buf)
1308 uint64_t val;
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)
1316 return NULL;
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
1329 * to an integer.)
1331 return NULL;
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);
1340 } else {
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);
1352 else
1353 ws_assert_not_reached();
1355 else {
1356 return try_val_to_str((uint32_t)val, hfinfo->strings);
1358 ws_assert_not_reached();
1361 static bool
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;
1367 const char *str;
1368 fvalue_t *old_fv;
1369 fvalue_t *new_fv;
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);
1381 if (str) {
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);
1396 static bool
1397 call_function(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg2,
1398 dfvm_value_t *arg3)
1400 df_func_def_t *funcdef;
1401 bool accum;
1402 df_cell_t *rp_return;
1403 uint32_t arg_count;
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);
1414 return accum;
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);
1422 g_free(s1);
1423 g_free(s2);
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). */
1428 static void _U_
1429 debug_register(GSList *reg, uint32_t num)
1431 wmem_strbuf_t *buf;
1432 GSList *l;
1433 char *s;
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));
1441 g_free(s);
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 **);
1454 static void
1455 mk_binary_internal(DFVMBinaryFunc func, GPtrArray *fv1, GPtrArray *fv2, df_cell_t *retval)
1457 fvalue_t *result;
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);
1465 g_free(err_msg);
1466 err_msg = NULL;
1468 else {
1469 df_cell_append(retval, result);
1475 static void
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;
1480 df_cell_t *to_rp;
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;
1488 else {
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;
1498 else {
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);
1509 static void
1510 mk_minus_internal(GPtrArray *fv, df_cell_t *retval)
1512 fvalue_t *result;
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);
1519 g_free(err_msg);
1520 err_msg = NULL;
1522 else {
1523 df_cell_append(retval, result);
1528 static void
1529 mk_minus(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *to_arg)
1531 GPtrArray *val;
1532 df_cell_t *to_rp;
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;
1540 else {
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);
1550 static void
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));
1559 static void
1560 stack_push(dfilter_t *df, dfvm_value_t *arg1)
1562 GPtrArray *arg;
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]);
1570 else {
1571 ws_assert_not_reached();
1573 df->function_stack = g_slist_prepend(df->function_stack, arg);
1576 static void
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);
1591 static void
1592 set_push(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg2)
1594 GPtrArray **range;
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]);
1607 else {
1608 ws_assert_not_reached();
1611 if (arg2) {
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]);
1618 else {
1619 ws_assert_not_reached();
1623 df->set_stack = g_slist_prepend(df->set_stack, range);
1626 static void
1627 set_clear(dfilter_t *df)
1629 g_slist_free_full(df->set_stack, g_free);
1630 df->set_stack = NULL;
1633 static bool
1634 check_exists_finfos(proto_tree *tree, header_field_info *hfinfo, drange_t *range)
1636 GPtrArray *finfos;
1638 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
1639 if (finfos == NULL || g_ptr_array_len(finfos) == 0) {
1640 return false;
1642 if (range == NULL) {
1643 return true;
1645 return filter_finfo_fvalues(NULL, finfos, range, false) > 0;
1648 static bool
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;
1655 if (arg2)
1656 range = arg2->value.drange;
1658 while (hfinfo) {
1659 if (check_exists_finfos(tree, hfinfo, range)) {
1660 return true;
1662 hfinfo = hfinfo->same_name_next;
1665 return false;
1668 bool
1669 dfvm_apply_full(dfilter_t *df, proto_tree *tree, GPtrArray **fvals)
1671 int id, length;
1672 bool accum = true;
1673 dfvm_insn_t *insn;
1674 dfvm_value_t *arg1;
1675 dfvm_value_t *arg2;
1676 dfvm_value_t *arg3 = NULL;
1678 ws_assert(tree);
1680 length = df->insns->len;
1682 for (id = 0; id < length; id++) {
1684 AGAIN:
1685 insn = g_ptr_array_index(df->insns, id);
1686 arg1 = insn->arg1;
1687 arg2 = insn->arg2;
1688 arg3 = insn->arg3;
1690 switch (insn->op) {
1691 case DFVM_CHECK_EXISTS:
1692 accum = check_exists(tree, arg1, NULL);
1693 break;
1695 case DFVM_CHECK_EXISTS_R:
1696 accum = check_exists(tree, arg1, arg2);
1697 break;
1699 case DFVM_READ_TREE:
1700 accum = read_tree(df, tree, arg1, arg2, NULL);
1701 break;
1703 case DFVM_READ_TREE_R:
1704 accum = read_tree(df, tree, arg1, arg2, arg3);
1705 break;
1707 case DFVM_READ_REFERENCE:
1708 accum = read_reference(df, arg1, arg2, NULL);
1709 break;
1711 case DFVM_READ_REFERENCE_R:
1712 accum = read_reference(df, arg1, arg2, arg3);
1713 break;
1715 case DFVM_PUT_FVALUE:
1716 put_fvalue(df, arg1, arg2);
1717 break;
1719 case DFVM_CALL_FUNCTION:
1720 accum = call_function(df, arg1, arg2, arg3);
1721 break;
1723 case DFVM_STACK_PUSH:
1724 stack_push(df, arg1);
1725 break;
1727 case DFVM_STACK_POP:
1728 stack_pop(df, arg1);
1729 break;
1731 case DFVM_SLICE:
1732 mk_slice(df, arg1, arg2, arg3);
1733 break;
1735 case DFVM_LENGTH:
1736 mk_length(df, arg1, arg2);
1737 break;
1739 case DFVM_VALUE_STRING:
1740 accum = mk_value_string(df, arg1, arg2, arg3);
1741 break;
1743 case DFVM_ALL_EQ:
1744 accum = all_test(df, fvalue_eq, arg1, arg2);
1745 break;
1747 case DFVM_ANY_EQ:
1748 accum = any_test(df, fvalue_eq, arg1, arg2);
1749 break;
1751 case DFVM_ALL_NE:
1752 accum = all_test(df, fvalue_ne, arg1, arg2);
1753 break;
1755 case DFVM_ANY_NE:
1756 accum = any_test(df, fvalue_ne, arg1, arg2);
1757 break;
1759 case DFVM_ALL_GT:
1760 accum = all_test(df, fvalue_gt, arg1, arg2);
1761 break;
1763 case DFVM_ANY_GT:
1764 accum = any_test(df, fvalue_gt, arg1, arg2);
1765 break;
1767 case DFVM_ALL_GE:
1768 accum = all_test(df, fvalue_ge, arg1, arg2);
1769 break;
1771 case DFVM_ANY_GE:
1772 accum = any_test(df, fvalue_ge, arg1, arg2);
1773 break;
1775 case DFVM_ALL_LT:
1776 accum = all_test(df, fvalue_lt, arg1, arg2);
1777 break;
1779 case DFVM_ANY_LT:
1780 accum = any_test(df, fvalue_lt, arg1, arg2);
1781 break;
1783 case DFVM_ALL_LE:
1784 accum = all_test(df, fvalue_le, arg1, arg2);
1785 break;
1787 case DFVM_ANY_LE:
1788 accum = any_test(df, fvalue_le, arg1, arg2);
1789 break;
1791 case DFVM_BITWISE_AND:
1792 mk_binary(df, fvalue_bitwise_and, arg1, arg2, arg3);
1793 break;
1795 case DFVM_ADD:
1796 mk_binary(df, fvalue_add, arg1, arg2, arg3);
1797 break;
1799 case DFVM_SUBTRACT:
1800 mk_binary(df, fvalue_subtract, arg1, arg2, arg3);
1801 break;
1803 case DFVM_MULTIPLY:
1804 mk_binary(df, fvalue_multiply, arg1, arg2, arg3);
1805 break;
1807 case DFVM_DIVIDE:
1808 mk_binary(df, fvalue_divide, arg1, arg2, arg3);
1809 break;
1811 case DFVM_MODULO:
1812 mk_binary(df, fvalue_modulo, arg1, arg2, arg3);
1813 break;
1815 case DFVM_NOT_ALL_ZERO:
1816 accum = !all_test_unary(df, fvalue_is_zero, arg1);
1817 break;
1819 case DFVM_ALL_CONTAINS:
1820 accum = all_test(df, fvalue_contains, arg1, arg2);
1821 break;
1823 case DFVM_ANY_CONTAINS:
1824 accum = any_test(df, fvalue_contains, arg1, arg2);
1825 break;
1827 case DFVM_ALL_MATCHES:
1828 accum = all_matches(df, arg1, arg2);
1829 break;
1831 case DFVM_ANY_MATCHES:
1832 accum = any_matches(df, arg1, arg2);
1833 break;
1835 case DFVM_SET_ADD:
1836 set_push(df, arg1, NULL);
1837 break;
1839 case DFVM_SET_ADD_RANGE:
1840 set_push(df, arg1, arg2);
1841 break;
1843 case DFVM_SET_ALL_IN:
1844 accum = all_in(df, arg1);
1845 break;
1847 case DFVM_SET_ANY_IN:
1848 accum = any_in(df, arg1);
1849 break;
1851 case DFVM_SET_ALL_NOT_IN:
1852 accum = !all_in(df, arg1);
1853 break;
1855 case DFVM_SET_ANY_NOT_IN:
1856 accum = !any_in(df, arg1);
1857 break;
1859 case DFVM_SET_CLEAR:
1860 set_clear(df);
1861 break;
1863 case DFVM_UNARY_MINUS:
1864 mk_minus(df, arg1, arg2);
1865 break;
1867 case DFVM_NOT:
1868 accum = !accum;
1869 break;
1871 case DFVM_RETURN:
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);
1879 return accum;
1881 case DFVM_NO_OP:
1882 break;
1884 case DFVM_IF_TRUE_GOTO:
1885 if (accum) {
1886 id = arg1->value.numeric;
1887 goto AGAIN;
1889 break;
1891 case DFVM_IF_FALSE_GOTO:
1892 if (!accum) {
1893 id = arg1->value.numeric;
1894 goto AGAIN;
1896 break;
1898 case DFVM_NULL:
1899 ASSERT_DFVM_OP_NOT_REACHED(insn->op);
1903 ws_assert_not_reached();
1906 bool
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
1915 * Local variables:
1916 * c-basic-offset: 8
1917 * tab-width: 8
1918 * indent-tabs-mode: t
1919 * End:
1921 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1922 * :indentSize=8:tabSize=8:noTabs=false: