aboutsummaryrefslogtreecommitdiffstats
path: root/src/p2p
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-04-01 21:13:38 +0300
committerJouni Malinen <j@w1.fi>2012-04-01 21:14:48 +0300
commit2d43d37ff2c3115da812bec8ea4c72048e1194d8 (patch)
tree42a666b285ec68a6ad9525a3238886eb541ea51b /src/p2p
parentbaf513d6952c67b94925c5e82291be19f858ad1e (diff)
downloadexternal_wpa_supplicant_8_ti-2d43d37ff2c3115da812bec8ea4c72048e1194d8.zip
external_wpa_supplicant_8_ti-2d43d37ff2c3115da812bec8ea4c72048e1194d8.tar.gz
external_wpa_supplicant_8_ti-2d43d37ff2c3115da812bec8ea4c72048e1194d8.tar.bz2
DBus: Add ability to report probe requests
Some applications require knowing about probe requests to identify devices. This can be the case in AP mode to see the devices before they connect, or even in P2P mode when operating as a P2P device to identify non-P2P peers (P2P peers are identified via PeerFound signals). As there are typically a lot of probe requests, require that an interested application subscribes to this signal so the bus isn't always flooded with these notifications. The notifications in DBus are then unicast only to that application. A small test script is also included. Signed-hostap: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'src/p2p')
-rw-r--r--src/p2p/p2p.c53
-rw-r--r--src/p2p/p2p.h24
2 files changed, 51 insertions, 26 deletions
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 6c19774..a0da48f 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -1830,9 +1830,9 @@ static int supp_rates_11b_only(struct ieee802_11_elems *elems)
}
-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)
+static enum p2p_probe_req_status
+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;
struct wpabuf *buf;
@@ -1842,55 +1842,55 @@ static void p2p_reply_probe(struct p2p_data *p2p, const u8 *addr,
if (!p2p->in_listen || !p2p->drv_in_listen) {
/* not in Listen state - ignore Probe Request */
- return;
+ return P2P_PREQ_NOT_LISTEN;
}
if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) ==
ParseFailed) {
/* Ignore invalid Probe Request frames */
- return;
+ return P2P_PREQ_MALFORMED;
}
if (elems.p2p == NULL) {
/* not a P2P probe - ignore it */
- return;
+ return P2P_PREQ_NOT_P2P;
}
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;
+ return P2P_PREQ_NOT_PROCESSED;
}
if (bssid && !is_broadcast_ether_addr(bssid)) {
/* Not sent to the Wildcard BSSID */
- return;
+ return P2P_PREQ_NOT_PROCESSED;
}
if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN ||
os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) !=
0) {
/* not using P2P Wildcard SSID - ignore */
- return;
+ return P2P_PREQ_NOT_PROCESSED;
}
if (supp_rates_11b_only(&elems)) {
/* Indicates support for 11b rates only */
- return;
+ return P2P_PREQ_NOT_P2P;
}
os_memset(&msg, 0, sizeof(msg));
if (p2p_parse_ies(ie, ie_len, &msg) < 0) {
/* Could not parse P2P attributes */
- return;
+ return P2P_PREQ_NOT_P2P;
}
if (msg.device_id &&
os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN != 0)) {
/* Device ID did not match */
p2p_parse_free(&msg);
- return;
+ return P2P_PREQ_NOT_PROCESSED;
}
/* Check Requested Device Type match */
@@ -1898,12 +1898,14 @@ static void p2p_reply_probe(struct p2p_data *p2p, const u8 *addr,
!p2p_match_dev_type(p2p, msg.wps_attributes)) {
/* No match with Requested Device Type */
p2p_parse_free(&msg);
- return;
+ return P2P_PREQ_NOT_PROCESSED;
}
p2p_parse_free(&msg);
- if (!p2p->cfg->send_probe_resp)
- return; /* Response generated elsewhere */
+ if (!p2p->cfg->send_probe_resp) {
+ /* Response generated elsewhere */
+ return P2P_PREQ_NOT_PROCESSED;
+ }
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Reply to P2P Probe Request in Listen state");
@@ -1916,12 +1918,12 @@ static void p2p_reply_probe(struct p2p_data *p2p, const u8 *addr,
*/
ies = p2p_build_probe_resp_ies(p2p);
if (ies == NULL)
- return;
+ return P2P_PREQ_NOT_PROCESSED;
buf = wpabuf_alloc(200 + wpabuf_len(ies));
if (buf == NULL) {
wpabuf_free(ies);
- return;
+ return P2P_PREQ_NOT_PROCESSED;
}
resp = NULL;
@@ -1964,15 +1966,20 @@ static void p2p_reply_probe(struct p2p_data *p2p, const u8 *addr,
p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf);
wpabuf_free(buf);
+
+ return P2P_PREQ_NOT_PROCESSED;
}
-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)
+enum p2p_probe_req_status
+p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
+ const u8 *bssid, const u8 *ie, size_t ie_len)
{
+ enum p2p_probe_req_status res;
+
p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len);
- p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len);
+ res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len);
if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) &&
p2p->go_neg_peer &&
@@ -1983,7 +1990,7 @@ int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
"P2P: Found GO Negotiation peer - try to start GO "
"negotiation from timeout");
eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL);
- return 1;
+ return P2P_PREQ_PROCESSED;
}
if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) &&
@@ -1995,10 +2002,10 @@ int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
"P2P: Found Invite peer - try to start Invite from "
"timeout");
eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL);
- return 1;
+ return P2P_PREQ_PROCESSED;
}
- return 0;
+ return res;
}
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 31d5cd1..a4d4256 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -1087,6 +1087,23 @@ void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr);
/* Event notifications from lower layer driver operations */
/**
+ * enum p2p_probe_req_status
+ *
+ * @P2P_PREQ_MALFORMED: frame was not well-formed
+ * @P2P_PREQ_NOT_LISTEN: device isn't in listen state, frame ignored
+ * @P2P_PREQ_NOT_P2P: frame was not a P2P probe request
+ * @P2P_PREQ_P2P_NOT_PROCESSED: frame was P2P but wasn't processed
+ * @P2P_PREQ_P2P_PROCESSED: frame has been processed by P2P
+ */
+enum p2p_probe_req_status {
+ P2P_PREQ_MALFORMED,
+ P2P_PREQ_NOT_LISTEN,
+ P2P_PREQ_NOT_P2P,
+ P2P_PREQ_NOT_PROCESSED,
+ P2P_PREQ_PROCESSED
+};
+
+/**
* p2p_probe_req_rx - Report reception of a Probe Request frame
* @p2p: P2P module context from p2p_init()
* @addr: Source MAC address
@@ -1094,10 +1111,11 @@ void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr);
* @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
+ * Returns: value indicating the type and status of the probe request
*/
-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);
+enum p2p_probe_req_status
+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