diff options
author | Simon Barber <simon.barber@meraki.net> | 2016-01-06 17:23:00 -0800 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2017-04-30 13:22:50 +0000 |
commit | bb83fe45519eb280e6545ad69868e4e7f5fbef93 (patch) | |
tree | 997f88afebd94c1cd60ea22b28b1341e324b2c52 /epan/dissectors/packet-ieee80211-radio.c | |
parent | 7f2c6e13001bed11ae113b0aca47e562735d6e26 (diff) |
packet-ieee80211-radio.c: Minor refactor and whitespace cleanup
Change-Id: Idad8f7eeed968eeed9f553fef98d58453f328afb
Reviewed-on: https://code.wireshark.org/review/21421
Petri-Dish: Michael Mann <mmann78@netscape.net>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Tested-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-ieee80211-radio.c')
-rw-r--r-- | epan/dissectors/packet-ieee80211-radio.c | 622 |
1 files changed, 306 insertions, 316 deletions
diff --git a/epan/dissectors/packet-ieee80211-radio.c b/epan/dissectors/packet-ieee80211-radio.c index 5b847b38e5..ebe72fea5b 100644 --- a/epan/dissectors/packet-ieee80211-radio.c +++ b/epan/dissectors/packet-ieee80211-radio.c @@ -175,30 +175,30 @@ static const value_string fec_vals[] = { * Note: MCS 32 is special - only valid for 40Mhz channel. */ WS_DLL_PUBLIC_DEF const guint16 ieee80211_ht_Dbps[MAX_MCS_INDEX+1] = { - /* MCS 0 - 1 stream */ - 26, 52, 78, 104, 156, 208, 234, 260, + /* MCS 0 - 1 stream */ + 26, 52, 78, 104, 156, 208, 234, 260, - /* MCS 8 - 2 stream */ - 52, 104, 156, 208, 312, 416, 468, 520, + /* MCS 8 - 2 stream */ + 52, 104, 156, 208, 312, 416, 468, 520, - /* MCS 16 - 3 stream */ - 78, 156, 234, 312, 468, 624, 702, 780, + /* MCS 16 - 3 stream */ + 78, 156, 234, 312, 468, 624, 702, 780, - /* MCS 24 - 4 stream */ - 104, 208, 312, 416, 624, 832, 936, 1040, + /* MCS 24 - 4 stream */ + 104, 208, 312, 416, 624, 832, 936, 1040, - /* MCS 32 - 1 stream */ - 12, /* only valid for 40Mhz - 11a/g DUP mode */ + /* MCS 32 - 1 stream */ + 12, /* only valid for 40Mhz - 11a/g DUP mode */ - /* MCS 33 - 2 stream */ - 156, 208, 260, 234, 312, 390, + /* MCS 33 - 2 stream */ + 156, 208, 260, 234, 312, 390, - /* MCS 39 - 3 stream */ - 208, 260, 260, 312, 364, 364, 416, 312, 390, 390, 468, 546, 546, 624, + /* MCS 39 - 3 stream */ + 208, 260, 260, 312, 364, 364, 416, 312, 390, 390, 468, 546, 546, 624, - /* MCS 53 - 4 stream */ - 260, 312, 364, 312, 364, 416, 468, 416, 468, 520, 520, 572, - 390, 468, 546, 468, 546, 624, 702, 624, 702, 780, 780, 858 + /* MCS 53 - 4 stream */ + 260, 312, 364, 312, 364, 416, 468, 416, 468, 520, 520, 572, + 390, 468, 546, 468, 546, 624, 702, 624, 702, 780, 780, 858 }; /* @@ -379,12 +379,15 @@ static void dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *data) { struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; - proto_item *ti = NULL; - proto_tree *radio_tree = NULL; + proto_item *ti; + proto_tree *radio_tree; float data_rate = 0.0f; gboolean have_data_rate = FALSE; gboolean has_short_preamble = FALSE; gboolean short_preamble = 1; + guint bandwidth = 0; + gboolean can_calculate_rate = FALSE; + proto_item *p_item; guint frame_length = tvb_reported_length(tvb); /* length of 802.11 frame data */ @@ -392,6 +395,9 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint preamble = 0; /* duration of plcp */ guint duration = 0; /* duration of whole frame (plcp + mac data + any trailing parts) */ + int phy = phdr->phy; + union ieee_802_11_phy_info *phy_info = &phdr->phy_info; + col_set_str(pinfo->cinfo, COL_PROTOCOL, "Radio"); col_clear(pinfo->cinfo, COL_INFO); @@ -407,19 +413,17 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, col_add_fstr(pinfo->cinfo, COL_RSSI, "%u%%", phdr->signal_percent); } - if (tree) { - ti = proto_tree_add_item(tree, proto_wlan_radio, tvb, 0, 0, ENC_NA); - radio_tree = proto_item_add_subtree (ti, ett_wlan_radio); + ti = proto_tree_add_item(tree, proto_wlan_radio, tvb, 0, 0, ENC_NA); + radio_tree = proto_item_add_subtree (ti, ett_wlan_radio); - if (phdr->phy != PHDR_802_11_PHY_UNKNOWN) { - proto_tree_add_uint(radio_tree, hf_wlan_radio_phy, tvb, 0, 0, - phdr->phy); + if (phy != PHDR_802_11_PHY_UNKNOWN) { + proto_tree_add_uint(radio_tree, hf_wlan_radio_phy, tvb, 0, 0, phy); - switch (phdr->phy) { + switch (phy) { case PHDR_802_11_PHY_11_FHSS: { - struct ieee_802_11_fhss *info_fhss = &phdr->phy_info.info_11_fhss; + struct ieee_802_11_fhss *info_fhss = &phy_info->info_11_fhss; if (info_fhss->has_hop_set) { proto_tree_add_uint(radio_tree, hf_wlan_radio_11_fhss_hop_set, tvb, 0, 0, @@ -438,7 +442,7 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, case PHDR_802_11_PHY_11B: { - struct ieee_802_11b *info_b = &phdr->phy_info.info_11b; + struct ieee_802_11b *info_b = &phy_info->info_11b; has_short_preamble = info_b->has_short_preamble; short_preamble = info_b->short_preamble; @@ -452,7 +456,7 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, case PHDR_802_11_PHY_11A: { - struct ieee_802_11a *info_a = &phdr->phy_info.info_11a; + struct ieee_802_11a *info_a = &phy_info->info_11a; if (info_a->has_channel_type) { proto_tree_add_uint(radio_tree, hf_wlan_radio_11a_channel_type, tvb, 0, 0, @@ -467,7 +471,7 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, case PHDR_802_11_PHY_11G: { - struct ieee_802_11g *info_g = &phdr->phy_info.info_11g; + struct ieee_802_11g *info_g = &phy_info->info_11g; has_short_preamble = info_g->has_short_preamble; short_preamble = info_g->short_preamble; @@ -485,9 +489,23 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, case PHDR_802_11_PHY_11N: { - struct ieee_802_11n *info_n = &phdr->phy_info.info_11n; + struct ieee_802_11n *info_n = &phy_info->info_11n; guint bandwidth_40; + /* + * If we have all the fields needed to look up the data rate, + * do so. + */ + if (info_n->has_mcs_index && + info_n->has_bandwidth && + info_n->has_short_gi) { + bandwidth_40 = (info_n->bandwidth == PHDR_802_11_BANDWIDTH_40_MHZ) ? 1 : 0; + if (info_n->mcs_index < MAX_MCS_INDEX) { + data_rate = ieee80211_htrate(info_n->mcs_index, bandwidth_40, info_n->short_gi); + have_data_rate = TRUE; + } + } + if (info_n->has_mcs_index) { proto_tree_add_uint(radio_tree, hf_wlan_radio_11n_mcs_index, tvb, 0, 0, info_n->mcs_index); @@ -522,32 +540,44 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, proto_tree_add_uint(radio_tree, hf_wlan_radio_11n_ness, tvb, 0, 0, info_n->ness); } - - /* - * If we have all the fields needed to look up the data rate, - * do so. - */ - if (info_n->has_mcs_index && - info_n->has_bandwidth && - info_n->has_short_gi) { - bandwidth_40 = - (info_n->bandwidth == PHDR_802_11_BANDWIDTH_40_MHZ) ? - 1 : 0; - if (info_n->mcs_index <= MAX_MCS_INDEX) { - data_rate = ieee80211_htrate(info_n->mcs_index, bandwidth_40, info_n->short_gi); - have_data_rate = TRUE; - } - } } break; case PHDR_802_11_PHY_11AC: { - struct ieee_802_11ac *info_ac = &phdr->phy_info.info_11ac; - gboolean can_calculate_rate; - guint bandwidth = 0; + struct ieee_802_11ac *info_ac = &phy_info->info_11ac; guint i; + if (info_ac->has_short_gi) { + can_calculate_rate = TRUE; /* well, if we also have the bandwidth */ + proto_tree_add_boolean(radio_tree, hf_wlan_radio_11ac_short_gi, tvb, 0, 0, info_ac->short_gi); + } else { + can_calculate_rate = FALSE; /* unknown GI length */ + } + + if (info_ac->has_bandwidth) { + proto_tree_add_uint(radio_tree, hf_wlan_radio_11ac_bandwidth, tvb, 0, 0, info_ac->bandwidth); + if (info_ac->bandwidth < G_N_ELEMENTS(ieee80211_vht_bw2rate_index)) + bandwidth = ieee80211_vht_bw2rate_index[info_ac->bandwidth]; + else + can_calculate_rate = FALSE; /* unknown bandwidth */ + } else { + can_calculate_rate = FALSE; /* no bandwidth */ + } + + for (i = 0; i < 4; i++) { + + if (info_ac->nss[i] != 0) { + /* + * If we can calculate the data rate for this user, do so. + */ + if (can_calculate_rate && info_ac->mcs[i] <= MAX_MCS_VHT_INDEX) { + data_rate = ieee80211_vhtrate(info_ac->mcs[i], bandwidth, info_ac->short_gi) * info_ac->nss[i]; + have_data_rate = TRUE; + } + } + } + if (info_ac->has_stbc) { proto_tree_add_boolean(radio_tree, hf_wlan_radio_11ac_stbc, tvb, 0, 0, info_ac->stbc); @@ -558,14 +588,6 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, info_ac->txop_ps_not_allowed); } - if (info_ac->has_short_gi) { - can_calculate_rate = TRUE; /* well, if we also have the bandwidth */ - proto_tree_add_boolean(radio_tree, hf_wlan_radio_11ac_short_gi, tvb, 0, 0, - info_ac->short_gi); - } else { - can_calculate_rate = FALSE; /* unknown GI length */ - } - if (info_ac->has_short_gi_nsym_disambig) { proto_tree_add_boolean(radio_tree, hf_wlan_radio_11ac_short_gi_nsym_disambig, tvb, 0, 0, info_ac->short_gi_nsym_disambig); @@ -581,17 +603,6 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, info_ac->beamformed); } - if (info_ac->has_bandwidth) { - if (info_ac->bandwidth < G_N_ELEMENTS(ieee80211_vht_bw2rate_index)) - bandwidth = ieee80211_vht_bw2rate_index[info_ac->bandwidth]; - else - can_calculate_rate = FALSE; /* unknown bandwidth */ - proto_tree_add_uint(radio_tree, hf_wlan_radio_11ac_bandwidth, tvb, 0, 0, - info_ac->bandwidth); - } else { - can_calculate_rate = FALSE; /* no bandwidth */ - } - for (i = 0; i < 4; i++) { if (info_ac->nss[i] != 0) { @@ -661,267 +672,249 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, } } break; - } } + } - if (have_data_rate) { - col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%.1f", data_rate); - proto_tree_add_float_format_value(radio_tree, hf_wlan_radio_data_rate, tvb, 0, 0, + if (have_data_rate) { + col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%.1f", data_rate); + proto_tree_add_float_format_value(radio_tree, hf_wlan_radio_data_rate, tvb, 0, 0, data_rate, "%.1f Mb/s", data_rate); - } + } - if (phdr->has_channel) { - col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u", phdr->channel); - proto_tree_add_uint(radio_tree, hf_wlan_radio_channel, tvb, 0, 0, - phdr->channel); - } + if (phdr->has_channel) { + col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u", phdr->channel); + proto_tree_add_uint(radio_tree, hf_wlan_radio_channel, tvb, 0, 0, phdr->channel); + } - if (phdr->has_frequency) { - col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u MHz", phdr->frequency); - proto_tree_add_uint_format_value(radio_tree, hf_wlan_radio_frequency, tvb, 0, 0, - phdr->frequency, - "%u MHz", - phdr->frequency); - } + if (phdr->has_frequency) { + col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u MHz", phdr->frequency); + proto_tree_add_uint(radio_tree, hf_wlan_radio_frequency, tvb, 0, 0, phdr->frequency); + } - if (phdr->has_signal_percent) { - col_add_fstr(pinfo->cinfo, COL_RSSI, "%u%%", phdr->signal_percent); - proto_tree_add_uint(radio_tree, hf_wlan_radio_signal_percent, tvb, 0, 0, phdr->signal_percent); - } + if (phdr->has_signal_percent) { + col_add_fstr(pinfo->cinfo, COL_RSSI, "%u%%", phdr->signal_percent); + proto_tree_add_uint(radio_tree, hf_wlan_radio_signal_percent, tvb, 0, 0, phdr->signal_percent); + } - if (phdr->has_signal_dbm) { - col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", phdr->signal_dbm); - proto_tree_add_int(radio_tree, hf_wlan_radio_signal_dbm, tvb, 0, 0, phdr->signal_dbm); - } + if (phdr->has_signal_dbm) { + col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", phdr->signal_dbm); + proto_tree_add_int(radio_tree, hf_wlan_radio_signal_dbm, tvb, 0, 0, phdr->signal_dbm); + } - if (phdr->has_noise_percent) { - proto_tree_add_uint(radio_tree, hf_wlan_radio_noise_percent, tvb, 0, 0, phdr->noise_percent); - } + if (phdr->has_noise_percent) { + proto_tree_add_uint(radio_tree, hf_wlan_radio_noise_percent, tvb, 0, 0, phdr->noise_percent); + } - if (phdr->has_noise_dbm) { - proto_tree_add_int(radio_tree, hf_wlan_radio_noise_dbm, tvb, 0, 0, phdr->noise_dbm); - } + if (phdr->has_noise_dbm) { + proto_tree_add_int(radio_tree, hf_wlan_radio_noise_dbm, tvb, 0, 0, phdr->noise_dbm); + } - if (phdr->has_tsf_timestamp) { - proto_tree_add_uint64(radio_tree, hf_wlan_radio_timestamp, tvb, 0, 0, - phdr->tsf_timestamp); - } - if (phdr->has_aggregate_info) { - proto_tree_add_boolean(radio_tree, hf_wlan_last_part_of_a_mpdu, tvb, 0, 0, - (phdr->aggregate_flags & PHDR_802_11_LAST_PART_OF_A_MPDU) ? - TRUE : FALSE); - proto_tree_add_boolean(radio_tree, hf_wlan_a_mpdu_delim_crc_error, tvb, 0, 0, - (phdr->aggregate_flags & PHDR_802_11_A_MPDU_DELIM_CRC_ERROR) ? - TRUE : FALSE); - proto_tree_add_uint(radio_tree, hf_wlan_a_mpdu_aggregate_id, tvb, 0, 0, - phdr->aggregate_id); + if (phdr->has_tsf_timestamp) { + proto_tree_add_uint64(radio_tree, hf_wlan_radio_timestamp, tvb, 0, 0, phdr->tsf_timestamp); + } + if (phdr->has_aggregate_info) { + proto_tree_add_boolean(radio_tree, hf_wlan_last_part_of_a_mpdu, tvb, 0, 0, phdr->aggregate_flags); + proto_tree_add_boolean(radio_tree, hf_wlan_a_mpdu_delim_crc_error, tvb, 0, 0, phdr->aggregate_flags); + proto_tree_add_uint(radio_tree, hf_wlan_a_mpdu_aggregate_id, tvb, 0, 0, phdr->aggregate_id); + } + + if (have_data_rate) { + /* duration calculations */ + gboolean assumed_short_preamble = FALSE; + gboolean assumed_non_greenfield = FALSE; + gboolean assumed_no_stbc = FALSE; + gboolean assumed_no_extension_streams = FALSE; + gboolean assumed_bcc_fec = FALSE; + + /* some generators report CCK frames as 'dynamic-cck-ofdm', which are converted + * into the 11g PHY type, so we need to be smart and recognize which ones are + * DSSS/CCK and which are OFDM. Use the data_rate to do this. */ + if (phy == PHDR_802_11_PHY_11G && + (data_rate == 1.0f || data_rate == 2.0f || + data_rate == 5.5f || data_rate == 11.0f || + data_rate == 22.0f || data_rate == 33.0f)) { + phy = PHDR_802_11_PHY_11B; } - if (have_data_rate) { - gboolean assumed_short_preamble = FALSE; - gboolean assumed_non_greenfield = FALSE; - gboolean assumed_no_stbc = FALSE; - gboolean assumed_no_extension_streams = FALSE; - gboolean assumed_bcc_fec = FALSE; - - /* some generators report CCK frames as 'dynamic-cck-ofdm', which are converted - * into the 11g PHY type, so we need to be smart and recognize which ones are - * DSSS/CCK and which are OFDM. Use the data_rate to do this. */ - int phy = phdr->phy; - if (phy == PHDR_802_11_PHY_11G && - (data_rate == 1.0f || data_rate == 2.0f || - data_rate == 5.5f || data_rate == 11.0f || - data_rate == 22.0f || data_rate == 33.0f)) { - phy = PHDR_802_11_PHY_11B; - } + switch (phy) { - switch (phy) { + case PHDR_802_11_PHY_11_FHSS: + /* TODO: preamble/duration calc for FHSS */ + break; - case PHDR_802_11_PHY_11_FHSS: - break; - - case PHDR_802_11_PHY_11B: - if (!has_short_preamble || wlan_radio_always_short_preamble) { - assumed_short_preamble = TRUE; - short_preamble = TRUE; - } - preamble = short_preamble ? 72 + 24 : 144 + 48; + case PHDR_802_11_PHY_11B: + if (!has_short_preamble || wlan_radio_always_short_preamble) { + assumed_short_preamble = TRUE; + short_preamble = TRUE; + } + preamble = short_preamble ? 72 + 24 : 144 + 48; + + /* calculation of frame duration + * Things we need to know to calculate accurate duration + * 802.11 / 802.11b (DSSS or CCK modulation) + * - length of preamble + * - rate + */ + /* round up to whole microseconds */ + duration = (guint) ceil(preamble + frame_length * 8 / data_rate); + break; + + case PHDR_802_11_PHY_11A: + case PHDR_802_11_PHY_11G: + { + /* OFDM rate */ + /* calculation of frame duration + * Things we need to know to calculate accurate duration + * 802.11a / 802.11g (OFDM modulation) + * - rate + */ + + /* preamble + signal */ + preamble = 16 + 4; + + /* 16 service bits, data and 6 tail bits */ + guint bits = 16 + 8 * frame_length + 6; + guint symbols = (guint) ceil(bits / (data_rate * 4)); + + duration = preamble + symbols * 4; + break; + } - /* calculation of frame duration - * Things we need to know to calculate accurate duration - * 802.11 / 802.11b (DSSS or CCK modulation) - * - length of preamble - * - rate - */ - /* round up to whole microseconds */ - duration = (guint) ceil(preamble + frame_length * 8 / data_rate); + case PHDR_802_11_PHY_11N: + { + struct ieee_802_11n *info_n = &phdr->phy_info.info_11n; + + /* We have all the fields required to calculate the duration */ + static const guint Nhtdltf[4] = {1, 2, 4, 4}; + static const guint Nhteltf[4] = {0, 1, 2, 4}; + guint Nsts; + guint stbc_streams; + guint ness; + + /* + * If we don't have necessary fields, or if we have them but + * they have invalid values, then bail. + */ + if (!info_n->has_mcs_index || + info_n->mcs_index > MAX_MCS_INDEX || + !info_n->has_bandwidth || + !info_n->has_short_gi) break; - case PHDR_802_11_PHY_11A: - case PHDR_802_11_PHY_11G: - { - /* OFDM rate */ - /* calculation of frame duration - * Things we need to know to calculate accurate duration - * 802.11a / 802.11g (OFDM modulation) - * - rate - */ - - /* 16 service bits, data and 6 tail bits */ - guint bits = 16 + 8 * frame_length + 6; - guint symbols = (guint) ceil(bits / (data_rate * 4)); + /* calculation of frame duration + * Things we need to know to calculate accurate duration + * 802.11n / HT + * - whether frame preamble is mixed or greenfield, (assume mixed) + * - guard interval, 800ns or 400ns + * - bandwidth, 20Mhz or 40Mhz + * - MCS index - used with previous 2 to calculate rate + * - how many additional STBC streams are used (assume 0) + * - how many optional extension spatial streams are used (assume 0) + * - whether BCC or LDCP coding is used (assume BCC) + */ + + /* preamble duration + * see ieee802.11n-2009 Figure 20-1 - PPDU format + * for HT-mixed format + * L-STF 8us, L-LTF 8us, L-SIG 4us, HT-SIG 8us, HT_STF 4us + * for HT-greenfield + * HT-GF-STF 8us, HT-LTF1 8us, HT_SIG 8us + */ + if (info_n->has_greenfield) { + preamble = info_n->greenfield ? 24 : 32; + } else { + preamble = 32; + assumed_non_greenfield = TRUE; + } - /* preamble + signal */ - preamble = 16 + 4; + if (info_n->has_stbc_streams) { + stbc_streams = info_n->stbc_streams; + } else { + stbc_streams = 0; + assumed_no_stbc = TRUE; + } - duration = preamble + symbols * 4; - break; + if (info_n->has_ness) { + ness = info_n->ness; + if (ness >= G_N_ELEMENTS(Nhteltf)) { + /* Not valid */ + break; } + } else { + ness = 0; + assumed_no_extension_streams = TRUE; + } - case PHDR_802_11_PHY_11N: - { - struct ieee_802_11n *info_n = &phdr->phy_info.info_11n; - guint bandwidth_40; - - /* We have all the fields required to calculate the duration */ - static const guint Nhtdltf[4] = {1, 2, 4, 4}; - static const guint Nhteltf[4] = {0, 1, 2, 4}; - guint Nsts, bits, Mstbc, bits_per_symbol, symbols; - guint stbc_streams; - guint ness; - - /* - * If we don't have necessary fields, or if we have them but - * they have invalid values, then bail. - */ - if (!info_n->has_mcs_index || - info_n->mcs_index > MAX_MCS_INDEX || - !info_n->has_bandwidth || - !info_n->has_short_gi) - break; - - bandwidth_40 = info_n->bandwidth == PHDR_802_11_BANDWIDTH_40_MHZ; - - /* calculation of frame duration - * Things we need to know to calculate accurate duration - * 802.11n / HT - * - whether frame preamble is mixed or greenfield, (assume mixed) - * - guard interval, 800ns or 400ns - * - bandwidth, 20Mhz or 40Mhz - * - MCS index - used with previous 2 to calculate rate - * - how many additional STBC streams are used (assume 0) - * - how many optional extension spatial streams are used (assume 0) - * - whether BCC or LDCP coding is used (assume BCC) - */ - - /* preamble duration - * see ieee802.11n-2009 Figure 20-1 - PPDU format - * for HT-mixed format - * L-STF 8us, L-LTF 8us, L-SIG 4us, HT-SIG 8us, HT_STF 4us - * for HT-greenfield - * HT-GF-STF 8us, HT-LTF1 8us, HT_SIG 8us - */ - if (info_n->has_greenfield) { - preamble = info_n->greenfield ? 24 : 32; - } else { - preamble = 32; - assumed_non_greenfield = TRUE; - } - - if (info_n->has_stbc_streams) { - stbc_streams = info_n->stbc_streams; - } else { - stbc_streams = 0; - assumed_no_stbc = TRUE; - } - - if (info_n->has_ness) { - ness = info_n->ness; - if (ness >= G_N_ELEMENTS(Nhteltf)) { - /* Not valid */ - break; - } - } else { - ness = 0; - assumed_no_extension_streams = TRUE; - } + /* calculate number of HT-LTF training symbols. + * see ieee80211n-2009 20.3.9.4.6 table 20-11 */ + Nsts = ieee80211_ht_streams[info_n->mcs_index] + stbc_streams; + if (Nsts == 0 || Nsts - 1 >= G_N_ELEMENTS(Nhtdltf)) { + /* Not usable */ + break; + } + preamble += 4 * (Nhtdltf[Nsts-1] + Nhteltf[ness]); - /* calculate number of HT-LTF training symbols. - * see ieee80211n-2009 20.3.9.4.6 table 20-11 */ - Nsts = ieee80211_ht_streams[info_n->mcs_index] + stbc_streams; - if (Nsts == 0 || Nsts - 1 >= G_N_ELEMENTS(Nhtdltf)) { - /* Not usable */ - break; - } - preamble += 4 * (Nhtdltf[Nsts-1] + Nhteltf[ness]); + if (info_n->has_stbc_streams) { + stbc_streams = info_n->stbc_streams; + } else { + stbc_streams = 0; + assumed_no_stbc = TRUE; + } - if (!info_n->has_fec) { - assumed_bcc_fec = TRUE; - } + if (info_n->has_ness) { + ness = info_n->ness; + } else { + ness = 0; + assumed_no_extension_streams = TRUE; + } - /* data field calculation */ - /* see ieee80211n-2009 20.3.11 (20-32) - for BCC FEC */ - /* TODO: handle LDPC FEC (info_n->fec == 1), it changes the rounding - * Currently this is the same logic as BCC */ - bits = 8 * frame_length + 16 + ieee80211_ht_Nes[info_n->mcs_index] * 6; - Mstbc = stbc_streams ? 2 : 1; - bits_per_symbol = ieee80211_ht_Dbps[info_n->mcs_index] * (bandwidth_40 ? 2 : 1); - symbols = bits / (bits_per_symbol * Mstbc); - - /* round up to whole symbols */ - if((bits % (bits_per_symbol * Mstbc)) > 0) - symbols++; - - symbols *= Mstbc; - duration = preamble + (symbols * (info_n->short_gi ? 36 : 40) + 5) / 10; - break; - } + /* calculate number of HT-LTF training symbols. + * see ieee80211n-2009 20.3.9.4.6 table 20-11 */ + Nsts = ieee80211_ht_streams[info_n->mcs_index] + stbc_streams; + preamble += 4 * (Nhtdltf[Nsts-1] + Nhteltf[ness]); - case PHDR_802_11_PHY_11AC: - { - struct ieee_802_11ac *info_ac = &phdr->phy_info.info_11ac; - int bits, stbc; + if (!info_n->has_fec) { + assumed_bcc_fec = TRUE; + } + break; + } - /* TODO: this is a crude quick hack, need proper calculation of bits/symbols/FEC/rounding/etc */ - if (info_ac->has_stbc) { - stbc = info_ac->stbc; - } else { - stbc = 0; - assumed_no_stbc = TRUE; - } + case PHDR_802_11_PHY_11AC: + { + struct ieee_802_11ac *info_ac = &phy_info->info_11ac; - preamble = 32 + 4 * info_ac->nss[0] * (stbc+1); - bits = 8 * frame_length + 16; - duration = (guint) (preamble + bits / data_rate); - break; - } + if (!info_ac->has_stbc) { + assumed_no_stbc = TRUE; } + preamble = 32 + 4 * info_ac->nss[0] * (info_ac->has_stbc ? info_ac->stbc+1 : 1); + break; + } + } if (duration) { - proto_item *item = proto_tree_add_uint(radio_tree, hf_wlan_radio_duration, tvb, 0, 0, duration); - PROTO_ITEM_SET_GENERATED(item); - - if (assumed_short_preamble) - expert_add_info(pinfo, item, &ei_wlan_radio_assumed_short_preamble); - if (assumed_non_greenfield) - expert_add_info(pinfo, item, &ei_wlan_radio_assumed_non_greenfield); - if (assumed_no_stbc) - expert_add_info(pinfo, item, &ei_wlan_radio_assumed_no_stbc); - if (assumed_no_extension_streams) - expert_add_info(pinfo, item, &ei_wlan_radio_assumed_no_extension_streams); - if (assumed_bcc_fec) - expert_add_info(pinfo, item, &ei_wlan_radio_assumed_bcc_fec); - - if (preamble) { - proto_tree *d_tree = proto_item_add_subtree(item, ett_wlan_radio_duration); - proto_item *p_item = proto_tree_add_uint(d_tree, hf_wlan_radio_preamble, tvb, 0, 0, preamble); - PROTO_ITEM_SET_GENERATED(p_item); - } + proto_item *item = proto_tree_add_uint(radio_tree, hf_wlan_radio_duration, tvb, 0, 0, duration); + proto_tree *d_tree = proto_item_add_subtree(item, ett_wlan_radio_duration); + PROTO_ITEM_SET_GENERATED(item); + + if (assumed_short_preamble) + expert_add_info(pinfo, item, &ei_wlan_radio_assumed_short_preamble); + if (assumed_non_greenfield) + expert_add_info(pinfo, item, &ei_wlan_radio_assumed_non_greenfield); + if (assumed_no_stbc) + expert_add_info(pinfo, item, &ei_wlan_radio_assumed_no_stbc); + if (assumed_no_extension_streams) + expert_add_info(pinfo, item, &ei_wlan_radio_assumed_no_extension_streams); + if (assumed_bcc_fec) + expert_add_info(pinfo, item, &ei_wlan_radio_assumed_bcc_fec); + + if (preamble) { + p_item = proto_tree_add_uint(d_tree, hf_wlan_radio_preamble, tvb, 0, 0, preamble); + PROTO_ITEM_SET_GENERATED(p_item); } } - } /* if (tree) */ + } /* if (have_data_rate) */ } /* @@ -950,7 +943,9 @@ dissect_wlan_noqos_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree return call_dissector_with_data(ieee80211_noqos_handle, tvb, pinfo, tree, data); } -static hf_register_info hf_wlan_radio[] = { +void proto_register_ieee80211_radio(void) +{ + static hf_register_info hf_wlan_radio[] = { {&hf_wlan_radio_phy, {"PHY type", "wlan_radio.phy", FT_UINT32, BASE_DEC, VALS(phy_vals), 0, NULL, HFILL }}, @@ -1100,11 +1095,11 @@ static hf_register_info hf_wlan_radio[] = { NULL, HFILL }}, {&hf_wlan_last_part_of_a_mpdu, - {"Last part of an A-MPDU", "wlan_radio.last_part_of_an_ampdu", FT_BOOLEAN, 0, NULL, 0, + {"Last part of an A-MPDU", "wlan_radio.last_part_of_an_ampdu", FT_BOOLEAN, 32, NULL, PHDR_802_11_LAST_PART_OF_A_MPDU, "This is the last part of an A-MPDU", HFILL }}, {&hf_wlan_a_mpdu_delim_crc_error, - {"A-MPDU delimiter CRC error", "wlan_radio.a_mpdu_delim_crc_error", FT_BOOLEAN, 0, NULL, 0, + {"A-MPDU delimiter CRC error", "wlan_radio.a_mpdu_delim_crc_error", FT_BOOLEAN, 32, NULL, PHDR_802_11_A_MPDU_DELIM_CRC_ERROR, NULL, HFILL }}, {&hf_wlan_a_mpdu_aggregate_id, @@ -1119,10 +1114,15 @@ static hf_register_info hf_wlan_radio[] = { {&hf_wlan_radio_preamble, {"Preamble", "wlan_radio.preamble", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, &units_microseconds, 0, "Duration of the PLCP or preamble in microseconds, calculated from PHY data", HFILL }}, + }; -}; + static gint *ett[] = { + &ett_wlan_radio, + &ett_wlan_radio_11ac_user, + &ett_wlan_radio_duration, + }; -static ei_register_info ei[] = { + static ei_register_info ei[] = { { &ei_wlan_radio_assumed_short_preamble, { "wlan_radio.assumed.short_preamble", PI_ASSUMPTION, PI_WARN, "No preamble length information was available, assuming short preamble.", EXPFILL }}, @@ -1142,23 +1142,14 @@ static ei_register_info ei[] = { { &ei_wlan_radio_assumed_bcc_fec, { "wlan_radio.assumed.bcc_fec", PI_ASSUMPTION, PI_WARN, "No fec type information was available, assuming bcc fec.", EXPFILL }}, -}; + }; -module_t *wlan_radio_module; -expert_module_t* expert_wlan_radio; + module_t *wlan_radio_module; + expert_module_t* expert_wlan_radio; -static gint *tree_array[] = { - &ett_wlan_radio, - &ett_wlan_radio_11ac_user, - &ett_wlan_radio_duration -}; - -void proto_register_ieee80211_radio(void) -{ - proto_wlan_radio = proto_register_protocol("802.11 radio information", "802.11 Radio", - "wlan_radio"); + proto_wlan_radio = proto_register_protocol("802.11 radio information", "802.11 Radio", "wlan_radio"); proto_register_field_array(proto_wlan_radio, hf_wlan_radio, array_length(hf_wlan_radio)); - proto_register_subtree_array(tree_array, array_length(tree_array)); + proto_register_subtree_array(ett, array_length(ett)); expert_wlan_radio = expert_register_protocol(proto_wlan_radio); expert_register_field_array(expert_wlan_radio, ei, array_length(ei)); @@ -1172,7 +1163,6 @@ void proto_register_ieee80211_radio(void) "Some generators incorrectly indicate long preamble when the preamble was actually" "short. Always assume short preamble when calculating duration.", &wlan_radio_always_short_preamble); - } void proto_reg_handoff_ieee80211_radio(void) |