Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ieee802a.c
blobecc92cf1e181843556f99a40dc1318ae4a277da1
1 /* packet-ieee802a.c
2 * Routines for IEEE 802a
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "config.h"
13 #include <epan/packet.h>
14 #include <epan/addr_resolv.h>
15 #include <epan/etypes.h>
17 #include "packet-ieee802a.h"
19 void proto_register_ieee802a(void);
20 void proto_reg_handoff_ieee802a(void);
22 static dissector_handle_t ieee802a_handle;
24 static int proto_ieee802a;
25 static int hf_ieee802a_oui;
26 static int hf_ieee802a_pid;
28 static int ett_ieee802a;
31 * Hash table for translating OUIs to a dissector table/field info pair;
32 * the dissector table maps PID values to dissectors, and the field
33 * corresponds to the PID for that OUI.
35 typedef struct {
36 dissector_table_t table;
37 hf_register_info *field_info;
38 } oui_info_t;
40 static GHashTable *oui_info_table;
43 * Add an entry for a new OUI.
45 void
46 ieee802a_add_oui(uint32_t oui, const char *table_name, const char *table_ui_name,
47 hf_register_info *hf_item, const int proto)
49 oui_info_t *new_info;
51 new_info = g_new(oui_info_t, 1);
52 new_info->table = register_dissector_table(table_name,
53 table_ui_name, proto, FT_UINT16, BASE_HEX);
54 new_info->field_info = hf_item;
57 * Create the hash table for OUI information, if it doesn't
58 * already exist.
60 if (oui_info_table == NULL) {
61 oui_info_table = g_hash_table_new_full(g_direct_hash,
62 g_direct_equal, NULL, g_free);
64 g_hash_table_insert(oui_info_table, GUINT_TO_POINTER(oui), new_info);
67 static int
68 dissect_ieee802a(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
70 proto_tree *ieee802a_tree;
71 proto_item *ti;
72 tvbuff_t *next_tvb;
73 const char *manuf;
74 uint32_t oui32;
75 uint16_t pid;
76 oui_info_t *oui_info;
77 dissector_table_t subdissector_table;
78 int hf;
80 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE802a");
81 col_clear(pinfo->cinfo, COL_INFO);
83 ti = proto_tree_add_item(tree, proto_ieee802a, tvb, 0, 5, ENC_NA);
84 ieee802a_tree = proto_item_add_subtree(ti, ett_ieee802a);
86 proto_tree_add_item_ret_uint(ieee802a_tree, hf_ieee802a_oui, tvb, 0, 3, ENC_BIG_ENDIAN, &oui32);
87 manuf = uint_get_manuf_name_if_known(oui32);
88 pid = tvb_get_ntohs(tvb, 3);
90 col_add_fstr(pinfo->cinfo, COL_INFO, "OUI %s (%s), PID 0x%04X",
91 tvb_bytes_to_str_punct(pinfo->pool, tvb, 0, 3, ':'),
92 manuf ? manuf : "Unknown", pid);
95 * Do we have information for this OUI?
97 if (oui_info_table != NULL &&
98 (oui_info = (oui_info_t *)g_hash_table_lookup(oui_info_table,
99 GUINT_TO_POINTER(oui32))) != NULL) {
101 * Yes - use it.
103 hf = *oui_info->field_info->p_id;
104 subdissector_table = oui_info->table;
105 } else {
107 * No, use hf_ieee802a_pid for the PID and just dissect
108 * the payload as data.
110 hf = hf_ieee802a_pid;
111 subdissector_table = NULL;
114 proto_tree_add_uint(ieee802a_tree, hf, tvb, 3, 2, pid);
115 next_tvb = tvb_new_subset_remaining(tvb, 5);
116 if ((subdissector_table == NULL) ||
117 /* do lookup with the subdissector table */
118 (!dissector_try_uint(subdissector_table, pid, next_tvb, pinfo, tree))) {
119 call_data_dissector(next_tvb, pinfo, tree);
121 return tvb_captured_length(tvb);
124 static void
125 ieee802a_shutdown(void)
127 g_hash_table_destroy(oui_info_table);
130 void
131 proto_register_ieee802a(void)
133 static hf_register_info hf[] = {
134 { &hf_ieee802a_oui,
135 { "Organization Code", "ieee802a.oui", FT_UINT24, BASE_OUI,
136 NULL, 0x0, NULL, HFILL }},
138 { &hf_ieee802a_pid,
139 { "Protocol ID", "ieee802a.pid", FT_UINT16, BASE_HEX,
140 NULL, 0x0, NULL, HFILL }}
142 static int *ett[] = {
143 &ett_ieee802a,
146 proto_ieee802a = proto_register_protocol("IEEE802a OUI Extended Ethertype", "IEEE802a", "ieee802a");
147 proto_register_field_array(proto_ieee802a, hf, array_length(hf));
148 proto_register_subtree_array(ett, array_length(ett));
149 register_shutdown_routine(ieee802a_shutdown);
151 ieee802a_handle = register_dissector("ieee802a", dissect_ieee802a, proto_ieee802a);
154 static void
155 register_hf(void *key _U_, void *value, void *user_data _U_)
157 oui_info_t *info = (oui_info_t *)value;
159 proto_register_field_array(proto_ieee802a, info->field_info, 1);
162 void
163 proto_reg_handoff_ieee802a(void)
165 dissector_add_uint("ethertype", ETHERTYPE_IEEE802_OUI_EXTENDED,
166 ieee802a_handle);
169 * Register all the fields for PIDs for various OUIs.
171 if (oui_info_table != NULL)
172 g_hash_table_foreach(oui_info_table, register_hf, NULL);
176 * Editor modelines - https://www.wireshark.org/tools/modelines.html
178 * Local variables:
179 * c-basic-offset: 8
180 * tab-width: 8
181 * indent-tabs-mode: t
182 * End:
184 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
185 * :indentSize=8:tabSize=8:noTabs=false: