Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ecp-oui.c
blob36306326fcb7a1ecd88d7515b3b4678d22bfe0d3
1 /* packet-ecp-oui.c
2 * ECP/VDP dissector for wireshark (according to IEEE 802.1Qbg draft 0)
3 * By Jens Osterkamp <jens at linux.vnet.ibm.com>
4 * Mijo Safradin <mijo at linux.vnet.ibm.com>
5 * Copyright 2011,2012 IBM Corp.
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
16 #include <epan/packet.h>
17 #include <epan/addr_resolv.h>
18 #include <epan/oui.h>
19 #include <epan/addr_resolv.h>
21 #include <wsutil/str_util.h>
23 #include "packet-ieee802a.h"
25 void proto_register_ecp_oui(void);
26 void proto_reg_handoff_ecp(void);
28 #define ECP_SUBTYPE 0x00
30 #define END_OF_VDPDU_TLV_TYPE 0x00 /* Mandatory */
31 #define VDP_TLV_TYPE 0x02
32 #define ORG_SPECIFIC_TLV_TYPE 0x7F
34 /* IEEE 802.1Qbg VDP filter info formats */
35 #define VDP_FIF_VID 0x01
36 #define VDP_FIF_MACVID 0x02
37 #define VDP_FIF_GROUPVID 0x03
38 #define VDP_FIF_GROUPVMACVID 0x04
40 /* Masks */
41 #define TLV_TYPE_MASK 0xFE00
42 #define TLV_TYPE(value) (((value) & TLV_TYPE_MASK) >> 9)
43 #define TLV_INFO_LEN_MASK 0x01FF
44 #define TLV_INFO_LEN(value) ((value) & TLV_INFO_LEN_MASK)
46 static int proto_ecp;
47 static int hf_ecp_pid;
48 static int hf_ecp_tlv_type;
49 static int hf_ecp_tlv_len;
50 static int hf_ecp_subtype;
51 static int hf_ecp_mode;
52 static int hf_ecp_sequence;
53 /* static int hf_ecp_vdp_oui; */
54 static int hf_ecp_vdp_mode;
55 static int hf_ecp_vdp_response;
56 static int hf_ecp_vdp_mgrid;
57 static int hf_ecp_vdp_vsitypeid;
58 static int hf_ecp_vdp_vsitypeidversion;
59 static int hf_ecp_vdp_instanceid;
60 static int hf_ecp_vdp_format;
61 static int hf_ecp_vdp_mac;
62 static int hf_ecp_vdp_vlan;
64 static int ett_ecp;
65 static int ett_end_of_vdpdu;
66 static int ett_802_1qbg_capabilities_flags;
68 static dissector_handle_t ecp_handle;
70 static const value_string ecp_pid_vals[] = {
71 { 0x0000, "ECP draft 0" },
72 { 0, NULL }
75 /* IEEE 802.1Qbg ECP subtypes */
76 static const value_string ecp_subtypes[] = {
77 { 0x00, "ECP default subtype" },
78 { 0, NULL }
81 /* IEEE 802.1Qbg ECP modes */
82 static const value_string ecp_modes[] = {
83 { 0x00, "REQUEST" },
84 { 0x01, "ACK" },
85 { 0, NULL }
88 /* IEEE 802.1Qbg VDP modes */
89 static const value_string ecp_vdp_modes[] = {
90 { 0x00, "Pre-Associate" },
91 { 0x01, "Pre-Associate with resource reservation" },
92 { 0x02, "Associate" },
93 { 0x03, "De-Associate" },
94 { 0, NULL }
97 /* IEEE 802.1Qbg VDP responses */
98 static const value_string ecp_vdp_responses[] = {
99 { 0x00, "success" },
100 { 0x01, "invalid format" },
101 { 0x02, "insufficient resources" },
102 { 0x03, "unused VTID" },
103 { 0x04, "VTID violation" },
104 { 0x05, "VTID version violation" },
105 { 0x06, "out of sync" },
106 { 0, NULL }
109 /* IEEE 802.1Qbg VDP filter info formats */
110 static const value_string ecp_vdp_formats[] = {
111 { VDP_FIF_VID, "VID values" },
112 { VDP_FIF_MACVID, "MAC/VID pairs" },
113 { VDP_FIF_GROUPVID, "GROUPID/VID pairs" },
114 { VDP_FIF_GROUPVMACVID, "GROUPID/MAC/VID triples" },
115 { 0, NULL }
118 /* IEEE 802.1Qbg Subtypes */
119 static const value_string ieee_802_1qbg_subtypes[] = {
120 { 0x00, "EVB" },
121 { 0x01, "CDCP" },
122 { 0x02, "VDP" },
123 { 0, NULL }
126 /* Dissect Unknown TLV */
127 static int32_t
128 dissect_ecp_unknown_tlv(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, uint32_t offset)
130 uint16_t tempLen;
131 uint16_t tempShort;
133 proto_tree *ecp_unknown_tlv_tree;
135 /* Get tlv type and length */
136 tempShort = tvb_get_ntohs(tvb, offset);
138 /* Get tlv length */
139 tempLen = TLV_INFO_LEN(tempShort);
141 ecp_unknown_tlv_tree = proto_tree_add_subtree(tree, tvb, offset, (tempLen + 2), ett_ecp, NULL, "Unknown TLV");
143 proto_tree_add_item(ecp_unknown_tlv_tree, hf_ecp_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
145 return -1;
148 /* Dissect mac/vid pairs in VDP TLVs */
149 static int32_t
150 dissect_vdp_fi_macvid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, uint32_t offset)
152 int i;
153 uint16_t entries;
154 uint32_t tempOffset = offset;
156 proto_tree *ecp_vdp_tlv_fi_subtree;
158 entries = tvb_get_ntohs(tvb, offset);
160 ecp_vdp_tlv_fi_subtree = proto_tree_add_subtree_format(tree, tvb, tempOffset, 2, ett_ecp, NULL,
161 "%i MAC/VID pair%s", entries, plurality(entries, "", "s"));
163 tempOffset += 2;
165 for (i=0; i < entries; i++) {
166 proto_tree_add_item(ecp_vdp_tlv_fi_subtree, hf_ecp_vdp_mac, tvb, tempOffset, 6, ENC_NA);
168 tempOffset += 6;
170 proto_tree_add_item(ecp_vdp_tlv_fi_subtree, hf_ecp_vdp_vlan, tvb, tempOffset, 2, ENC_BIG_ENDIAN);
172 tempOffset += 2;
175 return tempOffset-offset;
178 /* Dissect Organizationally Defined TLVs */
179 static int32_t
180 dissect_vdp_org_specific_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset)
182 uint16_t tempLen;
183 uint16_t len;
184 uint16_t tempShort;
185 uint32_t tempOffset = offset;
186 uint32_t oui;
187 const char *ouiStr;
188 uint8_t subType, format;
189 const char *subTypeStr;
191 proto_tree *ecp_vdp_tlv_subtree;
193 tempLen = 0;
194 tempShort = tvb_get_ntohs(tvb, offset);
195 len = TLV_INFO_LEN(tempShort);
197 tempOffset += 2;
199 oui = tvb_get_ntoh24(tvb, (tempOffset));
200 /* Look in manuf database for OUI */
201 ouiStr = uint_get_manuf_name_if_known(oui);
202 if(ouiStr==NULL) ouiStr="Unknown";
204 tempOffset += 3;
206 subType = tvb_get_uint8(tvb, tempOffset);
207 tempOffset++;
209 switch(oui) {
210 case OUI_IEEE_802_1QBG:
211 subTypeStr = val_to_str(subType, ieee_802_1qbg_subtypes, "Unknown subtype 0x%x");
212 break;
213 default:
214 subTypeStr = "Unknown";
215 break;
218 ecp_vdp_tlv_subtree = proto_tree_add_subtree_format(tree, tvb, offset, (len + 2), ett_ecp, NULL,
219 "%s - %s", ouiStr, subTypeStr);
221 proto_tree_add_item(ecp_vdp_tlv_subtree, hf_ecp_vdp_mode, tvb, tempOffset, 1, ENC_BIG_ENDIAN);
222 tempOffset++;
224 proto_tree_add_item(ecp_vdp_tlv_subtree, hf_ecp_vdp_response, tvb, tempOffset, 1, ENC_BIG_ENDIAN);
225 tempOffset++;
227 proto_tree_add_item(ecp_vdp_tlv_subtree, hf_ecp_vdp_mgrid, tvb, tempOffset, 1, ENC_BIG_ENDIAN);
228 tempOffset++;
230 proto_tree_add_item(ecp_vdp_tlv_subtree, hf_ecp_vdp_vsitypeid, tvb, tempOffset, 3, ENC_BIG_ENDIAN);
231 tempOffset += 3;
233 proto_tree_add_item(ecp_vdp_tlv_subtree, hf_ecp_vdp_vsitypeidversion, tvb, tempOffset, 1, ENC_BIG_ENDIAN);
234 tempOffset += 1;
236 proto_tree_add_item(ecp_vdp_tlv_subtree, hf_ecp_vdp_instanceid, tvb, tempOffset, 16, ENC_NA);
237 tempOffset += 16;
239 format = tvb_get_uint8(tvb, tempOffset);
240 proto_tree_add_item(ecp_vdp_tlv_subtree, hf_ecp_vdp_format, tvb, tempOffset, 1, ENC_BIG_ENDIAN);
241 tempOffset++;
243 switch (format) {
244 case VDP_FIF_VID:
245 /* place holder for future enablement */
246 /* For compatibility of different implementations proceed to next entry */
247 case VDP_FIF_MACVID:
248 tempLen = dissect_vdp_fi_macvid(tvb, pinfo, ecp_vdp_tlv_subtree, tempOffset);
249 break;
250 case VDP_FIF_GROUPVID:
251 /* place holder for future enablement */
252 break;
253 case VDP_FIF_GROUPVMACVID:
254 /* place holder for future enablement */
255 break;
256 default:
257 break;
260 tempOffset += tempLen;
262 return tempOffset-offset;
265 /* Dissect End of VDP TLV (Mandatory) */
266 static int32_t
267 dissect_vdp_end_of_vdpdu_tlv(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, uint32_t offset)
269 uint16_t tempLen;
270 uint16_t tempShort;
272 proto_tree *end_of_vdpdu_tree;
274 /* Get tlv type and length */
275 tempShort = tvb_get_ntohs(tvb, offset);
277 /* Get tlv length */
278 tempLen = TLV_INFO_LEN(tempShort);
280 if (tree)
282 /* Set port tree */
283 end_of_vdpdu_tree = proto_tree_add_subtree(tree, tvb, offset, (tempLen + 2),
284 ett_end_of_vdpdu, NULL, "End of VDPDU");
286 proto_tree_add_item(end_of_vdpdu_tree, hf_ecp_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
287 proto_tree_add_item(end_of_vdpdu_tree, hf_ecp_tlv_len, tvb, offset, 2, ENC_BIG_ENDIAN);
290 return -1; /* Force the VDP dissector to terminate */
293 static int
294 dissect_ecp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
296 proto_tree *ecp_tree;
297 proto_item *ti;
298 int32_t tempLen = 0;
299 uint32_t offset = 0;
300 uint16_t tempShort;
301 uint8_t tempType;
302 bool end = false;
304 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ECP");
306 ti = proto_tree_add_item(tree, proto_ecp, tvb, 0, -1, ENC_NA);
307 ecp_tree = proto_item_add_subtree(ti, ett_ecp);
309 proto_tree_add_item(ecp_tree, hf_ecp_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
310 proto_tree_add_item(ecp_tree, hf_ecp_mode, tvb, offset+1, 1, ENC_BIG_ENDIAN);
311 proto_tree_add_item(ecp_tree, hf_ecp_sequence, tvb, offset+2, 2, ENC_BIG_ENDIAN);
313 offset += 4;
315 while (!end) {
316 if (!tvb_bytes_exist(tvb, offset, 1))
317 break;
319 tempShort = tvb_get_ntohs(tvb, offset);
320 tempType = TLV_TYPE(tempShort);
322 switch (tempType) {
323 case ORG_SPECIFIC_TLV_TYPE:
324 tempLen = dissect_vdp_org_specific_tlv(tvb, pinfo, ecp_tree, offset);
325 break;
326 case END_OF_VDPDU_TLV_TYPE:
327 tempLen = dissect_vdp_end_of_vdpdu_tlv(tvb, pinfo, ecp_tree, offset);
328 break;
329 default:
330 tempLen = dissect_ecp_unknown_tlv(tvb, pinfo, ecp_tree, offset);
331 break;
334 offset += tempLen;
336 if (tempLen < 0)
337 end = true;
339 return tvb_captured_length(tvb);
342 void proto_register_ecp_oui(void)
344 static hf_register_info hf_reg = {
345 &hf_ecp_pid,
346 { "PID", "ieee802a.ecp_pid", FT_UINT16, BASE_HEX,
347 VALS(ecp_pid_vals), 0x0, NULL, HFILL },
350 static hf_register_info hf[] = {
351 { &hf_ecp_tlv_type,
352 { "TLV Type", "ecp.tlv.type", FT_UINT16, BASE_DEC,
353 NULL, TLV_TYPE_MASK, NULL, HFILL }
355 { &hf_ecp_tlv_len,
356 { "TLV Length", "ecp.tlv.len", FT_UINT16, BASE_DEC,
357 NULL, TLV_INFO_LEN_MASK, NULL, HFILL }
360 { &hf_ecp_subtype,
361 { "subtype", "ecp.subtype", FT_UINT8, BASE_HEX,
362 VALS(ecp_subtypes), 0x0, NULL, HFILL },
364 { &hf_ecp_mode,
365 { "mode", "ecp.mode", FT_UINT8, BASE_HEX,
366 VALS(ecp_modes), 0x0, NULL, HFILL },
368 { &hf_ecp_sequence,
369 { "sequence number", "ecp.seq", FT_UINT16, BASE_HEX,
370 NULL, 0x0, NULL, HFILL },
372 #if 0
373 { &hf_ecp_vdp_oui,
374 { "Organization Unique Code", "ecp.vdp.oui", FT_UINT24, BASE_OUI,
375 NULL, 0x0, NULL, HFILL }
377 #endif
378 { &hf_ecp_vdp_mode,
379 { "mode", "ecp.vdp.mode", FT_UINT8, BASE_HEX,
380 VALS(ecp_vdp_modes), 0x0, NULL, HFILL },
382 { &hf_ecp_vdp_response,
383 { "response", "ecp.vdp.response", FT_UINT8, BASE_HEX,
384 VALS(ecp_vdp_responses), 0x0, NULL, HFILL },
386 { &hf_ecp_vdp_mgrid,
387 { "Manager ID", "ecp.vdp.mgrid", FT_UINT8, BASE_HEX,
388 NULL, 0x0, NULL, HFILL },
390 { &hf_ecp_vdp_vsitypeid,
391 { "VSI type ID", "ecp.vdp.vsitypeid", FT_UINT24, BASE_HEX,
392 NULL, 0x0, NULL, HFILL },
394 { &hf_ecp_vdp_vsitypeidversion,
395 { "VSI type ID version", "ecp.vdp.vsitypeidversion", FT_UINT8, BASE_HEX,
396 NULL, 0x0, NULL, HFILL },
398 { &hf_ecp_vdp_instanceid,
399 { "VSI Instance ID version", "ecp.vdp.instanceid", FT_BYTES, BASE_NONE,
400 NULL, 0x0, NULL, HFILL },
402 { &hf_ecp_vdp_format,
403 { "VSI filter info format", "ecp.vdp.format", FT_UINT8, BASE_HEX,
404 VALS(ecp_vdp_formats), 0x0, NULL, HFILL },
406 { &hf_ecp_vdp_mac,
407 { "VSI Mac Address", "ecp.vdp.mac", FT_ETHER, BASE_NONE,
408 NULL, 0x0, NULL, HFILL }
410 { &hf_ecp_vdp_vlan,
411 { "VSI VLAN ID", "ecp.vdp.vlan", FT_UINT16, BASE_DEC,
412 NULL, 0x0, NULL, HFILL }
416 static int *ett[] = {
417 &ett_ecp,
418 &ett_end_of_vdpdu,
419 &ett_802_1qbg_capabilities_flags,
422 proto_ecp = proto_register_protocol("ECP Protocol", "ECP", "ecp");
423 proto_register_field_array(proto_ecp, hf, array_length(hf));
424 proto_register_subtree_array(ett, array_length(ett));
426 ieee802a_add_oui(OUI_IEEE_802_1QBG, "ieee802a.ecp_pid",
427 "IEEE802a ECP PID", &hf_reg, proto_ecp);
429 ecp_handle = register_dissector("ecp", dissect_ecp, proto_ecp);
432 void proto_reg_handoff_ecp(void)
434 dissector_add_uint("ieee802a.ecp_pid", 0x0000, ecp_handle);
438 * Editor modelines - https://www.wireshark.org/tools/modelines.html
440 * Local variables:
441 * c-basic-offset: 8
442 * tab-width: 8
443 * indent-tabs-mode: t
444 * End:
446 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
447 * :indentSize=8:tabSize=8:noTabs=false: