WNM: Add support for SSID List element matching
This allows Probe Request frame processing to compare the configured SSID to the SSID List element in addition to the SSID element. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
b93c8509cc
commit
0a66ce3c49
5 changed files with 67 additions and 10 deletions
|
@ -2,7 +2,7 @@
|
||||||
* hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response
|
* hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response
|
||||||
* Copyright (c) 2002-2004, Instant802 Networks, Inc.
|
* Copyright (c) 2002-2004, Instant802 Networks, Inc.
|
||||||
* Copyright (c) 2005-2006, Devicescape Software, Inc.
|
* Copyright (c) 2005-2006, Devicescape Software, Inc.
|
||||||
* Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -310,6 +310,46 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum ssid_match_result {
|
||||||
|
NO_SSID_MATCH,
|
||||||
|
EXACT_SSID_MATCH,
|
||||||
|
WILDCARD_SSID_MATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
|
||||||
|
const u8 *ssid, size_t ssid_len,
|
||||||
|
const u8 *ssid_list,
|
||||||
|
size_t ssid_list_len)
|
||||||
|
{
|
||||||
|
const u8 *pos, *end;
|
||||||
|
int wildcard = 0;
|
||||||
|
|
||||||
|
if (ssid_len == 0)
|
||||||
|
wildcard = 1;
|
||||||
|
if (ssid_len == hapd->conf->ssid.ssid_len &&
|
||||||
|
os_memcmp(ssid, hapd->conf->ssid.ssid, ssid_len) == 0)
|
||||||
|
return EXACT_SSID_MATCH;
|
||||||
|
|
||||||
|
if (ssid_list == NULL)
|
||||||
|
return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
|
||||||
|
|
||||||
|
pos = ssid_list;
|
||||||
|
end = ssid_list + ssid_list_len;
|
||||||
|
while (pos + 1 <= end) {
|
||||||
|
if (pos + 2 + pos[1] > end)
|
||||||
|
break;
|
||||||
|
if (pos[1] == 0)
|
||||||
|
wildcard = 1;
|
||||||
|
if (pos[1] == hapd->conf->ssid.ssid_len &&
|
||||||
|
os_memcmp(pos + 2, hapd->conf->ssid.ssid, pos[1]) == 0)
|
||||||
|
return EXACT_SSID_MATCH;
|
||||||
|
pos += 2 + pos[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void handle_probe_req(struct hostapd_data *hapd,
|
void handle_probe_req(struct hostapd_data *hapd,
|
||||||
const struct ieee80211_mgmt *mgmt, size_t len,
|
const struct ieee80211_mgmt *mgmt, size_t len,
|
||||||
int ssi_signal)
|
int ssi_signal)
|
||||||
|
@ -321,6 +361,7 @@ void handle_probe_req(struct hostapd_data *hapd,
|
||||||
struct sta_info *sta = NULL;
|
struct sta_info *sta = NULL;
|
||||||
size_t i, resp_len;
|
size_t i, resp_len;
|
||||||
int noack;
|
int noack;
|
||||||
|
enum ssid_match_result res;
|
||||||
|
|
||||||
ie = mgmt->u.probe_req.variable;
|
ie = mgmt->u.probe_req.variable;
|
||||||
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
|
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
|
||||||
|
@ -376,7 +417,8 @@ void handle_probe_req(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0) {
|
if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
|
||||||
|
elems.ssid_list_len == 0) {
|
||||||
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
|
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
|
||||||
"broadcast SSID ignored", MAC2STR(mgmt->sa));
|
"broadcast SSID ignored", MAC2STR(mgmt->sa));
|
||||||
return;
|
return;
|
||||||
|
@ -394,10 +436,9 @@ void handle_probe_req(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
if (elems.ssid_len == 0 ||
|
res = ssid_match(hapd, elems.ssid, elems.ssid_len,
|
||||||
(elems.ssid_len == hapd->conf->ssid.ssid_len &&
|
elems.ssid_list, elems.ssid_list_len);
|
||||||
os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) ==
|
if (res != NO_SSID_MATCH) {
|
||||||
0)) {
|
|
||||||
if (sta)
|
if (sta)
|
||||||
sta->ssid_probe = &hapd->conf->ssid;
|
sta->ssid_probe = &hapd->conf->ssid;
|
||||||
} else {
|
} else {
|
||||||
|
@ -406,9 +447,10 @@ void handle_probe_req(struct hostapd_data *hapd,
|
||||||
ieee802_11_print_ssid(ssid_txt, elems.ssid,
|
ieee802_11_print_ssid(ssid_txt, elems.ssid,
|
||||||
elems.ssid_len);
|
elems.ssid_len);
|
||||||
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
|
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
|
||||||
" for foreign SSID '%s' (DA " MACSTR ")",
|
" for foreign SSID '%s' (DA " MACSTR ")%s",
|
||||||
MAC2STR(mgmt->sa), ssid_txt,
|
MAC2STR(mgmt->sa), ssid_txt,
|
||||||
MAC2STR(mgmt->da));
|
MAC2STR(mgmt->da),
|
||||||
|
elems.ssid_list ? " (SSID list)" : "");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -455,7 +497,8 @@ void handle_probe_req(struct hostapd_data *hapd,
|
||||||
* If this is a broadcast probe request, apply no ack policy to avoid
|
* If this is a broadcast probe request, apply no ack policy to avoid
|
||||||
* excessive retries.
|
* excessive retries.
|
||||||
*/
|
*/
|
||||||
noack = !!(elems.ssid_len == 0 && is_broadcast_ether_addr(mgmt->da));
|
noack = !!(res == WILDCARD_SSID_MATCH &&
|
||||||
|
is_broadcast_ether_addr(mgmt->da));
|
||||||
|
|
||||||
if (hostapd_drv_send_mlme(hapd, resp, resp_len, noack) < 0)
|
if (hostapd_drv_send_mlme(hapd, resp, resp_len, noack) < 0)
|
||||||
perror("handle_probe_req: send");
|
perror("handle_probe_req: send");
|
||||||
|
|
|
@ -177,6 +177,10 @@ u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid)
|
||||||
len = 3;
|
len = 3;
|
||||||
if (len < 7 && hapd->conf->ssid.utf8_ssid)
|
if (len < 7 && hapd->conf->ssid.utf8_ssid)
|
||||||
len = 7;
|
len = 7;
|
||||||
|
#ifdef CONFIG_WNM
|
||||||
|
if (len < 4)
|
||||||
|
len = 4;
|
||||||
|
#endif /* CONFIG_WNM */
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return eid;
|
return eid;
|
||||||
|
|
||||||
|
@ -193,6 +197,9 @@ u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid)
|
||||||
if (len < 4)
|
if (len < 4)
|
||||||
return pos;
|
return pos;
|
||||||
*pos = 0x00;
|
*pos = 0x00;
|
||||||
|
#ifdef CONFIG_WNM
|
||||||
|
*pos |= 0x02; /* Bit 25 - SSID List */
|
||||||
|
#endif /* CONFIG_WNM */
|
||||||
if (hapd->conf->time_advertisement == 2)
|
if (hapd->conf->time_advertisement == 2)
|
||||||
*pos |= 0x08; /* Bit 27 - UTC TSF Offset */
|
*pos |= 0x08; /* Bit 27 - UTC TSF Offset */
|
||||||
if (hapd->conf->interworking)
|
if (hapd->conf->interworking)
|
||||||
|
|
|
@ -284,6 +284,10 @@ ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
|
||||||
break;
|
break;
|
||||||
elems->bss_max_idle_period = pos;
|
elems->bss_max_idle_period = pos;
|
||||||
break;
|
break;
|
||||||
|
case WLAN_EID_SSID_LIST:
|
||||||
|
elems->ssid_list = pos;
|
||||||
|
elems->ssid_list_len = elen;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
unknown++;
|
unknown++;
|
||||||
if (!show_errors)
|
if (!show_errors)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* IEEE 802.11 Common routines
|
* IEEE 802.11 Common routines
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -43,6 +43,7 @@ struct ieee802_11_elems {
|
||||||
const u8 *hs20;
|
const u8 *hs20;
|
||||||
const u8 *ext_capab;
|
const u8 *ext_capab;
|
||||||
const u8 *bss_max_idle_period;
|
const u8 *bss_max_idle_period;
|
||||||
|
const u8 *ssid_list;
|
||||||
|
|
||||||
u8 ssid_len;
|
u8 ssid_len;
|
||||||
u8 supp_rates_len;
|
u8 supp_rates_len;
|
||||||
|
@ -74,6 +75,7 @@ struct ieee802_11_elems {
|
||||||
u8 interworking_len;
|
u8 interworking_len;
|
||||||
u8 hs20_len;
|
u8 hs20_len;
|
||||||
u8 ext_capab_len;
|
u8 ext_capab_len;
|
||||||
|
u8 ssid_list_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
|
typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
|
||||||
|
|
|
@ -232,6 +232,7 @@
|
||||||
#define WLAN_EID_20_40_BSS_INTOLERANT 73
|
#define WLAN_EID_20_40_BSS_INTOLERANT 73
|
||||||
#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74
|
#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74
|
||||||
#define WLAN_EID_MMIE 76
|
#define WLAN_EID_MMIE 76
|
||||||
|
#define WLAN_EID_SSID_LIST 84
|
||||||
#define WLAN_EID_BSS_MAX_IDLE_PERIOD 90
|
#define WLAN_EID_BSS_MAX_IDLE_PERIOD 90
|
||||||
#define WLAN_EID_TFS_REQ 91
|
#define WLAN_EID_TFS_REQ 91
|
||||||
#define WLAN_EID_TFS_RESP 92
|
#define WLAN_EID_TFS_RESP 92
|
||||||
|
|
Loading…
Add table
Reference in a new issue