cfg80211: add cfg80211_find_vendor_ie() function
authorEliad Peller <eliad@wizery.com>
Thu, 15 Sep 2011 08:53:01 +0000 (11:53 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 19 Sep 2011 19:49:11 +0000 (15:49 -0400)
Add function to find vendor-specific ie (along with
vendor-specific ie struct definition and P2P OUI values)

Signed-off-by: Eliad Peller <eliad@wizery.com>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/linux/ieee80211.h
include/net/cfg80211.h
net/wireless/scan.c

index 72f3933938c0e850982c90c69b48a851ccd4086f..b5e0a5c344fd69677507f8e24ed4890d143e6136 100644 (file)
@@ -777,6 +777,13 @@ struct ieee80211_mmie {
        u8 mic[8];
 } __attribute__ ((packed));
 
+struct ieee80211_vendor_ie {
+       u8 element_id;
+       u8 len;
+       u8 oui[3];
+       u8 oui_type;
+} __packed;
+
 /* Control frames */
 struct ieee80211_rts {
        __le16 frame_control;
@@ -1470,6 +1477,9 @@ enum ieee80211_sa_query_action {
 
 #define WLAN_PMKID_LEN                 16
 
+#define WLAN_OUI_WFA                   0x506f9a
+#define WLAN_OUI_TYPE_WFA_P2P          9
+
 /*
  * WMM/802.11e Tspec Element
  */
index b42136a61f3ac0bf4ba8d37b1d4ca4cfbe9e3fe4..9518b5cfb82274598f26b4cbb88d23ca6c4b1df1 100644 (file)
@@ -2458,6 +2458,24 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb);
  */
 const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len);
 
+/**
+ * cfg80211_find_vendor_ie - find vendor specific information element in data
+ *
+ * @oui: vendor OUI
+ * @oui_type: vendor-specific OUI type
+ * @ies: data consisting of IEs
+ * @len: length of data
+ *
+ * This function will return %NULL if the vendor specific element ID
+ * could not be found or if the element is invalid (claims to be
+ * longer than the given data), or a pointer to the first byte
+ * of the requested element, that is the byte containing the
+ * element ID. There are no checks on the element length
+ * other than having to fit into the given data.
+ */
+const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
+                                 const u8 *ies, int len);
+
 /**
  * DOC: Regulatory enforcement infrastructure
  *
index b0f0039669536164f0f9d67147030f3f43c8a0a0..0fb1424104047ced0d99949be89388509e05fc5c 100644 (file)
@@ -228,6 +228,33 @@ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
 }
 EXPORT_SYMBOL(cfg80211_find_ie);
 
+const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
+                                 const u8 *ies, int len)
+{
+       struct ieee80211_vendor_ie *ie;
+       const u8 *pos = ies, *end = ies + len;
+       int ie_oui;
+
+       while (pos < end) {
+               pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos,
+                                      end - pos);
+               if (!pos)
+                       return NULL;
+
+               if (end - pos < sizeof(*ie))
+                       return NULL;
+
+               ie = (struct ieee80211_vendor_ie *)pos;
+               ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2];
+               if (ie_oui == oui && ie->oui_type == oui_type)
+                       return pos;
+
+               pos += 2 + ie->len;
+       }
+       return NULL;
+}
+EXPORT_SYMBOL(cfg80211_find_vendor_ie);
+
 static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
 {
        const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);