P2PS: Add intended iface address during PD for persistent group

When persistent group is used and the peer is GO in this group,
intended interface attribute should be added to PD request/response.
Not doing so violates the spec.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Max Stepanov <Max.Stepanov@intel.com>
Reviewed-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
Andrei Otcheretianski 2015-07-02 10:45:05 +03:00 committed by Jouni Malinen
parent 23bb9828a3
commit 1f1a08b4cc
3 changed files with 36 additions and 7 deletions

View File

@ -955,18 +955,21 @@ struct p2p_config {
/**
* Determine if we have a persistent group we share with remote peer
* and allocate interface for this group if needed
* @ctx: Callback context from cb_ctx
* @addr: Peer device address to search for
* @ssid: Persistent group SSID or %NULL if any
* @ssid_len: Length of @ssid
* @go_dev_addr: Buffer for returning intended GO P2P Device Address
* @go_dev_addr: Buffer for returning GO P2P Device Address
* @ret_ssid: Buffer for returning group SSID
* @ret_ssid_len: Buffer for returning length of @ssid
* @intended_iface_addr: Buffer for returning intended iface address
* Returns: 1 if a matching persistent group was found, 0 otherwise
*/
int (*get_persistent_group)(void *ctx, const u8 *addr, const u8 *ssid,
size_t ssid_len, u8 *go_dev_addr,
u8 *ret_ssid, size_t *ret_ssid_len);
u8 *ret_ssid, size_t *ret_ssid_len,
u8 *intended_iface_addr);
/**
* Get information about a possible local GO role

View File

@ -87,6 +87,7 @@ static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
u8 ssid[SSID_MAX_LEN];
size_t ssid_len;
u8 go_dev_addr[ETH_ALEN];
u8 intended_addr[ETH_ALEN];
/* If we might be explicite group owner, add GO details */
if (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
@ -101,7 +102,7 @@ static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
if (p2p->cfg->get_persistent_group) {
shared_group = p2p->cfg->get_persistent_group(
p2p->cfg->cb_ctx, dev->info.p2p_device_addr, NULL, 0,
go_dev_addr, ssid, &ssid_len);
go_dev_addr, ssid, &ssid_len, intended_addr);
}
/* Add Operating Channel if conncap includes GO */
@ -149,9 +150,15 @@ static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
p2p_buf_add_feature_capability(buf, sizeof(feat_cap_mask),
feat_cap_mask);
if (shared_group)
if (shared_group) {
p2p_buf_add_persistent_group_info(buf, go_dev_addr,
ssid, ssid_len);
/* Add intended interface address if it is not added yet */
if ((prov->conncap == P2PS_SETUP_NONE ||
prov->conncap == P2PS_SETUP_CLIENT) &&
!is_zero_ether_addr(intended_addr))
p2p_buf_add_intended_addr(buf, intended_addr);
}
}
@ -296,15 +303,20 @@ static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
u8 ssid[SSID_MAX_LEN];
size_t ssid_len;
u8 go_dev_addr[ETH_ALEN];
u8 intended_addr[ETH_ALEN];
persist = p2p->cfg->get_persistent_group(
p2p->cfg->cb_ctx,
dev->info.p2p_device_addr,
persist_ssid, persist_ssid_len, go_dev_addr,
ssid, &ssid_len);
if (persist)
ssid, &ssid_len, intended_addr);
if (persist) {
p2p_buf_add_persistent_group_info(
buf, go_dev_addr, ssid, ssid_len);
if (!is_zero_ether_addr(intended_addr))
p2p_buf_add_intended_addr(
buf, intended_addr);
}
}
if (!persist && (prov->conncap & P2PS_SETUP_GROUP_OWNER))

View File

@ -3508,7 +3508,8 @@ static void wpas_presence_resp(void *ctx, const u8 *src, u8 status,
static int wpas_get_persistent_group(void *ctx, const u8 *addr, const u8 *ssid,
size_t ssid_len, u8 *go_dev_addr,
u8 *ret_ssid, size_t *ret_ssid_len)
u8 *ret_ssid, size_t *ret_ssid_len,
u8 *intended_iface_addr)
{
struct wpa_supplicant *wpa_s = ctx;
struct wpa_ssid *s;
@ -3518,6 +3519,19 @@ static int wpas_get_persistent_group(void *ctx, const u8 *addr, const u8 *ssid,
os_memcpy(ret_ssid, s->ssid, s->ssid_len);
*ret_ssid_len = s->ssid_len;
os_memcpy(go_dev_addr, s->bssid, ETH_ALEN);
if (s->mode != WPAS_MODE_P2P_GO) {
os_memset(intended_iface_addr, 0, ETH_ALEN);
} else if (wpas_p2p_create_iface(wpa_s)) {
if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO))
return 0;
os_memcpy(intended_iface_addr,
wpa_s->pending_interface_addr, ETH_ALEN);
} else {
os_memcpy(intended_iface_addr, wpa_s->own_addr,
ETH_ALEN);
}
return 1;
}