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 186107 2008-12-15 01:26:33Z 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 MALLOC(p, void *, 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 MALLOC(p, void *, 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 MALLOC(dc, struct ieee80211_devcaps_req *,
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 MALLOC(reg, struct ieee80211_regdomain_req *,
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 MALLOC(napp, struct ieee80211_appie *,
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 ---
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 186107 2008-12-15 01:26:33Z 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 MALLOC(p, void *, 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 MALLOC(p, void *, 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 MALLOC(dc, struct ieee80211_devcaps_req *,
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 MALLOC(reg, struct ieee80211_regdomain_req *,
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 MALLOC(napp, struct ieee80211_appie *,
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 ---