for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
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;
if (!hapd->iconf->send_probe_response)
}
-int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa,
- const u8 *ie, size_t ie_len)
+int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
+ const u8 *bssid, const u8 *ie, size_t ie_len)
{
size_t i;
int ret = 0;
random_add_randomness(sa, ETH_ALEN);
for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
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;
break;
}
data->rx_probe_req.ie == NULL)
break;
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_len);
break;
union wps_event_data;
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;
};
/* utils.c */
int hostapd_register_probereq_cb(struct hostapd_data *hapd,
int (*cb)(void *ctx, const u8 *sa,
+ const u8 *da, const u8 *bssid,
const u8 *ie, size_t ie_len),
void *ctx);
void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr);
const u8 *ie, size_t ielen, int reassoc);
void hostapd_notif_disassoc(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,
- const u8 *ie, size_t ie_len);
+int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
+ const u8 *bssid, const u8 *ie, size_t ie_len);
#endif /* HOSTAPD_H */
int hostapd_register_probereq_cb(struct hostapd_data *hapd,
int (*cb)(void *ctx, const u8 *sa,
+ const u8 *da, const u8 *bssid,
const u8 *ie, size_t ie_len),
void *ctx)
{
static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd);
#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);
static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
#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)
{
struct hostapd_data *hapd = ctx;
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
*/
const u8 *ie;
os_memset(&event, 0, sizeof(event));
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_len =
len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
os_memset(&event, 0, sizeof(event));
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_len =
len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
wpa_supplicant_event(drv->ctx, EVENT_RX_PROBE_REQ, &event);
#ifdef CONFIG_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 */
}
WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ) {
os_memset(&event, 0, sizeof(event));
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_len =
data_len - (mgmt->u.probe_req.variable - data);
#ifdef CONFIG_P2P
if (drv->p2p)
p2p_probe_req_rx(drv->p2p, mgmt->sa,
+ mgmt->da, mgmt->bssid,
event.rx_probe_req.ie,
event.rx_probe_req.ie_len);
#endif /* CONFIG_P2P */
ielen = 0;
drv->probe_from = from;
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;
}
#endif /* CONFIG_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)
{
struct ieee802_11_elems elems;
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 ||
os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) !=
0) {
}
-int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *ie,
- size_t ie_len)
+int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
+ const u8 *bssid, const u8 *ie, size_t 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) &&
p2p->go_neg_peer &&
* p2p_probe_req_rx - Report reception of a Probe Request frame
* @p2p: P2P module context from p2p_init()
* @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_len: Length of ie buffer in octets
* 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,
- size_t ie_len);
+int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
+ const u8 *bssid, const u8 *ie, size_t ie_len);
/**
* p2p_rx_action - Report received Action frame
}
-static int ap_probe_req_rx(void *ctx, const u8 *addr, const u8 *ie,
- size_t ie_len)
+static int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da,
+ const u8 *bssid, const u8 *ie, size_t ie_len)
{
#ifdef CONFIG_P2P
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 */
return 0;
#endif /* CONFIG_P2P */
size_t ie_len = data->rx_mgmt.frame_len -
(mgmt->u.probe_req.variable -
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;
}
#endif /* CONFIG_P2P */
if (wpa_s->ap_iface) {
hostapd_probe_req_rx(wpa_s->ap_iface->bss[0],
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_len);
break;
#endif /* CONFIG_AP */
#ifdef CONFIG_P2P
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_len);
#endif /* CONFIG_P2P */
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)
{
if (wpa_s->global->p2p_disabled)
if (wpa_s->global->p2p == NULL)
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);
}
int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
u8 *buf, size_t len, int p2p_group);
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);
void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
const u8 *sa, const u8 *bssid,