diff options
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-aruba-erm.c | 75 | ||||
-rw-r--r-- | epan/dissectors/packet-cisco-wids.c | 15 | ||||
-rw-r--r-- | epan/dissectors/packet-ieee80211-airopeek.c | 19 | ||||
-rw-r--r-- | epan/dissectors/packet-ieee80211-netmon.c | 142 | ||||
-rw-r--r-- | epan/dissectors/packet-ieee80211-radio.c | 183 | ||||
-rw-r--r-- | epan/dissectors/packet-ieee80211-radiotap.c | 97 | ||||
-rw-r--r-- | epan/dissectors/packet-ieee80211.c | 126 | ||||
-rw-r--r-- | epan/dissectors/packet-ixveriwave.c | 29 | ||||
-rw-r--r-- | epan/dissectors/packet-peekremote.c | 63 | ||||
-rw-r--r-- | epan/dissectors/packet-ppi.c | 122 |
10 files changed, 560 insertions, 311 deletions
diff --git a/epan/dissectors/packet-aruba-erm.c b/epan/dissectors/packet-aruba-erm.c index 931c031d69..fffb839b16 100644 --- a/epan/dissectors/packet-aruba-erm.c +++ b/epan/dissectors/packet-aruba-erm.c @@ -89,6 +89,8 @@ #include "config.h" +#include <wiretap/wtap.h> + #include <epan/packet.h> #include <epan/expert.h> #include <epan/prefs.h> @@ -151,8 +153,8 @@ static dissector_handle_t aruba_erm_handle_type1; static dissector_handle_t aruba_erm_handle_type2; static dissector_handle_t aruba_erm_handle_type3; static dissector_handle_t aruba_erm_handle_type4; -static dissector_handle_t wlan_withoutfcs; -static dissector_handle_t wlan_withfcs; +static dissector_handle_t wlan_radio_handle; +static dissector_handle_t wlan_withfcs_handle; static dissector_handle_t peek_handle; static dissector_handle_t ppi_handle; static dissector_handle_t data_handle; @@ -177,30 +179,6 @@ dissect_aruba_erm_pcap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *aruba_ return offset; } -static int -dissect_aruba_erm_pcap_radio(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *aruba_erm_tree, gint offset, guint32 *signal_strength) -{ - proto_item *ti_data_rate; - guint16 data_rate; - - data_rate = tvb_get_ntohs(tvb, offset); - proto_tree_add_item(aruba_erm_tree, hf_aruba_erm_data_rate, tvb, offset, 2, ENC_BIG_ENDIAN); - ti_data_rate = proto_tree_add_float_format(aruba_erm_tree, hf_aruba_erm_data_rate_gen, - tvb, 16, 2, - (float)data_rate / 2, - "Data Rate: %.1f Mb/s", - (float)data_rate / 2); - PROTO_ITEM_SET_GENERATED(ti_data_rate); - offset += 2; - - proto_tree_add_item(aruba_erm_tree, hf_aruba_erm_channel, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - - proto_tree_add_item_ret_uint(aruba_erm_tree, hf_aruba_erm_signal_strength, tvb, offset, 1, ENC_BIG_ENDIAN, signal_strength); - offset += 1; - - return offset; -} static proto_tree * dissect_aruba_erm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset _U_) @@ -257,7 +235,7 @@ dissect_aruba_erm_type0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) next_tvb = tvb_new_subset_remaining(tvb, offset); /* No way to determine if TX or RX packet... (TX = no FCS, RX = FCS...)*/ - call_dissector(wlan_withfcs, next_tvb, pinfo, tree); + call_dissector(wlan_withfcs_handle, next_tvb, pinfo, tree); } @@ -292,22 +270,51 @@ dissect_aruba_erm_type3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) tvbuff_t * next_tvb; int offset = 0; proto_tree *aruba_erm_tree; + struct ieee_802_11_phdr phdr; guint32 signal_strength; + proto_item *ti_data_rate; + guint16 data_rate; + guint channel; aruba_erm_tree = dissect_aruba_erm_common(tvb, pinfo, tree, &offset); - offset = dissect_aruba_erm_pcap(tvb, pinfo, aruba_erm_tree, offset); - offset = dissect_aruba_erm_pcap_radio(tvb, pinfo, aruba_erm_tree, offset, &signal_strength); + + phdr.decrypted = FALSE; + phdr.presence_flags |= + PHDR_802_11_HAS_DATA_RATE| + PHDR_802_11_HAS_CHANNEL| + PHDR_802_11_HAS_SIGNAL_PERCENT; + data_rate = tvb_get_ntohs(tvb, offset); + phdr.data_rate = data_rate; + proto_tree_add_item(aruba_erm_tree, hf_aruba_erm_data_rate, tvb, offset, 2, ENC_BIG_ENDIAN); + ti_data_rate = proto_tree_add_float_format(aruba_erm_tree, hf_aruba_erm_data_rate_gen, + tvb, 16, 2, + (float)data_rate / 2, + "Data Rate: %.1f Mb/s", + (float)data_rate / 2); + PROTO_ITEM_SET_GENERATED(ti_data_rate); + offset += 2; + + proto_tree_add_item_ret_uint(aruba_erm_tree, hf_aruba_erm_channel, tvb, offset, 1, ENC_BIG_ENDIAN, &channel); + phdr.channel = channel; + offset += 1; + + proto_tree_add_item_ret_uint(aruba_erm_tree, hf_aruba_erm_signal_strength, tvb, offset, 1, ENC_BIG_ENDIAN, &signal_strength); + phdr.signal_percent = signal_strength; + offset += 1; + proto_item_set_len(aruba_erm_tree, offset); next_tvb = tvb_new_subset_remaining(tvb, offset); if(signal_strength == 100){ /* When signal = 100 %, it is TX packet and there is no FCS */ - call_dissector(wlan_withoutfcs, next_tvb, pinfo, tree); + phdr.fcs_len = 0; /* TX packet, no FCS */ } else { - call_dissector(wlan_withfcs, next_tvb, pinfo, tree); + phdr.fcs_len = 4; /* We have an FCS */ } - + phdr.decrypted = FALSE; + phdr.datapad = FALSE; + call_dissector_with_data(wlan_radio_handle, next_tvb, pinfo, tree, &phdr); } static void @@ -446,8 +453,8 @@ proto_reg_handoff_aruba_erm(void) static gboolean initialized = FALSE; if (!initialized) { - wlan_withoutfcs = find_dissector("wlan_withoutfcs"); - wlan_withfcs = find_dissector("wlan_withfcs"); + wlan_radio_handle = find_dissector("wlan_radio"); + wlan_withfcs_handle = find_dissector("wlan_withfcs"); ppi_handle = find_dissector("ppi"); peek_handle = find_dissector("peekremote"); data_handle = find_dissector("data"); diff --git a/epan/dissectors/packet-cisco-wids.c b/epan/dissectors/packet-cisco-wids.c index bd0b3b7f4a..d194fdb735 100644 --- a/epan/dissectors/packet-cisco-wids.c +++ b/epan/dissectors/packet-cisco-wids.c @@ -45,6 +45,8 @@ #include "config.h" +#include <wiretap/wtap.h> + #include <epan/packet.h> #include <epan/exceptions.h> #include <epan/expert.h> @@ -66,7 +68,7 @@ static gint ett_cwids = -1; static expert_field ie_ieee80211_subpacket = EI_INIT; -static dissector_handle_t ieee80211_handle; +static dissector_handle_t ieee80211_radio_handle; static void dissect_cwids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) @@ -83,13 +85,20 @@ dissect_cwids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) cwids_tree = NULL; while(tvb_reported_length_remaining(tvb, offset) > 0) { + struct ieee_802_11_phdr phdr; + ti = proto_tree_add_item(tree, proto_cwids, tvb, offset, 28, ENC_NA); cwids_tree = proto_item_add_subtree(ti, ett_cwids); + phdr.fcs_len = 0; /* no FCS */ + phdr.decrypted = FALSE; + phdr.datapad = FALSE; + phdr.presence_flags = PHDR_802_11_HAS_CHANNEL; proto_tree_add_item(cwids_tree, hf_cwids_version, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(cwids_tree, hf_cwids_unknown1, tvb, offset, 7, ENC_NA); offset += 7; + phdr.channel = tvb_get_guint8(tvb, offset); proto_tree_add_item(cwids_tree, hf_cwids_channel, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(cwids_tree, hf_cwids_unknown2, tvb, offset, 6, ENC_NA); @@ -105,7 +114,7 @@ dissect_cwids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) wlan_tvb = tvb_new_subset_length(tvb, offset, capturelen); /* Continue after ieee80211 dissection errors */ TRY { - call_dissector(ieee80211_handle, wlan_tvb, pinfo, tree); + call_dissector_with_data(ieee80211_radio_handle, wlan_tvb, pinfo, tree, &phdr); } CATCH_BOUNDS_ERRORS { show_exception(wlan_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); @@ -187,7 +196,7 @@ proto_reg_handoff_cwids(void) if (!initialized) { cwids_handle = create_dissector_handle(dissect_cwids, proto_cwids); dissector_add_for_decode_as("udp.port", cwids_handle); - ieee80211_handle = find_dissector("wlan_withoutfcs"); + ieee80211_radio_handle = find_dissector("wlan_radio"); initialized = TRUE; } else { if (saved_udp_port != 0) { diff --git a/epan/dissectors/packet-ieee80211-airopeek.c b/epan/dissectors/packet-ieee80211-airopeek.c index 6a321b6776..ff82d9892e 100644 --- a/epan/dissectors/packet-ieee80211-airopeek.c +++ b/epan/dissectors/packet-ieee80211-airopeek.c @@ -29,7 +29,7 @@ void proto_register_ieee80211_airopeek(void); void proto_reg_handoff_ieee80211_airopeek(void); -static dissector_handle_t ieee80211_handle; +static dissector_handle_t ieee80211_radio_handle; static int proto_airopeek = -1; @@ -47,6 +47,7 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) guint8 data_rate; guint8 signal_level; tvbuff_t *next_tvb; + struct ieee_802_11_phdr phdr; col_set_str(pinfo->cinfo, COL_PROTOCOL, "AiroPeek"); col_clear(pinfo->cinfo, COL_INFO); @@ -57,7 +58,17 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) airopeek_tree = proto_item_add_subtree(ti, ett_airopeek); } + /* We don't have any 802.11 metadata yet. */ + phdr.fcs_len = 0; + phdr.decrypted = FALSE; + phdr.datapad = FALSE; + phdr.presence_flags = + PHDR_802_11_HAS_CHANNEL| + PHDR_802_11_HAS_DATA_RATE| + PHDR_802_11_HAS_SIGNAL_PERCENT; + data_rate = tvb_get_guint8(tvb, 0); + phdr.data_rate = data_rate; /* Add the radio information to the column information */ col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u", data_rate / 2, @@ -70,6 +81,7 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) data_rate & 1 ? 5 : 0); } + phdr.channel = tvb_get_guint8(tvb, 1); if (tree) proto_tree_add_item(airopeek_tree, hf_channel, tvb, 1, 1, ENC_BIG_ENDIAN); @@ -84,6 +96,7 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) * an adapter-dependent process, so, as we don't know what type of * adapter was used to do the capture, we can't do the conversion. */ + phdr.signal_percent = signal_level; col_add_fstr(pinfo->cinfo, COL_RSSI, "%u%%", signal_level); proto_tree_add_uint_format_value(airopeek_tree, hf_signal_strength, tvb, 2, 1, @@ -94,7 +107,7 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* dissect the 802.11 header next */ pinfo->current_proto = "IEEE 802.11"; next_tvb = tvb_new_subset_remaining(tvb, 4); - call_dissector(ieee80211_handle, next_tvb, pinfo, tree); + call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, &phdr); } void proto_register_ieee80211_airopeek(void) @@ -132,7 +145,7 @@ void proto_reg_handoff_ieee80211_airopeek(void) airopeek_handle = create_dissector_handle(dissect_airopeek, proto_airopeek); dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_AIROPEEK, airopeek_handle); - ieee80211_handle = find_dissector("wlan"); + ieee80211_radio_handle = find_dissector("wlan_radio"); } /* diff --git a/epan/dissectors/packet-ieee80211-netmon.c b/epan/dissectors/packet-ieee80211-netmon.c index 27a188ff08..bfc650e9f6 100644 --- a/epan/dissectors/packet-ieee80211-netmon.c +++ b/epan/dissectors/packet-ieee80211-netmon.c @@ -64,12 +64,13 @@ static int hf_netmon_802_11_timestamp = -1; static gint ett_netmon_802_11 = -1; static gint ett_netmon_802_11_op_mode = -1; -static dissector_handle_t ieee80211_handle; +static dissector_handle_t ieee80211_radio_handle; static int -dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { - proto_tree *wlan_tree, *opmode_tree; + struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; + proto_tree *wlan_tree = NULL, *opmode_tree; proto_item *ti; tvbuff_t *next_tvb; int offset; @@ -98,76 +99,93 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void } /* Dissect the packet */ - if (tree) { - ti = proto_tree_add_item(tree, proto_netmon_802_11, tvb, 0, length, - ENC_NA); - wlan_tree = proto_item_add_subtree(ti, ett_netmon_802_11); - proto_tree_add_item(wlan_tree, hf_netmon_802_11_version, tvb, offset, 1, + ti = proto_tree_add_item(tree, proto_netmon_802_11, tvb, 0, length, + ENC_NA); + wlan_tree = proto_item_add_subtree(ti, ett_netmon_802_11); + proto_tree_add_item(wlan_tree, hf_netmon_802_11_version, tvb, offset, 1, + ENC_LITTLE_ENDIAN); + offset += 1; + proto_tree_add_item(wlan_tree, hf_netmon_802_11_length, tvb, offset, 2, + ENC_LITTLE_ENDIAN); + offset += 2; + ti = proto_tree_add_item(wlan_tree, hf_netmon_802_11_op_mode, tvb, offset, + 4, ENC_LITTLE_ENDIAN); + opmode_tree = proto_item_add_subtree(ti, ett_netmon_802_11_op_mode); + proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta, tvb, offset, + 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_ap, tvb, offset, + 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta_ext, tvb, + offset, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_mon, tvb, offset, + 4, ENC_LITTLE_ENDIAN); + offset += 4; + flags = tvb_get_letohl(tvb, offset); + offset += 4; + if (flags != 0xffffffff) { + proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); - offset += 1; - proto_tree_add_item(wlan_tree, hf_netmon_802_11_length, tvb, offset, 2, - ENC_LITTLE_ENDIAN); - offset += 2; - ti = proto_tree_add_item(wlan_tree, hf_netmon_802_11_op_mode, tvb, offset, - 4, ENC_LITTLE_ENDIAN); - opmode_tree = proto_item_add_subtree(ti, ett_netmon_802_11_op_mode); - proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta, tvb, offset, - 4, ENC_LITTLE_ENDIAN); - proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_ap, tvb, offset, - 4, ENC_LITTLE_ENDIAN); - proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta_ext, tvb, - offset, 4, ENC_LITTLE_ENDIAN); - proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_mon, tvb, offset, - 4, ENC_LITTLE_ENDIAN); - offset += 4; - flags = tvb_get_letohl(tvb, offset); offset += 4; - if (flags != 0xffffffff) { - proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4, - ENC_LITTLE_ENDIAN); - offset += 4; - channel = tvb_get_letohl(tvb, offset); - if (channel < 1000) { + channel = tvb_get_letohl(tvb, offset); + if (channel < 1000) { + if (channel == 0) { + proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_channel, + tvb, offset, 4, channel, + "Unknown"); + } else { + phdr->presence_flags |= PHDR_802_11_HAS_CHANNEL; + phdr->channel = channel; proto_tree_add_uint(wlan_tree, hf_netmon_802_11_channel, tvb, offset, 4, channel); - } else { - proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_frequency, - tvb, offset, 4, channel, - "%u Mhz", channel); } - offset += 4; - rssi = tvb_get_letohl(tvb, offset); + } else { + phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY; + phdr->frequency = channel; + proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_frequency, + tvb, offset, 4, channel, + "%u Mhz", channel); + } + offset += 4; + rssi = tvb_get_letohl(tvb, offset); + if (rssi == 0) { + proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, + tvb, offset, 4, rssi, + "Unknown"); + } else { + phdr->presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM; + phdr->signal_dbm = rssi; proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, tvb, offset, 4, rssi, "%d dBm", rssi); - offset += 4; - rate = tvb_get_guint8(tvb, offset); - if (rate == 0) { - proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, - tvb, offset, 1, rate, - "Unknown"); - } else { - proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, - tvb, offset, 1, rate, - "%f Mb/s", rate*.5); - } - offset += 1; - } else - offset += 13; - proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8, - ENC_LITTLE_ENDIAN); - /*offset += 8;*/ - - } - - /* no return */ + } + offset += 4; + rate = tvb_get_guint8(tvb, offset); + if (rate == 0) { + proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, + tvb, offset, 1, rate, + "Unknown"); + } else { + phdr->presence_flags |= PHDR_802_11_HAS_DATA_RATE; + phdr->data_rate = rate; + proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, + tvb, offset, 1, rate, + "%f Mb/s", rate*.5); + } + offset += 1; + } else + offset += 13; + phdr->presence_flags |= PHDR_802_11_HAS_TSF_TIMESTAMP; + phdr->tsf_timestamp = tvb_get_letoh64(tvb, offset); + proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8, + ENC_LITTLE_ENDIAN); + /*offset += 8;*/ skip: offset = length; - /* dissect the 802.11 header next */ + /* dissect the 802.11 packet next */ next_tvb = tvb_new_subset_remaining(tvb, offset); - call_dissector(ieee80211_handle, next_tvb, pinfo, tree); + call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, phdr); return offset; } @@ -235,8 +253,8 @@ proto_reg_handoff_netmon_802_11(void) { dissector_handle_t netmon_802_11_handle; - /* handle for 802.11 dissector */ - ieee80211_handle = find_dissector("wlan"); + /* handle for 802.11+radio information dissector */ + ieee80211_radio_handle = find_dissector("wlan_radio"); netmon_802_11_handle = new_create_dissector_handle(dissect_netmon_802_11, proto_netmon_802_11); dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_NETMON, netmon_802_11_handle); diff --git a/epan/dissectors/packet-ieee80211-radio.c b/epan/dissectors/packet-ieee80211-radio.c index f965396e14..549cf4377b 100644 --- a/epan/dissectors/packet-ieee80211-radio.c +++ b/epan/dissectors/packet-ieee80211-radio.c @@ -32,23 +32,25 @@ void proto_register_ieee80211_radio(void); void proto_reg_handoff_ieee80211_radio(void); +static dissector_handle_t wlan_radio_handle; static dissector_handle_t ieee80211_handle; -static int proto_radio = -1; +static int proto_wlan_radio = -1; /* ************************************************************************* */ /* Header field info values for radio information */ /* ************************************************************************* */ -static int hf_data_rate = -1; -static int hf_mcs_index = -1; -static int hf_bandwidth = -1; -static int hf_short_gi = -1; -static int hf_channel = -1; -static int hf_frequency = -1; -static int hf_signal_percent = -1; -static int hf_signal_dbm = -1; -static int hf_noise_percent = -1; -static int hf_noise_dbm = -1; +static int hf_wlan_radio_data_rate = -1; +static int hf_wlan_radio_mcs_index = -1; +static int hf_wlan_radio_bandwidth = -1; +static int hf_wlan_radio_short_gi = -1; +static int hf_wlan_radio_channel = -1; +static int hf_wlan_radio_frequency = -1; +static int hf_wlan_radio_signal_percent = -1; +static int hf_wlan_radio_signal_dbm = -1; +static int hf_wlan_radio_noise_percent = -1; +static int hf_wlan_radio_noise_dbm = -1; +static int hf_wlan_radio_timestamp = -1; static const value_string bandwidth_vals[] = { { PHDR_802_11_BANDWIDTH_20_MHZ, "20 MHz" }, @@ -458,15 +460,16 @@ const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = { }, }; -static gint ett_radio = -1; +static gint ett_wlan_radio = -1; /* * Dissect 802.11 with a variable-length link-layer header and a pseudo- * header containing radio information. */ static int -dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *data) +dissect_wlan_radio (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; float data_rate = 0.0f; @@ -476,8 +479,8 @@ dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *dat col_clear(pinfo->cinfo, COL_INFO); /* Calculate the data rate, if we have the necessary data */ - if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_DATA_RATE) { - data_rate = pinfo->pseudo_header->ieee_802_11.data_rate * 0.5f; + if (phdr->presence_flags & PHDR_802_11_HAS_DATA_RATE) { + data_rate = phdr->data_rate * 0.5f; have_data_rate = TRUE; } else { /* Do we have all the fields we need to look it up? */ @@ -488,12 +491,12 @@ dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *dat guint bandwidth_40; - if ((pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_ALL_MCS_FIELDS) == PHDR_802_11_ALL_MCS_FIELDS) { + if ((phdr->presence_flags & PHDR_802_11_ALL_MCS_FIELDS) == PHDR_802_11_ALL_MCS_FIELDS) { bandwidth_40 = - (pinfo->pseudo_header->ieee_802_11.bandwidth == PHDR_802_11_BANDWIDTH_40_MHZ) ? + (phdr->bandwidth == PHDR_802_11_BANDWIDTH_40_MHZ) ? 1 : 0; - if (pinfo->pseudo_header->ieee_802_11.mcs_index < MAX_MCS_INDEX) { - data_rate = ieee80211_float_htrates[pinfo->pseudo_header->ieee_802_11.mcs_index][bandwidth_40][pinfo->pseudo_header->ieee_802_11.short_gi]; + if (phdr->mcs_index < MAX_MCS_INDEX) { + data_rate = ieee80211_float_htrates[phdr->mcs_index][bandwidth_40][phdr->short_gi]; have_data_rate = TRUE; } } @@ -503,7 +506,7 @@ dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *dat if (have_data_rate) col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%.1f", data_rate); - if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_SIGNAL_PERCENT) { + if (phdr->presence_flags & PHDR_802_11_HAS_SIGNAL_PERCENT) { /* * For tagged Peek files, this is presumably signal strength as a * percentage of the maximum, as it is for classic Peek files, @@ -518,143 +521,151 @@ dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *dat * It's *probably* something similar for other capture file formats. */ col_add_fstr(pinfo->cinfo, COL_RSSI, "%u%%", - pinfo->pseudo_header->ieee_802_11.signal_percent); + phdr->signal_percent); } if (tree) { - ti = proto_tree_add_item(tree, proto_radio, tvb, 0, 0, ENC_NA); - radio_tree = proto_item_add_subtree (ti, ett_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 (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_MCS_INDEX) { - proto_tree_add_uint(radio_tree, hf_mcs_index, tvb, 0, 0, - pinfo->pseudo_header->ieee_802_11.mcs_index); + if (phdr->presence_flags & PHDR_802_11_HAS_MCS_INDEX) { + proto_tree_add_uint(radio_tree, hf_wlan_radio_mcs_index, tvb, 0, 0, + phdr->mcs_index); } - if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_BANDWIDTH) { - proto_tree_add_uint(radio_tree, hf_bandwidth, tvb, 0, 0, - pinfo->pseudo_header->ieee_802_11.bandwidth); + if (phdr->presence_flags & PHDR_802_11_HAS_BANDWIDTH) { + proto_tree_add_uint(radio_tree, hf_wlan_radio_bandwidth, tvb, 0, 0, + phdr->bandwidth); } - if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_SHORT_GI) { - proto_tree_add_boolean(radio_tree, hf_short_gi, tvb, 0, 0, - pinfo->pseudo_header->ieee_802_11.short_gi); + if (phdr->presence_flags & PHDR_802_11_HAS_SHORT_GI) { + proto_tree_add_boolean(radio_tree, hf_wlan_radio_short_gi, tvb, 0, 0, + phdr->short_gi); } if (have_data_rate) { - proto_tree_add_float_format_value(radio_tree, hf_data_rate, tvb, 0, 0, + proto_tree_add_float_format_value(radio_tree, hf_wlan_radio_data_rate, tvb, 0, 0, data_rate, "%.1f Mb/s", data_rate); } - if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_CHANNEL) { - proto_tree_add_uint(radio_tree, hf_channel, tvb, 0, 0, - pinfo->pseudo_header->ieee_802_11.channel); + if (phdr->presence_flags & PHDR_802_11_HAS_CHANNEL) { + proto_tree_add_uint(radio_tree, hf_wlan_radio_channel, tvb, 0, 0, + phdr->channel); } - if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_FREQUENCY) { - proto_tree_add_uint_format_value(radio_tree, hf_frequency, tvb, 0, 0, - pinfo->pseudo_header->ieee_802_11.frequency, + if (phdr->presence_flags & PHDR_802_11_HAS_FREQUENCY) { + proto_tree_add_uint_format_value(radio_tree, hf_wlan_radio_frequency, tvb, 0, 0, + phdr->frequency, "%u MHz", - pinfo->pseudo_header->ieee_802_11.frequency); + phdr->frequency); } - if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_SIGNAL_PERCENT) { - proto_tree_add_uint_format_value(radio_tree, hf_signal_percent, tvb, 0, 0, - pinfo->pseudo_header->ieee_802_11.signal_percent, + if (phdr->presence_flags & PHDR_802_11_HAS_SIGNAL_PERCENT) { + proto_tree_add_uint_format_value(radio_tree, hf_wlan_radio_signal_percent, tvb, 0, 0, + phdr->signal_percent, "%u%%", - pinfo->pseudo_header->ieee_802_11.signal_percent); + phdr->signal_percent); } - if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_SIGNAL_DBM) { - proto_tree_add_int_format_value(radio_tree, hf_signal_dbm, tvb, 0, 0, - pinfo->pseudo_header->ieee_802_11.signal_dbm, + if (phdr->presence_flags & PHDR_802_11_HAS_SIGNAL_DBM) { + proto_tree_add_int_format_value(radio_tree, hf_wlan_radio_signal_dbm, tvb, 0, 0, + phdr->signal_dbm, "%d dBm", - pinfo->pseudo_header->ieee_802_11.signal_dbm); + phdr->signal_dbm); } - if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_NOISE_PERCENT) { - proto_tree_add_uint_format_value(radio_tree, hf_noise_percent, tvb, 0, 0, - pinfo->pseudo_header->ieee_802_11.noise_percent, + if (phdr->presence_flags & PHDR_802_11_HAS_NOISE_PERCENT) { + proto_tree_add_uint_format_value(radio_tree, hf_wlan_radio_noise_percent, tvb, 0, 0, + phdr->noise_percent, "%u%%", - pinfo->pseudo_header->ieee_802_11.noise_percent); + phdr->noise_percent); } - if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_NOISE_DBM) { - proto_tree_add_int_format_value(radio_tree, hf_noise_dbm, tvb, 0, 0, - pinfo->pseudo_header->ieee_802_11.noise_dbm, + if (phdr->presence_flags & PHDR_802_11_HAS_NOISE_DBM) { + proto_tree_add_int_format_value(radio_tree, hf_wlan_radio_noise_dbm, tvb, 0, 0, + phdr->noise_dbm, "%d dBm", - pinfo->pseudo_header->ieee_802_11.noise_dbm); + phdr->noise_dbm); + } + + if (phdr->presence_flags & PHDR_802_11_HAS_TSF_TIMESTAMP) { + proto_tree_add_uint64(radio_tree, hf_wlan_radio_timestamp, tvb, 0, 0, + phdr->tsf_timestamp); } } - /* dissect the 802.11 header next */ + /* dissect the 802.11 packet next */ pinfo->current_proto = "IEEE 802.11"; return call_dissector_with_data(ieee80211_handle, tvb, pinfo, tree, data); } -static hf_register_info hf_radio[] = { - {&hf_data_rate, - {"Data rate", "wlan.data_rate", FT_FLOAT, BASE_NONE, NULL, 0, +static hf_register_info hf_wlan_radio[] = { + {&hf_wlan_radio_data_rate, + {"Data rate", "wlan_radio.data_rate", FT_FLOAT, BASE_NONE, NULL, 0, "Data rate (bits/s)", HFILL }}, - {&hf_mcs_index, - {"MCS index", "wlan.mcs_index", FT_UINT32, BASE_DEC, NULL, 0, + {&hf_wlan_radio_mcs_index, + {"MCS index", "wlan_radio.mcs_index", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, - {&hf_bandwidth, - {"Bandwidth", "wlan.bandwidth", FT_UINT32, BASE_DEC, VALS(bandwidth_vals), 0, + {&hf_wlan_radio_bandwidth, + {"Bandwidth", "wlan_radio.bandwidth", FT_UINT32, BASE_DEC, VALS(bandwidth_vals), 0, NULL, HFILL }}, - {&hf_short_gi, - {"Short GI", "wlan.short_gi", FT_BOOLEAN, 0, NULL, 0, + {&hf_wlan_radio_short_gi, + {"Short GI", "wlan_radio.short_gi", FT_BOOLEAN, 0, NULL, 0, NULL, HFILL }}, - {&hf_channel, - {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0, + {&hf_wlan_radio_channel, + {"Channel", "wlan_radio.channel", FT_UINT8, BASE_DEC, NULL, 0, "802.11 channel number that this frame was sent/received on", HFILL }}, - {&hf_frequency, - {"Frequency", "wlan.frequency", FT_UINT16, BASE_DEC, NULL, 0, + {&hf_wlan_radio_frequency, + {"Frequency", "wlan_radio.frequency", FT_UINT16, BASE_DEC, NULL, 0, "Center frequency of the 802.11 channel that this frame was sent/received on", HFILL }}, - {&hf_signal_percent, - {"Signal strength (percentage)", "wlan.signal_dbm", FT_UINT8, BASE_DEC, NULL, 0, + {&hf_wlan_radio_signal_percent, + {"Signal strength (percentage)", "wlan_radio.signal_dbm", FT_UINT8, BASE_DEC, NULL, 0, "Signal strength, as percentage of maximum RSSI", HFILL }}, - {&hf_signal_dbm, - {"Signal strength (dBm)", "wlan.signal_dbm", FT_INT8, BASE_DEC, NULL, 0, + {&hf_wlan_radio_signal_dbm, + {"Signal strength (dBm)", "wlan_radio.signal_dbm", FT_INT8, BASE_DEC, NULL, 0, + NULL, HFILL }}, + + {&hf_wlan_radio_noise_percent, + {"Noise level (percentage)", "wlan_radio.noise_percentage", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, - {&hf_noise_percent, - {"Noise level (percentage)", "wlan.noise_percentage", FT_UINT8, BASE_DEC, NULL, 0, + {&hf_wlan_radio_noise_dbm, + {"Noise level (dBm)", "wlan_radio.noise_dbm", FT_INT8, BASE_DEC, NULL, 0, NULL, HFILL }}, - {&hf_noise_dbm, - {"Noise level (dBm)", "wlan.noise_dbm", FT_INT8, BASE_DEC, NULL, 0, + {&hf_wlan_radio_timestamp, + {"TSF timestamp", "wlan_radio.timestamp", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL }}, }; static gint *tree_array[] = { - &ett_radio + &ett_wlan_radio }; void proto_register_ieee80211_radio(void) { - proto_radio = proto_register_protocol("802.11 radio information", "Radio", - "radio"); - proto_register_field_array(proto_radio, hf_radio, array_length(hf_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)); + + wlan_radio_handle = new_register_dissector("wlan_radio", dissect_wlan_radio, proto_wlan_radio); } void proto_reg_handoff_ieee80211_radio(void) { - dissector_handle_t radio_handle; - /* Register handoff to radio-header dissectors */ - radio_handle = new_create_dissector_handle(dissect_radio, proto_radio); dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO, - radio_handle); + wlan_radio_handle); ieee80211_handle = find_dissector("wlan"); } diff --git a/epan/dissectors/packet-ieee80211-radiotap.c b/epan/dissectors/packet-ieee80211-radiotap.c index be696547a2..78bb206a17 100644 --- a/epan/dissectors/packet-ieee80211-radiotap.c +++ b/epan/dissectors/packet-ieee80211-radiotap.c @@ -215,8 +215,7 @@ static expert_field ei_radiotap_data_past_header = EI_INIT; static expert_field ei_radiotap_present_reserved = EI_INIT; static expert_field ei_radiotap_present = EI_INIT; -static dissector_handle_t ieee80211_handle; -static dissector_handle_t ieee80211_datapad_handle; +static dissector_handle_t ieee80211_radio_handle; static int radiotap_tap = -1; @@ -608,6 +607,7 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) /* We don't have any 802.11 metadata yet. */ phdr.fcs_len = -1; phdr.decrypted = FALSE; + phdr.datapad = FALSE; phdr.presence_flags = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN"); @@ -826,6 +826,8 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) case IEEE80211_RADIOTAP_TSFT: radiotap_info->tsft = tvb_get_letoh64(tvb, offset); + phdr.tsf_timestamp = radiotap_info->tsft; + phdr.presence_flags |= PHDR_802_11_HAS_TSF_TIMESTAMP; if (tree) { proto_tree_add_uint64(radiotap_tree, hf_radiotap_mactime, tvb, @@ -836,10 +838,22 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) case IEEE80211_RADIOTAP_FLAGS: { rflags = tvb_get_guint8(tvb, offset); + if (rflags & IEEE80211_RADIOTAP_F_DATAPAD) + phdr.datapad = TRUE; if (rflags & IEEE80211_RADIOTAP_F_FCS) phdr.fcs_len = 4; else phdr.fcs_len = 0; + /* + * This is "Currently unspecified but used", + * according to the radiotap.org page for + * the Flags field. + */ + phdr.presence_flags |= PHDR_802_11_HAS_SHORT_GI; + if (rflags & 0x80) + phdr.short_gi = 1; + else + phdr.short_gi = 0; if (tree) { proto_tree *flags_tree; @@ -938,11 +952,22 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) (float)rate / 2); } radiotap_info->rate = rate; + phdr.presence_flags |= PHDR_802_11_HAS_DATA_RATE; + phdr.data_rate = rate; } break; } case IEEE80211_RADIOTAP_CHANNEL: { + freq = tvb_get_letohs(tvb, offset); + if (freq != 0) { + /* + * XXX - some captures have 0, which is + * obviously bogus. + */ + phdr.presence_flags |= PHDR_802_11_HAS_FREQUENCY; + phdr.frequency = freq; + } if (tree) { guint16 flags; gchar *chan_str; @@ -962,7 +987,6 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) NULL }; - freq = tvb_get_letohs(tvb, offset); flags = tvb_get_letohs(tvb, offset + 2); chan_str = ieee80211_mhz_to_str(freq); col_add_fstr(pinfo->cinfo, @@ -1153,7 +1177,46 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) mcs_known = tvb_get_guint8(tvb, offset); mcs_flags = tvb_get_guint8(tvb, offset + 1); - mcs = tvb_get_guint8(tvb, offset + 2); + if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_MCS) { + mcs = tvb_get_guint8(tvb, offset + 2); + phdr.presence_flags |= PHDR_802_11_HAS_MCS_INDEX; + phdr.mcs_index = mcs; + } else { + mcs = 0; + can_calculate_rate = FALSE; /* no MCS index */ + } + if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_BW) { + phdr.presence_flags |= PHDR_802_11_HAS_BANDWIDTH; + phdr.bandwidth = (mcs_flags & IEEE80211_RADIOTAP_MCS_BW_MASK); + } + if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI) { + gi_length = (mcs_flags & IEEE80211_RADIOTAP_MCS_SGI) ? + 1 : 0; + phdr.presence_flags |= PHDR_802_11_HAS_SHORT_GI; + phdr.short_gi = (gi_length == 0); + } else { + gi_length = 0; + can_calculate_rate = FALSE; /* no GI width */ + } + if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FMT) { + phdr.presence_flags |= PHDR_802_11_HAS_GREENFIELD; + phdr.greenfield = (mcs_flags & IEEE80211_RADIOTAP_MCS_FMT_GF) != 0; + } + if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FEC) { + phdr.presence_flags |= PHDR_802_11_HAS_LDPC; + phdr.ldpc = (mcs_flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) != 0; + } + if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_STBC) { + phdr.presence_flags |= PHDR_802_11_HAS_STBC_STREAMS; + phdr.stbc_streams = (mcs_flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT; + } + if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_NESS) { + phdr.presence_flags |= PHDR_802_11_HAS_NESS; + /* This is stored a bit weirdly */ + phdr.ness = + ((mcs_known & IEEE80211_RADIOTAP_MCS_NESS_BIT1) >> 6) | + ((mcs_flags & IEEE80211_RADIOTAP_MCS_NESS_BIT0) >> 7); + } if (tree) { proto_item *it; @@ -1198,13 +1261,8 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) can_calculate_rate = FALSE; /* no bandwidth */ } if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI) { - gi_length = (mcs_flags & IEEE80211_RADIOTAP_MCS_SGI) ? - 1 : 0; proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_gi, tvb, offset + 1, 1, mcs_flags); - } else { - gi_length = 0; - can_calculate_rate = FALSE; /* no GI width */ } if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FMT) { proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_format, @@ -1225,8 +1283,7 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_MCS) { proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_index, tvb, offset + 2, 1, mcs); - } else - can_calculate_rate = FALSE; /* no MCS index */ + } /* * If we have the MCS index, channel width, and @@ -1516,8 +1573,7 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) } /* dissect the 802.11 packet next */ - call_dissector_with_data((rflags & IEEE80211_RADIOTAP_F_DATAPAD) ? - ieee80211_datapad_handle : ieee80211_handle, next_tvb, pinfo, + call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, &phdr); tap_queue_packet(radiotap_tap, pinfo, radiotap_info); @@ -1991,6 +2047,11 @@ void proto_register_radiotap(void) FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_BW, "Bandwidth information present", HFILL}}, + {&hf_radiotap_mcs_have_index, + {"MCS index", "radiotap.mcs.have_index", + FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_MCS, + "MCS index information present", HFILL}}, + {&hf_radiotap_mcs_have_gi, {"Guard interval", "radiotap.mcs.have_gi", FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_GI, @@ -2021,11 +2082,6 @@ void proto_register_radiotap(void) FT_BOOLEAN, 8, TFS(&tfs_1_0), IEEE80211_RADIOTAP_MCS_NESS_BIT1, "Bit 1 of number of extension spatial streams information", HFILL}}, - {&hf_radiotap_mcs_have_index, - {"MCS index", "radiotap.mcs.have_index", - FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_MCS, - "MCS index information present", HFILL}}, - {&hf_radiotap_mcs_bw, {"Bandwidth", "radiotap.mcs.bw", FT_UINT8, BASE_DEC, VALS(mcs_bandwidth), @@ -2391,9 +2447,8 @@ void proto_reg_handoff_radiotap(void) { dissector_handle_t radiotap_handle; - /* handle for 802.11 dissector */ - ieee80211_handle = find_dissector("wlan"); - ieee80211_datapad_handle = find_dissector("wlan_datapad"); + /* handle for 802.11+radio information dissector */ + ieee80211_radio_handle = find_dissector("wlan_radio"); radiotap_handle = find_dissector("radiotap"); diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c index a09caaca2c..aa22747cd9 100644 --- a/epan/dissectors/packet-ieee80211.c +++ b/epan/dissectors/packet-ieee80211.c @@ -16563,10 +16563,9 @@ typedef enum { static int dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo, - proto_tree *tree, gboolean fixed_length_header, gint fcs_len, - gboolean wlan_broken_fc, gboolean datapad, - gboolean is_ht, gboolean is_centrino, - struct ieee_802_11_phdr *phdr) + proto_tree *tree, gboolean fixed_length_header, + gboolean wlan_broken_fc, gboolean is_ht, + gboolean is_centrino, struct ieee_802_11_phdr *phdr) { guint16 fcf, flags, frame_type_subtype, ctrl_fcf, ctrl_type_subtype; guint16 seq_control; @@ -16673,7 +16672,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo, * of recalculating it every time we need it. */ ohdr_len = hdr_len; - if (datapad) + if (phdr->datapad) hdr_len = roundup2(hdr_len, 4); /* Add the FC and duration/id to the current tree */ @@ -16687,7 +16686,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo, dissect_durid(hdr_tree, tvb, frame_type_subtype, 2); } - switch (fcs_len) + switch (phdr->fcs_len) { case 0: /* Definitely has no FCS */ has_fcs = FALSE; @@ -17507,7 +17506,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo, guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len); guint32 fcs; - if (datapad) + if (phdr->datapad) fcs = crc32_802_tvb_padded(tvb, ohdr_len, hdr_len, len); else fcs = crc32_802_tvb(tvb, hdr_len + len); @@ -17770,7 +17769,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo, } if (IS_PROTECTED(FCF_FLAGS(fcf)) - && (phdr == NULL || !phdr->decrypted) + && !phdr->decrypted && (wlan_ignore_wep != WLAN_IGNORE_WEP_WO_IV)) { /* * It's a WEP or WPA encrypted frame, and it hasn't already been @@ -18272,80 +18271,76 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo, /* * Dissect 802.11 with a variable-length link-layer header and with the FCS - * presence or absence indicated by the pseudo-header. + * presence or absence indicated by the pseudo-header, if there is one. */ static int dissect_ieee80211 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; + struct ieee_802_11_phdr ourphdr; - return dissect_ieee80211_common (tvb, pinfo, tree, FALSE, - (phdr == NULL) ? -1 : phdr->fcs_len, FALSE, FALSE, FALSE, FALSE, phdr); + if (phdr == NULL) { + /* + * Fake a pseudo-header. + * XXX - what are we supposed to do if the FCS length is unknown? + */ + ourphdr.fcs_len = -1; + ourphdr.decrypted = FALSE; + ourphdr.datapad = FALSE; + ourphdr.presence_flags = 0; + phdr = &ourphdr; + } + return dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, FALSE, FALSE, phdr); } /* * Dissect 802.11 with a variable-length link-layer header and with an - * FCS. + * FCS, but no pseudo-header. */ static void dissect_ieee80211_withfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - dissect_ieee80211_common (tvb, pinfo, tree, FALSE, 4, FALSE, FALSE, FALSE, FALSE, NULL); + struct ieee_802_11_phdr phdr; + + /* Construct a pseudo-header to hand to the common code. */ + phdr.fcs_len = 4; + phdr.decrypted = FALSE; + phdr.datapad = FALSE; + phdr.presence_flags = 0; + dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, FALSE, FALSE, &phdr); } /* * Dissect 802.11 with a variable-length link-layer header and without an - * FCS. + * FCS, but no pseudo-header. */ static void dissect_ieee80211_withoutfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - dissect_ieee80211_common (tvb, pinfo, tree, FALSE, 0, FALSE, FALSE, FALSE, FALSE, NULL); -} - -/* - * Dissect 802.11 with a variable-length link-layer header. - */ -static int -dissect_ieee80211_centrino(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) -{ - struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; - - return dissect_ieee80211_common (tvb, pinfo, tree, FALSE, - (phdr == NULL) ? -1 : phdr->fcs_len, FALSE, FALSE, FALSE, TRUE, phdr); -} - -/* - * Dissect 802.11 with a variable-length link-layer header and data padding - * and with the FCS presence or absence indicated by the pseudo-header. - */ -static int -dissect_ieee80211_datapad (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) -{ - struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; + struct ieee_802_11_phdr phdr; - return dissect_ieee80211_common (tvb, pinfo, tree, FALSE, - (phdr == NULL) ? -1 : phdr->fcs_len, FALSE, TRUE, FALSE, FALSE, phdr); + /* Construct a pseudo-header to hand to the common code. */ + phdr.fcs_len = 0; + phdr.decrypted = FALSE; + phdr.datapad = FALSE; + phdr.presence_flags = 0; + dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, FALSE, FALSE, &phdr); } /* - * Dissect 802.11 with a variable-length link-layer header and data padding - * and with an FCS. + * Dissect 802.11 with a variable-length link-layer header. */ static void -dissect_ieee80211_datapad_withfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +dissect_ieee80211_centrino(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - dissect_ieee80211_common (tvb, pinfo, tree, FALSE, 4, FALSE, TRUE, FALSE, FALSE, NULL); -} + struct ieee_802_11_phdr phdr; -/* - * Dissect 802.11 with a variable-length link-layer header and data padding - * and without an FCS. - */ -static void -dissect_ieee80211_datapad_withoutfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) -{ - dissect_ieee80211_common (tvb, pinfo, tree, FALSE, 0, FALSE, TRUE, FALSE, FALSE, NULL); + /* Construct a pseudo-header to hand to the common code. */ + phdr.fcs_len = 0; + phdr.decrypted = FALSE; + phdr.datapad = FALSE; + phdr.presence_flags = 0; + dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, FALSE, TRUE, &phdr); } /* @@ -18356,7 +18351,14 @@ dissect_ieee80211_datapad_withoutfcs (tvbuff_t *tvb, packet_info *pinfo, proto_t static void dissect_ieee80211_bsfc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - dissect_ieee80211_common (tvb, pinfo, tree, FALSE, 0, TRUE, FALSE, FALSE, FALSE, NULL); + struct ieee_802_11_phdr phdr; + + /* Construct a pseudo-header to hand to the common code. */ + phdr.fcs_len = 0; + phdr.decrypted = FALSE; + phdr.datapad = FALSE; + phdr.presence_flags = 0; + dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE, FALSE, FALSE, &phdr); } /* @@ -18366,7 +18368,14 @@ dissect_ieee80211_bsfc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) static void dissect_ieee80211_fixed (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - dissect_ieee80211_common (tvb, pinfo, tree, TRUE, 0, FALSE, FALSE, FALSE, FALSE, NULL); + struct ieee_802_11_phdr phdr; + + /* Construct a pseudo-header to hand to the common code. */ + phdr.fcs_len = 0; + phdr.decrypted = FALSE; + phdr.datapad = FALSE; + phdr.presence_flags = 0; + dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, FALSE, FALSE, &phdr); } /* @@ -18379,8 +18388,7 @@ dissect_ieee80211_ht (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void { struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; - return dissect_ieee80211_common (tvb, pinfo, tree, FALSE, - (phdr == NULL) ? -1 : phdr->fcs_len, FALSE, FALSE, TRUE, FALSE, phdr); + return dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, TRUE, FALSE, phdr); } static void @@ -26932,9 +26940,6 @@ proto_register_ieee80211 (void) register_dissector("wlan_withoutfcs", dissect_ieee80211_withoutfcs, proto_wlan); register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan); register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan); - new_register_dissector("wlan_datapad", dissect_ieee80211_datapad, proto_wlan); - register_dissector("wlan_datapad_withfcs", dissect_ieee80211_datapad_withfcs, proto_wlan); - register_dissector("wlan_datapad_withoutfcs", dissect_ieee80211_datapad_withoutfcs, proto_wlan); new_register_dissector("wlan_ht", dissect_ieee80211_ht, proto_wlan); register_init_routine(wlan_defragment_init); @@ -27158,9 +27163,8 @@ proto_reg_handoff_ieee80211(void) ieee80211_handle = find_dissector("wlan"); dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle); - dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO, ieee80211_handle); - centrino_handle = new_create_dissector_handle( dissect_ieee80211_centrino, proto_wlan ); + centrino_handle = create_dissector_handle( dissect_ieee80211_centrino, proto_wlan ); dissector_add_uint("ethertype", ETHERTYPE_CENTRINO_PROMISC, centrino_handle); /* Register handoff to Aruba GRE */ diff --git a/epan/dissectors/packet-ixveriwave.c b/epan/dissectors/packet-ixveriwave.c index 8dfd4872e6..c0fd5331d3 100644 --- a/epan/dissectors/packet-ixveriwave.c +++ b/epan/dissectors/packet-ixveriwave.c @@ -124,7 +124,7 @@ static gint ett_radiotap_present = -1; static gint ett_radiotap_flags = -1; /* static gint ett_radiotap_channel_flags = -1; */ -static dissector_handle_t ieee80211_handle; +static dissector_handle_t ieee80211_radio_handle; /* Ethernet fields */ static int hf_ixveriwave_vw_info = -1; @@ -653,6 +653,7 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree guint length; gint8 dbm; guint8 mcs_index; + guint8 ness; float phyRate; proto_tree *vweft, *vw_errorFlags_tree = NULL, *vwift,*vw_infoFlags_tree = NULL; @@ -661,6 +662,13 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree ifg_info *p_ifg_info; proto_item *ti; + struct ieee_802_11_phdr phdr; + + /* We don't have any 802.11 metadata yet. */ + phdr.fcs_len = 0; /* no FCS */ + phdr.decrypted = FALSE; + phdr.datapad = FALSE; + phdr.presence_flags = 0; /* First add the IFG information, need to grab the info bit field here */ vw_info = tvb_get_letohs(tvb, 20); @@ -679,6 +687,10 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree offset += 2; vw_rflags = tvb_get_letohs(tvb, offset); + if ((vw_rflags & FLAGS_CHAN_HT) || (vw_rflags & FLAGS_CHAN_VHT) ) { + phdr.presence_flags |= PHDR_802_11_HAS_SHORT_GI; + phdr.short_gi = ((vw_rflags & FLAGS_CHAN_SHORTGI) != 0); + } if (tree) { ft = proto_tree_add_uint(tap_tree, hf_radiotap_flags, tvb, offset, 2, vw_rflags); flags_tree = proto_item_add_subtree(ft, ett_radiotap_flags); @@ -711,12 +723,16 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree offset +=2; phyRate = (float)tvb_get_letohs(tvb, offset) / 10; offset +=2; + ness = tvb_get_guint8(tvb, offset); offset++; mcs_index = tvb_get_guint8(tvb, offset); offset++; offset++; if ((vw_rflags & FLAGS_CHAN_HT) || (vw_rflags & FLAGS_CHAN_VHT) ) { + phdr.presence_flags |= (PHDR_802_11_HAS_MCS_INDEX|PHDR_802_11_HAS_NESS); + phdr.mcs_index = mcs_index; + phdr.ness = ness; if (tree) { proto_tree_add_item(tap_tree, hf_radiotap_mcsindex, tvb, offset - 2, 1, ENC_BIG_ENDIAN); @@ -729,6 +745,8 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree "%.1f (MCS %d)", phyRate, mcs_index); } } else { + phdr.presence_flags |= PHDR_802_11_HAS_DATA_RATE; + phdr.data_rate = tvb_get_letohs(tvb, offset-5) / 5; if (tree) { proto_tree_add_uint_format_value(tap_tree, hf_radiotap_datarate, tvb, offset - 5, 2, tvb_get_letohs(tvb, offset-5), @@ -738,7 +756,8 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%.1f", phyRate); dbm = (gint8) tvb_get_guint8(tvb, offset); - + phdr.presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM; + phdr.signal_dbm = dbm; col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm); if (tree) { proto_tree_add_int_format_value(tap_tree, @@ -905,7 +924,7 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree next_tvb = tvb_new_subset_remaining(tvb, length); /* dissect the 802.11 packet next */ - call_dissector(ieee80211_handle, next_tvb, pinfo, tree); + call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, &phdr); } void proto_register_ixveriwave(void) @@ -1350,8 +1369,8 @@ void proto_reg_handoff_ixveriwave(void) { /* handle for ethertype dissector */ ethernet_handle = find_dissector("eth_withoutfcs"); - /* handle for 802.11 dissector */ - ieee80211_handle = find_dissector("wlan_withoutfcs"); + /* handle for 802.11+radio information dissector */ + ieee80211_radio_handle = find_dissector("wlan_radio"); ixveriwave_handle = create_dissector_handle(dissect_ixveriwave, proto_ixveriwave); dissector_add_uint("wtap_encap", WTAP_ENCAP_IXVERIWAVE, ixveriwave_handle); diff --git a/epan/dissectors/packet-peekremote.c b/epan/dissectors/packet-peekremote.c index 49e4050e09..864c382c13 100644 --- a/epan/dissectors/packet-peekremote.c +++ b/epan/dissectors/packet-peekremote.c @@ -54,6 +54,8 @@ #include "config.h" +#include <wiretap/wtap.h> + #include <epan/packet.h> #include <epan/expert.h> @@ -312,8 +314,7 @@ static gint ett_peekremote_flags = -1; static gint ett_peekremote_status = -1; static gint ett_peekremote_extflags = -1; -static dissector_handle_t wlan_withfcs; -static dissector_handle_t wlan_withoutfcs; +static dissector_handle_t wlan_radio_handle; static int @@ -380,6 +381,8 @@ dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void proto_item *ti_header_version, *ti_header_size; guint8 header_version; guint header_size; + struct ieee_802_11_phdr phdr; + guint16 frequency; tvbuff_t *next_tvb; if (tvb_memeql(tvb, 0, magic, 4) == -1) { @@ -390,6 +393,12 @@ dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void return FALSE; } + /* We don't have any 802.11 metadata yet. */ + phdr.fcs_len = 4; /* has an FCS */ + phdr.decrypted = FALSE; + phdr.datapad = FALSE; + phdr.presence_flags = 0; + col_set_str(pinfo->cinfo, COL_PROTOCOL, "PEEKREMOTE"); col_clear(pinfo->cinfo, COL_INFO); @@ -412,23 +421,42 @@ dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void if (header_size > 9) offset += (header_size - 9); } else { + phdr.presence_flags |= + PHDR_802_11_HAS_MCS_INDEX| + PHDR_802_11_HAS_CHANNEL| + PHDR_802_11_HAS_SIGNAL_PERCENT| + PHDR_802_11_HAS_NOISE_PERCENT| + PHDR_802_11_HAS_SIGNAL_DBM| + PHDR_802_11_HAS_NOISE_DBM| + PHDR_802_11_HAS_TSF_TIMESTAMP; proto_tree_add_item(peekremote_tree, &hfi_peekremote_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; + phdr.mcs_index = tvb_get_ntohs(tvb, offset); proto_tree_add_item(peekremote_tree, &hfi_peekremote_mcs_index, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; + phdr.channel = tvb_get_ntohs(tvb, offset); proto_tree_add_item(peekremote_tree, &hfi_peekremote_channel, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; + frequency = tvb_get_ntohl(tvb, offset); + if (frequency != 0) { + phdr.presence_flags |= PHDR_802_11_HAS_FREQUENCY; + phdr.frequency = frequency; + } proto_tree_add_item(peekremote_tree, &hfi_peekremote_frequency, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(peekremote_tree, &hfi_peekremote_band, tvb, offset, 4, ENC_BIG_ENDIAN); offset +=4; offset += dissect_peekremote_extflags(tvb, pinfo, peekremote_tree, offset); + phdr.signal_percent = tvb_get_guint8(tvb, offset); proto_tree_add_item(peekremote_tree, &hfi_peekremote_signal_percent, tvb, offset, 1, ENC_NA); offset += 1; + phdr.noise_percent = tvb_get_guint8(tvb, offset); proto_tree_add_item(peekremote_tree, &hfi_peekremote_noise_percent, tvb, offset, 1, ENC_NA); offset += 1; + phdr.signal_dbm = tvb_get_guint8(tvb, offset); proto_tree_add_item(peekremote_tree, &hfi_peekremote_signal_dbm, tvb, offset, 1, ENC_NA); offset += 1; + phdr.noise_dbm = tvb_get_guint8(tvb, offset); proto_tree_add_item(peekremote_tree, &hfi_peekremote_noise_dbm, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(peekremote_tree, &hfi_peekremote_signal_1_dbm, tvb, offset, 1, ENC_NA); @@ -454,6 +482,7 @@ dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void offset += dissect_peekremote_flags(tvb, pinfo, peekremote_tree, offset); offset += dissect_peekremote_status(tvb, pinfo, peekremote_tree, offset); proto_tree_add_item(peekremote_tree, &hfi_peekremote_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN); + phdr.tsf_timestamp = tvb_get_ntoh64(tvb, offset); offset += 8; } break; @@ -467,7 +496,7 @@ dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void proto_item_set_end(ti, tvb, offset); next_tvb = tvb_new_subset_remaining(tvb, offset); - call_dissector(wlan_withfcs, next_tvb, pinfo, tree); + call_dissector_with_data(wlan_radio_handle, next_tvb, pinfo, tree, &phdr); return TRUE; } @@ -477,6 +506,7 @@ dissect_peekremote_legacy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v tvbuff_t *next_tvb; proto_tree *peekremote_tree = NULL; proto_item *ti = NULL; + struct ieee_802_11_phdr phdr; guint8 signal_percent; /* @@ -511,11 +541,29 @@ dissect_peekremote_legacy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v proto_item_set_end(ti, tvb, 20); next_tvb = tvb_new_subset_remaining(tvb, 20); /* When signal = 100 % and coming from ARUBA ERM, it is TX packet and there is no FCS */ - if (GPOINTER_TO_INT(data) == IS_ARUBA && signal_percent == 100){ - return 20 + call_dissector(wlan_withoutfcs, next_tvb, pinfo, tree); + if (GPOINTER_TO_INT(data) == IS_ARUBA && signal_percent == 100) { + phdr.fcs_len = 0; /* TX packet, no FCS */ } else { - return 20 + call_dissector(wlan_withfcs, next_tvb, pinfo, tree); + phdr.fcs_len = 4; /* We have an FCS */ } + phdr.decrypted = FALSE; + phdr.presence_flags = + PHDR_802_11_HAS_CHANNEL| + PHDR_802_11_HAS_DATA_RATE| + PHDR_802_11_HAS_SIGNAL_PERCENT| + PHDR_802_11_HAS_NOISE_PERCENT| + PHDR_802_11_HAS_SIGNAL_DBM| + PHDR_802_11_HAS_NOISE_DBM| + PHDR_802_11_HAS_TSF_TIMESTAMP; + phdr.channel = tvb_get_guint8(tvb, 17); + phdr.data_rate = tvb_get_guint8(tvb, 16); + phdr.signal_percent = tvb_get_guint8(tvb, 18); + phdr.noise_percent = tvb_get_guint8(tvb, 18); + phdr.signal_dbm = tvb_get_guint8(tvb, 0); + phdr.noise_dbm = tvb_get_guint8(tvb, 1); + phdr.tsf_timestamp = tvb_get_ntoh64(tvb, 8); + + return 20 + call_dissector_with_data(wlan_radio_handle, next_tvb, pinfo, tree, &phdr); } void @@ -598,8 +646,7 @@ proto_reg_handoff_peekremote(void) { dissector_handle_t peekremote_handle; - wlan_withfcs = find_dissector("wlan_withfcs"); - wlan_withoutfcs = find_dissector("wlan_withoutfcs"); + wlan_radio_handle = find_dissector("wlan_radio"); peekremote_handle = new_create_dissector_handle(dissect_peekremote_legacy, proto_peekremote); dissector_add_uint("udp.port", 5000, peekremote_handle); diff --git a/epan/dissectors/packet-ppi.c b/epan/dissectors/packet-ppi.c index 5541bcd779..15c2dee156 100644 --- a/epan/dissectors/packet-ppi.c +++ b/epan/dissectors/packet-ppi.c @@ -115,11 +115,18 @@ #define PPI_FLAG_ALIGN 0x01 #define IS_PPI_FLAG_ALIGN(x) ((x) & PPI_FLAG_ALIGN) -#define DOT11_FLAG_HAVE_FCS 0x0001 - -#define DOT11N_FLAG_IS_AGGREGATE 0x0010 +#define DOT11_FLAG_HAVE_FCS 0x0001 +#define DOT11_FLAG_TSF_TIMER_MS 0x0002 +#define DOT11_FLAG_FCS_INVALID 0x0004 +#define DOT11_FLAG_PHY_ERROR 0x0008 + +#define DOT11N_FLAG_GREENFIELD 0x0001 +#define DOT11N_FLAG_HT40 0x0002 +#define DOT11N_FLAG_SHORT_GI 0x0004 +#define DOT11N_FLAG_DUPLICATE_RX 0x0008 +#define DOT11N_FLAG_IS_AGGREGATE 0x0010 #define DOT11N_FLAG_MORE_AGGREGATES 0x0020 -#define DOT11N_FLAG_AGG_CRC_ERROR 0x0040 +#define DOT11N_FLAG_AGG_CRC_ERROR 0x0040 #define DOT11N_IS_AGGREGATE(flags) (flags & DOT11N_FLAG_IS_AGGREGATE) #define DOT11N_MORE_AGGREGATES(flags) ( \ @@ -333,7 +340,7 @@ static expert_field ei_ppi_invalid_length = EI_INIT; static dissector_handle_t ppi_handle; static dissector_handle_t data_handle; -static dissector_handle_t ieee80211_handle; +static dissector_handle_t ieee80211_radio_handle; static dissector_handle_t ieee80211_ht_handle; static dissector_handle_t ppi_gps_handle, ppi_vector_handle, ppi_sensor_handle, ppi_antenna_handle; static dissector_handle_t ppi_fnet_handle; @@ -482,9 +489,12 @@ dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of proto_tree *ftree; proto_item *ti; ptvcursor_t *csr; - gint rate_kbps; + guint64 tsft_raw; + guint rate_raw; + guint rate_kbps; guint32 common_flags; guint16 common_frequency; + gint8 dbm_value; gchar *chan_str; ftree = proto_tree_add_subtree(tree, tvb, offset, data_len, ett_dot11_common, NULL, "802.11-Common"); @@ -504,6 +514,15 @@ dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of csr = ptvcursor_new(ftree, tvb, offset); + tsft_raw = tvb_get_letoh64(tvb, offset); + if (tsft_raw != 0) { + phdr->presence_flags |= PHDR_802_11_HAS_TSF_TIMESTAMP; + if (common_flags & DOT11_FLAG_TSF_TIMER_MS) + phdr->tsf_timestamp = tsft_raw * 1000; + else + phdr->tsf_timestamp = tsft_raw; + } + ptvcursor_add_invalid_check(csr, hf_80211_common_tsft, 8, 0); ptvcursor_add_with_subtree(csr, hf_80211_common_flags, 2, ENC_LITTLE_ENDIAN, @@ -514,7 +533,12 @@ dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of ptvcursor_add(csr, hf_80211_common_flags_phy_err, 2, ENC_LITTLE_ENDIAN); ptvcursor_pop_subtree(csr); - rate_kbps = tvb_get_letohs(tvb, ptvcursor_current_offset(csr)) * 500; + rate_raw = tvb_get_letohs(tvb, ptvcursor_current_offset(csr)); + if (rate_raw != 0) { + phdr->presence_flags |= PHDR_802_11_HAS_DATA_RATE; + phdr->data_rate = rate_raw; + } + rate_kbps = rate_raw * 500; ti = proto_tree_add_uint_format(ftree, hf_80211_common_rate, tvb, ptvcursor_current_offset(csr), 2, rate_kbps, "Rate: %.1f Mbps", rate_kbps / 1000.0); @@ -524,6 +548,10 @@ dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of ptvcursor_advance(csr, 2); common_frequency = tvb_get_letohs(ptvcursor_tvbuff(csr), ptvcursor_current_offset(csr)); + if (common_frequency != 0) { + phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY; + phdr->frequency = common_frequency; + } chan_str = ieee80211_mhz_to_str(common_frequency); proto_tree_add_uint_format_value(ptvcursor_tree(csr), hf_80211_common_chan_freq, ptvcursor_tvbuff(csr), ptvcursor_current_offset(csr), 2, common_frequency, "%s", chan_str); @@ -547,21 +575,43 @@ dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of ptvcursor_add(csr, hf_80211_common_fhss_hopset, 1, ENC_LITTLE_ENDIAN); ptvcursor_add(csr, hf_80211_common_fhss_pattern, 1, ENC_LITTLE_ENDIAN); - col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", - (gint8) tvb_get_guint8(tvb, ptvcursor_current_offset(csr))); - + dbm_value = (gint8) tvb_get_guint8(tvb, ptvcursor_current_offset(csr)); + if (dbm_value != -128 && dbm_value != 0) { + /* + * XXX - the spec says -128 is invalid, presumably meaning "use + * -128 if you don't have the signal strength", but some captures + * have 0 for noise, presumably meaning it's incorrectly being + * used for "don't have it", so we check for it as well. + */ + col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm_value); + phdr->presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM; + phdr->signal_dbm = dbm_value; + } ptvcursor_add_invalid_check(csr, hf_80211_common_dbm_antsignal, 1, 0x80); /* -128 */ + + dbm_value = (gint8) tvb_get_guint8(tvb, ptvcursor_current_offset(csr)); + if (dbm_value != -128 && dbm_value != 0) { + /* + * XXX - the spec says -128 is invalid, presumably meaning "use + * -128 if you don't have the noise level", but some captures + * have 0, presumably meaning it's incorrectly being used for + * "don't have it", so we check for it as well. + */ + phdr->presence_flags |= PHDR_802_11_HAS_NOISE_DBM; + phdr->noise_dbm = dbm_value; + } ptvcursor_add_invalid_check(csr, hf_80211_common_dbm_antnoise, 1, 0x80); ptvcursor_free(csr); } static void -dissect_80211n_mac(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, int data_len, gboolean add_subtree, guint32 *n_mac_flags, guint32 *ampdu_id) +dissect_80211n_mac(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, int data_len, gboolean add_subtree, guint32 *n_mac_flags, guint32 *ampdu_id, struct ieee_802_11_phdr *phdr) { proto_tree *ftree = tree; ptvcursor_t *csr; int subtree_off = add_subtree ? 4 : 0; + guint32 flags; *n_mac_flags = tvb_get_letohl(tvb, offset + subtree_off); *ampdu_id = tvb_get_letohl(tvb, offset + 4 + subtree_off); @@ -579,6 +629,10 @@ dissect_80211n_mac(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int csr = ptvcursor_new(ftree, tvb, offset); + flags = tvb_get_letohl(tvb, ptvcursor_current_offset(csr)); + phdr->presence_flags |= PHDR_802_11_HAS_SHORT_GI|PHDR_802_11_HAS_GREENFIELD; + phdr->short_gi = ((flags & DOT11N_FLAG_SHORT_GI) != 0); + phdr->greenfield = ((flags & DOT11N_FLAG_GREENFIELD) != 0); ptvcursor_add_with_subtree(csr, hf_80211n_mac_flags, 4, ENC_LITTLE_ENDIAN, ett_dot11n_mac_flags); ptvcursor_add_no_advance(csr, hf_80211n_mac_flags_greenfield, 4, ENC_LITTLE_ENDIAN); @@ -601,11 +655,13 @@ dissect_80211n_mac(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int } static void -dissect_80211n_mac_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int data_len, guint32 *n_mac_flags, guint32 *ampdu_id) +dissect_80211n_mac_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int data_len, guint32 *n_mac_flags, guint32 *ampdu_id, struct ieee_802_11_phdr *phdr) { proto_tree *ftree; proto_item *ti; ptvcursor_t *csr; + guint8 mcs; + guint8 ness; guint16 ext_frequency; gchar *chan_str; @@ -619,12 +675,21 @@ dissect_80211n_mac_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int } dissect_80211n_mac(tvb, pinfo, ftree, offset, PPI_80211N_MAC_LEN, - FALSE, n_mac_flags, ampdu_id); + FALSE, n_mac_flags, ampdu_id, phdr); offset += PPI_80211N_MAC_PHY_OFF; csr = ptvcursor_new(ftree, tvb, offset); + mcs = tvb_get_guint8(tvb, ptvcursor_current_offset(csr)); + if (mcs != 255) { + phdr->presence_flags |= PHDR_802_11_HAS_MCS_INDEX; + phdr->mcs_index = mcs; + } ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_mcs, 1, 255); + + ness = tvb_get_guint8(tvb, ptvcursor_current_offset(csr)); + phdr->presence_flags |= PHDR_802_11_HAS_NESS; + phdr->ness = ness; ti = ptvcursor_add(csr, hf_80211n_mac_phy_num_streams, 1, ENC_LITTLE_ENDIAN); if (tvb_get_guint8(tvb, ptvcursor_current_offset(csr) - 1) == 0) proto_item_append_text(ti, " (unknown)"); @@ -795,6 +860,7 @@ dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* We don't have any 802.11 metadata yet. */ phdr.fcs_len = -1; phdr.decrypted = FALSE; + phdr.datapad = FALSE; phdr.presence_flags = 0; while (tot_len > 0) { @@ -810,13 +876,13 @@ dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) case PPI_80211N_MAC: dissect_80211n_mac(tvb, pinfo, ppi_tree, offset, data_len, - TRUE, &n_ext_flags, &du_id); + TRUE, &n_ext_flags, &du_id, &phdr); is_ht = TRUE; break; case PPI_80211N_MAC_PHY: dissect_80211n_mac_phy(tvb, pinfo, ppi_tree, offset, - data_len, &n_ext_flags, &du_id); + data_len, &n_ext_flags, &du_id, &phdr); is_ht = TRUE; break; @@ -1028,7 +1094,7 @@ dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) if (is_ht) { /* We didn't hit the reassembly code */ call_dissector_with_data(ieee80211_ht_handle, next_tvb, pinfo, tree, &phdr); } else { - call_dissector_with_data(ieee80211_handle, next_tvb, pinfo, tree, &phdr); + call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, &phdr); } } else { /* Everything else. This will pass a NULL data argument. */ @@ -1089,16 +1155,16 @@ proto_register_ppi(void) FT_UINT16, BASE_HEX, NULL, 0x0, "PPI 802.11-Common Flags", HFILL } }, { &hf_80211_common_flags_fcs, { "FCS present flag", "ppi.80211-common.flags.fcs", - FT_BOOLEAN, 16, TFS(&tfs_present_absent), 0x0001, "PPI 802.11-Common Frame Check Sequence (FCS) Present Flag", HFILL } }, + FT_BOOLEAN, 16, TFS(&tfs_present_absent), DOT11_FLAG_HAVE_FCS, "PPI 802.11-Common Frame Check Sequence (FCS) Present Flag", HFILL } }, { &hf_80211_common_flags_tsft, { "TSFT flag", "ppi.80211-common.flags.tsft", - FT_BOOLEAN, 16, TFS(&tfs_tsft_ms), 0x0002, "PPI 802.11-Common Timing Synchronization Function Timer (TSFT) msec/usec flag", HFILL } }, + FT_BOOLEAN, 16, TFS(&tfs_tsft_ms), DOT11_FLAG_TSF_TIMER_MS, "PPI 802.11-Common Timing Synchronization Function Timer (TSFT) msec/usec flag", HFILL } }, { &hf_80211_common_flags_fcs_valid, { "FCS validity", "ppi.80211-common.flags.fcs-invalid", - FT_BOOLEAN, 16, TFS(&tfs_invalid_valid), 0x0004, "PPI 802.11-Common Frame Check Sequence (FCS) Validity flag", HFILL } }, + FT_BOOLEAN, 16, TFS(&tfs_invalid_valid), DOT11_FLAG_FCS_INVALID, "PPI 802.11-Common Frame Check Sequence (FCS) Validity flag", HFILL } }, { &hf_80211_common_flags_phy_err, { "PHY error flag", "ppi.80211-common.flags.phy-err", - FT_BOOLEAN, 16, TFS(&tfs_phy_error), 0x0008, "PPI 802.11-Common Physical level (PHY) Error", HFILL } }, + FT_BOOLEAN, 16, TFS(&tfs_phy_error), DOT11_FLAG_PHY_ERROR, "PPI 802.11-Common Physical level (PHY) Error", HFILL } }, { &hf_80211_common_rate, { "Data rate", "ppi.80211-common.rate", FT_UINT16, BASE_DEC, NULL, 0x0, "PPI 802.11-Common Data Rate (x 500 Kbps)", HFILL } }, @@ -1154,25 +1220,25 @@ proto_register_ppi(void) FT_UINT32, BASE_HEX, NULL, 0x0, "PPI 802.11n MAC flags", HFILL } }, { &hf_80211n_mac_flags_greenfield, { "Greenfield flag", "ppi.80211n-mac.flags.greenfield", - FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0001, "PPI 802.11n MAC Greenfield Flag", HFILL } }, + FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_GREENFIELD, "PPI 802.11n MAC Greenfield Flag", HFILL } }, { &hf_80211n_mac_flags_ht20_40, { "HT20/HT40 flag", "ppi.80211n-mac.flags.ht20_40", - FT_BOOLEAN, 32, TFS(&tfs_ht20_40), 0x0002, "PPI 802.11n MAC HT20/HT40 Flag", HFILL } }, + FT_BOOLEAN, 32, TFS(&tfs_ht20_40), DOT11N_FLAG_HT40, "PPI 802.11n MAC HT20/HT40 Flag", HFILL } }, { &hf_80211n_mac_flags_rx_guard_interval, { "RX Short Guard Interval (SGI) flag", "ppi.80211n-mac.flags.rx.short_guard_interval", - FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0004, "PPI 802.11n MAC RX Short Guard Interval (SGI) Flag", HFILL } }, + FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_SHORT_GI, "PPI 802.11n MAC RX Short Guard Interval (SGI) Flag", HFILL } }, { &hf_80211n_mac_flags_duplicate_rx, { "Duplicate RX flag", "ppi.80211n-mac.flags.rx.duplicate", - FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0008, "PPI 802.11n MAC Duplicate RX Flag", HFILL } }, + FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_DUPLICATE_RX, "PPI 802.11n MAC Duplicate RX Flag", HFILL } }, { &hf_80211n_mac_flags_aggregate, { "Aggregate flag", "ppi.80211n-mac.flags.agg", - FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0010, "PPI 802.11 MAC Aggregate Flag", HFILL } }, + FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_IS_AGGREGATE, "PPI 802.11 MAC Aggregate Flag", HFILL } }, { &hf_80211n_mac_flags_more_aggregates, { "More aggregates flag", "ppi.80211n-mac.flags.more_agg", - FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0020, "PPI 802.11n MAC More Aggregates Flag", HFILL } }, + FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_MORE_AGGREGATES, "PPI 802.11n MAC More Aggregates Flag", HFILL } }, { &hf_80211n_mac_flags_delimiter_crc_after, { "A-MPDU Delimiter CRC error after this frame flag", "ppi.80211n-mac.flags.delim_crc_error_after", - FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0040, "PPI 802.11n MAC A-MPDU Delimiter CRC Error After This Frame Flag", HFILL } }, + FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_AGG_CRC_ERROR, "PPI 802.11n MAC A-MPDU Delimiter CRC Error After This Frame Flag", HFILL } }, { &hf_80211n_mac_ampdu_id, { "AMPDU-ID", "ppi.80211n-mac.ampdu_id", FT_UINT32, BASE_HEX, NULL, 0x0, "PPI 802.11n MAC AMPDU-ID", HFILL } }, @@ -1401,7 +1467,7 @@ void proto_reg_handoff_ppi(void) { data_handle = find_dissector("data"); - ieee80211_handle = find_dissector("wlan"); + ieee80211_radio_handle = find_dissector("wlan_radio"); ieee80211_ht_handle = find_dissector("wlan_ht"); ppi_gps_handle = find_dissector("ppi_gps"); ppi_vector_handle = find_dissector("ppi_vector"); |