]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add MASK=0xH option for the ctrl_iface BSS command
authorDmitry Shmidt <dimitrysh@google.com>
Sat, 7 Apr 2012 09:23:21 +0000 (12:23 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 9 Aug 2012 20:06:00 +0000 (23:06 +0300)
This optional parameter to the BSS command can be used to select which
fields are included in the output to avoid having to parse through
unneeded information and to reduce the buffer size.

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
(cherry picked from commit 5f97dd1c57f1b72b3493ac4237b505bdd4416a57)

src/common/wpa_ctrl.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/wpa_cli.c

index 5b4846fdfe480b06751e469e1408a6245a93536d..35012e86b5399ff86c4f002bef211ee1f013257a 100644 (file)
@@ -139,6 +139,27 @@ extern "C" {
 #define AP_STA_DISCONNECTED "AP-STA-DISCONNECTED "
 
 
+/* BSS command information masks */
+
+#define WPA_BSS_MASK_ALL               0xFFFFFFFF
+#define WPA_BSS_MASK_ID                        BIT(0)
+#define WPA_BSS_MASK_BSSID             BIT(1)
+#define WPA_BSS_MASK_FREQ              BIT(2)
+#define WPA_BSS_MASK_BEACON_INT                BIT(3)
+#define WPA_BSS_MASK_CAPABILITIES      BIT(4)
+#define WPA_BSS_MASK_QUAL              BIT(5)
+#define WPA_BSS_MASK_NOISE             BIT(6)
+#define WPA_BSS_MASK_LEVEL             BIT(7)
+#define WPA_BSS_MASK_TSF               BIT(8)
+#define WPA_BSS_MASK_AGE               BIT(9)
+#define WPA_BSS_MASK_IE                        BIT(10)
+#define WPA_BSS_MASK_FLAGS             BIT(11)
+#define WPA_BSS_MASK_SSID              BIT(12)
+#define WPA_BSS_MASK_WPS_SCAN          BIT(13)
+#define WPA_BSS_MASK_P2P_SCAN          BIT(14)
+#define WPA_BSS_MASK_INTERNETW         BIT(15)
+
+
 /* wpa_supplicant/hostapd control interface access */
 
 /**
index 73a7dfb568ee26244b738dfc6df408eb480b87a3..2d9a6dbef8cff5a045f619f423bad76f1aac2386 100644 (file)
@@ -2178,127 +2178,204 @@ static char * anqp_add_hex(char *pos, char *end, const char *title,
 
 
 static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
-                         char *buf, size_t buflen)
+                         unsigned long mask, char *buf, size_t buflen)
 {
        size_t i;
        int ret;
        char *pos, *end;
        const u8 *ie, *ie2;
-       struct os_time now;
 
-       os_get_time(&now);
        pos = buf;
        end = buf + buflen;
-       ret = os_snprintf(pos, end - pos,
-                         "id=%u\n"
-                         "bssid=" MACSTR "\n"
-                         "freq=%d\n"
-                         "beacon_int=%d\n"
-                         "capabilities=0x%04x\n"
-                         "qual=%d\n"
-                         "noise=%d\n"
-                         "level=%d\n"
-                         "tsf=%016llu\n"
-                         "age=%d\n"
-                         "ie=",
-                         bss->id,
-                         MAC2STR(bss->bssid), bss->freq, bss->beacon_int,
-                         bss->caps, bss->qual, bss->noise, bss->level,
-                         (unsigned long long) bss->tsf,
-                         (int) (now.sec - bss->last_update.sec));
-       if (ret < 0 || ret >= end - pos)
-               return pos - buf;
-       pos += ret;
 
-       ie = (const u8 *) (bss + 1);
-       for (i = 0; i < bss->ie_len; i++) {
-               ret = os_snprintf(pos, end - pos, "%02x", *ie++);
+       if (mask & WPA_BSS_MASK_ID) {
+               ret = os_snprintf(pos, end - pos, "id=%u\n", bss->id);
                if (ret < 0 || ret >= end - pos)
-                       return pos - buf;
+                       return 0;
                pos += ret;
        }
 
-       ret = os_snprintf(pos, end - pos, "\n");
-       if (ret < 0 || ret >= end - pos)
-               return pos - buf;
-       pos += ret;
+       if (mask & WPA_BSS_MASK_BSSID) {
+               ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
+                                 MAC2STR(bss->bssid));
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+       }
 
-       ret = os_snprintf(pos, end - pos, "flags=");
-       if (ret < 0 || ret >= end - pos)
-               return pos - buf;
-       pos += ret;
+       if (mask & WPA_BSS_MASK_FREQ) {
+               ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq);
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+       }
 
-       ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
-       if (ie)
-               pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
-       ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
-       if (ie2)
-               pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
-       pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
-       if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
-               ret = os_snprintf(pos, end - pos, "[WEP]");
+       if (mask & WPA_BSS_MASK_BEACON_INT) {
+               ret = os_snprintf(pos, end - pos, "beacon_int=%d\n",
+                                 bss->beacon_int);
                if (ret < 0 || ret >= end - pos)
-                       return pos - buf;
+                       return 0;
                pos += ret;
        }
-       if (bss->caps & IEEE80211_CAP_IBSS) {
-               ret = os_snprintf(pos, end - pos, "[IBSS]");
+
+       if (mask & WPA_BSS_MASK_CAPABILITIES) {
+               ret = os_snprintf(pos, end - pos, "capabilities=0x%04x\n",
+                                 bss->caps);
                if (ret < 0 || ret >= end - pos)
-                       return pos - buf;
+                       return 0;
                pos += ret;
        }
-       if (bss->caps & IEEE80211_CAP_ESS) {
-               ret = os_snprintf(pos, end - pos, "[ESS]");
+
+       if (mask & WPA_BSS_MASK_QUAL) {
+               ret = os_snprintf(pos, end - pos, "qual=%d\n", bss->qual);
                if (ret < 0 || ret >= end - pos)
-                       return pos - buf;
+                       return 0;
                pos += ret;
        }
-       if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) {
-               ret = os_snprintf(pos, end - pos, "[P2P]");
+
+       if (mask & WPA_BSS_MASK_NOISE) {
+               ret = os_snprintf(pos, end - pos, "noise=%d\n", bss->noise);
                if (ret < 0 || ret >= end - pos)
-                       return pos - buf;
+                       return 0;
                pos += ret;
        }
 
-       ret = os_snprintf(pos, end - pos, "\n");
-       if (ret < 0 || ret >= end - pos)
-               return pos - buf;
-       pos += ret;
+       if (mask & WPA_BSS_MASK_LEVEL) {
+               ret = os_snprintf(pos, end - pos, "level=%d\n", bss->level);
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+       }
 
-       ret = os_snprintf(pos, end - pos, "ssid=%s\n",
-                         wpa_ssid_txt(bss->ssid, bss->ssid_len));
-       if (ret < 0 || ret >= end - pos)
-               return pos - buf;
-       pos += ret;
+       if (mask & WPA_BSS_MASK_TSF) {
+               ret = os_snprintf(pos, end - pos, "tsf=%016llu\n",
+                                 (unsigned long long) bss->tsf);
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+       }
+
+       if (mask & WPA_BSS_MASK_AGE) {
+               struct os_time now;
+
+               os_get_time(&now);
+               ret = os_snprintf(pos, end - pos, "age=%d\n",
+                                 (int) (now.sec - bss->last_update.sec));
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+       }
+
+       if (mask & WPA_BSS_MASK_IE) {
+               ret = os_snprintf(pos, end - pos, "ie=");
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+
+               ie = (const u8 *) (bss + 1);
+               for (i = 0; i < bss->ie_len; i++) {
+                       ret = os_snprintf(pos, end - pos, "%02x", *ie++);
+                       if (ret < 0 || ret >= end - pos)
+                               return 0;
+                       pos += ret;
+               }
+
+               ret = os_snprintf(pos, end - pos, "\n");
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+       }
+
+       if (mask & WPA_BSS_MASK_FLAGS) {
+               ret = os_snprintf(pos, end - pos, "flags=");
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+
+               ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
+               if (ie)
+                       pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie,
+                                                   2 + ie[1]);
+               ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+               if (ie2)
+                       pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2,
+                                                   2 + ie2[1]);
+               pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
+               if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
+                       ret = os_snprintf(pos, end - pos, "[WEP]");
+                       if (ret < 0 || ret >= end - pos)
+                               return 0;
+                       pos += ret;
+               }
+               if (bss->caps & IEEE80211_CAP_IBSS) {
+                       ret = os_snprintf(pos, end - pos, "[IBSS]");
+                       if (ret < 0 || ret >= end - pos)
+                               return 0;
+                       pos += ret;
+               }
+               if (bss->caps & IEEE80211_CAP_ESS) {
+                       ret = os_snprintf(pos, end - pos, "[ESS]");
+                       if (ret < 0 || ret >= end - pos)
+                               return 0;
+                       pos += ret;
+               }
+               if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) {
+                       ret = os_snprintf(pos, end - pos, "[P2P]");
+                       if (ret < 0 || ret >= end - pos)
+                               return 0;
+                       pos += ret;
+               }
+
+               ret = os_snprintf(pos, end - pos, "\n");
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+       }
+
+       if (mask & WPA_BSS_MASK_SSID) {
+               ret = os_snprintf(pos, end - pos, "ssid=%s\n",
+                                 wpa_ssid_txt(bss->ssid, bss->ssid_len));
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+       }
 
 #ifdef CONFIG_WPS
-       ie = (const u8 *) (bss + 1);
-       ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
-       if (ret < 0 || ret >= end - pos)
-               return pos - buf;
-       pos += ret;
+       if (mask & WPA_BSS_MASK_WPS_SCAN) {
+               ie = (const u8 *) (bss + 1);
+               ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+       }
 #endif /* CONFIG_WPS */
 
 #ifdef CONFIG_P2P
-       ie = (const u8 *) (bss + 1);
-       ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end);
-       if (ret < 0 || ret >= end - pos)
-               return pos - buf;
-       pos += ret;
+       if (mask & WPA_BSS_MASK_P2P_SCAN) {
+               ie = (const u8 *) (bss + 1);
+               ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end);
+               if (ret < 0 || ret >= end - pos)
+                       return 0;
+               pos += ret;
+       }
 #endif /* CONFIG_P2P */
 
 #ifdef CONFIG_INTERWORKING
-       pos = anqp_add_hex(pos, end, "anqp_venue_name", bss->anqp_venue_name);
-       pos = anqp_add_hex(pos, end, "anqp_network_auth_type",
-                          bss->anqp_network_auth_type);
-       pos = anqp_add_hex(pos, end, "anqp_roaming_consortium",
-                          bss->anqp_roaming_consortium);
-       pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability",
-                          bss->anqp_ip_addr_type_availability);
-       pos = anqp_add_hex(pos, end, "anqp_nai_realm", bss->anqp_nai_realm);
-       pos = anqp_add_hex(pos, end, "anqp_3gpp", bss->anqp_3gpp);
-       pos = anqp_add_hex(pos, end, "anqp_domain_name",
-                          bss->anqp_domain_name);
+       if (mask & WPA_BSS_MASK_INTERNETW) {
+               pos = anqp_add_hex(pos, end, "anqp_venue_name",
+                                  bss->anqp_venue_name);
+               pos = anqp_add_hex(pos, end, "anqp_network_auth_type",
+                                  bss->anqp_network_auth_type);
+               pos = anqp_add_hex(pos, end, "anqp_roaming_consortium",
+                                  bss->anqp_roaming_consortium);
+               pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability",
+                                  bss->anqp_ip_addr_type_availability);
+               pos = anqp_add_hex(pos, end, "anqp_nai_realm",
+                                  bss->anqp_nai_realm);
+               pos = anqp_add_hex(pos, end, "anqp_3gpp", bss->anqp_3gpp);
+               pos = anqp_add_hex(pos, end, "anqp_domain_name",
+                                  bss->anqp_domain_name);
+       }
 #endif /* CONFIG_INTERWORKING */
 
        return pos - buf;
@@ -2312,6 +2389,8 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
        u8 bssid[ETH_ALEN];
        size_t i;
        struct wpa_bss *bss;
+       char *ctmp;
+       unsigned long mask = WPA_BSS_MASK_ALL;
 
        if (os_strcmp(cmd, "FIRST") == 0)
                bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list);
@@ -2351,10 +2430,16 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
                }
        }
 
+       if ((ctmp = os_strstr(cmd, "MASK=")) != NULL) {
+               mask = strtoul(ctmp + 5, NULL, 0x10);
+               if (mask == 0)
+                       mask = WPA_BSS_MASK_ALL;
+       }
+
        if (bss == NULL)
                return 0;
 
-       return print_bss_info(wpa_s, bss, buf, buflen);
+       return print_bss_info(wpa_s, bss, mask, buf, buflen);
 }
 
 
index af2e991187f0ceea2d12033201e2950f2b718751..4cd289bf51abeb8faa2d344ab27f789e8b82e1d8 100644 (file)
@@ -1636,13 +1636,16 @@ static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
        char cmd[64];
        int res;
 
-       if (argc != 1) {
-               printf("Invalid BSS command: need one argument (index or "
-                      "BSSID)\n");
+       if (argc < 1) {
+               printf("Invalid BSS command: need at least one argument"
+                      "(index or BSSID)\n");
                return -1;
        }
 
-       res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
+       res = os_snprintf(cmd, sizeof(cmd), "BSS %s%s%s%s%s", argv[0],
+                         argc > 1 ? " " : "", argc > 1 ? argv[1] : "",
+                         argc > 2 ? " " : "", argc > 2 ? argv[2] : "");
+
        if (res < 0 || (size_t) res >= sizeof(cmd))
                return -1;
        cmd[sizeof(cmd) - 1] = '\0';