aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r--net/wireless/util.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 5b6c1df72f31..b99f01cda1f6 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -980,6 +980,105 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
980} 980}
981EXPORT_SYMBOL(cfg80211_calculate_bitrate); 981EXPORT_SYMBOL(cfg80211_calculate_bitrate);
982 982
983unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
984 u8 attr, u8 *buf, unsigned int bufsize)
985{
986 u8 *out = buf;
987 u16 attr_remaining = 0;
988 bool desired_attr = false;
989 u16 desired_len = 0;
990
991 while (len > 0) {
992 unsigned int iedatalen;
993 unsigned int copy;
994 const u8 *iedata;
995
996 if (len < 2)
997 return -EILSEQ;
998 iedatalen = ies[1];
999 if (iedatalen + 2 > len)
1000 return -EILSEQ;
1001
1002 if (ies[0] != WLAN_EID_VENDOR_SPECIFIC)
1003 goto cont;
1004
1005 if (iedatalen < 4)
1006 goto cont;
1007
1008 iedata = ies + 2;
1009
1010 /* check WFA OUI, P2P subtype */
1011 if (iedata[0] != 0x50 || iedata[1] != 0x6f ||
1012 iedata[2] != 0x9a || iedata[3] != 0x09)
1013 goto cont;
1014
1015 iedatalen -= 4;
1016 iedata += 4;
1017
1018 /* check attribute continuation into this IE */
1019 copy = min_t(unsigned int, attr_remaining, iedatalen);
1020 if (copy && desired_attr) {
1021 desired_len += copy;
1022 if (out) {
1023 memcpy(out, iedata, min(bufsize, copy));
1024 out += min(bufsize, copy);
1025 bufsize -= min(bufsize, copy);
1026 }
1027
1028
1029 if (copy == attr_remaining)
1030 return desired_len;
1031 }
1032
1033 attr_remaining -= copy;
1034 if (attr_remaining)
1035 goto cont;
1036
1037 iedatalen -= copy;
1038 iedata += copy;
1039
1040 while (iedatalen > 0) {
1041 u16 attr_len;
1042
1043 /* P2P attribute ID & size must fit */
1044 if (iedatalen < 3)
1045 return -EILSEQ;
1046 desired_attr = iedata[0] == attr;
1047 attr_len = get_unaligned_le16(iedata + 1);
1048 iedatalen -= 3;
1049 iedata += 3;
1050
1051 copy = min_t(unsigned int, attr_len, iedatalen);
1052
1053 if (desired_attr) {
1054 desired_len += copy;
1055 if (out) {
1056 memcpy(out, iedata, min(bufsize, copy));
1057 out += min(bufsize, copy);
1058 bufsize -= min(bufsize, copy);
1059 }
1060
1061 if (copy == attr_len)
1062 return desired_len;
1063 }
1064
1065 iedata += copy;
1066 iedatalen -= copy;
1067 attr_remaining = attr_len - copy;
1068 }
1069
1070 cont:
1071 len -= ies[1] + 2;
1072 ies += ies[1] + 2;
1073 }
1074
1075 if (attr_remaining && desired_attr)
1076 return -EILSEQ;
1077
1078 return -ENOENT;
1079}
1080EXPORT_SYMBOL(cfg80211_get_p2p_attr);
1081
983int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, 1082int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
984 u32 beacon_int) 1083 u32 beacon_int)
985{ 1084{