* [PATCH] cfg80211: add cfg80211_find_vendor_ie() function
@ 2011-09-15 8:53 Eliad Peller
2011-09-15 9:03 ` Johannes Berg
0 siblings, 1 reply; 4+ messages in thread
From: Eliad Peller @ 2011-09-15 8:53 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
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>
---
include/linux/ieee80211.h | 10 ++++++++++
include/net/cfg80211.h | 18 ++++++++++++++++++
net/wireless/scan.c | 27 +++++++++++++++++++++++++++
3 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 37f95f2..3185650 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -775,6 +775,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;
@@ -1468,6 +1475,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
*/
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a535b39..540a99e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2456,6 +2456,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
*
* TODO
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index b0f0039..0fb1424 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -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);
--
1.7.6.401.g6a319
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] cfg80211: add cfg80211_find_vendor_ie() function
2011-09-15 8:53 [PATCH] cfg80211: add cfg80211_find_vendor_ie() function Eliad Peller
@ 2011-09-15 9:03 ` Johannes Berg
2011-09-15 9:09 ` Eliad Peller
0 siblings, 1 reply; 4+ messages in thread
From: Johannes Berg @ 2011-09-15 9:03 UTC (permalink / raw)
To: Eliad Peller; +Cc: linux-wireless
> +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;
I think it should also check that the whole IE including ie->len (not
just sizeof(*ie) fits into the buffer, before returning it. That is, add
something like
if (end - pos < 2 + ie->len)
return NULL;
after the sizeof(*ie) check.
johannes
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] cfg80211: add cfg80211_find_vendor_ie() function
2011-09-15 9:03 ` Johannes Berg
@ 2011-09-15 9:09 ` Eliad Peller
2011-09-15 9:18 ` Johannes Berg
0 siblings, 1 reply; 4+ messages in thread
From: Eliad Peller @ 2011-09-15 9:09 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On Thu, Sep 15, 2011 at 12:03 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
>
>> +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;
>
> I think it should also check that the whole IE including ie->len (not
> just sizeof(*ie) fits into the buffer, before returning it. That is, add
> something like
>
> if (end - pos < 2 + ie->len)
> return NULL;
>
> after the sizeof(*ie) check.
>
cfg80211_find_ie() already checks for it.
Eliad.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] cfg80211: add cfg80211_find_vendor_ie() function
2011-09-15 9:09 ` Eliad Peller
@ 2011-09-15 9:18 ` Johannes Berg
0 siblings, 0 replies; 4+ messages in thread
From: Johannes Berg @ 2011-09-15 9:18 UTC (permalink / raw)
To: Eliad Peller; +Cc: linux-wireless
On Thu, 2011-09-15 at 12:09 +0300, Eliad Peller wrote:
> On Thu, Sep 15, 2011 at 12:03 PM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
> >
> >> +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;
> >
> > I think it should also check that the whole IE including ie->len (not
> > just sizeof(*ie) fits into the buffer, before returning it. That is, add
> > something like
> >
> > if (end - pos < 2 + ie->len)
> > return NULL;
> >
> > after the sizeof(*ie) check.
> >
> cfg80211_find_ie() already checks for it.
Oh, good point. Sorry for the interruption :)
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
johannes
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-09-15 9:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-15 8:53 [PATCH] cfg80211: add cfg80211_find_vendor_ie() function Eliad Peller
2011-09-15 9:03 ` Johannes Berg
2011-09-15 9:09 ` Eliad Peller
2011-09-15 9:18 ` Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox