Ethereal-dev: Re: [Ethereal-dev] tapping commentary
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Jason House <jhouse@xxxxxxxxx>
Date: Wed, 23 Oct 2002 11:07:56 -0400
Guy Harris wrote: > > OK. Can actual field values like the value of "ip.addr" be extracted from > > edt->tree? > > Yes. Currently, it may be a bit of work, as the routine would have to > walk the tree itself, but it can be done. It definitely can be done, below is code of mine to do the physical traversal. I tried to make any simple changes from C++ to C. I left the STL in there, but I know that with some effort, the STL data structures can be replaced with glib structures and functions instead. Hopefully this will save a bit of work for whoever implements the tap extension to handle filterable fields. Protocols like OSPF cause trouble in that they can have multiple of the same set of fields. The traversal code below attempts to control that by "forgetting" what was found in a sub tree of a protocol (ie. handle each LSA separately). I still have to submit my patch for OSPF that provides filter names as well as restructuring one small part of the tree output (there is a comment like "should we put this in a tree?"... for this code the answer is yes). This allows generation of complete tuples of results for a variety of proto_tree structures. There are multiple find_result functions in order to merge the lowest level of the tree for all protocols together... allowing things such as ip.len and udp.srcport to be searched for together, without having "ip.len" be forgotten before reaching "udp.srcport". It also allows things such as ip.len" and "ospf.lsa.type" to be searched for together, and simply return multiple tuples for a single packet. The code would work ok with ip.len and ip.flags.df, but not ip.flags.df and ospf.lsa.type because ip.flags.df would be forgotten before finding ospf.lsa.type. I'm sure there is room for plenty of discussion on how to fix that kind of problem. If no forgetting is done, then protocols like OSPF will create trouble (something I really need to work for my applications). code for finding out which integers to look for to identify a particular field ***************************************************************** set<int> find_translation(char *field_abbrev){ set<int> field_id; n_symbols = proto_registrar_n(); for (id = 0; id<n_symbols; id++){ if (strcmp(field_abbrev, proto_registrar_get_abbrev(id))==0) field_id.insert(id); } return field_id; } Actual tree traversal *********************************************************** typedef map<set<int>, field_info *> tree_scan_result; struct tree_scan_results{ tree_scan_result cur_result; list<tree_scan_result> *all_results; }; update_tables(proto_tree *protocol_tree, table_def &tbl, list<set<int> > key_ids, list<set<int> > value_ids){ tree_scan_results status; status.all_results = new list<tree_scan_result>(); g_node_children_foreach((GNode*)protocol_tree,G_TRAVERSE_ALL, find_results_no_forget,(gpointer)&status); save_results(*status.all_results,tbl,key_ids,value_ids); } /* not forgetting for the list of protocols in the packet */ void find_results_no_forget(GNode *node, gpointer data){ tree_scan_results &status = *(tree_scan_results*)data; /* copy results */ if (update_result(status.cur_result,(field_info*)node->data)) status.all_results->push_back(status.cur_result); g_node_children_foreach(node,G_TRAVERSE_ALL,find_results_no_forget2, (gpointer)&status); } /* not fogetting for the list of fields within a protocol */ void find_results_no_forget2(GNode *node, gpointer data){ tree_scan_results &status = *(tree_scan_results*)data; /* copy results */ if (update_result(status.cur_result,(field_info*)node->data)) status.all_results->push_back(status.cur_result); g_node_children_foreach(node,G_TRAVERSE_ALL,find_results, (gpointer)&status); } /* allow forgetting for subtrees of a protocol... allow complex items like OSPF to work */ void find_results(GNode *node, gpointer data){ tree_scan_results &status = *(tree_scan_results*)data; tree_scan_results copied_status; if (update_result(status.cur_result,(field_info*)node->data)) status.all_results->push_back(status.cur_result); /* make copy to allow "forgetting" everyting inside of this subtree*/ copied_status.cur_result = status.cur_result; copied_status.all_results = status.all_results; g_node_children_foreach(node,G_TRAVERSE_ALL,find_results, (gpointer)&copied_results); } bool update_result(tree_scan_result &x, field_info *fi){ tree_scan_result::iterator itr; bool found_empty = false; bool updated_result = false; if (fi==NULL) return false; for (itr = x.begin(); itr != x.end(); itr++){ //This currently does not work with multiple fields with the same name if ((*itr).first.count(fi->hfinfo->id) > 0){ (*itr).second = fi; updated_result = true; } /* ordering is important!... what we just updated could have been empty * ie, if this line was before the if, it would detect an empty that * really isn't any more. */ found_empty |= ((*itr).second==NULL); } return updated_result && !found_empty; }
- References:
- Re: [Ethereal-dev] tapping commentary
- From: Pia Sahlberg
- Re: [Ethereal-dev] tapping commentary
- From: Guy Harris
- Re: [Ethereal-dev] tapping commentary
- Prev by Date: [Ethereal-dev] "Latest CVS" compiling error: "NETSNMP_DS_LIBRARY_ID not defined"
- Next by Date: Re: [Ethereal-dev] New dissector for TZSP
- Previous by thread: Re: [Ethereal-dev] tapping commentary
- Next by thread: [Ethereal-dev] rsync - conversation candidate?
- Index(es):