diff options
author | Guy Harris <guy@alum.mit.edu> | 2003-08-28 01:29:16 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2003-08-28 01:29:16 +0000 |
commit | 4059b02fe949c2cd6bd53441859416c210607355 (patch) | |
tree | 219d4c528010f1cbd47fefc791538485f168cf3d /packet-llc.c | |
parent | fadeb72b2e21ad9a758dceb6a105eb286d3c5e2d (diff) |
Add an API to let a dissector register a dissector table and field for a
given OUI; the field is used when the PID for that OUI is put into the
protocol tree, and the dissector table is used to find a dissector for
that PID.
Not yet used, thus not yet tested; API is subject to change.
(Eventually, several of the cases in the big switch statement in
"dissect_llc()" should be handled by registering information for those
OUIs.)
svn path=/trunk/; revision=8291
Diffstat (limited to 'packet-llc.c')
-rw-r--r-- | packet-llc.c | 75 |
1 files changed, 72 insertions, 3 deletions
diff --git a/packet-llc.c b/packet-llc.c index b9506fc027..35afe43e9d 100644 --- a/packet-llc.c +++ b/packet-llc.c @@ -2,7 +2,7 @@ * Routines for IEEE 802.2 LLC layer * Gilbert Ramirez <gram@alumni.rice.edu> * - * $Id: packet-llc.c,v 1.111 2003/08/28 00:11:32 guy Exp $ + * $Id: packet-llc.c,v 1.112 2003/08/28 01:29:15 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -172,6 +172,44 @@ http://www.cisco.com/univercd/cc/td/doc/product/software/ios113ed/113ed_cr/ibm_r { 0, NULL } }; +/* + * Hash table for translating OUIs to a dissector table/field ID pair; + * the dissector table maps PID values to dissectors, and the field + * corresponds to the PID for that OUI. + */ +typedef struct { + dissector_table_t table; + int field_id; +} oui_info_t; + +static GHashTable *oui_dissector_tables = NULL; + +/* + * Add an entry for a new OID. + */ +void +llc_add_oid(guint32 oid, const char *table_name, char *table_ui_name, + int field_id) +{ + oui_info_t *new_info; + + new_info = g_malloc(sizeof (oui_info_t)); + new_info->table = register_dissector_table(table_name, + table_ui_name, FT_UINT16, BASE_HEX); + new_info->field_id = field_id; + + /* + * Create the hash table for OUI information, if it doesn't + * already exist. + */ + if (oui_dissector_tables == NULL) { + oui_dissector_tables = g_hash_table_new(g_direct_hash, + g_direct_equal); + } + g_hash_table_insert(oui_dissector_tables, (gpointer)oid, + new_info->table); +} + void capture_llc(const guchar *pd, int offset, int len, packet_counts *ld) { @@ -382,6 +420,9 @@ dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint32 oui; guint16 etype; tvbuff_t *next_tvb; + oui_info_t *oui_info; + dissector_table_t subdissector_table; + int hf; oui = tvb_get_ntoh24(tvb, offset); etype = tvb_get_ntohs(tvb, offset+3); @@ -520,13 +561,41 @@ dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, } else call_dissector(data_handle, next_tvb, pinfo, tree); break; + default: + /* + * Do we have information for this OUI? + */ + oui_info = g_hash_table_lookup(oui_dissector_tables, + (gpointer)oui); + if (oui_info != NULL) { + /* + * Yes - use it. + */ + hf = oui_info->field_id; + subdissector_table = oui_info->table; + } else { + /* + * No, use hf_pid for the PID and just dissect + * the payload as data. + */ + hf = hf_pid; + subdissector_table = NULL; + } if (tree) { - proto_tree_add_uint(snap_tree, hf_pid, tvb, offset+3, 2, + proto_tree_add_uint(snap_tree, hf, tvb, offset+3, 2, etype); } next_tvb = tvb_new_subset(tvb, offset+5, -1, -1); - call_dissector(data_handle,next_tvb, pinfo, tree); + if (XDLC_IS_INFORMATION(control)) { + if (subdissector_table != NULL) { + /* do lookup with the subdissector table */ + if (dissector_try_port(subdissector_table, + etype, next_tvb, pinfo, tree)) + break; + } + } + call_dissector(data_handle, next_tvb, pinfo, tree); break; } } |