netmon: fill in all of the 802.11 pseudo-header in the dissector.

All the NetMon reading code does is initialize the pseudo-header; the
bulk of the work is done in the dissector.  Give the dissector its own
pseudo-header structure, and do the initialization there.

That's the way other packet formats in which the 802.11 radio metadata
is a header at the beginning of the packet data, such as radiotap, work.
This commit is contained in:
Guy Harris 2021-04-02 00:45:57 -07:00
parent 4c16875759
commit c01dd585c7
2 changed files with 55 additions and 51 deletions

View File

@ -71,9 +71,9 @@ static gint ett_netmon_802_11_op_mode = -1;
static dissector_handle_t ieee80211_radio_handle; static dissector_handle_t ieee80211_radio_handle;
static int static int
dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{ {
struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; struct ieee_802_11_phdr phdr;
proto_tree *wlan_tree = NULL, *opmode_tree; proto_tree *wlan_tree = NULL, *opmode_tree;
proto_item *ti; proto_item *ti;
tvbuff_t *next_tvb; tvbuff_t *next_tvb;
@ -88,6 +88,25 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
gint32 rssi; gint32 rssi;
guint8 rate; guint8 rate;
/*
* It appears to be the case that management frames (and control and
* extension frames ?) may or may not have an FCS and data frames don't.
* (Netmon capture files have been seen for this encapsulation
* management frames either completely with or without an FCS. Also:
* instances have been seen where both Management and Control frames
* do not have an FCS). An "FCS length" of -2 means "NetMon weirdness".
*
* The metadata header also has a bit indicating whether the adapter
* was in monitor mode or not; if it isn't, we set "decrypted" to TRUE,
* as, for those frames, the Protected bit is preserved in received
* frames, but the frame is decrypted.
*/
memset(&phdr, 0, sizeof(phdr));
phdr.fcs_len = -2;
phdr.decrypted = FALSE;
phdr.datapad = FALSE;
phdr.phy = PHDR_802_11_PHY_UNKNOWN;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN"); col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
col_clear(pinfo->cinfo, COL_INFO); col_clear(pinfo->cinfo, COL_INFO);
offset = 0; offset = 0;
@ -152,14 +171,14 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
* the "monitor mode" flag wasn't set, so supporess treating the * the "monitor mode" flag wasn't set, so supporess treating the
* Protect flag as an indication that the frame was encrypted. * Protect flag as an indication that the frame was encrypted.
*/ */
phdr->decrypted = TRUE; phdr.decrypted = TRUE;
/* /*
* Furthermore, we may see frames with the A-MSDU Present flag set * Furthermore, we may see frames with the A-MSDU Present flag set
* in the QoS Control field but that have a regular frame, nto a * in the QoS Control field but that have a regular frame, nto a
* sequence of A-MSDUs, in the payload. * sequence of A-MSDUs, in the payload.
*/ */
phdr->no_a_msdus = TRUE; phdr.no_a_msdus = TRUE;
} }
offset += 4; offset += 4;
@ -173,7 +192,7 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
* uPhyId? * uPhyId?
*/ */
phy_type = tvb_get_letohl(tvb, offset); phy_type = tvb_get_letohl(tvb, offset);
memset(&phdr->phy_info, 0, sizeof(phdr->phy_info)); memset(&phdr.phy_info, 0, sizeof(phdr.phy_info));
/* /*
* Unlike the channel flags in radiotap, this appears * Unlike the channel flags in radiotap, this appears
@ -183,43 +202,43 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
switch (phy_type) { switch (phy_type) {
case PHY_TYPE_UNKNOWN: case PHY_TYPE_UNKNOWN:
phdr->phy = PHDR_802_11_PHY_UNKNOWN; phdr.phy = PHDR_802_11_PHY_UNKNOWN;
break; break;
case PHY_TYPE_FHSS: case PHY_TYPE_FHSS:
phdr->phy = PHDR_802_11_PHY_11_FHSS; phdr.phy = PHDR_802_11_PHY_11_FHSS;
break; break;
case PHY_TYPE_IR_BASEBAND: case PHY_TYPE_IR_BASEBAND:
phdr->phy = PHDR_802_11_PHY_11_IR; phdr.phy = PHDR_802_11_PHY_11_IR;
break; break;
case PHY_TYPE_DSSS: case PHY_TYPE_DSSS:
phdr->phy = PHDR_802_11_PHY_11_DSSS; phdr.phy = PHDR_802_11_PHY_11_DSSS;
break; break;
case PHY_TYPE_HR_DSSS: case PHY_TYPE_HR_DSSS:
phdr->phy = PHDR_802_11_PHY_11B; phdr.phy = PHDR_802_11_PHY_11B;
break; break;
case PHY_TYPE_OFDM: case PHY_TYPE_OFDM:
phdr->phy = PHDR_802_11_PHY_11A; phdr.phy = PHDR_802_11_PHY_11A;
break; break;
case PHY_TYPE_ERP: case PHY_TYPE_ERP:
phdr->phy = PHDR_802_11_PHY_11G; phdr.phy = PHDR_802_11_PHY_11G;
break; break;
case PHY_TYPE_HT: case PHY_TYPE_HT:
phdr->phy = PHDR_802_11_PHY_11N; phdr.phy = PHDR_802_11_PHY_11N;
break; break;
case PHY_TYPE_VHT: case PHY_TYPE_VHT:
phdr->phy = PHDR_802_11_PHY_11AC; phdr.phy = PHDR_802_11_PHY_11AC;
break; break;
default: default:
phdr->phy = PHDR_802_11_PHY_UNKNOWN; phdr.phy = PHDR_802_11_PHY_UNKNOWN;
break; break;
} }
proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4, proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4,
@ -238,11 +257,11 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
} else { } else {
guint frequency; guint frequency;
phdr->has_channel = TRUE; phdr.has_channel = TRUE;
phdr->channel = channel; phdr.channel = channel;
proto_tree_add_uint(wlan_tree, hf_netmon_802_11_channel, proto_tree_add_uint(wlan_tree, hf_netmon_802_11_channel,
tvb, offset, 4, channel); tvb, offset, 4, channel);
switch (phdr->phy) { switch (phdr.phy) {
case PHDR_802_11_PHY_11B: case PHDR_802_11_PHY_11B:
case PHDR_802_11_PHY_11G: case PHDR_802_11_PHY_11G:
@ -260,19 +279,19 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
break; break;
} }
if (frequency != 0) { if (frequency != 0) {
phdr->has_frequency = TRUE; phdr.has_frequency = TRUE;
phdr->frequency = frequency; phdr.frequency = frequency;
} }
} }
} else { } else {
phdr->has_frequency = TRUE; phdr.has_frequency = TRUE;
phdr->frequency = channel; phdr.frequency = channel;
proto_tree_add_uint(wlan_tree, hf_netmon_802_11_frequency, proto_tree_add_uint(wlan_tree, hf_netmon_802_11_frequency,
tvb, offset, 4, channel); tvb, offset, 4, channel);
calc_channel = ieee80211_mhz_to_chan(channel); calc_channel = ieee80211_mhz_to_chan(channel);
if (calc_channel != -1) { if (calc_channel != -1) {
phdr->has_channel = TRUE; phdr.has_channel = TRUE;
phdr->channel = calc_channel; phdr.channel = calc_channel;
} }
} }
offset += 4; offset += 4;
@ -290,8 +309,8 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
tvb, offset, 4, rssi, tvb, offset, 4, rssi,
"Unknown"); "Unknown");
} else { } else {
phdr->has_signal_dbm = TRUE; phdr.has_signal_dbm = TRUE;
phdr->signal_dbm = rssi; phdr.signal_dbm = rssi;
proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi,
tvb, offset, 4, rssi, tvb, offset, 4, rssi,
"%d dBm", rssi); "%d dBm", rssi);
@ -307,8 +326,8 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
tvb, offset, 1, rate, tvb, offset, 1, rate,
"Unknown"); "Unknown");
} else { } else {
phdr->has_data_rate = TRUE; phdr.has_data_rate = TRUE;
phdr->data_rate = rate; phdr.data_rate = rate;
proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate,
tvb, offset, 1, rate, tvb, offset, 1, rate,
"%f Mb/s", rate*.5); "%f Mb/s", rate*.5);
@ -322,8 +341,8 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
* *
* If so, should this check the presense flag in flags? * If so, should this check the presense flag in flags?
*/ */
phdr->has_tsf_timestamp = TRUE; phdr.has_tsf_timestamp = TRUE;
phdr->tsf_timestamp = tvb_get_letoh64(tvb, offset); phdr.tsf_timestamp = tvb_get_letoh64(tvb, offset);
proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8, proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8,
ENC_LITTLE_ENDIAN); ENC_LITTLE_ENDIAN);
/*offset += 8;*/ /*offset += 8;*/
@ -333,7 +352,7 @@ skip:
/* dissect the 802.11 packet next */ /* dissect the 802.11 packet next */
next_tvb = tvb_new_subset_remaining(tvb, offset); next_tvb = tvb_new_subset_remaining(tvb, offset);
call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, phdr); call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, &phdr);
return offset; return offset;
} }

View File

@ -997,27 +997,12 @@ netmon_set_pseudo_header_info(wtap_rec *rec, Buffer *buf)
case WTAP_ENCAP_IEEE_802_11_NETMON: case WTAP_ENCAP_IEEE_802_11_NETMON:
/* /*
* It appears to be the case that management * The 802.11 metadata at the beginnning of the frame data
* frames (and control and extension frames ?) may * is processed by a dissector, which fills in a pseudo-
* or may not have an FCS and data frames don't. * header and passes it to the 802.11 radio dissector,
* (Netmon capture files have been seen for this * just as is done with other 802.11 radio metadata headers
* encapsulation having management frames either * that are part of the packet data, such as radiotap.
* completely with or without an FCS. Also: instances have been
* seen where both Management and Control frames
* do not have an FCS).
* An "FCS length" of -2 means "NetMon weirdness".
*
* The metadata header also has a bit indicating whether
* the adapter was in monitor mode or not; if it isn't,
* we set "decrypted" to TRUE, as, for those frames, the
* Protected bit is preserved in received frames, but
* the frame is decrypted.
*/ */
memset(&rec->rec_header.packet_header.pseudo_header.ieee_802_11, 0, sizeof(rec->rec_header.packet_header.pseudo_header.ieee_802_11));
rec->rec_header.packet_header.pseudo_header.ieee_802_11.fcs_len = -2;
rec->rec_header.packet_header.pseudo_header.ieee_802_11.decrypted = FALSE;
rec->rec_header.packet_header.pseudo_header.ieee_802_11.datapad = FALSE;
rec->rec_header.packet_header.pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN;
break; break;
} }
} }