aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 58693e52d458..223e536e8426 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1300,6 +1300,142 @@ static int ieee80211_scan(struct wiphy *wiphy,
1300 return ieee80211_request_scan(sdata, req); 1300 return ieee80211_request_scan(sdata, req);
1301} 1301}
1302 1302
1303static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
1304 struct cfg80211_auth_request *req)
1305{
1306 struct ieee80211_sub_if_data *sdata;
1307
1308 if (!netif_running(dev))
1309 return -ENETDOWN;
1310
1311 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1312
1313 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1314 return -EOPNOTSUPP;
1315
1316 switch (req->auth_type) {
1317 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1318 sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_OPEN;
1319 break;
1320 case NL80211_AUTHTYPE_SHARED_KEY:
1321 sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_SHARED_KEY;
1322 break;
1323 case NL80211_AUTHTYPE_FT:
1324 sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_FT;
1325 break;
1326 case NL80211_AUTHTYPE_NETWORK_EAP:
1327 sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_LEAP;
1328 break;
1329 default:
1330 return -EOPNOTSUPP;
1331 }
1332
1333 memcpy(sdata->u.mgd.bssid, req->peer_addr, ETH_ALEN);
1334 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
1335 sdata->u.mgd.flags |= IEEE80211_STA_BSSID_SET;
1336
1337 /* TODO: req->chan */
1338 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_CHANNEL_SEL;
1339
1340 if (req->ssid) {
1341 sdata->u.mgd.flags |= IEEE80211_STA_SSID_SET;
1342 memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
1343 sdata->u.mgd.ssid_len = req->ssid_len;
1344 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
1345 }
1346
1347 kfree(sdata->u.mgd.sme_auth_ie);
1348 sdata->u.mgd.sme_auth_ie = NULL;
1349 sdata->u.mgd.sme_auth_ie_len = 0;
1350 if (req->ie) {
1351 sdata->u.mgd.sme_auth_ie = kmalloc(req->ie_len, GFP_KERNEL);
1352 if (sdata->u.mgd.sme_auth_ie == NULL)
1353 return -ENOMEM;
1354 memcpy(sdata->u.mgd.sme_auth_ie, req->ie, req->ie_len);
1355 sdata->u.mgd.sme_auth_ie_len = req->ie_len;
1356 }
1357
1358 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
1359 sdata->u.mgd.state = IEEE80211_STA_MLME_DIRECT_PROBE;
1360 ieee80211_sta_req_auth(sdata);
1361 return 0;
1362}
1363
1364static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1365 struct cfg80211_assoc_request *req)
1366{
1367 struct ieee80211_sub_if_data *sdata;
1368 int ret;
1369
1370 if (!netif_running(dev))
1371 return -ENETDOWN;
1372
1373 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1374
1375 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1376 return -EOPNOTSUPP;
1377
1378 if (memcmp(sdata->u.mgd.bssid, req->peer_addr, ETH_ALEN) != 0 ||
1379 !(sdata->u.mgd.flags & IEEE80211_STA_AUTHENTICATED))
1380 return -ENOLINK; /* not authenticated */
1381
1382 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
1383 sdata->u.mgd.flags |= IEEE80211_STA_BSSID_SET;
1384
1385 /* TODO: req->chan */
1386 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_CHANNEL_SEL;
1387
1388 if (req->ssid) {
1389 sdata->u.mgd.flags |= IEEE80211_STA_SSID_SET;
1390 memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
1391 sdata->u.mgd.ssid_len = req->ssid_len;
1392 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
1393 } else
1394 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
1395
1396 ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);
1397 if (ret)
1398 return ret;
1399
1400 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
1401 sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
1402 ieee80211_sta_req_auth(sdata);
1403 return 0;
1404}
1405
1406static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
1407 struct cfg80211_deauth_request *req)
1408{
1409 struct ieee80211_sub_if_data *sdata;
1410
1411 if (!netif_running(dev))
1412 return -ENETDOWN;
1413
1414 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1415 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1416 return -EOPNOTSUPP;
1417
1418 /* TODO: req->ie */
1419 return ieee80211_sta_deauthenticate(sdata, req->reason_code);
1420}
1421
1422static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
1423 struct cfg80211_disassoc_request *req)
1424{
1425 struct ieee80211_sub_if_data *sdata;
1426
1427 if (!netif_running(dev))
1428 return -ENETDOWN;
1429
1430 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1431
1432 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1433 return -EOPNOTSUPP;
1434
1435 /* TODO: req->ie */
1436 return ieee80211_sta_disassociate(sdata, req->reason_code);
1437}
1438
1303struct cfg80211_ops mac80211_config_ops = { 1439struct cfg80211_ops mac80211_config_ops = {
1304 .add_virtual_intf = ieee80211_add_iface, 1440 .add_virtual_intf = ieee80211_add_iface,
1305 .del_virtual_intf = ieee80211_del_iface, 1441 .del_virtual_intf = ieee80211_del_iface,
@@ -1333,4 +1469,8 @@ struct cfg80211_ops mac80211_config_ops = {
1333 .suspend = ieee80211_suspend, 1469 .suspend = ieee80211_suspend,
1334 .resume = ieee80211_resume, 1470 .resume = ieee80211_resume,
1335 .scan = ieee80211_scan, 1471 .scan = ieee80211_scan,
1472 .auth = ieee80211_auth,
1473 .assoc = ieee80211_assoc,
1474 .deauth = ieee80211_deauth,
1475 .disassoc = ieee80211_disassoc,
1336}; 1476};