summaryrefslogtreecommitdiff
path: root/caputils
diff options
context:
space:
mode:
authorMikael Kanstrup <mikael.kanstrup@gmail.com>2016-02-07 00:40:51 +0100
committerMichael Mann <mmann78@netscape.net>2016-03-01 15:23:44 +0000
commit9f27e5d7d19027ddf8f29c5a6a321912e7c2f9dd (patch)
treedf58180c18aa9d7c05086ac41d2beb445fcc8590 /caputils
parent7a1f75ed2f91f212317902020ab762ebaa3098ad (diff)
downloadwireshark-9f27e5d7d19027ddf8f29c5a6a321912e7c2f9dd.tar.gz
dumpcap: Add support for 802.11ac monitor modes
Add dumpcap support for configuring 80MHz, 80+80MHz, 160MHz monitor modes via nl80211. Change-Id: I2ae8955670c2a9b5051e2223d45ce522459f2c5f Reviewed-on: https://code.wireshark.org/review/13964 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'caputils')
-rw-r--r--caputils/ws80211_utils.c89
-rw-r--r--caputils/ws80211_utils.h14
2 files changed, 95 insertions, 8 deletions
diff --git a/caputils/ws80211_utils.c b/caputils/ws80211_utils.c
index e374372fff..c556773a1d 100644
--- a/caputils/ws80211_utils.c
+++ b/caputils/ws80211_utils.c
@@ -266,6 +266,25 @@ static void parse_band_ht_capa(struct ws80211_interface *iface,
}
#endif /* NL80211_BAND_ATTR_HT_CAPA */
+#ifdef HAVE_NL80211_VHT_CAPABILITY
+static void parse_band_vht_capa(struct ws80211_interface *iface,
+ struct nlattr *tb)
+{
+ guint32 chan_capa;
+ if (!tb) return;
+
+ chan_capa = (nla_get_u32(tb) >> 2) & 3;
+ if (chan_capa == 1) {
+ iface->channel_types |= 1 << WS80211_CHAN_VHT160;
+ }
+ if (chan_capa == 2) {
+ iface->channel_types |= 1 << WS80211_CHAN_VHT160;
+ iface->channel_types |= 1 << WS80211_CHAN_VHT80P80;
+ }
+ iface->channel_types |= 1 << WS80211_CHAN_VHT80;
+}
+#endif /* HAVE_NL80211_VHT_CAPABILITY */
+
static void parse_supported_iftypes(struct ws80211_interface *iface,
struct nlattr *tb)
{
@@ -333,6 +352,9 @@ static void parse_wiphy_bands(struct ws80211_interface *iface,
#ifdef NL80211_BAND_ATTR_HT_CAPA
parse_band_ht_capa(iface, tb_band[NL80211_BAND_ATTR_HT_CAPA]);
#endif /* NL80211_BAND_ATTR_HT_CAPA */
+#ifdef HAVE_NL80211_VHT_CAPABILITY
+ parse_band_vht_capa(iface, tb_band[NL80211_BAND_ATTR_VHT_CAPA]);
+#endif /* HAVE_NL80211_VHT_CAPABILITY */
parse_band_freqs(iface, tb_band[NL80211_BAND_ATTR_FREQS]);
}
}
@@ -489,10 +511,36 @@ static int get_iface_info_handler(struct nl_msg *msg, void *arg)
}
if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) {
+ gboolean found_ch_width = FALSE;
iface_info->pub->current_freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]);
iface_info->pub->current_chan_type = WS80211_CHAN_NO_HT;
-
- if (tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
+#ifdef HAVE_NL80211_VHT_CAPABILITY
+ if (tb_msg[NL80211_ATTR_CHANNEL_WIDTH]) {
+ switch (nla_get_u32(tb_msg[NL80211_ATTR_CHANNEL_WIDTH])) {
+ case NL80211_CHAN_WIDTH_80:
+ iface_info->pub->current_chan_type = WS80211_CHAN_VHT80;
+ found_ch_width = TRUE;
+ break;
+ case NL80211_CHAN_WIDTH_80P80:
+ iface_info->pub->current_chan_type = WS80211_CHAN_VHT80P80;
+ found_ch_width = TRUE;
+ break;
+ case NL80211_CHAN_WIDTH_160:
+ iface_info->pub->current_chan_type = WS80211_CHAN_VHT160;
+ found_ch_width = TRUE;
+ break;
+ }
+ }
+ if (tb_msg[NL80211_ATTR_CENTER_FREQ1]) {
+ iface_info->pub->current_center_freq1 =
+ nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ1]);
+ }
+ if (tb_msg[NL80211_ATTR_CENTER_FREQ2]) {
+ iface_info->pub->current_center_freq2 =
+ nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ2]);
+ }
+#endif
+ if (!found_ch_width && tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
switch (nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
case NL80211_CHAN_NO_HT:
@@ -598,7 +646,7 @@ static int ws80211_populate_devices(GArray *interfaces)
int i;
unsigned int j;
- struct ws80211_iface_info pub = {-1, WS80211_CHAN_NO_HT, WS80211_FCS_ALL};
+ struct ws80211_iface_info pub = {-1, WS80211_CHAN_NO_HT, -1, -1, WS80211_FCS_ALL};
struct __iface_info iface_info;
struct ws80211_interface *iface;
@@ -722,7 +770,7 @@ nla_put_failure:
}
DIAG_ON(shorten-64-to-32)
-int ws80211_set_freq(const char *name, int freq, int chan_type)
+int ws80211_set_freq(const char *name, int freq, int chan_type, int _U_ center_freq, int _U_ center_freq2)
{
int devidx, err;
struct nl_msg *msg;
@@ -772,7 +820,23 @@ int ws80211_set_freq(const char *name, int freq, int chan_type)
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, NL80211_CHAN_HT40PLUS);
break;
#endif
+#ifdef HAVE_NL80211_VHT_CAPABILITY
+ case WS80211_CHAN_VHT80:
+ NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH, NL80211_CHAN_WIDTH_80);
+ NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, center_freq);
+ break;
+ case WS80211_CHAN_VHT80P80:
+ NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH, NL80211_CHAN_WIDTH_80P80);
+ NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, center_freq);
+ NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ2, center_freq2);
+ break;
+
+ case WS80211_CHAN_VHT160:
+ NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH, NL80211_CHAN_WIDTH_160);
+ NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, center_freq);
+ break;
+#endif
default:
break;
}
@@ -820,6 +884,13 @@ ws80211_str_to_chan_type(const gchar *s)
ret = WS80211_CHAN_HT40MINUS;
if (!strcmp(s, CHAN_HT40PLUS))
ret = WS80211_CHAN_HT40PLUS;
+ if (!strcmp(s, CHAN_VHT80))
+ ret = WS80211_CHAN_VHT80;
+ if (!strcmp(s, CHAN_VHT80P80))
+ ret = WS80211_CHAN_VHT80P80;
+ if (!strcmp(s, CHAN_VHT160))
+ ret = WS80211_CHAN_VHT160;
+
return ret;
}
@@ -835,6 +906,12 @@ const gchar
return CHAN_HT40MINUS;
case WS80211_CHAN_HT40PLUS:
return CHAN_HT40PLUS;
+ case WS80211_CHAN_VHT80:
+ return CHAN_VHT80;
+ case WS80211_CHAN_VHT80P80:
+ return CHAN_VHT80P80;
+ case WS80211_CHAN_VHT160:
+ return CHAN_VHT160;
}
return NULL;
}
@@ -987,7 +1064,7 @@ int ws80211_get_iface_info(const char *name, struct ws80211_iface_info *iface_in
return 0;
}
-int ws80211_set_freq(const char *name, int freq, int chan_type)
+int ws80211_set_freq(const char *name, int freq, int chan_type, int _U_ center_freq, int _U_ center_freq2)
{
GList *airpcap_if_list;
int err;
@@ -1145,7 +1222,7 @@ int ws80211_get_iface_info(const char *name _U_, struct ws80211_iface_info *ifac
return -1;
}
-int ws80211_set_freq(const char *name _U_, int freq _U_, int _U_ chan_type)
+int ws80211_set_freq(const char *name _U_, int freq _U_, int _U_ chan_type, int _U_ center_freq, int _U_ center_freq2)
{
return -1;
}
diff --git a/caputils/ws80211_utils.h b/caputils/ws80211_utils.h
index d111030e25..3f58576758 100644
--- a/caputils/ws80211_utils.h
+++ b/caputils/ws80211_utils.h
@@ -31,13 +31,19 @@ enum ws80211_channel_type {
WS80211_CHAN_NO_HT,
WS80211_CHAN_HT20,
WS80211_CHAN_HT40MINUS,
- WS80211_CHAN_HT40PLUS
+ WS80211_CHAN_HT40PLUS,
+ WS80211_CHAN_VHT80,
+ WS80211_CHAN_VHT80P80,
+ WS80211_CHAN_VHT160
};
#define CHAN_NO_HT "NOHT"
#define CHAN_HT20 "HT20"
#define CHAN_HT40MINUS "HT40-"
#define CHAN_HT40PLUS "HT40+"
+#define CHAN_VHT80 "VHT80"
+#define CHAN_VHT80P80 "VHT80+80"
+#define CHAN_VHT160 "VHT160"
/* XXX This doesn't match AirpcapValidationType. Should it? */
enum ws80211_fcs_validation {
@@ -59,6 +65,8 @@ struct ws80211_interface
struct ws80211_iface_info {
int current_freq;
enum ws80211_channel_type current_chan_type;
+ int current_center_freq1;
+ int current_center_freq2;
enum ws80211_fcs_validation current_fcs_validation;
};
@@ -92,9 +100,11 @@ void ws80211_free_interfaces(GArray *interfaces);
* @param name The interface name.
* @param freq The frequency in MHz.
* @param chan_type The HT channel type (no, 20Mhz, 40Mhz...).
+ * @param center_freq The center frequency in MHz (if 80MHz, 80+80MHz or 160MHz).
+ * @param center_freq2 The 2nd center frequency in MHz (if 80+80MHz).
* @return Zero on success, nonzero on failure.
*/
-int ws80211_set_freq(const char *name, int freq, int chan_type);
+int ws80211_set_freq(const char *name, int freq, int chan_type, int _U_ center_freq, int _U_ center_freq2);
int ws80211_str_to_chan_type(const gchar *s); /* GTK+ only? */
const gchar *ws80211_chan_type_to_str(int type); /* GTK+ only? */