ieee80211_ioctl.c (160686) | ieee80211_ioctl.c (161146) |
---|---|
1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_ioctl.c 160686 2006-07-26 03:07:36Z sam $"); | 34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_ioctl.c 161146 2006-08-10 06:04:00Z sam $"); |
35 36/* 37 * IEEE 802.11 ioctl support (FreeBSD-specific) 38 */ 39 40#include "opt_inet.h" 41#include "opt_ipx.h" 42 --- 912 unchanged lines hidden (view full) --- 955 int error; 956 957 if (ireq->i_len < off) 958 return EINVAL; 959 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 960 if (error != 0) 961 return error; 962 ni = ieee80211_find_node(&ic->ic_sta, macaddr); | 35 36/* 37 * IEEE 802.11 ioctl support (FreeBSD-specific) 38 */ 39 40#include "opt_inet.h" 41#include "opt_ipx.h" 42 --- 912 unchanged lines hidden (view full) --- 955 int error; 956 957 if (ireq->i_len < off) 958 return EINVAL; 959 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 960 if (error != 0) 961 return error; 962 ni = ieee80211_find_node(&ic->ic_sta, macaddr); |
963 if (ni == NULL) 964 return EINVAL; /* XXX */ | 963 if (ni == NULL) { 964 /* XXX special-case sta-mode until bss is node in ic_sta */ 965 if (ic->ic_opmode != IEEE80211_M_STA) 966 return ENOENT; 967 ni = ieee80211_ref_node(ic->ic_bss); 968 } |
965 if (ireq->i_len > sizeof(struct ieee80211req_sta_stats)) 966 ireq->i_len = sizeof(struct ieee80211req_sta_stats); 967 /* NB: copy out only the statistics */ 968 error = copyout(&ni->ni_stats, (u_int8_t *) ireq->i_data + off, 969 ireq->i_len - off); 970 ieee80211_free_node(ni); 971 return error; 972} --- 273 unchanged lines hidden (view full) --- 1246 KASSERT(len <= 65535 && ielen <= 65535, ("len %zu ie %zu", len, ielen)); 1247 si->isi_len = len; 1248 si->isi_ie_len = ielen; 1249 si->isi_freq = ni->ni_chan->ic_freq; 1250 si->isi_flags = ni->ni_chan->ic_flags; 1251 si->isi_state = ni->ni_flags; 1252 si->isi_authmode = ni->ni_authmode; 1253 si->isi_rssi = ic->ic_node_getrssi(ni); | 969 if (ireq->i_len > sizeof(struct ieee80211req_sta_stats)) 970 ireq->i_len = sizeof(struct ieee80211req_sta_stats); 971 /* NB: copy out only the statistics */ 972 error = copyout(&ni->ni_stats, (u_int8_t *) ireq->i_data + off, 973 ireq->i_len - off); 974 ieee80211_free_node(ni); 975 return error; 976} --- 273 unchanged lines hidden (view full) --- 1250 KASSERT(len <= 65535 && ielen <= 65535, ("len %zu ie %zu", len, ielen)); 1251 si->isi_len = len; 1252 si->isi_ie_len = ielen; 1253 si->isi_freq = ni->ni_chan->ic_freq; 1254 si->isi_flags = ni->ni_chan->ic_flags; 1255 si->isi_state = ni->ni_flags; 1256 si->isi_authmode = ni->ni_authmode; 1257 si->isi_rssi = ic->ic_node_getrssi(ni); |
1258 si->isi_noise = 0; /* XXX */ |
|
1254 si->isi_capinfo = ni->ni_capinfo; 1255 si->isi_erp = ni->ni_erp; 1256 IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr); 1257 si->isi_nrates = ni->ni_rates.rs_nrates; 1258 if (si->isi_nrates > 15) 1259 si->isi_nrates = 15; 1260 memcpy(si->isi_rates, ni->ni_rates.rs_rates, si->isi_nrates); 1261 si->isi_txrate = ni->ni_txrate; --- 26 unchanged lines hidden (view full) --- 1288 cp += 2+ni->ni_wme_ie[1]; 1289 } 1290 1291 req->si = (struct ieee80211req_sta_info *)(((u_int8_t *)si) + len); 1292 req->space -= len; 1293} 1294 1295static int | 1259 si->isi_capinfo = ni->ni_capinfo; 1260 si->isi_erp = ni->ni_erp; 1261 IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr); 1262 si->isi_nrates = ni->ni_rates.rs_nrates; 1263 if (si->isi_nrates > 15) 1264 si->isi_nrates = 15; 1265 memcpy(si->isi_rates, ni->ni_rates.rs_rates, si->isi_nrates); 1266 si->isi_txrate = ni->ni_txrate; --- 26 unchanged lines hidden (view full) --- 1293 cp += 2+ni->ni_wme_ie[1]; 1294 } 1295 1296 req->si = (struct ieee80211req_sta_info *)(((u_int8_t *)si) + len); 1297 req->space -= len; 1298} 1299 1300static int |
1296ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq) | 1301getstainfo_common(struct ieee80211com *ic, struct ieee80211req *ireq, 1302 struct ieee80211_node *ni, int off) |
1297{ 1298 struct stainforeq req; | 1303{ 1304 struct stainforeq req; |
1305 size_t space; 1306 void *p; |
|
1299 int error; 1300 | 1307 int error; 1308 |
1301 if (ireq->i_len < sizeof(struct stainforeq)) 1302 return EFAULT; 1303 | |
1304 error = 0; 1305 req.space = 0; | 1309 error = 0; 1310 req.space = 0; |
1306 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req); | 1311 if (ni == NULL) 1312 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req); 1313 else 1314 get_sta_space(&req, ni); |
1307 if (req.space > ireq->i_len) 1308 req.space = ireq->i_len; 1309 if (req.space > 0) { | 1315 if (req.space > ireq->i_len) 1316 req.space = ireq->i_len; 1317 if (req.space > 0) { |
1310 size_t space; 1311 void *p; 1312 | |
1313 space = req.space; 1314 /* XXX M_WAITOK after driver lock released */ 1315 MALLOC(p, void *, space, M_TEMP, M_NOWAIT); | 1318 space = req.space; 1319 /* XXX M_WAITOK after driver lock released */ 1320 MALLOC(p, void *, space, M_TEMP, M_NOWAIT); |
1316 if (p == NULL) 1317 return ENOMEM; | 1321 if (p == NULL) { 1322 error = ENOMEM; 1323 goto bad; 1324 } |
1318 req.si = p; | 1325 req.si = p; |
1319 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req); | 1326 if (ni == NULL) 1327 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req); 1328 else 1329 get_sta_info(&req, ni); |
1320 ireq->i_len = space - req.space; | 1330 ireq->i_len = space - req.space; |
1321 error = copyout(p, ireq->i_data, ireq->i_len); | 1331 error = copyout(p, (u_int8_t *) ireq->i_data+off, ireq->i_len); |
1322 FREE(p, M_TEMP); 1323 } else 1324 ireq->i_len = 0; | 1332 FREE(p, M_TEMP); 1333 } else 1334 ireq->i_len = 0; |
1325 | 1335bad: 1336 if (ni != NULL) 1337 ieee80211_free_node(ni); |
1326 return error; 1327} 1328 1329static int | 1338 return error; 1339} 1340 1341static int |
1342ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq) 1343{ 1344 u_int8_t macaddr[IEEE80211_ADDR_LEN]; 1345 const int off = __offsetof(struct ieee80211req_sta_req, info); 1346 struct ieee80211_node *ni; 1347 int error; 1348 1349 if (ireq->i_len < sizeof(struct ieee80211req_sta_req)) 1350 return EFAULT; 1351 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 1352 if (error != 0) 1353 return error; 1354 if (IEEE80211_ADDR_EQ(macaddr, ic->ic_ifp->if_broadcastaddr)) { 1355 ni = NULL; 1356 } else { 1357 ni = ieee80211_find_node(&ic->ic_sta, macaddr); 1358 if (ni == NULL) { 1359 /* XXX special-case sta-mode until bss is in ic_sta */ 1360 if (ic->ic_opmode != IEEE80211_M_STA) 1361 return EINVAL; /* XXX */ 1362 ni = ieee80211_ref_node(ic->ic_bss); 1363 } 1364 } 1365 return getstainfo_common(ic, ireq, ni, off); 1366} 1367 1368#ifdef COMPAT_FREEBSD6 1369#define IEEE80211_IOC_STA_INFO_OLD 45 1370 1371static int 1372old_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq) 1373{ 1374 if (ireq->i_len < sizeof(struct ieee80211req_sta_info)) 1375 return EFAULT; 1376 return getstainfo_common(ic, ireq, NULL, 0); 1377} 1378#endif /* COMPAT_FREEBSD6 */ 1379 1380static int |
|
1330ieee80211_ioctl_getstatxpow(struct ieee80211com *ic, struct ieee80211req *ireq) 1331{ 1332 struct ieee80211_node *ni; 1333 struct ieee80211req_sta_txpow txpow; 1334 int error; 1335 1336 if (ireq->i_len != sizeof(txpow)) 1337 return EINVAL; --- 268 unchanged lines hidden (view full) --- 1606 error = ieee80211_ioctl_getstastats(ic, ireq); 1607 break; 1608 case IEEE80211_IOC_TXPOWMAX: 1609 ireq->i_val = ic->ic_bss->ni_txpower; 1610 break; 1611 case IEEE80211_IOC_STA_TXPOW: 1612 error = ieee80211_ioctl_getstatxpow(ic, ireq); 1613 break; | 1381ieee80211_ioctl_getstatxpow(struct ieee80211com *ic, struct ieee80211req *ireq) 1382{ 1383 struct ieee80211_node *ni; 1384 struct ieee80211req_sta_txpow txpow; 1385 int error; 1386 1387 if (ireq->i_len != sizeof(txpow)) 1388 return EINVAL; --- 268 unchanged lines hidden (view full) --- 1657 error = ieee80211_ioctl_getstastats(ic, ireq); 1658 break; 1659 case IEEE80211_IOC_TXPOWMAX: 1660 ireq->i_val = ic->ic_bss->ni_txpower; 1661 break; 1662 case IEEE80211_IOC_STA_TXPOW: 1663 error = ieee80211_ioctl_getstatxpow(ic, ireq); 1664 break; |
1665#ifdef COMPAT_FREEBSD6 1666 case IEEE80211_IOC_STA_INFO_OLD: 1667 error = old_getstainfo(ic, ireq); 1668 break; 1669#endif |
|
1614 case IEEE80211_IOC_STA_INFO: 1615 error = ieee80211_ioctl_getstainfo(ic, ireq); 1616 break; 1617 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 1618 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 1619 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 1620 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 1621 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ --- 1093 unchanged lines hidden --- | 1670 case IEEE80211_IOC_STA_INFO: 1671 error = ieee80211_ioctl_getstainfo(ic, ireq); 1672 break; 1673 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 1674 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 1675 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 1676 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 1677 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ --- 1093 unchanged lines hidden --- |