wireshark/epan/dissectors/packet-vntag.c
Guy Harris e1d9a226a2 Fix the type of arrays of pointers to hf_ values for bitfield routines.
The static arrays are supposed to be arrays of const pointers to int,
not arrays of non-const pointers to const int.

Fixing that means some bugs (scribbling on what's *supposed* to be a
const array) will be caught (see packet-ieee80211-radiotap.c for
examples, the first of which inspired this change and the second of
which was discovered while testing compiles with this change), and
removes the need for some annoying casts.

Also make some of those arrays static while we're at it.

Update documentation and dissector-generator tools.

Change-Id: I789da5fc60aadc15797cefecfd9a9fbe9a130ccc
Reviewed-on: https://code.wireshark.org/review/37517
Petri-Dish: Guy Harris <gharris@sonic.net>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2020-06-19 11:32:26 +00:00

194 lines
5.4 KiB
C

/* packet-vntag.c
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <epan/packet.h>
#include <epan/etypes.h>
#include <epan/expert.h>
#include <epan/tfs.h>
#include <epan/dissectors/packet-ieee8023.h>
void proto_register_vntag(void);
void proto_reg_handoff_vntag(void);
static dissector_handle_t ethertype_handle;
static int proto_vntag = -1;
static int hf_vntag_etype = -1;
static int hf_vntag_dir = -1;
static int hf_vntag_ptr = -1;
static int hf_vntag_dst = -1;
static int hf_vntag_looped = -1;
static int hf_vntag_r = -1;
static int hf_vntag_version = -1;
static int hf_vntag_src = -1;
static int hf_vntag_len = -1;
static int hf_vntag_trailer = -1;
static gint ett_vntag = -1;
static expert_field ei_vntag_len = EI_INIT;
static const true_false_string vntag_dir_tfs = {
"From Bridge",
"To Bridge"
};
static const true_false_string vntag_ptr_tfs = {
"vif_list_id",
"vif_id"
};
static int
dissect_vntag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
guint16 encap_proto;
proto_tree *vntag_tree = NULL;
ethertype_data_t ethertype_data;
/* Documentation:
https://d2zmdbbm9feqrf.cloudfront.net/2012/usa/pdf/BRKDCT-2340.pdf p.61
http://www.definethecloud.net/access-layer-network-virtualization-vn-tag-and-vepa
*/
static int * const fields[] = {
&hf_vntag_dir,
&hf_vntag_ptr,
&hf_vntag_dst,
&hf_vntag_looped,
&hf_vntag_r,
&hf_vntag_version,
&hf_vntag_src,
NULL
};
col_set_str(pinfo->cinfo, COL_PROTOCOL, "VNTAG");
col_clear(pinfo->cinfo, COL_INFO);
if (tree) {
proto_item *ti = proto_tree_add_item(tree, proto_vntag, tvb, 0, 4, ENC_NA);
vntag_tree = proto_item_add_subtree(ti, ett_vntag);
proto_tree_add_bitmask_list(vntag_tree, tvb, 0, 4, fields, ENC_BIG_ENDIAN);
}
encap_proto = tvb_get_ntohs(tvb, 4);
/* VNTAG may also carry 802.2 encapsulated data */
if (encap_proto <= IEEE_802_3_MAX_LEN) {
gboolean is_802_2;
/* Is there an 802.2 layer? I can tell by looking at the first 2
bytes after the VLAN header. If they are 0xffff, then what
follows the VLAN header is an IPX payload, meaning no 802.2.
(IPX/SPX is they only thing that can be contained inside a
straight 802.3 packet, so presumably the same applies for
Ethernet VLAN packets). A non-0xffff value means that there's an
802.2 layer inside the VLAN layer */
is_802_2 = TRUE;
/* Don't throw an exception for this check (even a BoundsError) */
if (tvb_captured_length_remaining(tvb, 6) >= 2) {
if (tvb_get_ntohs(tvb, 6) == 0xffff)
is_802_2 = FALSE;
}
dissect_802_3(encap_proto, is_802_2, tvb, 6, pinfo, tree, vntag_tree, hf_vntag_len, hf_vntag_trailer, &ei_vntag_len, 0);
} else {
proto_tree_add_uint(vntag_tree, hf_vntag_etype, tvb, 4, 2,
encap_proto);
ethertype_data.etype = encap_proto;
ethertype_data.payload_offset = 6;
ethertype_data.fh_tree = vntag_tree;
ethertype_data.trailer_id = hf_vntag_trailer;
ethertype_data.fcs_len = 0;
call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, &ethertype_data);
}
return tvb_captured_length(tvb);
}
void
proto_register_vntag(void)
{
static hf_register_info hf[] = {
{ &hf_vntag_etype,
{ "Type", "vntag.etype", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0, NULL, HFILL }
},
{ &hf_vntag_dir,
{ "Direction", "vntag.dir", FT_BOOLEAN, 32, TFS(&vntag_dir_tfs), 0x80000000, NULL, HFILL }
},
{ &hf_vntag_ptr,
{ "Pointer", "vntag.ptr", FT_BOOLEAN, 32, TFS(&vntag_ptr_tfs), 0x40000000, NULL, HFILL }
},
{ &hf_vntag_dst,
{ "Destination", "vntag.dst", FT_UINT32, BASE_DEC, NULL, 0x3FFF0000, NULL, HFILL }
},
{ &hf_vntag_looped,
{ "Looped", "vntag.looped", FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x00008000, NULL, HFILL }
},
{ &hf_vntag_r,
{ "Reserved", "vntag.r", FT_UINT32, BASE_DEC, NULL, 0x00004000, NULL, HFILL }
},
{ &hf_vntag_version,
{ "Version", "vntag.version", FT_UINT32, BASE_DEC, NULL, 0x00003000, NULL, HFILL }
},
{ &hf_vntag_src,
{ "Source", "vntag.src", FT_UINT32, BASE_DEC, NULL, 0x00000FFF, NULL, HFILL }
},
{ &hf_vntag_len,
{ "Length", "vntag.len", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_vntag_trailer,
{ "Trailer", "vntag.trailer", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
}
};
static gint *ett[] = {
&ett_vntag
};
static ei_register_info ei[] = {
{ &ei_vntag_len, { "vntag.len.past_end", PI_MALFORMED, PI_ERROR, "Length field value goes past the end of the payload", EXPFILL }},
};
expert_module_t* expert_vntag;
proto_vntag = proto_register_protocol("VN-Tag", "VNTAG", "vntag");
proto_register_field_array(proto_vntag, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_vntag = expert_register_protocol(proto_vntag);
expert_register_field_array(expert_vntag, ei, array_length(ei));
}
void
proto_reg_handoff_vntag(void)
{
dissector_handle_t vntag_handle;
vntag_handle = create_dissector_handle(dissect_vntag, proto_vntag);
dissector_add_uint("ethertype", ETHERTYPE_VNTAG, vntag_handle);
ethertype_handle = find_dissector_add_dependency("ethertype", proto_vntag);
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/