]> 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>
Sat, 7 Apr 2012 09:50:25 +0000 (12:50 +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>
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 ad292b02233297109d7f4d0c2ce9acff2729310d..4314d6995baee22fe183670b90d6e4e50b973db8 100644 (file)
@@ -2398,127 +2398,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;
@@ -2532,6 +2609,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);
@@ -2571,10 +2650,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 843acc7567ffce512fb14f2834b2fdae53f4f62f..18759abf283648771e974d3999df14967667ed07 100644 (file)
@@ -1696,13 +1696,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';