diff mbox series

[IWINFO,v4,1/4] iwinfo: export ht and vht operation in scan results

Message ID 20201206011827.20782-2-ansuelsmth@gmail.com
State New
Headers show
Series Add support channel with to iwinfo | expand

Commit Message

Ansuel Smith Dec. 6, 2020, 1:18 a.m. UTC
Export ht and vht operation data in scan results. These additional data
can be usefull to check wifi channel utilizzation by neraby stations.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
 include/iwinfo.h | 34 ++++++++++++++++++++++++++++++++++
 iwinfo_cli.c     | 35 ++++++++++++++++++++++++++++++++++-
 iwinfo_nl80211.c | 10 ++++++++++
 3 files changed, 78 insertions(+), 1 deletion(-)

Comments

Jo-Philipp Wich Jan. 5, 2021, 10:20 p.m. UTC | #1
Hi,

comments inline below.

> [...]@@ -2306,6 +2306,16 @@ static void nl80211_get_scanlist_ie(struct nlattr **bss,
>  				iwinfo_parse_rsn(&e->crypto, ie + 6, ie[1] - 4,
>  				                 IWINFO_CIPHER_TKIP, IWINFO_KMGMT_PSK);
>  			break;
> +		case 61: /* HT oeration */

Wrap the next three lines into  if (ie[1] >= 3) { ... } to avoid reading
beyond buffer end on malformed data.

> +			e->ht_chan_info.primary_chan = ie[2];
> +			e->ht_chan_info.secondary_chan_off = ie[3] & 0x3;
> +			e->ht_chan_info.chan_width = (ie[4] & 0x4)>>2;
> +			break;
> +		case 192: /* VHT operation */

Wrap the next three lines into  if (ie[1] >= 3) { ... } to avoid reading
beyond buffer end on malformed data.

> +			e->vht_chan_info.chan_width = ie[2];
> +			e->vht_chan_info.center_chan_1 = ie[3];
> +			e->vht_chan_info.center_chan_2 = ie[4];
> +			break;
>  		}
>  
>  		ielen -= ie[1] + 2;
> 

~ Jo
diff mbox series

Patch

diff --git a/include/iwinfo.h b/include/iwinfo.h
index 5e64294..676db91 100644
--- a/include/iwinfo.h
+++ b/include/iwinfo.h
@@ -170,6 +170,38 @@  struct iwinfo_crypto_entry {
 	uint8_t auth_algs;
 };
 
+struct iwinfo_scanlist_ht_chan_entry {
+	uint8_t primary_chan;
+	uint8_t secondary_chan_off;
+	uint8_t chan_width;
+};
+
+struct iwinfo_scanlist_vht_chan_entry {
+	uint8_t chan_width;
+	uint8_t center_chan_1;
+	uint8_t center_chan_2;
+};
+
+static const char *ht_secondary_offset[4] = {
+	"no secondary",
+	"above",
+	"[reserved!]",
+	"below",
+};
+
+
+static uint16_t ht_chan_width[2] = {
+	20, /* 20 MHz */
+	2040, /* 40 MHz or higher (refer to vht if supported) */
+};
+
+static uint16_t vht_chan_width[] = {
+	[0] = 40, /* 40 MHz or lower (refer to ht to a more precise width) */
+	[1] = 80, /* 80 MHz */
+	[3] = 8080, /* 80+80 MHz */
+	[2] = 160, /* 160 MHz */
+};
+
 struct iwinfo_scanlist_entry {
 	uint8_t mac[6];
 	char ssid[IWINFO_ESSID_MAX_SIZE+1];
@@ -179,6 +211,8 @@  struct iwinfo_scanlist_entry {
 	uint8_t quality;
 	uint8_t quality_max;
 	struct iwinfo_crypto_entry crypto;
+	struct iwinfo_scanlist_ht_chan_entry ht_chan_info;
+	struct iwinfo_scanlist_vht_chan_entry vht_chan_info;
 };
 
 struct iwinfo_country_entry {
diff --git a/iwinfo_cli.c b/iwinfo_cli.c
index 0332bc2..6bfe0ab 100644
--- a/iwinfo_cli.c
+++ b/iwinfo_cli.c
@@ -323,6 +323,20 @@  static char * format_assocrate(struct iwinfo_rate_entry *r)
 	return buf;
 }
 
+static const char* format_chan_width(uint16_t width)
+{
+	switch (width) {
+		case 20: return "20 MHz";
+		case 2040: return "40 MHz and upper or 20 MHz with intolerant bit";
+		case 40: return "40 MHz or lower";
+		case 80: return "80 MHz";
+		case 8080: return "80+80 MHz";
+		case 160: return "160 MHz";
+	}
+
+	return "unknown";
+}
+
 
 static const char * print_type(const struct iwinfo_ops *iw, const char *ifname)
 {
@@ -612,8 +626,27 @@  static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname)
 			format_signal(e->signal - 0x100),
 			format_quality(e->quality),
 			format_quality_max(e->quality_max));
-		printf("          Encryption: %s\n\n",
+		printf("          Encryption: %s\n",
 		       format_encryption(&e->crypto));
+		printf("          HT Operation:\n");
+		printf("                    Primary Channel: %d\n",
+		       e->ht_chan_info.primary_chan);
+		printf("                    Secondary Channel Offset: %s\n",
+		       ht_secondary_offset[e->ht_chan_info.secondary_chan_off]);
+		printf("                    Channel Width: %s\n",
+		       format_chan_width(ht_chan_width[e->ht_chan_info.chan_width]));
+
+		if (e->vht_chan_info.center_chan_1) {
+		  printf("          VHT Operation:\n");
+		  printf("                    Channel Width: %s\n",
+		         format_chan_width(vht_chan_width[e->vht_chan_info.chan_width]));
+		  printf("                    Center Frequency 1: %d\n",
+		         e->vht_chan_info.center_chan_1);
+		  printf("                    Center Frequency 2: %d\n",
+		         e->vht_chan_info.center_chan_2);
+		}
+
+		printf("\n");
 	}
 }
 
diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c
index 2b2a043..5917e3a 100644
--- a/iwinfo_nl80211.c
+++ b/iwinfo_nl80211.c
@@ -2306,6 +2306,16 @@  static void nl80211_get_scanlist_ie(struct nlattr **bss,
 				iwinfo_parse_rsn(&e->crypto, ie + 6, ie[1] - 4,
 				                 IWINFO_CIPHER_TKIP, IWINFO_KMGMT_PSK);
 			break;
+		case 61: /* HT oeration */
+			e->ht_chan_info.primary_chan = ie[2];
+			e->ht_chan_info.secondary_chan_off = ie[3] & 0x3;
+			e->ht_chan_info.chan_width = (ie[4] & 0x4)>>2;
+			break;
+		case 192: /* VHT operation */
+			e->vht_chan_info.chan_width = ie[2];
+			e->vht_chan_info.center_chan_1 = ie[3];
+			e->vht_chan_info.center_chan_2 = ie[4];
+			break;
 		}
 
 		ielen -= ie[1] + 2;