aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-01-13 09:03:29 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 16:00:35 -0500
commit9aed3cc124343d92be6697e9af3928bdfe8eb03e (patch)
tree6a49a68422656790f944f37e3f34379b753d1dab /net/wireless/nl80211.c
parent0c1aa495961f03c964b3287cf5800217cf6f2cee (diff)
nl80211: New command for adding extra IE(s) into management frames
A new nl80211 command, NL80211_CMD_SET_MGMT_EXTRA_IE, can be used to add arbitrary IE data into the end of management frames. The interface allows extra IEs to be configured for each management frame subtype, but only some of them (ProbeReq, ProbeResp, Auth, (Re)AssocReq, Deauth, Disassoc) are currently accepted in mac80211 implementation. This makes it easier to implement IEEE 802.11 extensions like WPS and FT that add IE(s) into some management frames. In addition, this can be useful for testing and experimentation purposes. Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 123d3b160fad..09a5d0f1d6dc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -105,6 +105,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
105 105
106 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 106 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
107 .len = NL80211_HT_CAPABILITY_LEN }, 107 .len = NL80211_HT_CAPABILITY_LEN },
108
109 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
110 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
111 .len = IEEE80211_MAX_DATA_LEN },
108}; 112};
109 113
110/* message building helper */ 114/* message building helper */
@@ -2149,6 +2153,43 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2149 return -EINVAL; 2153 return -EINVAL;
2150} 2154}
2151 2155
2156static int nl80211_set_mgmt_extra_ie(struct sk_buff *skb,
2157 struct genl_info *info)
2158{
2159 struct cfg80211_registered_device *drv;
2160 int err;
2161 struct net_device *dev;
2162 struct mgmt_extra_ie_params params;
2163
2164 memset(&params, 0, sizeof(params));
2165
2166 if (!info->attrs[NL80211_ATTR_MGMT_SUBTYPE])
2167 return -EINVAL;
2168 params.subtype = nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
2169 if (params.subtype > 15)
2170 return -EINVAL; /* FC Subtype field is 4 bits (0..15) */
2171
2172 if (info->attrs[NL80211_ATTR_IE]) {
2173 params.ies = nla_data(info->attrs[NL80211_ATTR_IE]);
2174 params.ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2175 }
2176
2177 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2178 if (err)
2179 return err;
2180
2181 if (drv->ops->set_mgmt_extra_ie) {
2182 rtnl_lock();
2183 err = drv->ops->set_mgmt_extra_ie(&drv->wiphy, dev, &params);
2184 rtnl_unlock();
2185 } else
2186 err = -EOPNOTSUPP;
2187
2188 cfg80211_put_dev(drv);
2189 dev_put(dev);
2190 return err;
2191}
2192
2152static struct genl_ops nl80211_ops[] = { 2193static struct genl_ops nl80211_ops[] = {
2153 { 2194 {
2154 .cmd = NL80211_CMD_GET_WIPHY, 2195 .cmd = NL80211_CMD_GET_WIPHY,
@@ -2310,6 +2351,12 @@ static struct genl_ops nl80211_ops[] = {
2310 .policy = nl80211_policy, 2351 .policy = nl80211_policy,
2311 .flags = GENL_ADMIN_PERM, 2352 .flags = GENL_ADMIN_PERM,
2312 }, 2353 },
2354 {
2355 .cmd = NL80211_CMD_SET_MGMT_EXTRA_IE,
2356 .doit = nl80211_set_mgmt_extra_ie,
2357 .policy = nl80211_policy,
2358 .flags = GENL_ADMIN_PERM,
2359 },
2313}; 2360};
2314 2361
2315/* multicast groups */ 2362/* multicast groups */