4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 2001 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 dfvm_insn_new(dfvm_opcode_t op)
34 insn = g_new(dfvm_insn_t, 1);
44 dfvm_value_free(dfvm_value_t *v)
48 FVALUE_FREE(v->value.fvalue);
51 drange_free(v->value.drange);
61 dfvm_insn_free(dfvm_insn_t *insn)
64 dfvm_value_free(insn->arg1);
67 dfvm_value_free(insn->arg2);
70 dfvm_value_free(insn->arg3);
73 dfvm_value_free(insn->arg4);
80 dfvm_value_new(dfvm_value_type_t type)
84 v = g_new(dfvm_value_t, 1);
91 dfvm_dump(FILE *f, GPtrArray *insns)
101 drange_node *range_item;
105 for (id = 0; id < length; id++) {
107 insn = g_ptr_array_index(insns, id);
115 fprintf(f, "%05d CHECK_EXISTS\t%s\n",
116 id, arg1->value.hfinfo->abbrev);
120 fprintf(f, "%05d READ_TREE\t\t%s -> reg#%u\n",
121 id, arg1->value.hfinfo->abbrev,
122 arg2->value.numeric);
126 fprintf(f, "%05d CALL_FUNCTION\t%s (",
127 id, arg1->value.funcdef->name);
129 fprintf(f, "reg#%u", arg3->value.numeric);
132 fprintf(f, ", reg#%u", arg4->value.numeric);
134 fprintf(f, ") --> reg#%u\n", arg2->value.numeric);
138 value_str = fvalue_to_string_repr(arg1->value.fvalue,
139 FTREPR_DFILTER, NULL);
140 fprintf(f, "%05d PUT_FVALUE\t%s <%s> -> reg#%u\n",
142 fvalue_type_name(arg1->value.fvalue),
143 arg2->value.numeric);
149 fprintf(f, "%05d MK_RANGE\t\treg#%u[",
151 arg1->value.numeric);
152 for (range_list = arg3->value.drange->range_list;
154 range_list = range_list->next) {
155 range_item = range_list->data;
156 switch (range_item->ending) {
164 range_item->start_offset,
170 range_item->start_offset,
171 range_item->end_offset);
176 range_item->start_offset);
179 if (range_list->next != NULL)
182 fprintf(f, "] -> reg#%u\n",
183 arg2->value.numeric);
187 fprintf(f, "%05d ANY_EQ\t\treg#%u == reg#%u\n",
188 id, arg1->value.numeric, arg2->value.numeric);
192 fprintf(f, "%05d ANY_NE\t\treg#%u == reg#%u\n",
193 id, arg1->value.numeric, arg2->value.numeric);
197 fprintf(f, "%05d ANY_GT\t\treg#%u == reg#%u\n",
198 id, arg1->value.numeric, arg2->value.numeric);
202 fprintf(f, "%05d ANY_GE\t\treg#%u == reg#%u\n",
203 id, arg1->value.numeric, arg2->value.numeric);
207 fprintf(f, "%05d ANY_LT\t\treg#%u == reg#%u\n",
208 id, arg1->value.numeric, arg2->value.numeric);
212 fprintf(f, "%05d ANY_LE\t\treg#%u == reg#%u\n",
213 id, arg1->value.numeric, arg2->value.numeric);
216 case ANY_BITWISE_AND:
217 fprintf(f, "%05d ANY_BITWISE_AND\t\treg#%u == reg#%u\n",
218 id, arg1->value.numeric, arg2->value.numeric);
222 fprintf(f, "%05d ANY_CONTAINS\treg#%u contains reg#%u\n",
223 id, arg1->value.numeric, arg2->value.numeric);
227 fprintf(f, "%05d ANY_MATCHES\treg#%u matches reg#%u\n",
228 id, arg1->value.numeric, arg2->value.numeric);
232 fprintf(f, "%05d NOT\n", id);
236 fprintf(f, "%05d RETURN\n", id);
240 fprintf(f, "%05d IF-TRUE-GOTO\t%d\n",
241 id, arg1->value.numeric);
245 fprintf(f, "%05d IF-FALSE-GOTO\t%d\n",
246 id, arg1->value.numeric);
250 g_assert_not_reached();
256 /* Reads a field from the proto_tree and loads the fvalues into a register,
257 * if that field has not already been read. */
259 read_tree(dfilter_t *df, proto_tree *tree, header_field_info *hfinfo, int reg)
264 GList *fvalues = NULL;
265 gboolean found_something = FALSE;
267 /* Already loaded in this run of the dfilter? */
268 if (df->attempted_load[reg]) {
269 if (df->registers[reg]) {
277 df->attempted_load[reg] = TRUE;
280 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
282 hfinfo = hfinfo->same_name_next;
285 else if (g_ptr_array_len(finfos) == 0) {
286 hfinfo = hfinfo->same_name_next;
290 found_something = TRUE;
294 for (i = 0; i < len; i++) {
295 finfo = g_ptr_array_index(finfos, i);
296 fvalues = g_list_prepend(fvalues, &finfo->value);
299 hfinfo = hfinfo->same_name_next;
302 if (!found_something) {
306 df->registers[reg] = fvalues;
312 put_fvalue(dfilter_t *df, fvalue_t *fv, int reg)
314 df->registers[reg] = g_list_append(NULL, fv);
318 typedef gboolean (*FvalueCmpFunc)(fvalue_t*, fvalue_t*);
321 any_test(dfilter_t *df, FvalueCmpFunc cmp, int reg1, int reg2)
323 GList *list_a, *list_b;
325 list_a = df->registers[reg1];
328 list_b = df->registers[reg2];
330 if (cmp(list_a->data, list_b->data)) {
333 list_b = g_list_next(list_b);
335 list_a = g_list_next(list_a);
341 /* Free the list nodes w/o freeing the memory that each
342 * list node points to. */
344 free_register_overhead(dfilter_t* df)
348 for (i = 0; i < df->num_registers; i++) {
349 df->attempted_load[i] = FALSE;
350 if (df->registers[i]) {
351 g_list_free(df->registers[i]);
352 df->registers[i] = NULL;
357 /* Takes the list of fvalue_t's in a register, uses fvalue_slice()
358 * to make a new list of fvalue_t's (which are ranges, or byte-slices),
359 * and puts the new list into a new register. */
361 mk_range(dfilter_t *df, int from_reg, int to_reg, drange *d_range)
363 GList *from_list, *to_list;
364 fvalue_t *old_fv, *new_fv;
367 from_list = df->registers[from_reg];
370 old_fv = from_list->data;
371 new_fv = fvalue_slice(old_fv, d_range);
372 /* Assert here because semcheck.c should have
373 * already caught the cases in which a slice
376 to_list = g_list_append(to_list, new_fv);
378 from_list = g_list_next(from_list);
381 df->registers[to_reg] = to_list;
387 dfvm_apply(dfilter_t *df, proto_tree *tree)
390 gboolean accum = TRUE;
394 dfvm_value_t *arg3 = NULL;
395 dfvm_value_t *arg4 = NULL;
396 header_field_info *hfinfo;
402 length = df->insns->len;
404 for (id = 0; id < length; id++) {
407 insn = g_ptr_array_index(df->insns, id);
413 hfinfo = arg1->value.hfinfo;
415 accum = proto_check_for_protocol_or_field(tree,
421 hfinfo = hfinfo->same_name_next;
427 accum = read_tree(df, tree,
428 arg1->value.hfinfo, arg2->value.numeric);
437 param1 = df->registers[arg3->value.numeric];
440 param2 = df->registers[arg4->value.numeric];
442 accum = arg1->value.funcdef->function(param1, param2,
443 &df->registers[arg2->value.numeric]);
449 arg1->value.numeric, arg2->value.numeric,
454 accum = any_test(df, fvalue_eq,
455 arg1->value.numeric, arg2->value.numeric);
459 accum = any_test(df, fvalue_ne,
460 arg1->value.numeric, arg2->value.numeric);
464 accum = any_test(df, fvalue_gt,
465 arg1->value.numeric, arg2->value.numeric);
469 accum = any_test(df, fvalue_ge,
470 arg1->value.numeric, arg2->value.numeric);
474 accum = any_test(df, fvalue_lt,
475 arg1->value.numeric, arg2->value.numeric);
479 accum = any_test(df, fvalue_le,
480 arg1->value.numeric, arg2->value.numeric);
483 case ANY_BITWISE_AND:
484 accum = any_test(df, fvalue_bitwise_and,
485 arg1->value.numeric, arg2->value.numeric);
489 accum = any_test(df, fvalue_contains,
490 arg1->value.numeric, arg2->value.numeric);
494 accum = any_test(df, fvalue_matches,
495 arg1->value.numeric, arg2->value.numeric);
503 free_register_overhead(df);
508 id = arg1->value.numeric;
515 id = arg1->value.numeric;
522 accum = put_fvalue(df,
523 arg1->value.fvalue, arg2->value.numeric);
528 g_assert_not_reached();
533 g_assert_not_reached();
534 return FALSE; /* to appease the compiler */
538 dfvm_init_const(dfilter_t *df)
545 length = df->consts->len;
547 for (id = 0; id < length; id++) {
549 insn = g_ptr_array_index(df->consts, id);
556 arg1->value.fvalue, arg2->value.numeric);
568 case ANY_BITWISE_AND:
576 g_assert_not_reached();