aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn A. Thacker <johnthacker@gmail.com>2017-01-04 16:10:49 -0500
committerMichael Mann <mmann78@netscape.net>2017-01-06 12:43:38 +0000
commitf0b1099f819ecae61cf0ad3304ec5cf5e25bdfec (patch)
tree2ce177c30e4551c5f4faf70b91e782ecd4df17da
parentcea1063af1aaa66f430d34410252693b19c364d3 (diff)
VLAN: Support IEEE 802.1Q-2005 and -2011 changes
Supports the recommended meanings of the priority field as changed by 802.1Q-2005, and the change from the CFI to DEI in 802.1Q-2011. A preference is added to use the older (non-compatible) spec version. Note that 802.1Q-2011 is consistent with 802.1ad and ah, which got rolled up in 802.1Q, but ends up removing support for bridging Token Ring and FDDI over Ethernet. Bug: 13294 Change-Id: Ieeadb0f6dda2758750f9e6649f1390609d78c50e Reviewed-on: https://code.wireshark.org/review/19548 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--epan/dissectors/packet-vlan.c194
1 files changed, 174 insertions, 20 deletions
diff --git a/epan/dissectors/packet-vlan.c b/epan/dissectors/packet-vlan.c
index ff9c0209f4..76aedfeaa9 100644
--- a/epan/dissectors/packet-vlan.c
+++ b/epan/dissectors/packet-vlan.c
@@ -43,6 +43,22 @@ static unsigned int q_in_q_ethertype = ETHERTYPE_QINQ_OLD;
static gboolean vlan_summary_in_tree = TRUE;
+enum version_value {
+ IEEE_8021Q_1998,
+ IEEE_8021Q_2005,
+ IEEE_8021Q_2011
+};
+
+static gint vlan_version = (gint)IEEE_8021Q_2011;
+
+enum priority_drop_value {
+ Priority_Drop_8P0D,
+ Priority_Drop_7P1D,
+ Priority_Drop_6P2D,
+ Priority_Drop_5P3D,
+};
+
+static gint vlan_priority_drop = (gint)Priority_Drop_8P0D;
static dissector_handle_t vlan_handle;
static dissector_handle_t ethertype_handle;
@@ -55,10 +71,12 @@ static header_field_info *hfi_vlan = NULL;
#define VLAN_HFI_INIT HFI_INIT(proto_vlan)
/* From Table G-2 of IEEE standard 802.1D-2004 */
-static const value_string pri_vals[] = {
+/* Note that 0 is the default priority, but is above 1 and 2.
+ * Priority order from lowest to highest is 1,2,0,3,4,5,6,7 */
+static const value_string pri_vals_old[] = {
+ { 0, "Best Effort (default)" },
{ 1, "Background" },
{ 2, "Spare" },
- { 0, "Best Effort (default)" },
{ 3, "Excellent Effort" },
{ 4, "Controlled Load" },
{ 5, "Video, < 100ms latency and jitter" },
@@ -67,19 +85,92 @@ static const value_string pri_vals[] = {
{ 0, NULL }
};
+static header_field_info hfi_vlan_priority_old VLAN_HFI_INIT = {
+ "Priority", "vlan.priority", FT_UINT16, BASE_DEC,
+ VALS(pri_vals_old), 0xE000, "Descriptions are recommendations from IEEE standard 802.1D-2004", HFILL };
+
+/* From Table G-2 of IEEE standard 802.1Q-2005 (and I-2 of 2011 and 2014 revisions) */
+/* Note that 0 is still the default, but priority 2 was moved from below 0 to
+ * above it. The new order from lowest to highest is 1,0,2,3,4,5,6,7 */
+static const value_string pri_vals[] = {
+ { 0, "Best Effort (default)" },
+ { 1, "Background" },
+ { 2, "Excellent Effort" },
+ { 3, "Critical Applications" },
+ { 4, "Video, < 100ms latency and jitter" },
+ { 5, "Voice, < 10ms latency and jitter" },
+ { 6, "Internetwork Control" },
+ { 7, "Network Control" },
+ { 0, NULL }
+};
+
static header_field_info hfi_vlan_priority VLAN_HFI_INIT = {
"Priority", "vlan.priority", FT_UINT16, BASE_DEC,
- VALS(pri_vals), 0xE000, "Descriptions are recommendations from IEEE standard 802.1D-2004", HFILL };
+ VALS(pri_vals), 0xE000, "Descriptions are recommendations from IEEE standard 802.1Q-2014", HFILL };
+
+/* From Tables G-2,3 of IEEE standard 802.1Q-2005 (and I-2,3,7 of 2011 and 2014 revisions) */
+static const value_string pri_vals_7[] = {
+ { 0, "Best Effort (default)" },
+ { 1, "Background" },
+ { 2, "Excellent Effort" },
+ { 3, "Critical Applications" },
+ { 4, "Voice, < 10ms latency and jitter, Drop Eligible" },
+ { 5, "Voice, < 10ms latency and jitter" },
+ { 6, "Internetwork Control" },
+ { 7, "Network Control" },
+ { 0, NULL }
+};
-static const value_string cfi_vals[] = {
- { 0, "Canonical" },
- { 1, "Non-canonical" },
- { 0, NULL }
+static header_field_info hfi_vlan_priority_7 VLAN_HFI_INIT = {
+ "Priority", "vlan.priority", FT_UINT16, BASE_DEC,
+ VALS(pri_vals_7), 0xE000, "Descriptions are recommendations from IEEE standard 802.1Q-2014", HFILL };
+
+/* From Tables G-2,3 of IEEE standard 802.1Q-2005 (and I-2,3,7 of 2011 and 2015 revisions) */
+static const value_string pri_vals_6[] = {
+ { 0, "Best Effort (default)" },
+ { 1, "Background" },
+ { 2, "Critical Applications, Drop Eligible" },
+ { 3, "Critical Applications" },
+ { 4, "Voice, < 10ms latency and jitter, Drop Eligible" },
+ { 5, "Voice, < 10ms latency and jitter" },
+ { 6, "Internetwork Control" },
+ { 7, "Network Control" },
+ { 0, NULL }
};
+static header_field_info hfi_vlan_priority_6 VLAN_HFI_INIT = {
+ "Priority", "vlan.priority", FT_UINT16, BASE_DEC,
+ VALS(pri_vals_6), 0xE000, "Descriptions are recommendations from IEEE standard 802.1Q-2014", HFILL };
+
+/* From Tables G-2,3 of IEEE standard 802.1Q-2005 (and I-2,3,7 of 2011 and 2015 revisions) */
+static const value_string pri_vals_5[] = {
+ { 0, "Best Effort (default), Drop Eligible" },
+ { 1, "Best Effort (default)" },
+ { 2, "Critical Applications, Drop Eligible" },
+ { 3, "Critical Applications" },
+ { 4, "Voice, < 10ms latency and jitter, Drop Eligible" },
+ { 5, "Voice, < 10ms latency and jitter" },
+ { 6, "Internetwork Control" },
+ { 7, "Network Control" },
+ { 0, NULL }
+};
+
+static header_field_info hfi_vlan_priority_5 VLAN_HFI_INIT = {
+ "Priority", "vlan.priority", FT_UINT16, BASE_DEC,
+ VALS(pri_vals_5), 0xE000, "Descriptions are recommendations from IEEE standard 802.1Q-2014", HFILL };
+
+/* True is non-canonical (i.e., bit-reversed MACs like Token Ring) since usually 0 and canonical. */
+static const true_false_string tfs_noncanonical_canonical = { "Non-canonical", "Canonical" };
+
static header_field_info hfi_vlan_cfi VLAN_HFI_INIT = {
- "CFI", "vlan.cfi", FT_UINT16, BASE_DEC,
- VALS(cfi_vals), 0x1000, "Canonical Format Identifier", HFILL };
+ "CFI", "vlan.cfi", FT_BOOLEAN, 16,
+ TFS(&tfs_noncanonical_canonical), 0x1000, "Canonical Format Identifier", HFILL };
+
+static const true_false_string tfs_eligible_ineligible = { "Eligible", "Ineligible" };
+
+static header_field_info hfi_vlan_dei VLAN_HFI_INIT = {
+ "DEI", "vlan.dei", FT_BOOLEAN, 16,
+ TFS(&tfs_eligible_ineligible), 0x1000, "Drop Eligible Indicator", HFILL };
static header_field_info hfi_vlan_id VLAN_HFI_INIT = {
"ID", "vlan.id", FT_UINT16, BASE_DEC,
@@ -127,17 +218,19 @@ capture_vlan(const guchar *pd, int offset, int len, capture_packet_info_t *cpinf
static void
columns_set_vlan(column_info *cinfo, guint16 tci)
{
- static const char fast_str[][2] = { "0", "1", "2", "3", "4", "5", "6", "7" };
-
char id_str[16];
guint32_to_str_buf(tci & 0xFFF, id_str, sizeof(id_str));
- col_add_lstr(cinfo, COL_INFO,
- "PRI: ", fast_str[(tci >> 13) & 7], " "
- "CFI: ", fast_str[(tci >> 12) & 1], " "
- "ID: ", id_str,
- COL_ADD_LSTR_TERMINATOR);
+ if (vlan_version < IEEE_8021Q_2011) {
+ col_add_fstr(cinfo, COL_INFO,
+ "PRI: %d CFI: %d ID: %s",
+ (tci >> 13), ((tci >> 12) & 1), id_str);
+ } else {
+ col_add_fstr(cinfo, COL_INFO,
+ "PRI: %d DEI: %d ID: %s",
+ (tci >> 13), ((tci >> 12) & 1), id_str);
+ }
col_add_str(cinfo, COL_8021Q_VLAN_ID, id_str);
}
@@ -169,16 +262,46 @@ dissect_vlan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
ti = proto_tree_add_item(tree, hfi_vlan, tvb, 0, 4, ENC_NA);
if (vlan_summary_in_tree) {
+ if (vlan_version < IEEE_8021Q_2011) {
proto_item_append_text(ti, ", PRI: %u, CFI: %u, ID: %u",
(tci >> 13), ((tci >> 12) & 1), vlan_id);
+ } else {
+ proto_item_append_text(ti, ", PRI: %u, DEI: %u, ID: %u",
+ (tci >> 13), ((tci >> 12) & 1), vlan_id);
+ }
}
vlan_tree = proto_item_add_subtree(ti, ett_vlan);
- proto_tree_add_item(vlan_tree, &hfi_vlan_priority, tvb, 0, 2, ENC_BIG_ENDIAN);
- proto_tree_add_item(vlan_tree, &hfi_vlan_cfi, tvb, 0, 2, ENC_BIG_ENDIAN);
- proto_tree_add_item(vlan_tree, &hfi_vlan_id, tvb, 0, 2, ENC_BIG_ENDIAN);
+ if (vlan_version == IEEE_8021Q_1998) {
+ proto_tree_add_item(vlan_tree, &hfi_vlan_priority_old, tvb, 0, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(vlan_tree, &hfi_vlan_cfi, tvb, 0, 2, ENC_BIG_ENDIAN);
+ } else {
+ switch (vlan_priority_drop) {
+
+ case Priority_Drop_8P0D:
+ proto_tree_add_item(vlan_tree, &hfi_vlan_priority, tvb, 0, 2, ENC_BIG_ENDIAN);
+ break;
+ case Priority_Drop_7P1D:
+ proto_tree_add_item(vlan_tree, &hfi_vlan_priority_7, tvb, 0, 2, ENC_BIG_ENDIAN);
+ break;
+
+ case Priority_Drop_6P2D:
+ proto_tree_add_item(vlan_tree, &hfi_vlan_priority_6, tvb, 0, 2, ENC_BIG_ENDIAN);
+ break;
+
+ case Priority_Drop_5P3D:
+ proto_tree_add_item(vlan_tree, &hfi_vlan_priority_5, tvb, 0, 2, ENC_BIG_ENDIAN);
+ break;
+ }
+ if (vlan_version == IEEE_8021Q_2005) {
+ proto_tree_add_item(vlan_tree, &hfi_vlan_cfi, tvb, 0, 2, ENC_BIG_ENDIAN);
+ } else {
+ proto_tree_add_item(vlan_tree, &hfi_vlan_dei, tvb, 0, 2, ENC_BIG_ENDIAN);
+ }
+ }
+ proto_tree_add_item(vlan_tree, &hfi_vlan_id, tvb, 0, 2, ENC_BIG_ENDIAN);
if (gbl_resolv_flags.vlan_name) {
item = proto_tree_add_string(vlan_tree, &hfi_vlan_id_name, tvb, 0, 2,
get_vlan_name(wmem_packet_scope(), vlan_id));
@@ -186,6 +309,10 @@ dissect_vlan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
}
+ /* TODO: If the CFI is set on Ethernet (or FDDI MAC and not source routed,
+ * i.e. the RII bit in the source MAC address is 0, then a E-RIF follows.
+ * Only true before version 2011 since the CFI was replaced with DEI
+ * (Since who needs VLANs that bridge Token Ring and FDDI these days?) */
}
encap_proto = tvb_get_ntohs(tvb, 2);
@@ -228,8 +355,13 @@ proto_register_vlan(void)
{
#ifndef HAVE_HFI_SECTION_INIT
static header_field_info *hfi[] = {
+ &hfi_vlan_priority_old,
&hfi_vlan_priority,
+ &hfi_vlan_priority_7,
+ &hfi_vlan_priority_6,
+ &hfi_vlan_priority_5,
&hfi_vlan_cfi,
+ &hfi_vlan_dei,
&hfi_vlan_id,
&hfi_vlan_id_name,
&hfi_vlan_etype,
@@ -246,6 +378,21 @@ proto_register_vlan(void)
{ &ei_vlan_len, { "vlan.len.past_end", PI_MALFORMED, PI_ERROR, "Length field value goes past the end of the payload", EXPFILL }},
};
+ static const enum_val_t version_vals[] = {
+ {"1998", "IEEE 802.1Q-1998", IEEE_8021Q_1998},
+ {"2005", "IEEE 802.1Q-2005", IEEE_8021Q_2005},
+ {"2011", "IEEE 802.1Q-2011", IEEE_8021Q_2011},
+ {NULL, NULL, -1}
+ };
+
+ static const enum_val_t priority_drop_vals[] = {
+ {"8p0d", "8 Priorities, 0 Drop Eligible", Priority_Drop_8P0D},
+ {"7p1d", "7 Priorities, 1 Drop Eligible", Priority_Drop_7P1D},
+ {"6p2d", "6 Priorities, 2 Drop Eligible", Priority_Drop_6P2D},
+ {"5p3d", "5 Priorities, 3 Drop Eligible", Priority_Drop_5P3D},
+ {NULL, NULL, -1}
+ };
+
module_t *vlan_module;
expert_module_t* expert_vlan;
int proto_vlan;
@@ -267,7 +414,14 @@ proto_register_vlan(void)
"802.1QinQ Ethertype (in hex)",
"The (hexadecimal) Ethertype used to indicate 802.1QinQ VLAN in VLAN tunneling.",
16, &q_in_q_ethertype);
-
+ prefs_register_enum_preference(vlan_module, "version",
+ "IEEE 802.1Q version",
+ "IEEE 802.1Q specification version used (802.1Q-1998 uses 802.1D-2004 for PRI values)",
+ &vlan_version, version_vals, TRUE);
+ prefs_register_enum_preference(vlan_module, "priority_drop",
+ "Priorities and drop eligibility",
+ "Number of priorities supported, and number of those drop eligible (not used for 802.1Q-1998)",
+ &vlan_priority_drop, priority_drop_vals, TRUE);
vlan_handle = create_dissector_handle(dissect_vlan, proto_vlan);
}