Browse Source

New driver capability info: max number of scan SSIDs

The driver wrappers can now inform wpa_supplicant how many SSIDs can
be used in a single scan request (i.e., send multiple Probe Requests
per channel). This value is not yet used, but it can eventually be used
to allow a new scan command to specify multiple SSIDs to speed up
scan_ssid=1 operations. In addition, a warning could be printed if
scan_ssid=1 is used with a driver that does not support it
(max_scan_ssids=0).
Jouni Malinen 16 years ago
parent
commit
80bc75f135

+ 2 - 0
src/drivers/driver.h

@@ -322,6 +322,8 @@ struct wpa_driver_capa {
  * struct wpa_driver_ops::set_key using alg = WPA_ALG_PMK */
  * struct wpa_driver_ops::set_key using alg = WPA_ALG_PMK */
 #define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE 0x00000008
 #define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE 0x00000008
 	unsigned int flags;
 	unsigned int flags;
+
+	int max_scan_ssids;
 };
 };
 
 
 
 

+ 58 - 0
src/drivers/driver_nl80211.c

@@ -1402,6 +1402,62 @@ static int wpa_driver_nl80211_create_monitor_interface(
 #endif /* CONFIG_CLIENT_MLME */
 #endif /* CONFIG_CLIENT_MLME */
 
 
 
 
+struct wiphy_info_data {
+	int max_scan_ssids;
+};
+
+
+static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+{
+	struct nlattr *tb[NL80211_ATTR_MAX + 1];
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+	struct wiphy_info_data *info = arg;
+
+	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+		  genlmsg_attrlen(gnlh, 0), NULL);
+
+	if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
+		info->max_scan_ssids =
+			nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
+
+	return NL_SKIP;
+}
+
+
+static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
+				       struct wiphy_info_data *info)
+{
+	struct nl_msg *msg;
+
+	os_memset(info, 0, sizeof(*info));
+	msg = nlmsg_alloc();
+	if (!msg)
+		return -1;
+
+	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
+		    0, NL80211_CMD_GET_WIPHY, 0);
+
+	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+
+	if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info) == 0)
+		return 0;
+	msg = NULL;
+nla_put_failure:
+	nlmsg_free(msg);
+	return -1;
+}
+
+
+static void wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
+{
+	struct wiphy_info_data info;
+	if (wpa_driver_nl80211_get_info(drv, &info))
+		return;
+	drv->has_capability = 1;
+	drv->capa.max_scan_ssids = info.max_scan_ssids;
+}
+
+
 /**
 /**
  * wpa_driver_nl80211_init - Initialize nl80211 driver interface
  * wpa_driver_nl80211_init - Initialize nl80211 driver interface
  * @ctx: context to be used when calling wpa_supplicant functions,
  * @ctx: context to be used when calling wpa_supplicant functions,
@@ -1550,6 +1606,8 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
 
 
 	drv->ifindex = if_nametoindex(drv->ifname);
 	drv->ifindex = if_nametoindex(drv->ifname);
 
 
+	wpa_driver_nl80211_capa(drv);
+
 	wpa_driver_nl80211_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
 	wpa_driver_nl80211_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
 }
 }
 
 

+ 1 - 0
src/drivers/driver_test.c

@@ -1016,6 +1016,7 @@ static int wpa_driver_test_get_capa(void *priv, struct wpa_driver_capa *capa)
 		WPA_DRIVER_AUTH_LEAP;
 		WPA_DRIVER_AUTH_LEAP;
 	if (drv->use_mlme)
 	if (drv->use_mlme)
 		capa->flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME;
 		capa->flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME;
+	capa->max_scan_ssids = 10;
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 0
src/drivers/driver_wext.c

@@ -1608,6 +1608,7 @@ static int wpa_driver_wext_get_range(void *priv)
 			drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
 			drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
 		if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
 		if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
 			drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
 			drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
+		drv->capa.max_scan_ssids = 1;
 
 
 		wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x "
 		wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x "
 			   "flags 0x%x",
 			   "flags 0x%x",

+ 1 - 0
wpa_supplicant/wpa_supplicant.c

@@ -1898,6 +1898,7 @@ static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s)
 		}
 		}
 		if (capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)
 		if (capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)
 			wpa_s->driver_4way_handshake = 1;
 			wpa_s->driver_4way_handshake = 1;
+		wpa_s->max_scan_ssids = capa.max_scan_ssids;
 	}
 	}
 
 
 #ifdef CONFIG_IBSS_RSN
 #ifdef CONFIG_IBSS_RSN

+ 1 - 0
wpa_supplicant/wpa_supplicant_i.h

@@ -351,6 +351,7 @@ struct wpa_supplicant {
 	struct wpa_client_mlme mlme;
 	struct wpa_client_mlme mlme;
 	int use_client_mlme;
 	int use_client_mlme;
 	int driver_4way_handshake;
 	int driver_4way_handshake;
+	int max_scan_ssids;
 
 
 	int pending_mic_error_report;
 	int pending_mic_error_report;
 	int pending_mic_error_pairwise;
 	int pending_mic_error_pairwise;