2 * Routines for IEEE 802a
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <epan/packet.h>
29 #include <epan/addr_resolv.h>
30 #include <epan/strutil.h>
31 #include <epan/etypes.h>
33 #include "packet-ieee802a.h"
35 static int proto_ieee802a
= -1;
36 static int hf_ieee802a_oui
= -1;
37 static int hf_ieee802a_pid
= -1;
39 static gint ett_ieee802a
= -1;
41 static dissector_handle_t data_handle
;
44 * Hash table for translating OUIs to a dissector table/field info pair;
45 * the dissector table maps PID values to dissectors, and the field
46 * corresponds to the PID for that OUI.
49 dissector_table_t table
;
50 hf_register_info
*field_info
;
53 static GHashTable
*oui_info_table
= NULL
;
56 * Add an entry for a new OUI.
59 ieee802a_add_oui(guint32 oui
, const char *table_name
, const char *table_ui_name
,
60 hf_register_info
*hf_item
)
64 new_info
= (oui_info_t
*)g_malloc(sizeof (oui_info_t
));
65 new_info
->table
= register_dissector_table(table_name
,
66 table_ui_name
, FT_UINT16
, BASE_HEX
);
67 new_info
->field_info
= hf_item
;
70 * Create the hash table for OUI information, if it doesn't
73 if (oui_info_table
== NULL
) {
74 oui_info_table
= g_hash_table_new(g_direct_hash
,
77 g_hash_table_insert(oui_info_table
, GUINT_TO_POINTER(oui
), new_info
);
81 dissect_ieee802a(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
83 proto_tree
*ieee802a_tree
= NULL
;
91 dissector_table_t subdissector_table
;
94 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "IEEE802a");
95 col_clear(pinfo
->cinfo
, COL_INFO
);
98 ti
= proto_tree_add_item(tree
, proto_ieee802a
, tvb
, 0, 5, ENC_NA
);
99 ieee802a_tree
= proto_item_add_subtree(ti
, ett_ieee802a
);
102 tvb_memcpy(tvb
, oui
, 0, 3);
103 oui32
= oui
[0] << 16 | oui
[1] << 8 | oui
[2];
104 manuf
= get_manuf_name_if_known(oui
);
105 pid
= tvb_get_ntohs(tvb
, 3);
107 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "OUI %s (%s), PID 0x%04X",
108 bytes_to_str_punct(oui
, 3, ':'),
109 manuf
? manuf
: "Unknown", pid
);
111 proto_tree_add_uint_format_value(ieee802a_tree
, hf_ieee802a_oui
,
112 tvb
, 0, 3, oui32
, "%s (%s)",
113 bytes_to_str_punct(oui
, 3, ':'), manuf
? manuf
: "Unknown");
116 * Do we have information for this OUI?
118 if (oui_info_table
!= NULL
&&
119 (oui_info
= (oui_info_t
*)g_hash_table_lookup(oui_info_table
,
120 GUINT_TO_POINTER(oui32
))) != NULL
) {
124 hf
= *oui_info
->field_info
->p_id
;
125 subdissector_table
= oui_info
->table
;
128 * No, use hf_ieee802a_pid for the PID and just dissect
129 * the payload as data.
131 hf
= hf_ieee802a_pid
;
132 subdissector_table
= NULL
;
135 proto_tree_add_uint(ieee802a_tree
, hf
, tvb
, 3, 2, pid
);
136 next_tvb
= tvb_new_subset_remaining(tvb
, 5);
137 if (subdissector_table
!= NULL
) {
138 /* do lookup with the subdissector table */
139 if (dissector_try_uint(subdissector_table
, pid
, next_tvb
,
143 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
147 proto_register_ieee802a(void)
149 static hf_register_info hf
[] = {
151 { "Organization Code", "ieee802a.oui", FT_UINT24
, BASE_HEX
,
152 NULL
, 0x0, NULL
, HFILL
}},
155 { "Protocol ID", "ieee802a.pid", FT_UINT16
, BASE_HEX
,
156 NULL
, 0x0, NULL
, HFILL
}}
158 static gint
*ett
[] = {
162 proto_ieee802a
= proto_register_protocol("IEEE802a OUI Extended Ethertype", "IEEE802a", "ieee802a");
163 proto_register_field_array(proto_ieee802a
, hf
, array_length(hf
));
164 proto_register_subtree_array(ett
, array_length(ett
));
168 register_hf(gpointer key _U_
, gpointer value
, gpointer user_data _U_
)
170 oui_info_t
*info
= (oui_info_t
*)value
;
172 proto_register_field_array(proto_ieee802a
, info
->field_info
, 1);
176 proto_reg_handoff_ieee802a(void)
178 dissector_handle_t ieee802a_handle
;
180 data_handle
= find_dissector("data");
182 ieee802a_handle
= create_dissector_handle(dissect_ieee802a
,
184 dissector_add_uint("ethertype", ETHERTYPE_IEEE802_OUI_EXTENDED
,
188 * Register all the fields for PIDs for various OUIs.
190 if (oui_info_table
!= NULL
)
191 g_hash_table_foreach(oui_info_table
, register_hf
, NULL
);