diff options
-rw-r--r-- | epan/dfilter/dfilter-int.h | 4 | ||||
-rw-r--r-- | epan/dfilter/dfilter-macro.c | 4 | ||||
-rw-r--r-- | epan/dfilter/dfilter.c | 39 | ||||
-rw-r--r-- | epan/dfilter/dfvm.c | 40 | ||||
-rw-r--r-- | epan/dfilter/dfvm.h | 3 | ||||
-rw-r--r-- | epan/dfilter/gencode.c | 5 | ||||
-rw-r--r-- | epan/dfilter/grammar.lemon | 1 | ||||
-rw-r--r-- | test/suite_dfilter/group_syntax.py | 5 |
8 files changed, 85 insertions, 16 deletions
diff --git a/epan/dfilter/dfilter-int.h b/epan/dfilter/dfilter-int.h index 9b16393db8..ad38e368d6 100644 --- a/epan/dfilter/dfilter-int.h +++ b/epan/dfilter/dfilter-int.h @@ -34,6 +34,7 @@ struct epan_dfilter { GPtrArray *deprecated; char *expanded_text; GHashTable *references; + GHashTable *raw_references; char *syntax_tree_str; /* Used to pass arguments to functions. List of Lists (list of registers). */ GSList *function_stack; @@ -52,6 +53,7 @@ typedef struct { int next_register; GPtrArray *deprecated; GHashTable *references; /* hfinfo -> pointer to array of references */ + GHashTable *raw_references; /* hfinfo -> pointer to array of references */ char *expanded_text; stloc_t err_loc; } dfwork_t; @@ -119,7 +121,7 @@ dfilter_fvalue_from_charconst(dfwork_t *dfw, ftenum_t ftype, stnode_t *st); const char *tokenstr(int token); df_reference_t * -reference_new(const field_info *finfo); +reference_new(const field_info *finfo, gboolean raw); void reference_free(df_reference_t *ref); diff --git a/epan/dfilter/dfilter-macro.c b/epan/dfilter/dfilter-macro.c index ef693c4f5b..06e11e2d1d 100644 --- a/epan/dfilter/dfilter-macro.c +++ b/epan/dfilter/dfilter-macro.c @@ -111,6 +111,10 @@ static gboolean start_is_field_reference(const char *start) /* This violates constness but we will restore the original string. */ *(char *)end = '\0'; /* Search for name in registered fields. */ + + if (start[0] == '@') + start++; + hfinfo = dfilter_resolve_unparsed(NULL, start); /* Restore mangled string. */ *(char *)end = saved_c; diff --git a/epan/dfilter/dfilter.c b/epan/dfilter/dfilter.c index e74d454e27..3466b04271 100644 --- a/epan/dfilter/dfilter.c +++ b/epan/dfilter/dfilter.c @@ -202,6 +202,7 @@ dfilter_free(dfilter_t *df) g_free(df->interesting_fields); g_hash_table_destroy(df->references); + g_hash_table_destroy(df->raw_references); if (df->deprecated) g_ptr_array_unref(df->deprecated); @@ -235,6 +236,10 @@ dfwork_new(void) g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)free_refs_array); + dfw->raw_references = + g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify)free_refs_array); + return dfw; } @@ -261,6 +266,10 @@ dfwork_free(dfwork_t *dfw) g_hash_table_destroy(dfw->references); } + if (dfw->raw_references) { + g_hash_table_destroy(dfw->raw_references); + } + if (dfw->insns) { free_insns(dfw->insns); } @@ -504,6 +513,8 @@ dfilter_compile_real(const gchar *text, dfilter_t **dfp, dfw->expanded_text = NULL; dfilter->references = dfw->references; dfw->references = NULL; + dfilter->raw_references = dfw->raw_references; + dfw->raw_references = NULL; if (save_tree) { ws_assert(tree_str); @@ -658,8 +669,8 @@ compare_ref_layer(gconstpointer _a, gconstpointer _b) return a->proto_layer_num - b->proto_layer_num; } -void -dfilter_load_field_references(const dfilter_t *df, proto_tree *tree) +static void +load_references(GHashTable *table, proto_tree *tree, gboolean raw) { GHashTableIter iter; GPtrArray *finfos; @@ -668,13 +679,13 @@ dfilter_load_field_references(const dfilter_t *df, proto_tree *tree) GPtrArray *refs; int i, len; - if (g_hash_table_size(df->references) == 0) { + if (g_hash_table_size(table) == 0) { /* Nothing to do. */ return; } - g_hash_table_iter_init( &iter, df->references); - while (g_hash_table_iter_next (&iter, (void **)&hfinfo, (void **)&refs)) { + g_hash_table_iter_init(&iter, table); + while (g_hash_table_iter_next(&iter, (void **)&hfinfo, (void **)&refs)) { /* If we have a previous array free the data */ g_ptr_array_set_size(refs, 0); @@ -688,7 +699,7 @@ dfilter_load_field_references(const dfilter_t *df, proto_tree *tree) len = finfos->len; for (i = 0; i < len; i++) { finfo = g_ptr_array_index(finfos, i); - g_ptr_array_add(refs, reference_new(finfo)); + g_ptr_array_add(refs, reference_new(finfo, raw)); } hfinfo = hfinfo->same_name_next; @@ -698,12 +709,24 @@ dfilter_load_field_references(const dfilter_t *df, proto_tree *tree) } } +void +dfilter_load_field_references(const dfilter_t *df, proto_tree *tree) +{ + load_references(df->references, tree, FALSE); + load_references(df->raw_references, tree, TRUE); +} + df_reference_t * -reference_new(const field_info *finfo) +reference_new(const field_info *finfo, gboolean raw) { df_reference_t *ref = g_new(df_reference_t, 1); ref->hfinfo = finfo->hfinfo; - ref->value = fvalue_dup(&finfo->value); + if (raw) { + ref->value = dfvm_get_raw_fvalue(finfo); + } + else { + ref->value = fvalue_dup(&finfo->value); + } ref->proto_layer_num = finfo->proto_layer_num; return ref; } diff --git a/epan/dfilter/dfvm.c b/epan/dfilter/dfvm.c index 38951fc96d..ad1f41bbcd 100644 --- a/epan/dfilter/dfvm.c +++ b/epan/dfilter/dfvm.c @@ -509,6 +509,28 @@ dfvm_dump_str(wmem_allocator_t *alloc, dfilter_t *df, gboolean print_references) } } + if (print_references && g_hash_table_size(df->raw_references) > 0) { + wmem_strbuf_append(buf, "\nRaw references:\n"); + g_hash_table_iter_init(&ref_iter, df->raw_references); + while (g_hash_table_iter_next(&ref_iter, &key, &value)) { + const char *abbrev = ((header_field_info *)key)->abbrev; + GPtrArray *refs_array = value; + df_reference_t *ref; + + wmem_strbuf_append_printf(buf, "${@%s} = {", abbrev); + for (i = 0; i < refs_array->len; i++) { + if (i != 0) { + wmem_strbuf_append(buf, ", "); + } + ref = refs_array->pdata[i]; + str = fvalue_to_debug_repr(NULL, ref->value); + wmem_strbuf_append_printf(buf, "%s <%s>", str, fvalue_type_name(ref->value)); + g_free(str); + } + wmem_strbuf_append(buf, "}\n"); + } + } + return wmem_strbuf_finalize(buf); } @@ -563,8 +585,8 @@ drange_contains_layer(drange_t *dr, int num, int length) return FALSE; } -static fvalue_t * -get_raw_fvalue(field_info *fi) +fvalue_t * +dfvm_get_raw_fvalue(const field_info *fi) { GByteArray *bytes; fvalue_t *fv; @@ -614,7 +636,7 @@ filter_finfo_fvalues(GSList *fvalues, GPtrArray *finfos, drange_t *range, gboole if (cookie == layer) { if (cookie_matches) { if (raw) - fv = get_raw_fvalue(finfo); + fv = dfvm_get_raw_fvalue(finfo); else fv = &finfo->value; fvalues = g_slist_prepend(fvalues, fv); @@ -625,7 +647,7 @@ filter_finfo_fvalues(GSList *fvalues, GPtrArray *finfos, drange_t *range, gboole cookie_matches = drange_contains_layer(range, layer, length); if (cookie_matches) { if (raw) - fv = get_raw_fvalue(finfo); + fv = dfvm_get_raw_fvalue(finfo); else fv = &finfo->value; fvalues = g_slist_prepend(fvalues, fv); @@ -686,7 +708,7 @@ read_tree(dfilter_t *df, proto_tree *tree, for (i = 0; i < len; i++) { finfo = g_ptr_array_index(finfos, i); if (raw) - fv = get_raw_fvalue(finfo); + fv = dfvm_get_raw_fvalue(finfo); else fv = &finfo->value; fvalues = g_slist_prepend(fvalues, fv); @@ -759,8 +781,11 @@ read_reference(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg2, { GPtrArray *refs; drange_t *range = NULL; + gboolean raw; header_field_info *hfinfo = arg1->value.hfinfo; + raw = arg1->type == RAW_HFINFO; + int reg = arg2->value.numeric; if (arg3) { @@ -779,7 +804,10 @@ read_reference(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg2, df->attempted_load[reg] = TRUE; - refs = g_hash_table_lookup(df->references, hfinfo); + if (raw) + refs = g_hash_table_lookup(df->raw_references, hfinfo); + else + refs = g_hash_table_lookup(df->references, hfinfo); if (refs == NULL || refs->len == 0) { df->registers[reg] = NULL; return FALSE; diff --git a/epan/dfilter/dfvm.h b/epan/dfilter/dfvm.h index 8d58f73a74..554b2bf8ee 100644 --- a/epan/dfilter/dfvm.h +++ b/epan/dfilter/dfvm.h @@ -148,4 +148,7 @@ dfvm_dump_str(wmem_allocator_t *alloc, dfilter_t *df, gboolean print_references) gboolean dfvm_apply(dfilter_t *df, proto_tree *tree); +fvalue_t * +dfvm_get_raw_fvalue(const field_info *fi); + #endif diff --git a/epan/dfilter/gencode.c b/epan/dfilter/gencode.c index 2cafeec761..8653d487bc 100644 --- a/epan/dfilter/gencode.c +++ b/epan/dfilter/gencode.c @@ -237,7 +237,10 @@ dfw_append_read_reference(dfwork_t *dfw, header_field_info *hfinfo, dfw_append_insn(dfw, insn); refs_array = g_ptr_array_new_with_free_func((GDestroyNotify)reference_free); - g_hash_table_insert(dfw->references, hfinfo, refs_array); + if (raw) + g_hash_table_insert(dfw->raw_references, hfinfo, refs_array); + else + g_hash_table_insert(dfw->references, hfinfo, refs_array); /* Record the FIELD_ID in hash of interesting fields. */ while (hfinfo) { diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon index f1bed6ccef..a2297895e2 100644 --- a/epan/dfilter/grammar.lemon +++ b/epan/dfilter/grammar.lemon @@ -192,6 +192,7 @@ reference(R) ::= DOLLAR LBRACE field(F) RBRACE. /* convert field to reference */ R = stnode_new(STTYPE_REFERENCE, sttype_field_hfinfo(F), NULL, stnode_location(F)); sttype_field_set_drange(R, sttype_field_drange_steal(F)); + sttype_field_set_raw(R, sttype_field_raw(F)); stnode_free(F); } diff --git a/test/suite_dfilter/group_syntax.py b/test/suite_dfilter/group_syntax.py index c277ba97df..235c57468b 100644 --- a/test/suite_dfilter/group_syntax.py +++ b/test/suite_dfilter/group_syntax.py @@ -348,3 +348,8 @@ class case_raw_modifier(unittest.TestCase): def test_raw2(self, checkDFilterCount): dfilter = '@s7comm.blockinfo.blocktype == 30:fe' checkDFilterCount(dfilter, 1) + + def test_raw_ref(self, checkDFilterCountWithSelectedFrame): + dfilter = '@s7comm.blockinfo.blocktype == ${@s7comm.blockinfo.blocktype}' + # select frame 3, expect 2 frames out of 3. + checkDFilterCountWithSelectedFrame(dfilter, 2, 3) |