diff --git a/src/drivers/driver.h b/src/drivers/driver.h index d3bda1800..5927e4962 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -322,6 +322,8 @@ struct wpa_driver_capa { * struct wpa_driver_ops::set_key using alg = WPA_ALG_PMK */ #define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE 0x00000008 unsigned int flags; + + int max_scan_ssids; }; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 35de07384..cc8fdb715 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -1402,6 +1402,62 @@ static int wpa_driver_nl80211_create_monitor_interface( #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 * @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); + wpa_driver_nl80211_capa(drv); + wpa_driver_nl80211_send_oper_ifla(drv, 1, IF_OPER_DORMANT); } diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c index 49b21608e..f0d3b43bd 100644 --- a/src/drivers/driver_test.c +++ b/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; if (drv->use_mlme) capa->flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME; + capa->max_scan_ssids = 10; return 0; } diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c index 8c2daa827..bc2137b02 100644 --- a/src/drivers/driver_wext.c +++ b/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; if (range->enc_capa & IW_ENC_CAPA_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 " "flags 0x%x", diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 56b4fd547..6eb0eec72 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/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) wpa_s->driver_4way_handshake = 1; + wpa_s->max_scan_ssids = capa.max_scan_ssids; } #ifdef CONFIG_IBSS_RSN diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index b49f23ae3..1af64d2e2 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -351,6 +351,7 @@ struct wpa_supplicant { struct wpa_client_mlme mlme; int use_client_mlme; int driver_4way_handshake; + int max_scan_ssids; int pending_mic_error_report; int pending_mic_error_pairwise;