forked from osmocom/wireshark
Call the "802.11 radio information" dissector for radio headers.
Have dissectors of various forms of radio information headers in the packets fill in a struct ieee_802_11_phdr with radio information as appropriate, and call the "802.11 radio information" dissector rather than the raw 802.11 dissector. This means that the radio information can be found in a protocol-independent and encapsulation-independent form when you're looking at the packet; that information can be presented in a form somewhat easier to read than the raw metadata header format. It also enables having a single "radio information" tap that allows statistics to handle all different sorts of radio information encapsulation. In addition, it lets us clean up some of the arguments passed to the common 802.11 dissector routine, by having it pull that information from the struct ieee_802_11_phdr. Ensure that the right structure gets passed to that routine, and that all the appropriate parts of that structure are filled in. Rename the 802.11 radio protocol to "wlan_radio", rather than just "radio", as it's 802.11-specific. Give all its fields "wlan_radio." names rather than "wlan." names. Change-Id: I78d79afece0ce0cf5fc17293c1e29596413b31c8 Reviewed-on: https://code.wireshark.org/review/8992 Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
parent
77ed0387c6
commit
2895d58dc3
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_noise_percent,
|
||||
{"Noise level (percentage)", "wlan.noise_percentage", FT_UINT8, BASE_DEC, NULL, 0,
|
||||
{&hf_wlan_radio_noise_percent,
|
||||
{"Noise level (percentage)", "wlan_radio.noise_percentage", FT_UINT8, BASE_DEC, NULL, 0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{&hf_noise_dbm,
|
||||
{"Noise level (dBm)", "wlan.noise_dbm", FT_INT8, 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_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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
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, FALSE, FALSE, FALSE, &phdr);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
return dissect_ieee80211_common (tvb, pinfo, tree, FALSE,
|
||||
(phdr == NULL) ? -1 : phdr->fcs_len, FALSE, TRUE, FALSE, FALSE, phdr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dissect 802.11 with a variable-length link-layer header and data padding
|
||||
* and with an FCS.
|
||||
*/
|
||||
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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 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_IS_AGGREGATE 0x0010
|
||||
#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");
|
||||
|
|
|
@ -143,11 +143,13 @@ commview_read_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
|
|||
|
||||
case MEDIUM_WIFI :
|
||||
phdr->pkt_encap = WTAP_ENCAP_IEEE_802_11_WITH_RADIO;
|
||||
phdr->pseudo_header.ieee_802_11.fcs_len = -1; /* Unknown */
|
||||
phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
|
||||
phdr->pseudo_header.ieee_802_11.datapad = FALSE;
|
||||
phdr->pseudo_header.ieee_802_11.presence_flags =
|
||||
PHDR_802_11_HAS_CHANNEL |
|
||||
PHDR_802_11_HAS_DATA_RATE |
|
||||
PHDR_802_11_HAS_SIGNAL_PERCENT;
|
||||
phdr->pseudo_header.ieee_802_11.fcs_len = -1; /* Unknown */
|
||||
phdr->pseudo_header.ieee_802_11.channel = cv_hdr.channel;
|
||||
phdr->pseudo_header.ieee_802_11.data_rate =
|
||||
cv_hdr.rate | (cv_hdr.direction << 8);
|
||||
|
|
|
@ -428,9 +428,10 @@ netmon_set_pseudo_header_info(struct wtap_pkthdr *phdr, Buffer *buf)
|
|||
* do not have an FCS).
|
||||
* An "FCS length" of -2 means "NetMon weirdness".
|
||||
*/
|
||||
phdr->pseudo_header.ieee_802_11.presence_flags = 0; /* radio data is in the packet data */
|
||||
phdr->pseudo_header.ieee_802_11.fcs_len = -2;
|
||||
phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
|
||||
phdr->pseudo_header.ieee_802_11.datapad = FALSE;
|
||||
phdr->pseudo_header.ieee_802_11.presence_flags = 0; /* radio data is in the packet data */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ static gboolean observer_read(wtap *wth, int *err, gchar **err_info,
|
|||
gint64 *data_offset);
|
||||
static gboolean observer_seek_read(wtap *wth, gint64 seek_off,
|
||||
struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
|
||||
static int read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header,
|
||||
static int read_packet_header(wtap *wth, FILE_T fh, union wtap_pseudo_header *pseudo_header,
|
||||
packet_entry_header *packet_header, int *err, gchar **err_info);
|
||||
static gboolean process_packet_header(wtap *wth,
|
||||
packet_entry_header *packet_header, struct wtap_pkthdr *phdr, int *err,
|
||||
|
@ -254,7 +254,7 @@ static gboolean observer_read(wtap *wth, int *err, gchar **err_info,
|
|||
*data_offset = file_tell(wth->fh);
|
||||
|
||||
/* process the packet header, including TLVs */
|
||||
header_bytes_consumed = read_packet_header(wth->fh, &wth->phdr.pseudo_header, &packet_header, err,
|
||||
header_bytes_consumed = read_packet_header(wth, wth->fh, &wth->phdr.pseudo_header, &packet_header, err,
|
||||
err_info);
|
||||
if (header_bytes_consumed <= 0)
|
||||
return FALSE; /* EOF or error */
|
||||
|
@ -302,7 +302,7 @@ static gboolean observer_seek_read(wtap *wth, gint64 seek_off,
|
|||
return FALSE;
|
||||
|
||||
/* process the packet header, including TLVs */
|
||||
offset = read_packet_header(wth->random_fh, pseudo_header, &packet_header, err,
|
||||
offset = read_packet_header(wth, wth->random_fh, pseudo_header, &packet_header, err,
|
||||
err_info);
|
||||
if (offset <= 0)
|
||||
return FALSE; /* EOF or error */
|
||||
|
@ -321,7 +321,7 @@ static gboolean observer_seek_read(wtap *wth, gint64 seek_off,
|
|||
}
|
||||
|
||||
static int
|
||||
read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header,
|
||||
read_packet_header(wtap *wth, FILE_T fh, union wtap_pseudo_header *pseudo_header,
|
||||
packet_entry_header *packet_header, int *err, gchar **err_info)
|
||||
{
|
||||
int offset;
|
||||
|
@ -367,6 +367,21 @@ read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* initialize the pseudo header */
|
||||
switch (wth->file_encap) {
|
||||
case WTAP_ENCAP_ETHERNET:
|
||||
/* There is no FCS in the frame */
|
||||
pseudo_header->eth.fcs_len = 0;
|
||||
break;
|
||||
case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
|
||||
pseudo_header->ieee_802_11.fcs_len = 0;
|
||||
pseudo_header->ieee_802_11.decrypted = FALSE;
|
||||
pseudo_header->ieee_802_11.datapad = FALSE;
|
||||
pseudo_header->ieee_802_11.presence_flags = 0;
|
||||
/* Updated below */
|
||||
break;
|
||||
}
|
||||
|
||||
/* process extra information */
|
||||
for (i = 0; i < packet_header->number_of_information_elements; i++) {
|
||||
/* read the TLV header */
|
||||
|
@ -389,11 +404,10 @@ read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header,
|
|||
err, err_info))
|
||||
return -1;
|
||||
/* update the pseudo header */
|
||||
pseudo_header->ieee_802_11.presence_flags =
|
||||
pseudo_header->ieee_802_11.presence_flags |=
|
||||
PHDR_802_11_HAS_CHANNEL |
|
||||
PHDR_802_11_HAS_DATA_RATE |
|
||||
PHDR_802_11_HAS_SIGNAL_PERCENT;
|
||||
pseudo_header->ieee_802_11.fcs_len = 0;
|
||||
/* set decryption status */
|
||||
pseudo_header->ieee_802_11.decrypted = (wireless_header.conditions & WIRELESS_WEP_SUCCESS) != 0;
|
||||
pseudo_header->ieee_802_11.channel = wireless_header.frequency;
|
||||
|
@ -484,17 +498,6 @@ process_packet_header(wtap *wth, packet_entry_header *packet_header,
|
|||
}
|
||||
}
|
||||
|
||||
/* update the pseudo header */
|
||||
switch (wth->file_encap) {
|
||||
case WTAP_ENCAP_ETHERNET:
|
||||
/* There is no FCS in the frame */
|
||||
phdr->pseudo_header.eth.fcs_len = 0;
|
||||
break;
|
||||
case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
|
||||
/* Updated in read_packet_header */
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1251,6 +1251,7 @@ netxray_process_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
|
|||
phdr->pseudo_header.ieee_802_11.fcs_len = 0;
|
||||
|
||||
phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
|
||||
phdr->pseudo_header.ieee_802_11.datapad = FALSE;
|
||||
|
||||
phdr->pseudo_header.ieee_802_11.channel =
|
||||
hdr.hdr_2_x.xxx[12];
|
||||
|
|
|
@ -1604,9 +1604,10 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
|
|||
* XXX - in pcap-ng, there *could* be a packet option
|
||||
* indicating the FCS length.
|
||||
*/
|
||||
phdr->pseudo_header.ieee_802_11.presence_flags = 0; /* absent or supplied in the packet data */
|
||||
phdr->pseudo_header.ieee_802_11.fcs_len = -1;
|
||||
phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
|
||||
phdr->pseudo_header.ieee_802_11.datapad = FALSE;
|
||||
phdr->pseudo_header.ieee_802_11.presence_flags = 0; /* absent or supplied in the packet data */
|
||||
break;
|
||||
|
||||
case WTAP_ENCAP_IRDA:
|
||||
|
|
|
@ -445,9 +445,10 @@ static int peekclassic_read_packet_v7(wtap *wth, FILE_T fh,
|
|||
switch (wth->file_encap) {
|
||||
|
||||
case WTAP_ENCAP_IEEE_802_11_AIROPEEK:
|
||||
phdr->pseudo_header.ieee_802_11.presence_flags = 0; /* not present */
|
||||
phdr->pseudo_header.ieee_802_11.fcs_len = 0; /* no FCS */
|
||||
phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
|
||||
phdr->pseudo_header.ieee_802_11.datapad = FALSE;
|
||||
phdr->pseudo_header.ieee_802_11.presence_flags = 0; /* not present */
|
||||
|
||||
/*
|
||||
* The last 4 bytes appear to be random data - the length
|
||||
|
|
|
@ -751,6 +751,7 @@ peektagged_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
|
|||
skip_len = 4;
|
||||
}
|
||||
phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
|
||||
phdr->pseudo_header.ieee_802_11.datapad = FALSE;
|
||||
break;
|
||||
|
||||
case WTAP_ENCAP_ETHERNET:
|
||||
|
|
|
@ -738,11 +738,13 @@ snoop_read_shomiti_wireless_pseudoheader(FILE_T fh,
|
|||
if (file_seek(fh, rsize, SEEK_CUR, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
pseudo_header->ieee_802_11.fcs_len = 4;
|
||||
pseudo_header->ieee_802_11.decrypted = FALSE;
|
||||
pseudo_header->ieee_802_11.datapad = FALSE;
|
||||
pseudo_header->ieee_802_11.presence_flags =
|
||||
PHDR_802_11_HAS_CHANNEL |
|
||||
PHDR_802_11_HAS_DATA_RATE |
|
||||
PHDR_802_11_HAS_SIGNAL_PERCENT;
|
||||
pseudo_header->ieee_802_11.fcs_len = 4;
|
||||
pseudo_header->ieee_802_11.channel = whdr.channel;
|
||||
pseudo_header->ieee_802_11.data_rate = whdr.rate;
|
||||
pseudo_header->ieee_802_11.signal_percent = whdr.signal;
|
||||
|
|
|
@ -557,6 +557,7 @@ struct p2p_phdr {
|
|||
struct ieee_802_11_phdr {
|
||||
gint fcs_len; /* Number of bytes of FCS - -1 means "unknown" */
|
||||
gboolean decrypted; /* TRUE if frame is decrypted even if "protected" bit is set */
|
||||
gboolean datapad; /* TRUE if frame has padding between 802.11 header and payload */
|
||||
guint32 presence_flags; /* Flags indicating presence of fields */
|
||||
guint16 channel; /* Channel number */
|
||||
guint16 data_rate; /* Data rate, in .5 Mb/s units */
|
||||
|
@ -564,9 +565,9 @@ struct ieee_802_11_phdr {
|
|||
guint bandwidth:2; /* Bandwidth = 20 MHz, 40 MHz, 20+20L, 20+20U */
|
||||
guint short_gi:1; /* True for short guard interval */
|
||||
guint greenfield:1; /* True for greenfield, short for mixed */
|
||||
guint ldpc:1; /* Tue for LDPC FEC */
|
||||
guint ldpc:1; /* True for LDPC FEC */
|
||||
guint stbc_streams:2; /* Number of STBC streams */
|
||||
guint ness:1; /* Number of extension spatial streams */
|
||||
guint ness; /* Number of extension spatial streams */
|
||||
guint32 frequency; /* Channel center frequency */
|
||||
guint8 signal_percent; /* Signal level, as a percentage */
|
||||
guint8 noise_percent; /* Noise level, as a percentage */
|
||||
|
|
Loading…
Reference in New Issue