2 * Routines for IEEE 802a
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #include <epan/packet.h>
32 #include <epan/etypes.h>
34 #include "packet-ieee802a.h"
36 static int proto_ieee802a = -1;
37 static int hf_ieee802a_oui = -1;
38 static int hf_ieee802a_pid = -1;
40 static gint ett_ieee802a = -1;
42 static dissector_handle_t data_handle;
45 * Hash table for translating OUIs to a dissector table/field info pair;
46 * the dissector table maps PID values to dissectors, and the field
47 * corresponds to the PID for that OUI.
50 dissector_table_t table;
51 hf_register_info *field_info;
54 static GHashTable *oui_info_table = NULL;
57 * Add an entry for a new OUI.
60 ieee802a_add_oui(guint32 oui, const char *table_name, char *table_ui_name,
61 hf_register_info *hf_item)
65 new_info = g_malloc(sizeof (oui_info_t));
66 new_info->table = register_dissector_table(table_name,
67 table_ui_name, FT_UINT16, BASE_HEX);
68 new_info->field_info = hf_item;
71 * Create the hash table for OUI information, if it doesn't
74 if (oui_info_table == NULL) {
75 oui_info_table = g_hash_table_new(g_direct_hash,
78 g_hash_table_insert(oui_info_table, GUINT_TO_POINTER(oui), new_info);
82 dissect_ieee802a(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
84 proto_tree *ieee802a_tree = NULL;
91 dissector_table_t subdissector_table;
94 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
95 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE802a");
97 if (check_col(pinfo->cinfo, COL_INFO)) {
98 col_clear(pinfo->cinfo, COL_INFO);
102 ti = proto_tree_add_item(tree, proto_ieee802a, tvb, 0, -1, FALSE);
103 ieee802a_tree = proto_item_add_subtree(ti, ett_ieee802a);
105 ieee802a_tree = NULL;
107 oui = tvb_get_ntoh24(tvb, offset);
108 etype = tvb_get_ntohs(tvb, offset+3);
110 if (check_col(pinfo->cinfo, COL_INFO)) {
111 col_add_fstr(pinfo->cinfo, COL_INFO,
112 "OUI 0x%06X (%s), PID 0x%04X",
113 oui, val_to_str(oui, oui_vals, "Unknown"), etype);
116 proto_tree_add_uint(ieee802a_tree, hf_ieee802a_oui,
117 tvb, offset, 3, oui);
121 * Do we have information for this OUI?
123 if (oui_info_table != NULL &&
124 (oui_info = g_hash_table_lookup(oui_info_table,
125 GUINT_TO_POINTER(oui))) != NULL) {
129 hf = *oui_info->field_info->p_id;
130 subdissector_table = oui_info->table;
133 * No, use hf_ieee802a_pid for the PID and just dissect
134 * the payload as data.
136 hf = hf_ieee802a_pid;
137 subdissector_table = NULL;
140 proto_tree_add_uint(ieee802a_tree, hf, tvb, offset+3, 2, etype);
141 next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
142 if (subdissector_table != NULL) {
143 /* do lookup with the subdissector table */
144 if (dissector_try_port(subdissector_table, etype, next_tvb,
148 call_dissector(data_handle, next_tvb, pinfo, tree);
152 proto_register_ieee802a(void)
154 static hf_register_info hf[] = {
156 { "Organization Code", "ieee802a.oui", FT_UINT24, BASE_HEX,
157 VALS(oui_vals), 0x0, "", HFILL }},
160 { "Protocol ID", "ieee802a.pid", FT_UINT16, BASE_HEX,
161 NULL, 0x0, "", HFILL }}
163 static gint *ett[] = {
167 proto_ieee802a = proto_register_protocol("IEEE802a OUI Extended Ethertype", "IEEE802a", "ieee802a");
168 proto_register_field_array(proto_ieee802a, hf, array_length(hf));
169 proto_register_subtree_array(ett, array_length(ett));
173 register_hf(gpointer key _U_, gpointer value, gpointer user_data _U_)
175 oui_info_t *info = value;
177 proto_register_field_array(proto_ieee802a, info->field_info, 1);
181 proto_reg_handoff_ieee802a(void)
183 dissector_handle_t ieee802a_handle;
185 data_handle = find_dissector("data");
187 ieee802a_handle = create_dissector_handle(dissect_ieee802a,
189 dissector_add("ethertype", ETHERTYPE_IEEE802_OUI_EXTENDED,
193 * Register all the fields for PIDs for various OUIs.
195 if (oui_info_table != NULL)
196 g_hash_table_foreach(oui_info_table, register_hf, NULL);