aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wext.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/wext.c')
-rw-r--r--net/mac80211/wext.c141
1 files changed, 80 insertions, 61 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 2b023dce8b24..8a76a979bc92 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -132,13 +132,12 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
132 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) 132 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
133 return -EOPNOTSUPP; 133 return -EOPNOTSUPP;
134 134
135 if (sdata->vif.type == NL80211_IFTYPE_STATION || 135 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
136 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
137 int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length); 136 int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length);
138 if (ret) 137 if (ret)
139 return ret; 138 return ret;
140 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 139 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
141 ieee80211_sta_req_auth(sdata, &sdata->u.sta); 140 ieee80211_sta_req_auth(sdata);
142 return 0; 141 return 0;
143 } 142 }
144 143
@@ -255,16 +254,19 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
255{ 254{
256 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 255 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
257 256
258 if (sdata->vif.type == NL80211_IFTYPE_ADHOC || 257 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
259 sdata->vif.type == NL80211_IFTYPE_STATION) 258 sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_CHANNEL_SEL;
260 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL; 259 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
260 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
261 261
262 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ 262 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
263 if (freq->e == 0) { 263 if (freq->e == 0) {
264 if (freq->m < 0) { 264 if (freq->m < 0) {
265 if (sdata->vif.type == NL80211_IFTYPE_ADHOC || 265 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
266 sdata->vif.type == NL80211_IFTYPE_STATION) 266 sdata->u.ibss.flags |=
267 sdata->u.sta.flags |= 267 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
268 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
269 sdata->u.mgd.flags |=
268 IEEE80211_STA_AUTO_CHANNEL_SEL; 270 IEEE80211_STA_AUTO_CHANNEL_SEL;
269 return 0; 271 return 0;
270 } else 272 } else
@@ -301,32 +303,35 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
301{ 303{
302 struct ieee80211_sub_if_data *sdata; 304 struct ieee80211_sub_if_data *sdata;
303 size_t len = data->length; 305 size_t len = data->length;
306 int ret;
304 307
305 /* iwconfig uses nul termination in SSID.. */ 308 /* iwconfig uses nul termination in SSID.. */
306 if (len > 0 && ssid[len - 1] == '\0') 309 if (len > 0 && ssid[len - 1] == '\0')
307 len--; 310 len--;
308 311
309 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 312 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
310 if (sdata->vif.type == NL80211_IFTYPE_STATION || 313 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
311 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
312 int ret;
313 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) { 314 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
314 if (len > IEEE80211_MAX_SSID_LEN) 315 if (len > IEEE80211_MAX_SSID_LEN)
315 return -EINVAL; 316 return -EINVAL;
316 memcpy(sdata->u.sta.ssid, ssid, len); 317 memcpy(sdata->u.mgd.ssid, ssid, len);
317 sdata->u.sta.ssid_len = len; 318 sdata->u.mgd.ssid_len = len;
318 return 0; 319 return 0;
319 } 320 }
321
320 if (data->flags) 322 if (data->flags)
321 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_SSID_SEL; 323 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
322 else 324 else
323 sdata->u.sta.flags |= IEEE80211_STA_AUTO_SSID_SEL; 325 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
326
324 ret = ieee80211_sta_set_ssid(sdata, ssid, len); 327 ret = ieee80211_sta_set_ssid(sdata, ssid, len);
325 if (ret) 328 if (ret)
326 return ret; 329 return ret;
327 ieee80211_sta_req_auth(sdata, &sdata->u.sta); 330
331 ieee80211_sta_req_auth(sdata);
328 return 0; 332 return 0;
329 } 333 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
334 return ieee80211_ibss_set_ssid(sdata, ssid, len);
330 335
331 return -EOPNOTSUPP; 336 return -EOPNOTSUPP;
332} 337}
@@ -340,8 +345,7 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
340 345
341 struct ieee80211_sub_if_data *sdata; 346 struct ieee80211_sub_if_data *sdata;
342 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 347 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
343 if (sdata->vif.type == NL80211_IFTYPE_STATION || 348 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
344 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
345 int res = ieee80211_sta_get_ssid(sdata, ssid, &len); 349 int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
346 if (res == 0) { 350 if (res == 0) {
347 data->length = len; 351 data->length = len;
@@ -349,6 +353,14 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
349 } else 353 } else
350 data->flags = 0; 354 data->flags = 0;
351 return res; 355 return res;
356 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
357 int res = ieee80211_ibss_get_ssid(sdata, ssid, &len);
358 if (res == 0) {
359 data->length = len;
360 data->flags = 1;
361 } else
362 data->flags = 0;
363 return res;
352 } 364 }
353 365
354 return -EOPNOTSUPP; 366 return -EOPNOTSUPP;
@@ -362,26 +374,35 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
362 struct ieee80211_sub_if_data *sdata; 374 struct ieee80211_sub_if_data *sdata;
363 375
364 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 376 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
365 if (sdata->vif.type == NL80211_IFTYPE_STATION || 377 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
366 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
367 int ret; 378 int ret;
368 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) { 379 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
369 memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data, 380 memcpy(sdata->u.mgd.bssid, (u8 *) &ap_addr->sa_data,
370 ETH_ALEN); 381 ETH_ALEN);
371 return 0; 382 return 0;
372 } 383 }
373 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data)) 384 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
374 sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL | 385 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL |
375 IEEE80211_STA_AUTO_CHANNEL_SEL; 386 IEEE80211_STA_AUTO_CHANNEL_SEL;
376 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data)) 387 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
377 sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL; 388 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL;
378 else 389 else
379 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 390 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
380 ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data); 391 ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
381 if (ret) 392 if (ret)
382 return ret; 393 return ret;
383 ieee80211_sta_req_auth(sdata, &sdata->u.sta); 394 ieee80211_sta_req_auth(sdata);
384 return 0; 395 return 0;
396 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
397 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
398 sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
399 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
400 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
401 sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL;
402 else
403 sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_BSSID_SEL;
404
405 return ieee80211_ibss_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
385 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 406 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
386 /* 407 /*
387 * If it is necessary to update the WDS peer address 408 * If it is necessary to update the WDS peer address
@@ -410,17 +431,20 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
410 struct ieee80211_sub_if_data *sdata; 431 struct ieee80211_sub_if_data *sdata;
411 432
412 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 433 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
413 if (sdata->vif.type == NL80211_IFTYPE_STATION || 434 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
414 sdata->vif.type == NL80211_IFTYPE_ADHOC) { 435 if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) {
415 if (sdata->u.sta.state == IEEE80211_STA_MLME_ASSOCIATED ||
416 sdata->u.sta.state == IEEE80211_STA_MLME_IBSS_JOINED) {
417 ap_addr->sa_family = ARPHRD_ETHER; 436 ap_addr->sa_family = ARPHRD_ETHER;
418 memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN); 437 memcpy(&ap_addr->sa_data, sdata->u.mgd.bssid, ETH_ALEN);
419 return 0; 438 } else
420 } else {
421 memset(&ap_addr->sa_data, 0, ETH_ALEN); 439 memset(&ap_addr->sa_data, 0, ETH_ALEN);
422 return 0; 440 return 0;
423 } 441 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
442 if (sdata->u.ibss.state == IEEE80211_IBSS_MLME_JOINED) {
443 ap_addr->sa_family = ARPHRD_ETHER;
444 memcpy(&ap_addr->sa_data, sdata->u.ibss.bssid, ETH_ALEN);
445 } else
446 memset(&ap_addr->sa_data, 0, ETH_ALEN);
447 return 0;
424 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 448 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
425 ap_addr->sa_family = ARPHRD_ETHER; 449 ap_addr->sa_family = ARPHRD_ETHER;
426 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); 450 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
@@ -486,7 +510,7 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
486 510
487 rcu_read_lock(); 511 rcu_read_lock();
488 512
489 sta = sta_info_get(local, sdata->u.sta.bssid); 513 sta = sta_info_get(local, sdata->u.mgd.bssid);
490 514
491 if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) 515 if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
492 rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate; 516 rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate;
@@ -687,8 +711,7 @@ static int ieee80211_ioctl_siwmlme(struct net_device *dev,
687 struct iw_mlme *mlme = (struct iw_mlme *) extra; 711 struct iw_mlme *mlme = (struct iw_mlme *) extra;
688 712
689 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 713 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
690 if (sdata->vif.type != NL80211_IFTYPE_STATION && 714 if (!(sdata->vif.type == NL80211_IFTYPE_STATION))
691 sdata->vif.type != NL80211_IFTYPE_ADHOC)
692 return -EINVAL; 715 return -EINVAL;
693 716
694 switch (mlme->cmd) { 717 switch (mlme->cmd) {
@@ -784,8 +807,7 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev,
784 erq->flags |= IW_ENCODE_ENABLED; 807 erq->flags |= IW_ENCODE_ENABLED;
785 808
786 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 809 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
787 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 810 switch (sdata->u.mgd.auth_alg) {
788 switch (ifsta->auth_alg) {
789 case WLAN_AUTH_OPEN: 811 case WLAN_AUTH_OPEN:
790 case WLAN_AUTH_LEAP: 812 case WLAN_AUTH_LEAP:
791 erq->flags |= IW_ENCODE_OPEN; 813 erq->flags |= IW_ENCODE_OPEN;
@@ -849,7 +871,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
849 ret = ieee80211_hw_config(local, 871 ret = ieee80211_hw_config(local,
850 IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT); 872 IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT);
851 873
852 if (!(sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) 874 if (!(sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
853 return ret; 875 return ret;
854 876
855 if (conf->dynamic_ps_timeout > 0 && 877 if (conf->dynamic_ps_timeout > 0 &&
@@ -908,10 +930,10 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
908 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 930 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
909 if (data->value & (IW_AUTH_CIPHER_WEP40 | 931 if (data->value & (IW_AUTH_CIPHER_WEP40 |
910 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_TKIP)) 932 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_TKIP))
911 sdata->u.sta.flags |= 933 sdata->u.mgd.flags |=
912 IEEE80211_STA_TKIP_WEP_USED; 934 IEEE80211_STA_TKIP_WEP_USED;
913 else 935 else
914 sdata->u.sta.flags &= 936 sdata->u.mgd.flags &=
915 ~IEEE80211_STA_TKIP_WEP_USED; 937 ~IEEE80211_STA_TKIP_WEP_USED;
916 } 938 }
917 break; 939 break;
@@ -922,21 +944,20 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
922 if (sdata->vif.type != NL80211_IFTYPE_STATION) 944 if (sdata->vif.type != NL80211_IFTYPE_STATION)
923 ret = -EINVAL; 945 ret = -EINVAL;
924 else { 946 else {
925 sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; 947 sdata->u.mgd.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
926 /* 948 /*
927 * Privacy invoked by wpa_supplicant, store the 949 * Privacy invoked by wpa_supplicant, store the
928 * value and allow associating to a protected 950 * value and allow associating to a protected
929 * network without having a key up front. 951 * network without having a key up front.
930 */ 952 */
931 if (data->value) 953 if (data->value)
932 sdata->u.sta.flags |= 954 sdata->u.mgd.flags |=
933 IEEE80211_STA_PRIVACY_INVOKED; 955 IEEE80211_STA_PRIVACY_INVOKED;
934 } 956 }
935 break; 957 break;
936 case IW_AUTH_80211_AUTH_ALG: 958 case IW_AUTH_80211_AUTH_ALG:
937 if (sdata->vif.type == NL80211_IFTYPE_STATION || 959 if (sdata->vif.type == NL80211_IFTYPE_STATION)
938 sdata->vif.type == NL80211_IFTYPE_ADHOC) 960 sdata->u.mgd.auth_algs = data->value;
939 sdata->u.sta.auth_algs = data->value;
940 else 961 else
941 ret = -EOPNOTSUPP; 962 ret = -EOPNOTSUPP;
942 break; 963 break;
@@ -945,17 +966,16 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
945 ret = -EOPNOTSUPP; 966 ret = -EOPNOTSUPP;
946 break; 967 break;
947 } 968 }
948 if (sdata->vif.type == NL80211_IFTYPE_STATION || 969 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
949 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
950 switch (data->value) { 970 switch (data->value) {
951 case IW_AUTH_MFP_DISABLED: 971 case IW_AUTH_MFP_DISABLED:
952 sdata->u.sta.mfp = IEEE80211_MFP_DISABLED; 972 sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
953 break; 973 break;
954 case IW_AUTH_MFP_OPTIONAL: 974 case IW_AUTH_MFP_OPTIONAL:
955 sdata->u.sta.mfp = IEEE80211_MFP_OPTIONAL; 975 sdata->u.mgd.mfp = IEEE80211_MFP_OPTIONAL;
956 break; 976 break;
957 case IW_AUTH_MFP_REQUIRED: 977 case IW_AUTH_MFP_REQUIRED:
958 sdata->u.sta.mfp = IEEE80211_MFP_REQUIRED; 978 sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
959 break; 979 break;
960 default: 980 default:
961 ret = -EINVAL; 981 ret = -EINVAL;
@@ -980,9 +1000,9 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
980 1000
981 rcu_read_lock(); 1001 rcu_read_lock();
982 1002
983 if (sdata->vif.type == NL80211_IFTYPE_STATION || 1003 if (sdata->vif.type == NL80211_IFTYPE_STATION)
984 sdata->vif.type == NL80211_IFTYPE_ADHOC) 1004 sta = sta_info_get(local, sdata->u.mgd.bssid);
985 sta = sta_info_get(local, sdata->u.sta.bssid); 1005
986 if (!sta) { 1006 if (!sta) {
987 wstats->discard.fragment = 0; 1007 wstats->discard.fragment = 0;
988 wstats->discard.misc = 0; 1008 wstats->discard.misc = 0;
@@ -1011,9 +1031,8 @@ static int ieee80211_ioctl_giwauth(struct net_device *dev,
1011 1031
1012 switch (data->flags & IW_AUTH_INDEX) { 1032 switch (data->flags & IW_AUTH_INDEX) {
1013 case IW_AUTH_80211_AUTH_ALG: 1033 case IW_AUTH_80211_AUTH_ALG:
1014 if (sdata->vif.type == NL80211_IFTYPE_STATION || 1034 if (sdata->vif.type == NL80211_IFTYPE_STATION)
1015 sdata->vif.type == NL80211_IFTYPE_ADHOC) 1035 data->value = sdata->u.mgd.auth_algs;
1016 data->value = sdata->u.sta.auth_algs;
1017 else 1036 else
1018 ret = -EOPNOTSUPP; 1037 ret = -EOPNOTSUPP;
1019 break; 1038 break;