aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <gharris@sonic.net>2020-12-04 17:45:45 -0800
committerGuy Harris <gharris@sonic.net>2020-12-04 17:45:45 -0800
commit872fb08aad91903c0e4e0efe7fe114e0e4ce586a (patch)
tree84289d11bbbdf46eeb92c9cec7fe6cfe47d5f454
parent9f056c395a2303d1aaadf9b10145e865c7c277ef (diff)
wlan, llc: support EPD and LPD for 802.11 frames.
Replace the special-purpose hack in the 802.2 LLC dissector for WSMP, Ethertype 0x88DC, with a general mechanism in the 802.11 dissector to attempt to determine whether the frame uses Ethertype protocol discrimination (EPD) or LLC protocol discrimination (LPD) at the LLC sublayer, as defined in IEEE Std 802-2014.
-rw-r--r--epan/dissectors/packet-ieee80211.c105
-rw-r--r--epan/dissectors/packet-llc.c53
2 files changed, 135 insertions, 23 deletions
diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c
index 7f34c1a44c..e6acaf4b0b 100644
--- a/epan/dissectors/packet-ieee80211.c
+++ b/epan/dissectors/packet-ieee80211.c
@@ -6414,12 +6414,14 @@ static heur_dissector_list_t heur_subdissector_list;
static dissector_handle_t ieee80211_handle;
static dissector_handle_t wlan_withoutfcs_handle;
static dissector_handle_t llc_handle;
+static dissector_handle_t epd_llc_handle;
static dissector_handle_t ipx_handle;
static dissector_handle_t eth_withoutfcs_handle;
static capture_dissector_handle_t llc_cap_handle;
static capture_dissector_handle_t ipx_cap_handle;
+static dissector_table_t ethertype_subdissector_table;
static dissector_table_t tagged_field_table;
static dissector_table_t vendor_specific_action_table;
static dissector_table_t wifi_alliance_action_subtype_table;
@@ -25284,7 +25286,8 @@ crc32_802_tvb_padded(tvbuff_t *tvb, guint hdr_len, guint hdr_size, guint len)
typedef enum {
ENCAP_802_2,
ENCAP_IPX,
- ENCAP_ETHERNET
+ ENCAP_ETHERNET,
+ ENCAP_EPD
} encap_t;
/* ************************************************************************* */
@@ -25321,6 +25324,7 @@ dissect_ieee80211_common(tvbuff_t *tvb, packet_info *pinfo,
gboolean save_fragmented;
guint32 addr_type;
guint8 octet1, octet2;
+ guint16 etype;
char out_buff[SHORT_STR];
gint is_iv_bad;
guchar iv_buff[4];
@@ -26988,6 +26992,63 @@ dissect_ieee80211_common(tvbuff_t *tvb, packet_info *pinfo,
with Atheros chipsets. There the sequence control field
seems repeated.
+ And, on top of *that*, IEEE Std 802.11-2018 section
+ 5.1.4 "MSDU format" says:
+
+ Logical Link Control (LLC) sublayer entities use the MAC
+ sublayer service to exchange PDUs with peer LLC sublayer
+ entities. These PDUs are termed MAC sublayer SDUs (MSDUs)
+ when sent to the MAC sublayer. There are two LLC sublayer
+ protocols used (see IEEE Std 802-2014); LLC Protocol
+ Discrimination (LPD) (see ISO/IEC 8802-2:1998) and EtherType
+ Protocol Discrimination (EPD) (see IEEE Std 802.3-2012).
+ LPD is used for transmission of all IEEE 802.11 MSDUs with
+ the exception of the 5.9 GHz bands where EPD is used
+ (see E.2.3 and E.2.4).
+
+ and IEEE Std 1609.3-2016, section 5.2 "Logical link control",
+ subsection 5.2.1 "General", says:
+
+ A Networking Services implementation shall use EPD in the
+ LLC sublayer as described in IEEE Std 802, using an EtherType
+ in the LLC sublayer header Type9 field (see Figure 5 and
+ Figure 28). The LLC sublayer header consists solely of a
+ 2-octet field that contains an EtherType that identifies
+ the higher layer protocol.
+
+ and ISO 21215, second edition, 2018-06, "Intelligent transport
+ systems -- Localized communications -- ITS-M5", section 6.3
+ "Logical link control sub-layer" says:
+
+ IEEE Std 802.11TM-2016 does not specify a logical link control
+ sub-layer protocol. Related functionality is part of the
+ communication adaptation sub-layer specified in 6.4.
+
+ The Length/Type field specified in IEEE 802.3-2015 contains
+ a 2-octet unsigned Integer number. Dependent on the value,
+ the field provides either length information or EtherType
+ information. If the value contained in this field is equal
+ to or larger than 1 536 = 0x06.00, the field contains an
+ EtherType address. Ethertype addresses are assigned by the
+ IEEE Registration Authority, and are used to identify the
+ protocol employed directly above the ITS-S access layer.
+ This method of addressing is named "EtherType Protocol
+ Discrimination" (EPD). An ITS-M5 CI shall support EPD
+ specified in IEEE Std 802.
+
+ ...
+
+ NOTE 2 EPD replaces LLC Protocol Discrimination (LPD).
+ ETSI ITS-G5 is the only known ITS access technology still
+ using LPD.
+
+ Different to the information in IEEE Std 802.11-2016, 5.1.4,
+ EPD is applicable in all frequency bands as long as
+ dot11OCBActivated is set to true, i.e. activating the operation
+ mode "outside the context of a BSS" (OCB).
+
+ meaning that a packet might just begin with an Ethertype.
+
So, if the packet doesn't start with 0xaa 0xaa:
we first use the same scheme that linux-wlan-ng does to detect
@@ -27000,10 +27061,19 @@ dissect_ieee80211_common(tvbuff_t *tvb, packet_info *pinfo,
otherwise, we use the same scheme that we use in the Ethernet
dissector to recognize Netware 802.3 frames, namely checking
whether the packet starts with 0xff 0xff and, if so, treat it
- as an encapsulated IPX frame, and then check whether the
- packet starts with 0x00 0x00 and, if so, treat it as an OLPC
- frame, or check the packet starts with the repetition of the
- sequence control field and, if so, treat it as an Atheros frame. */
+ as an encapsulated IPX frame;
+
+ otherwise, we check whether the packet starts with 0x00 0x00
+ and, if so, treat it as an OLPC frame, or check the packet
+ starts with the repetition of the sequence control field
+ and, if so, treat it as an Atheros frame, both of which
+ use LPD;
+
+ otherwise, we check whether the first two octets, treated
+ as an Ethertype, has a dissector and, if so, treat this as
+ a frame using EPD;
+
+ otherwise, we treat this as a frame using LPD. */
heur_dtbl_entry_t *hdtbl_entry;
if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, &hdtbl_entry, NULL)) {
pinfo->fragmented = save_fragmented;
@@ -27023,6 +27093,16 @@ dissect_ieee80211_common(tvbuff_t *tvb, packet_info *pinfo,
(((octet2 << 8) | octet1) == seq_control)) {
proto_tree_add_item(tree, hf_ieee80211_mysterious_olpc_stuff, next_tvb, 0, 2, ENC_NA);
next_tvb = tvb_new_subset_remaining(next_tvb, 2);
+ } else if ((etype = ((octet1 << 8) | octet2)) > ETHERNET_II_MIN_LEN) {
+ /*
+ * This might be an Ethertype, so maybe this is 802.11
+ * using EPD rather than LPD. Is this a *known* Ethertype?
+ */
+ if (dissector_get_uint_handle(ethertype_subdissector_table,
+ etype) != NULL) {
+ /* Yes. */
+ encap_type = ENCAP_EPD;
+ }
}
}
}
@@ -27030,6 +27110,7 @@ dissect_ieee80211_common(tvbuff_t *tvb, packet_info *pinfo,
switch (encap_type) {
case ENCAP_802_2:
+ /* 802.2 LPD */
call_dissector(llc_handle, next_tvb, pinfo, tree);
break;
@@ -27040,6 +27121,11 @@ dissect_ieee80211_common(tvbuff_t *tvb, packet_info *pinfo,
case ENCAP_IPX:
call_dissector(ipx_handle, next_tvb, pinfo, tree);
break;
+
+ case ENCAP_EPD:
+ /* EPD */
+ call_dissector(epd_llc_handle, next_tvb, pinfo, tree);
+ break;
}
}
break;
@@ -40313,12 +40399,19 @@ proto_reg_handoff_ieee80211(void)
capture_dissector_handle_t ieee80211_cap_handle;
/*
- * Get handles for the LLC, IPX and Ethernet dissectors.
+ * Get handles for the 802.2 (LPD) LLC, EPD LLC, IPX and Ethernet
+ * dissectors.
*/
llc_handle = find_dissector_add_dependency("llc", proto_wlan);
+ epd_llc_handle = find_dissector_add_dependency("epd_llc", proto_wlan);
ipx_handle = find_dissector_add_dependency("ipx", proto_wlan);
eth_withoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_wlan);
+ /*
+ * Get the Ethertype dissector table.
+ */
+ ethertype_subdissector_table = find_dissector_table("ethertype");
+
llc_cap_handle = find_capture_dissector("llc");
ipx_cap_handle = find_capture_dissector("ipx");
diff --git a/epan/dissectors/packet-llc.c b/epan/dissectors/packet-llc.c
index 3e8732d36f..12b8c36338 100644
--- a/epan/dissectors/packet-llc.c
+++ b/epan/dissectors/packet-llc.c
@@ -88,7 +88,7 @@ static dissector_handle_t tr_handle;
static dissector_handle_t turbo_handle;
static dissector_handle_t mesh_handle;
static dissector_handle_t llc_handle;
-
+static dissector_handle_t epd_llc_handle;
/*
* Group/Individual bit, in the DSAP.
@@ -366,14 +366,20 @@ dissect_basicxid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data
return tvb_captured_length(tvb);
}
+/*
+ * IEEE Std 802.2-1998 and ISO/IEC 8802-2.
+ *
+ * This is what IEEE Std 802-2014 describes in section 5.2.2 "LLC sublayer"
+ * as "LLC protocol discrimination (LPD)".
+ */
static int
-dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
proto_tree *llc_tree;
proto_tree *field_tree;
proto_item *ti, *sap_item;
int is_snap;
- guint16 control, etype;
+ guint16 control;
int llc_header_len;
guint8 dsap, ssap, format;
tvbuff_t *next_tvb;
@@ -385,20 +391,6 @@ dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
ti = proto_tree_add_item(tree, proto_llc, tvb, 0, -1, ENC_NA);
llc_tree = proto_item_add_subtree(ti, ett_llc);
- /* IEEE 1609.3 Ch 5.2.1
- * The LLC sublayer header consists solely of a 2-octet field
- * that contains an EtherType that identifies the higher layer protocol...
- * Check for 0x86DD too?
- */
- if (tvb_bytes_exist(tvb, 0, 2) &&
- (etype = tvb_get_ntohs(tvb, 0)) == 0x88DC) {
- proto_tree_add_item(llc_tree, hf_llc_type, tvb, 0, 2, ENC_BIG_ENDIAN);
- next_tvb = tvb_new_subset_remaining(tvb, 2);
- if (!dissector_try_uint(ethertype_subdissector_table,
- etype, next_tvb, pinfo, tree))
- call_data_dissector(next_tvb, pinfo, tree);
- return tvb_captured_length(tvb);
- }
sap_item = proto_tree_add_item(llc_tree, hf_llc_dsap, tvb, 0, 1, ENC_BIG_ENDIAN);
field_tree = proto_item_add_subtree(sap_item, ett_llc_dsap);
@@ -707,6 +699,31 @@ get_snap_oui_info(guint32 oui)
return NULL;
}
+/*
+ * This is what IEEE Std 802-2014 describes in section 5.2.2 "LLC sublayer"
+ * as "EtherType protocol discrimination (EPD)".
+ */
+static int
+dissect_epd_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+ proto_tree *llc_tree;
+ proto_item *ti;
+ guint32 etype;
+ tvbuff_t *next_tvb;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLC");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ ti = proto_tree_add_item(tree, proto_llc, tvb, 0, 2, ENC_NA);
+ llc_tree = proto_item_add_subtree(ti, ett_llc);
+ proto_tree_add_item_ret_uint(llc_tree, hf_llc_type, tvb, 0, 2, ENC_BIG_ENDIAN, &etype);
+ next_tvb = tvb_new_subset_remaining(tvb, 2);
+ if (dissector_try_uint(ethertype_subdissector_table, etype, next_tvb,
+ pinfo, tree) == 0)
+ call_data_dissector(next_tvb, pinfo, tree);
+ return tvb_captured_length(tvb);
+}
+
void
proto_register_llc(void)
{
@@ -822,6 +839,8 @@ proto_register_llc(void)
register_capture_dissector_table("llc.dsap", "LLC");
llc_handle = register_dissector("llc", dissect_llc, proto_llc);
+ epd_llc_handle = register_dissector("epd_llc", dissect_epd_llc,
+ proto_llc);
register_capture_dissector("llc", capture_llc, proto_llc);
}