]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2PS: Add intended iface address during PD for persistent group
authorAndrei Otcheretianski <andrei.otcheretianski@intel.com>
Thu, 2 Jul 2015 07:45:05 +0000 (10:45 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 7 Jul 2015 17:41:19 +0000 (20:41 +0300)
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>
src/p2p/p2p.h
src/p2p/p2p_pd.c
wpa_supplicant/p2p_supplicant.c

index 67b8bdb6919c584ac81cdc53899f5a78d6acdcd5..20c6429d1b793f6ff8554f088c23f8a79e47d71f 100644 (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
index d17921c37865d6f98dd28fa031431a1baa5e9b26..33c65dc006062193f31c50445416482ec5e64b75 100644 (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))
index c44ebfe70f53125e11f74c97f9e22083c83cdddf..220f2d7ac62d03412bf43f617b25eb519244235d 100644 (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;
        }