]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Keep track of peer WPS vendor extensions
authorJean-Michel Bachot <jean-michelx.bachot@linux.intel.com>
Sat, 19 Mar 2011 10:16:20 +0000 (12:16 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 19 Mar 2011 10:22:21 +0000 (12:22 +0200)
Make the P2P code keep track of WPS vendor extensions received from
peers so they can be exposed via DBus later.

Signed-off-by: Jean-Michel Bachot <jean-michelx.bachot@linux.intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_i.h
src/p2p/p2p_parse.c
src/wps/wps.h
src/wps/wps_attr_parse.c
src/wps/wps_i.h

index de554124ac477477f76d456a69b0a39f4ffd0632..f5a6035888e586c50ed173f38b43dfca7df4a705 100644 (file)
@@ -431,6 +431,7 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level,
        struct p2p_device *dev;
        struct p2p_message msg;
        const u8 *p2p_dev_addr;
+       int i;
 
        os_memset(&msg, 0, sizeof(msg));
        if (p2p_parse_ies(ies, ies_len, &msg)) {
@@ -522,6 +523,20 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level,
                        msg.wps_sec_dev_type_list_len;
        }
 
+       for (i = 0; i < P2P_MAX_PEER_WPS_VENDOR_EXT; i++) {
+               wpabuf_free(dev->info.wps_vendor_ext[i]);
+               dev->info.wps_vendor_ext[i] = NULL;
+       }
+
+       for (i = 0; i < P2P_MAX_PEER_WPS_VENDOR_EXT; i++) {
+               if (msg.wps_vendor_ext[i] == NULL)
+                       break;
+               dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy(
+                       msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]);
+               if (dev->info.wps_vendor_ext[i] == NULL)
+                       break;
+       }
+
        if (msg.capability) {
                dev->info.dev_capab = msg.capability[0];
                dev->info.group_capab = msg.capability[1];
@@ -562,6 +577,8 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level,
 
 static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev)
 {
+       int i;
+
        if (p2p->go_neg_peer == dev)
                p2p->go_neg_peer = NULL;
        if (p2p->invite_peer == dev)
@@ -573,6 +590,11 @@ static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev)
 
        p2p->cfg->dev_lost(p2p->cfg->cb_ctx, dev->info.p2p_device_addr);
 
+       for (i = 0; i < P2P_MAX_PEER_WPS_VENDOR_EXT; i++) {
+               wpabuf_free(dev->info.wps_vendor_ext[i]);
+               dev->info.wps_vendor_ext[i] = NULL;
+       }
+
        os_free(dev);
 }
 
index eb57eb808b645fbe571acee1b3489ffc457c0557..40c58e9810aaec8090e0d116e38dc7ae34f701f2 100644 (file)
@@ -186,6 +186,8 @@ struct p2p_peer_info {
         */
        size_t wps_sec_dev_type_list_len;
 
+#define P2P_MAX_PEER_WPS_VENDOR_EXT 10
+       struct wpabuf *wps_vendor_ext[P2P_MAX_PEER_WPS_VENDOR_EXT];
 };
 
 /**
index c11aabe30c887aa54042834a7d6f2f6ef5cb11eb..4e12c70232fbd451a9eaddbe6660b588e08516d4 100644 (file)
@@ -445,6 +445,8 @@ struct p2p_message {
        const u8 *wps_pri_dev_type;
        const u8 *wps_sec_dev_type_list;
        size_t wps_sec_dev_type_list_len;
+       const u8 *wps_vendor_ext[P2P_MAX_WPS_VENDOR_EXTENSIONS];
+       size_t wps_vendor_ext_len[P2P_MAX_WPS_VENDOR_EXTENSIONS];
 
        /* DS Parameter Set IE */
        const u8 *ds_params;
index 56c1e71b9edad53b6a90ff4272346842330a2464..403162934f16657c856289622884b6410bba9474 100644 (file)
@@ -328,6 +328,7 @@ int p2p_parse_p2p_ie(const struct wpabuf *buf, struct p2p_message *msg)
 static int p2p_parse_wps_ie(const struct wpabuf *buf, struct p2p_message *msg)
 {
        struct wps_parse_attr attr;
+       int i;
 
        wpa_printf(MSG_DEBUG, "P2P: Parsing WPS IE");
        if (wps_parse_msg(buf, &attr))
@@ -358,6 +359,13 @@ static int p2p_parse_wps_ie(const struct wpabuf *buf, struct p2p_message *msg)
                msg->wps_sec_dev_type_list_len = attr.sec_dev_type_list_len;
        }
 
+       for (i = 0; i < P2P_MAX_PEER_WPS_VENDOR_EXT; i++) {
+               if (i >= P2P_MAX_WPS_VENDOR_EXTENSIONS)
+                       break;
+               msg->wps_vendor_ext[i] = attr.vendor_ext[i];
+               msg->wps_vendor_ext_len[i] = attr.vendor_ext_len[i];
+       }
+
        return 0;
 }
 
index 8b29982953ee6063c4f2a662b5f81d551ceb5d9e..fc706d9df6a3f46ec54b0e9e62f2a1862422682f 100644 (file)
@@ -66,6 +66,10 @@ struct wps_credential {
 #define WPS_SEC_DEV_TYPE_MAX_LEN 128
 /* maximum number of advertised WPS vendor extension attributes */
 #define MAX_WPS_VENDOR_EXTENSIONS 10
+/* maximum size of WPS Vendor extension attribute */
+#define WPS_MAX_VENDOR_EXT_LEN 1024
+/* maximum number of parsed WPS vendor extension attributes */
+#define MAX_WPS_PARSE_VENDOR_EXT 10
 
 /**
  * struct wps_device_data - WPS Device Data
index 0c4a4b4e6868a45144153a6f5064c148c6b75199..bc3766c5cc7422668c6fc7c6abf8383c57413f01 100644 (file)
@@ -108,12 +108,29 @@ static int wps_parse_vendor_ext(struct wps_parse_attr *attr, const u8 *pos,
        switch (vendor_id) {
        case WPS_VENDOR_ID_WFA:
                return wps_parse_vendor_ext_wfa(attr, pos + 3, len - 3);
-       default:
-               wpa_printf(MSG_MSGDUMP, "WPS: Skip unknown Vendor Extension "
-                          "(Vendor ID %u)", vendor_id);
-               break;
        }
 
+       /* Handle unknown vendor extensions */
+
+       wpa_printf(MSG_MSGDUMP, "WPS: Unknown Vendor Extension (Vendor ID %u)",
+                  vendor_id);
+
+       if (len > WPS_MAX_VENDOR_EXT_LEN) {
+               wpa_printf(MSG_DEBUG, "WPS: Too long Vendor Extension (%u)",
+                          len);
+               return -1;
+       }
+
+       if (attr->num_vendor_ext > MAX_WPS_PARSE_VENDOR_EXT) {
+               wpa_printf(MSG_DEBUG, "WPS: Skipped Vendor Extension "
+                          "attribute (max %d vendor extensions)",
+                          MAX_WPS_PARSE_VENDOR_EXT);
+               return -1;
+       }
+       attr->vendor_ext[attr->num_vendor_ext] = pos;
+       attr->vendor_ext_len[attr->num_vendor_ext] = len;
+       attr->num_vendor_ext++;
+
        return 0;
 }
 
index 827a82a677f414f875e075ead209e8665b944f4a..437999bb3503b12f17a7d705dab33654846e00cd 100644 (file)
@@ -207,6 +207,10 @@ struct wps_parse_attr {
 #define MAX_REQ_DEV_TYPE_COUNT 10
        const u8 *req_dev_type[MAX_REQ_DEV_TYPE_COUNT];
        size_t num_req_dev_type;
+
+       const u8 *vendor_ext[MAX_WPS_PARSE_VENDOR_EXT];
+       size_t vendor_ext_len[MAX_WPS_PARSE_VENDOR_EXT];
+       size_t num_vendor_ext;
 };
 
 /* wps_common.c */