1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2008 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: --- 11 unchanged lines hidden (view full) --- 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_ioctl.c 186302 2008-12-18 23:00:09Z sam $"); |
29 30/* 31 * IEEE 802.11 ioctl support (FreeBSD-specific) 32 */ 33 34#include "opt_inet.h" 35#include "opt_ipx.h" 36#include "opt_wlan.h" --- 278 unchanged lines hidden (view full) --- 315 if (req.space > ireq->i_len) 316 req.space = ireq->i_len; 317 if (req.space > 0) { 318 size_t space; 319 void *p; 320 321 space = req.space; 322 /* XXX M_WAITOK after driver lock released */ |
323 p = malloc(space, M_TEMP, M_NOWAIT | M_ZERO); |
324 if (p == NULL) 325 return ENOMEM; 326 req.sr = p; 327 ieee80211_scan_iterate(vap, get_scan_result, &req); 328 ireq->i_len = space - req.space; 329 error = copyout(p, ireq->i_data, ireq->i_len); |
330 free(p, M_TEMP); |
331 } else 332 ireq->i_len = 0; 333 334 return error; 335} 336 337struct stainforeq { 338 struct ieee80211vap *vap; --- 123 unchanged lines hidden (view full) --- 462 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req); 463 else 464 get_sta_space(&req, ni); 465 if (req.space > ireq->i_len) 466 req.space = ireq->i_len; 467 if (req.space > 0) { 468 space = req.space; 469 /* XXX M_WAITOK after driver lock released */ |
470 p = malloc(space, M_TEMP, M_NOWAIT | M_ZERO); |
471 if (p == NULL) { 472 error = ENOMEM; 473 goto bad; 474 } 475 req.si = p; 476 if (ni == NULL) 477 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req); 478 else 479 get_sta_info(&req, ni); 480 ireq->i_len = space - req.space; 481 error = copyout(p, (uint8_t *) ireq->i_data+off, ireq->i_len); |
482 free(p, M_TEMP); |
483 } else 484 ireq->i_len = 0; 485bad: 486 if (ni != NULL) 487 ieee80211_free_node(ni); 488 return error; 489} 490 --- 200 unchanged lines hidden (view full) --- 691 const struct ieee80211req *ireq) 692{ 693 struct ieee80211_devcaps_req *dc; 694 struct ieee80211req_chaninfo *ci; 695 int error; 696 697 if (ireq->i_len != sizeof(struct ieee80211_devcaps_req)) 698 return EINVAL; |
699 dc = (struct ieee80211_devcaps_req *) malloc( |
700 sizeof(struct ieee80211_devcaps_req), M_TEMP, M_NOWAIT | M_ZERO); 701 if (dc == NULL) 702 return ENOMEM; 703 dc->dc_drivercaps = ic->ic_caps; 704 dc->dc_cryptocaps = ic->ic_cryptocaps; 705 dc->dc_htcaps = ic->ic_htcaps; 706 ci = &dc->dc_chaninfo; 707 ic->ic_getradiocaps(ic, &ci->ic_nchans, ci->ic_chans); 708 ieee80211_sort_channels(ci->ic_chans, ci->ic_nchans); 709 error = copyout(dc, ireq->i_data, sizeof(*dc)); |
710 free(dc, M_TEMP); |
711 return error; 712} 713 714static __noinline int 715ieee80211_ioctl_getstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq) 716{ 717 struct ieee80211_node *ni; 718 struct ieee80211req_sta_vlan vlan; --- 1261 unchanged lines hidden (view full) --- 1980ieee80211_ioctl_setregdomain(struct ieee80211vap *vap, 1981 const struct ieee80211req *ireq) 1982{ 1983 struct ieee80211_regdomain_req *reg; 1984 int error; 1985 1986 if (ireq->i_len != sizeof(struct ieee80211_regdomain_req)) 1987 return EINVAL; |
1988 reg = (struct ieee80211_regdomain_req *) malloc( |
1989 sizeof(struct ieee80211_regdomain_req), M_TEMP, M_NOWAIT); 1990 if (reg == NULL) 1991 return ENOMEM; 1992 error = copyin(ireq->i_data, reg, sizeof(*reg)); 1993 if (error == 0) 1994 error = ieee80211_setregdomain(vap, reg); |
1995 free(reg, M_TEMP); |
1996 1997 return (error == 0 ? ENETRESET : error); 1998} 1999 2000static int 2001ieee80211_ioctl_setroam(struct ieee80211vap *vap, 2002 const struct ieee80211req *ireq) 2003{ --- 122 unchanged lines hidden (view full) --- 2126{ 2127 struct ieee80211_appie *app = *aie; 2128 struct ieee80211_appie *napp; 2129 int error; 2130 2131 if (ireq->i_len == 0) { /* delete any existing ie */ 2132 if (app != NULL) { 2133 *aie = NULL; /* XXX racey */ |
2134 free(app, M_80211_NODE_IE); |
2135 } 2136 return 0; 2137 } 2138 if (!(2 <= ireq->i_len && ireq->i_len <= IEEE80211_MAX_APPIE)) 2139 return EINVAL; 2140 /* 2141 * Allocate a new appie structure and copy in the user data. 2142 * When done swap in the new structure. Note that we do not 2143 * guard against users holding a ref to the old structure; 2144 * this must be handled outside this code. 2145 * 2146 * XXX bad bad bad 2147 */ |
2148 napp = (struct ieee80211_appie *) malloc( |
2149 sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE, M_NOWAIT); 2150 if (napp == NULL) 2151 return ENOMEM; 2152 /* XXX holding ic lock */ 2153 error = copyin(ireq->i_data, napp->ie_data, ireq->i_len); 2154 if (error) { |
2155 free(napp, M_80211_NODE_IE); |
2156 return error; 2157 } 2158 napp->ie_len = ireq->i_len; 2159 *aie = napp; 2160 if (app != NULL) |
2161 free(app, M_80211_NODE_IE); |
2162 return 0; 2163} 2164 2165static void 2166setwparsnie(struct ieee80211vap *vap, uint8_t *ie, int space) 2167{ 2168 /* validate data is present as best we can */ 2169 if (space == 0 || 2+ie[1] > space) --- 1137 unchanged lines hidden --- |