P2P: Filter Probe Request frames based on DA and BSSID in Listen state

Only accept Probe Request frames that have a Wildcard BSSID and a
destination address that matches with our P2P Device Address or is the
broadcast address per P2P specification 3.1.2.1.1.
This commit is contained in:
Jouni Malinen 2011-07-15 20:25:53 +03:00
parent 15f0961447
commit 04a85e4401
15 changed files with 72 additions and 22 deletions

View File

@ -217,7 +217,8 @@ void handle_probe_req(struct hostapd_data *hapd,
for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
mgmt->sa, ie, ie_len) > 0) mgmt->sa, mgmt->da, mgmt->bssid,
ie, ie_len) > 0)
return; return;
if (!hapd->iconf->send_probe_response) if (!hapd->iconf->send_probe_response)

View File

@ -250,8 +250,8 @@ void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
} }
int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
const u8 *ie, size_t ie_len) const u8 *bssid, const u8 *ie, size_t ie_len)
{ {
size_t i; size_t i;
int ret = 0; int ret = 0;
@ -262,7 +262,7 @@ int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa,
random_add_randomness(sa, ETH_ALEN); random_add_randomness(sa, ETH_ALEN);
for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) { for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
sa, ie, ie_len) > 0) { sa, da, bssid, ie, ie_len) > 0) {
ret = 1; ret = 1;
break; break;
} }
@ -540,6 +540,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->rx_probe_req.ie == NULL) data->rx_probe_req.ie == NULL)
break; break;
hostapd_probe_req_rx(hapd, data->rx_probe_req.sa, hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
data->rx_probe_req.da,
data->rx_probe_req.bssid,
data->rx_probe_req.ie, data->rx_probe_req.ie,
data->rx_probe_req.ie_len); data->rx_probe_req.ie_len);
break; break;

View File

@ -31,7 +31,8 @@ enum wps_event;
union wps_event_data; union wps_event_data;
struct hostapd_probereq_cb { struct hostapd_probereq_cb {
int (*cb)(void *ctx, const u8 *sa, const u8 *ie, size_t ie_len); int (*cb)(void *ctx, const u8 *sa, const u8 *da, const u8 *bssid,
const u8 *ie, size_t ie_len);
void *ctx; void *ctx;
}; };
@ -247,6 +248,7 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
/* utils.c */ /* utils.c */
int hostapd_register_probereq_cb(struct hostapd_data *hapd, int hostapd_register_probereq_cb(struct hostapd_data *hapd,
int (*cb)(void *ctx, const u8 *sa, int (*cb)(void *ctx, const u8 *sa,
const u8 *da, const u8 *bssid,
const u8 *ie, size_t ie_len), const u8 *ie, size_t ie_len),
void *ctx); void *ctx);
void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr); void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr);
@ -256,7 +258,7 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
const u8 *ie, size_t ielen, int reassoc); const u8 *ie, size_t ielen, int reassoc);
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr); void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr);
void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr); void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr);
int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
const u8 *ie, size_t ie_len); const u8 *bssid, const u8 *ie, size_t ie_len);
#endif /* HOSTAPD_H */ #endif /* HOSTAPD_H */

View File

@ -22,6 +22,7 @@
int hostapd_register_probereq_cb(struct hostapd_data *hapd, int hostapd_register_probereq_cb(struct hostapd_data *hapd,
int (*cb)(void *ctx, const u8 *sa, int (*cb)(void *ctx, const u8 *sa,
const u8 *da, const u8 *bssid,
const u8 *ie, size_t ie_len), const u8 *ie, size_t ie_len),
void *ctx) void *ctx)
{ {

View File

@ -41,7 +41,8 @@ static int hostapd_wps_upnp_init(struct hostapd_data *hapd,
static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd); static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd);
#endif /* CONFIG_WPS_UPNP */ #endif /* CONFIG_WPS_UPNP */
static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr, static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr, const u8 *da,
const u8 *bssid,
const u8 *ie, size_t ie_len); const u8 *ie, size_t ie_len);
static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx); static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
@ -1076,7 +1077,8 @@ error:
#endif /* CONFIG_WPS_OOB */ #endif /* CONFIG_WPS_OOB */
static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr, static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr, const u8 *da,
const u8 *bssid,
const u8 *ie, size_t ie_len) const u8 *ie, size_t ie_len)
{ {
struct hostapd_data *hapd = ctx; struct hostapd_data *hapd = ctx;

View File

@ -3080,6 +3080,18 @@ union wpa_event_data {
*/ */
const u8 *sa; const u8 *sa;
/**
* da - Destination address of the received Probe Request frame
* or %NULL if not available
*/
const u8 *da;
/**
* bssid - BSSID of the received Probe Request frame or %NULL
* if not available
*/
const u8 *bssid;
/** /**
* ie - IEs from the Probe Request body * ie - IEs from the Probe Request body
*/ */

View File

@ -748,6 +748,8 @@ static void atheros_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
os_memset(&event, 0, sizeof(event)); os_memset(&event, 0, sizeof(event));
event.rx_probe_req.sa = mgmt->sa; event.rx_probe_req.sa = mgmt->sa;
event.rx_probe_req.da = mgmt->da;
event.rx_probe_req.bssid = mgmt->bssid;
event.rx_probe_req.ie = mgmt->u.probe_req.variable; event.rx_probe_req.ie = mgmt->u.probe_req.variable;
event.rx_probe_req.ie_len = event.rx_probe_req.ie_len =
len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));

View File

@ -734,6 +734,8 @@ static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
os_memset(&event, 0, sizeof(event)); os_memset(&event, 0, sizeof(event));
event.rx_probe_req.sa = mgmt->sa; event.rx_probe_req.sa = mgmt->sa;
event.rx_probe_req.da = mgmt->da;
event.rx_probe_req.bssid = mgmt->bssid;
event.rx_probe_req.ie = mgmt->u.probe_req.variable; event.rx_probe_req.ie = mgmt->u.probe_req.variable;
event.rx_probe_req.ie_len = event.rx_probe_req.ie_len =
len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));

View File

@ -561,7 +561,7 @@ static void test_driver_scan(struct wpa_driver_test_data *drv,
wpa_supplicant_event(drv->ctx, EVENT_RX_PROBE_REQ, &event); wpa_supplicant_event(drv->ctx, EVENT_RX_PROBE_REQ, &event);
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
if (drv->p2p) if (drv->p2p)
p2p_probe_req_rx(drv->p2p, sa, ie, ielen); p2p_probe_req_rx(drv->p2p, sa, NULL, NULL, ie, ielen);
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
} }
@ -1966,6 +1966,8 @@ static void wpa_driver_test_mlme(struct wpa_driver_test_data *drv,
WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ) { WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ) {
os_memset(&event, 0, sizeof(event)); os_memset(&event, 0, sizeof(event));
event.rx_probe_req.sa = mgmt->sa; event.rx_probe_req.sa = mgmt->sa;
event.rx_probe_req.da = mgmt->da;
event.rx_probe_req.bssid = mgmt->bssid;
event.rx_probe_req.ie = mgmt->u.probe_req.variable; event.rx_probe_req.ie = mgmt->u.probe_req.variable;
event.rx_probe_req.ie_len = event.rx_probe_req.ie_len =
data_len - (mgmt->u.probe_req.variable - data); data_len - (mgmt->u.probe_req.variable - data);
@ -1974,6 +1976,7 @@ static void wpa_driver_test_mlme(struct wpa_driver_test_data *drv,
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
if (drv->p2p) if (drv->p2p)
p2p_probe_req_rx(drv->p2p, mgmt->sa, p2p_probe_req_rx(drv->p2p, mgmt->sa,
mgmt->da, mgmt->bssid,
event.rx_probe_req.ie, event.rx_probe_req.ie,
event.rx_probe_req.ie_len); event.rx_probe_req.ie_len);
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
@ -2028,7 +2031,7 @@ static void wpa_driver_test_scan_cmd(struct wpa_driver_test_data *drv,
ielen = 0; ielen = 0;
drv->probe_from = from; drv->probe_from = from;
drv->probe_from_len = fromlen; drv->probe_from_len = fromlen;
p2p_probe_req_rx(drv->p2p, sa, ie, ielen); p2p_probe_req_rx(drv->p2p, sa, NULL, NULL, ie, ielen);
drv->probe_from = NULL; drv->probe_from = NULL;
} }
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */

View File

@ -1644,7 +1644,8 @@ struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p)
} }
static void p2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *ie, static void p2p_reply_probe(struct p2p_data *p2p, const u8 *addr,
const u8 *dst, const u8 *bssid, const u8 *ie,
size_t ie_len) size_t ie_len)
{ {
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
@ -1669,6 +1670,18 @@ static void p2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *ie,
return; return;
} }
if (dst && !is_broadcast_ether_addr(dst) &&
os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) {
/* Not sent to the broadcast address or our P2P Device Address
*/
return;
}
if (bssid && !is_broadcast_ether_addr(bssid)) {
/* Not sent to the Wildcard BSSID */
return;
}
if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN || if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN ||
os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) != os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) !=
0) { 0) {
@ -1750,12 +1763,12 @@ static void p2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *ie,
} }
int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *ie, int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
size_t ie_len) const u8 *bssid, const u8 *ie, size_t ie_len)
{ {
p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len); p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len);
p2p_reply_probe(p2p, addr, ie, ie_len); p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len);
if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) && if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) &&
p2p->go_neg_peer && p2p->go_neg_peer &&

View File

@ -1035,12 +1035,14 @@ void p2p_group_formation_failed(struct p2p_data *p2p);
* p2p_probe_req_rx - Report reception of a Probe Request frame * p2p_probe_req_rx - Report reception of a Probe Request frame
* @p2p: P2P module context from p2p_init() * @p2p: P2P module context from p2p_init()
* @addr: Source MAC address * @addr: Source MAC address
* @dst: Destination MAC address if available or %NULL
* @bssid: BSSID if available or %NULL
* @ie: Information elements from the Probe Request frame body * @ie: Information elements from the Probe Request frame body
* @ie_len: Length of ie buffer in octets * @ie_len: Length of ie buffer in octets
* Returns: 0 to indicate the frame was not processed or 1 if it was * Returns: 0 to indicate the frame was not processed or 1 if it was
*/ */
int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *ie, int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
size_t ie_len); const u8 *bssid, const u8 *ie, size_t ie_len);
/** /**
* p2p_rx_action - Report received Action frame * p2p_rx_action - Report received Action frame

View File

@ -303,12 +303,12 @@ static int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
} }
static int ap_probe_req_rx(void *ctx, const u8 *addr, const u8 *ie, static int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da,
size_t ie_len) const u8 *bssid, const u8 *ie, size_t ie_len)
{ {
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
struct wpa_supplicant *wpa_s = ctx; struct wpa_supplicant *wpa_s = ctx;
return wpas_p2p_probe_req_rx(wpa_s, addr, ie, ie_len); return wpas_p2p_probe_req_rx(wpa_s, sa, da, bssid, ie, ie_len);
#else /* CONFIG_P2P */ #else /* CONFIG_P2P */
return 0; return 0;
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */

View File

@ -1987,7 +1987,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
size_t ie_len = data->rx_mgmt.frame_len - size_t ie_len = data->rx_mgmt.frame_len -
(mgmt->u.probe_req.variable - (mgmt->u.probe_req.variable -
data->rx_mgmt.frame); data->rx_mgmt.frame);
wpas_p2p_probe_req_rx(wpa_s, src, ie, ie_len); wpas_p2p_probe_req_rx(wpa_s, src, mgmt->da,
mgmt->bssid, ie, ie_len);
break; break;
} }
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
@ -2038,6 +2039,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
if (wpa_s->ap_iface) { if (wpa_s->ap_iface) {
hostapd_probe_req_rx(wpa_s->ap_iface->bss[0], hostapd_probe_req_rx(wpa_s->ap_iface->bss[0],
data->rx_probe_req.sa, data->rx_probe_req.sa,
data->rx_probe_req.da,
data->rx_probe_req.bssid,
data->rx_probe_req.ie, data->rx_probe_req.ie,
data->rx_probe_req.ie_len); data->rx_probe_req.ie_len);
break; break;
@ -2045,6 +2048,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
#endif /* CONFIG_AP */ #endif /* CONFIG_AP */
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
wpas_p2p_probe_req_rx(wpa_s, data->rx_probe_req.sa, wpas_p2p_probe_req_rx(wpa_s, data->rx_probe_req.sa,
data->rx_probe_req.da,
data->rx_probe_req.bssid,
data->rx_probe_req.ie, data->rx_probe_req.ie,
data->rx_probe_req.ie_len); data->rx_probe_req.ie_len);
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */

View File

@ -3650,6 +3650,7 @@ int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr, int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
const u8 *dst, const u8 *bssid,
const u8 *ie, size_t ie_len) const u8 *ie, size_t ie_len)
{ {
if (wpa_s->global->p2p_disabled) if (wpa_s->global->p2p_disabled)
@ -3657,7 +3658,8 @@ int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
if (wpa_s->global->p2p == NULL) if (wpa_s->global->p2p == NULL)
return 0; return 0;
return p2p_probe_req_rx(wpa_s->global->p2p, addr, ie, ie_len); return p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid,
ie, ie_len);
} }

View File

@ -58,6 +58,7 @@ int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout);
int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
u8 *buf, size_t len, int p2p_group); u8 *buf, size_t len, int p2p_group);
int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr, int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
const u8 *dst, const u8 *bssid,
const u8 *ie, size_t ie_len); const u8 *ie, size_t ie_len);
void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da, void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
const u8 *sa, const u8 *bssid, const u8 *sa, const u8 *bssid,