]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Make unrecognized vendor elements available in P2P_PEER
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 4 Jul 2014 17:14:19 +0000 (20:14 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 8 Jul 2014 12:57:30 +0000 (15:57 +0300)
This allows external programs to use vendor specific information from
P2P peers without wpa_supplicant having to be able to parse and
understand all such vendor specific elements.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/common/ieee802_11_defs.h
src/p2p/p2p.c
src/p2p/p2p.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/p2p_supplicant.c

index b8e9254f6b97ff82989ff56e6dbcce54889dae02..6de71e9e39e84485bf05a1c5905841f5eb4dcc69 100644 (file)
@@ -809,6 +809,7 @@ struct ieee80211_vht_operation {
 #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
                                * 00:50:F2 */
 #define WPA_IE_VENDOR_TYPE 0x0050f201
+#define WMM_IE_VENDOR_TYPE 0x0050f202
 #define WPS_IE_VENDOR_TYPE 0x0050f204
 #define OUI_WFA 0x506f9a
 #define P2P_IE_VENDOR_TYPE 0x506f9a09
index 69ee0d028f1a730f12fb4b1e22ca376f1c9c9c01..565cbdbd220c915c323082cd2ec11c58b13a19b8 100644 (file)
@@ -609,6 +609,46 @@ static void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev,
 }
 
 
+static void p2p_update_peer_vendor_elems(struct p2p_device *dev, const u8 *ies,
+                                        size_t ies_len)
+{
+       const u8 *pos, *end;
+       u8 id, len;
+
+       wpabuf_free(dev->info.vendor_elems);
+       dev->info.vendor_elems = NULL;
+
+       end = ies + ies_len;
+
+       for (pos = ies; pos + 1 < end; pos += len) {
+               id = *pos++;
+               len = *pos++;
+
+               if (pos + len > end)
+                       break;
+
+               if (id != WLAN_EID_VENDOR_SPECIFIC || len < 3)
+                       continue;
+
+               if (len >= 4) {
+                       u32 type = WPA_GET_BE32(pos);
+
+                       if (type == WPA_IE_VENDOR_TYPE ||
+                           type == WMM_IE_VENDOR_TYPE ||
+                           type == WPS_IE_VENDOR_TYPE ||
+                           type == P2P_IE_VENDOR_TYPE ||
+                           type == WFD_IE_VENDOR_TYPE)
+                               continue;
+               }
+
+               /* Unknown vendor element - make raw IE data available */
+               if (wpabuf_resize(&dev->info.vendor_elems, 2 + len) < 0)
+                       break;
+               wpabuf_put_data(dev->info.vendor_elems, pos - 2, 2 + len);
+       }
+}
+
+
 /**
  * p2p_add_device - Add peer entries based on scan results or P2P frames
  * @p2p: P2P module context from p2p_init()
@@ -757,6 +797,8 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq,
 
        p2p_parse_free(&msg);
 
+       p2p_update_peer_vendor_elems(dev, ies, ies_len);
+
        if (dev->flags & P2P_DEV_REPORTED)
                return 0;
 
@@ -826,6 +868,7 @@ static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev)
        }
 
        wpabuf_free(dev->info.wfd_subelems);
+       wpabuf_free(dev->info.vendor_elems);
        wpabuf_free(dev->go_neg_conf);
 
        os_free(dev);
index c4bc0d235f0960d5808b7a6d7c7f9c6d4aa51680..dee79dfb53bfb87b1874e4a1c44dbba1af7a7421 100644 (file)
@@ -230,6 +230,14 @@ struct p2p_peer_info {
         * wfd_subelems - Wi-Fi Display subelements from WFD IE(s)
         */
        struct wpabuf *wfd_subelems;
+
+       /**
+        * vendor_elems - Unrecognized vendor elements
+        *
+        * This buffer includes any other vendor element than P2P, WPS, and WFD
+        * IE(s) from the frame that was used to discover the peer.
+        */
+       struct wpabuf *vendor_elems;
 };
 
 enum p2p_prov_disc_status {
index 143c854cdb8921b36377739b06af1347e0410cab..f612b494db2058d29fabea7a1f92ebb13ac8fd16 100644 (file)
@@ -4715,6 +4715,22 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
                return pos - buf;
        pos += res;
 
+       if (info->vendor_elems) {
+               res = os_snprintf(pos, end - pos, "vendor_elems=");
+               if (res < 0 || res >= end - pos)
+                       return pos - buf;
+               pos += res;
+
+               pos += wpa_snprintf_hex(pos, end - pos,
+                                       wpabuf_head(info->vendor_elems),
+                                       wpabuf_len(info->vendor_elems));
+
+               res = os_snprintf(pos, end - pos, "\n");
+               if (res < 0 || res >= end - pos)
+                       return pos - buf;
+               pos += res;
+       }
+
        return pos - buf;
 }
 
index 0af5e3264acccd057c0b510215d5bbd1ea7c8d08..bcad4caa7ea62c67ef5f73e6099997741c909d23 100644 (file)
@@ -1693,14 +1693,15 @@ static void wpas_dev_found(void *ctx, const u8 *addr,
        wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR
                       " p2p_dev_addr=" MACSTR
                       " pri_dev_type=%s name='%s' config_methods=0x%x "
-                      "dev_capab=0x%x group_capab=0x%x%s%s",
+                      "dev_capab=0x%x group_capab=0x%x%s%s%s",
                       MAC2STR(addr), MAC2STR(info->p2p_device_addr),
                       wps_dev_type_bin2str(info->pri_dev_type, devtype,
                                            sizeof(devtype)),
                       info->device_name, info->config_methods,
                       info->dev_capab, info->group_capab,
                       wfd_dev_info_hex ? " wfd_dev_info=0x" : "",
-                      wfd_dev_info_hex ? wfd_dev_info_hex : "");
+                      wfd_dev_info_hex ? wfd_dev_info_hex : "",
+                      info->vendor_elems ? " vendor_elems=1" : "");
 
        os_free(wfd_dev_info_hex);
 #endif /* CONFIG_NO_STDOUT_DEBUG */