/*
- * $Id: dfvm.c,v 1.8 2002/08/28 20:40:55 jmayer Exp $
+ * $Id: dfvm.c,v 1.9 2002/10/16 16:32:59 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
switch (insn->op) {
case CHECK_EXISTS:
fprintf(f, "%05d CHECK_EXISTS\t%s\n",
- id, proto_registrar_get_abbrev(arg1->value.numeric));
+ id, arg1->value.hfinfo->abbrev);
break;
case READ_TREE:
fprintf(f, "%05d READ_TREE\t\t%s -> reg#%d\n",
- id, proto_registrar_get_abbrev(arg1->value.numeric),
+ id, arg1->value.hfinfo->abbrev,
arg2->value.numeric);
break;
/* Reads a field from the proto_tree and loads the fvalues into a register,
* if that field has not already been read. */
static gboolean
-read_tree(dfilter_t *df, proto_tree *tree, int field_id, int reg)
+read_tree(dfilter_t *df, proto_tree *tree, header_field_info *hfinfo, int reg)
{
GPtrArray *finfos;
field_info *finfo;
int i, len;
GList *fvalues = NULL;
+ gboolean found_something = FALSE;
/* Already loaded in this run of the dfilter? */
if (df->attempted_load[reg]) {
df->attempted_load[reg] = TRUE;
- finfos = proto_get_finfo_ptr_array(tree, field_id);
- if (!finfos) {
- return FALSE;
+ while (hfinfo) {
+ finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
+ if (!finfos) {
+ hfinfo = hfinfo->same_name_next;
+ continue;
+ }
+ else if (g_ptr_array_len(finfos) == 0) {
+ hfinfo = hfinfo->same_name_next;
+ continue;
+ }
+ else {
+ found_something = TRUE;
+ }
+
+ len = finfos->len;
+ for (i = 0; i < len; i++) {
+ finfo = g_ptr_array_index(finfos, i);
+ fvalues = g_list_prepend(fvalues, finfo->value);
+ }
+
+ hfinfo = hfinfo->same_name_next;
}
- else if (g_ptr_array_len(finfos) == 0) {
- return FALSE;
- }
-
- len = finfos->len;
- for (i = 0; i < len; i++) {
- finfo = g_ptr_array_index(finfos, i);
- fvalues = g_list_prepend(fvalues, finfo->value);
+
+ if (!found_something) {
+ return FALSE;
}
- fvalues = g_list_reverse(fvalues);
df->registers[reg] = fvalues;
return TRUE;
dfvm_value_t *arg1;
dfvm_value_t *arg2;
dfvm_value_t *arg3;
+ header_field_info *hfinfo;
g_assert(tree);
switch (insn->op) {
case CHECK_EXISTS:
- accum = proto_check_for_protocol_or_field(tree,
- arg1->value.numeric);
+ hfinfo = arg1->value.hfinfo;
+ while(hfinfo) {
+ accum = proto_check_for_protocol_or_field(tree,
+ arg1->value.hfinfo->id);
+ if (accum) {
+ break;
+ }
+ else {
+ hfinfo = hfinfo->same_name_next;
+ }
+ }
break;
case READ_TREE:
accum = read_tree(df, tree,
- arg1->value.numeric, arg2->value.numeric);
+ arg1->value.hfinfo, arg2->value.numeric);
break;
case PUT_FVALUE:
/*
- * $Id: gencode.c,v 1.7 2002/08/28 20:40:55 jmayer Exp $
+ * $Id: gencode.c,v 1.8 2002/10/16 16:32:59 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
/* returns register number */
static int
-dfw_append_read_tree(dfwork_t *dfw, int field_id)
+dfw_append_read_tree(dfwork_t *dfw, header_field_info *hfinfo)
{
dfvm_insn_t *insn;
dfvm_value_t *val1, *val2;
int reg = -1;
+ /* Rewind to find the first field of this name. */
+ while (hfinfo->same_name_prev) {
+ hfinfo = hfinfo->same_name_prev;
+ }
+
/* Keep track of which registers
- * were used for which field_id's so that we
+ * were used for which hfinfo's so that we
* can re-use registers. */
reg = GPOINTER_TO_UINT(
- g_hash_table_lookup(dfw->loaded_fields,
- GINT_TO_POINTER(field_id)));
+ g_hash_table_lookup(dfw->loaded_fields, hfinfo));
if (reg) {
/* Reg's are stored in has as reg+1, so
- * that the non-existence of a field_id in
+ * that the non-existence of a hfinfo in
* the hash, or 0, can be differentiated from
- * a field_id being loaded into register #0. */
+ * a hfinfo being loaded into register #0. */
reg--;
}
else {
reg = dfw->next_register++;
g_hash_table_insert(dfw->loaded_fields,
- GUINT_TO_POINTER(field_id),
- GUINT_TO_POINTER(reg + 1));
+ hfinfo, GUINT_TO_POINTER(reg + 1));
- /* Record the FIELD_ID in hash of interesting fields. */
- g_hash_table_insert(dfw->interesting_fields,
- GINT_TO_POINTER(field_id), GUINT_TO_POINTER(TRUE));
- }
+ insn = dfvm_insn_new(READ_TREE);
+ val1 = dfvm_value_new(HFINFO);
+ val1->value.hfinfo = hfinfo;
+ val2 = dfvm_value_new(REGISTER);
+ val2->value.numeric = reg;
- insn = dfvm_insn_new(READ_TREE);
- val1 = dfvm_value_new(FIELD_ID);
- val1->value.numeric = field_id;
- val2 = dfvm_value_new(REGISTER);
- val2->value.numeric = reg;
+ insn->arg1 = val1;
+ insn->arg2 = val2;
+ dfw_append_insn(dfw, insn);
+
+ while (hfinfo) {
+ /* Record the FIELD_ID in hash of interesting fields. */
+ g_hash_table_insert(dfw->interesting_fields,
+ GINT_TO_POINTER(hfinfo->id),
+ GUINT_TO_POINTER(TRUE));
+ hfinfo = hfinfo->same_name_next;
+ }
+
+ }
- insn->arg1 = val1;
- insn->arg2 = val2;
- dfw_append_insn(dfw, insn);
return reg;
}
dfvm_value_t *val;
hfinfo = sttype_range_hfinfo(node);
- hf_reg = dfw_append_read_tree(dfw, hfinfo->id);
+ hf_reg = dfw_append_read_tree(dfw, hfinfo);
insn = dfvm_insn_new(MK_RANGE);
if (type1 == STTYPE_FIELD) {
hfinfo = stnode_data(st_arg1);
- reg1 = dfw_append_read_tree(dfw, hfinfo->id);
+ reg1 = dfw_append_read_tree(dfw, hfinfo);
insn = dfvm_insn_new(IF_FALSE_GOTO);
jmp1 = dfvm_value_new(INSN_NUMBER);
if (type2 == STTYPE_FIELD) {
hfinfo = stnode_data(st_arg2);
- reg2 = dfw_append_read_tree(dfw, hfinfo->id);
+ reg2 = dfw_append_read_tree(dfw, hfinfo);
insn = dfvm_insn_new(IF_FALSE_GOTO);
jmp2 = dfvm_value_new(INSN_NUMBER);
break;
case TEST_OP_EXISTS:
- val1 = dfvm_value_new(FIELD_ID);
+ val1 = dfvm_value_new(HFINFO);
hfinfo = stnode_data(st_arg1);
- val1->value.numeric = hfinfo->id;
+
+ /* Rewind to find the first field of this name. */
+ while (hfinfo->same_name_prev) {
+ hfinfo = hfinfo->same_name_prev;
+ }
+ val1->value.hfinfo = hfinfo;
insn = dfvm_insn_new(CHECK_EXISTS);
insn->arg1 = val1;
dfw_append_insn(dfw, insn);
- /* Record the FIELD_ID in hash of interesting fields. */
- g_hash_table_insert(dfw->interesting_fields,
- GINT_TO_POINTER(hfinfo->id), GUINT_TO_POINTER(TRUE));
+ /* Record the FIELD_ID in hash of interesting fields. */
+ while (hfinfo) {
+ g_hash_table_insert(dfw->interesting_fields,
+ GINT_TO_POINTER(hfinfo->id),
+ GUINT_TO_POINTER(TRUE));
+ hfinfo = hfinfo->same_name_next;
+ }
break;