1/*- 2 * Copyright (c) 2004-2005 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_acl.c 149028 2005-08-13 17:31:48Z sam $"); |
34 35/* 36 * IEEE 802.11 MAC ACL support. 37 * 38 * When this module is loaded the sender address of each received 39 * frame is passed to the iac_check method and the module indicates 40 * if the frame should be accepted or rejected. If the policy is 41 * set to ACL_POLICY_OPEN then all frames are accepted w/o checking --- 28 unchanged lines hidden (view full) --- 70struct acl { 71 TAILQ_ENTRY(acl) acl_list; 72 LIST_ENTRY(acl) acl_hash; 73 u_int8_t acl_macaddr[IEEE80211_ADDR_LEN]; 74}; 75struct aclstate { 76 acl_lock_t as_lock; 77 int as_policy; |
78 int as_nacls; |
79 TAILQ_HEAD(, acl) as_list; /* list of all ACL's */ 80 LIST_HEAD(, acl) as_hash[ACL_HASHSIZE]; 81 struct ieee80211com *as_ic; 82}; 83 84/* simple hash is enough for variation of macaddr */ 85#define ACL_HASH(addr) \ 86 (((const u_int8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % ACL_HASHSIZE) 87 88MALLOC_DEFINE(M_80211_ACL, "acl", "802.11 station acl"); 89 90static int acl_free_all(struct ieee80211com *); 91 92static int 93acl_attach(struct ieee80211com *ic) 94{ 95 struct aclstate *as; 96 97 MALLOC(as, struct aclstate *, sizeof(struct aclstate), |
98 M_80211_ACL, M_NOWAIT | M_ZERO); |
99 if (as == NULL) 100 return 0; 101 ACL_LOCK_INIT(as, "acl"); 102 TAILQ_INIT(&as->as_list); 103 as->as_policy = ACL_POLICY_OPEN; 104 as->as_ic = ic; 105 ic->ic_as = as; 106 return 1; --- 27 unchanged lines hidden (view full) --- 134static void 135_acl_free(struct aclstate *as, struct acl *acl) 136{ 137 ACL_LOCK_ASSERT(as); 138 139 TAILQ_REMOVE(&as->as_list, acl, acl_list); 140 LIST_REMOVE(acl, acl_hash); 141 FREE(acl, M_80211_ACL); |
142 as->as_nacls--; |
143} 144 145static int 146acl_check(struct ieee80211com *ic, const u_int8_t mac[IEEE80211_ADDR_LEN]) 147{ 148 struct aclstate *as = ic->ic_as; 149 150 switch (as->as_policy) { --- 32 unchanged lines hidden (view full) --- 183 "ACL: add %s failed, already present\n", 184 ether_sprintf(mac)); 185 return EEXIST; 186 } 187 } 188 IEEE80211_ADDR_COPY(new->acl_macaddr, mac); 189 TAILQ_INSERT_TAIL(&as->as_list, new, acl_list); 190 LIST_INSERT_HEAD(&as->as_hash[hash], new, acl_hash); |
191 as->as_nacls++; |
192 ACL_UNLOCK(as); 193 194 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ACL, 195 "ACL: add %s\n", ether_sprintf(mac)); 196 return 0; 197} 198 199static int --- 58 unchanged lines hidden (view full) --- 258static int 259acl_getpolicy(struct ieee80211com *ic) 260{ 261 struct aclstate *as = ic->ic_as; 262 263 return as->as_policy; 264} 265 |
266static int 267acl_setioctl(struct ieee80211com *ic, struct ieee80211req *ireq) 268{ 269 270 return EINVAL; 271} 272 273static int 274acl_getioctl(struct ieee80211com *ic, struct ieee80211req *ireq) 275{ 276 struct aclstate *as = ic->ic_as; 277 struct acl *acl; 278 struct ieee80211req_maclist *ap; 279 int error, space, i; 280 281 switch (ireq->i_val) { 282 case IEEE80211_MACCMD_POLICY: 283 ireq->i_val = as->as_policy; 284 return 0; 285 case IEEE80211_MACCMD_LIST: 286 space = as->as_nacls * IEEE80211_ADDR_LEN; 287 if (ireq->i_len == 0) { 288 ireq->i_len = space; /* return required space */ 289 return 0; /* NB: must not error */ 290 } 291 MALLOC(ap, struct ieee80211req_maclist *, space, 292 M_TEMP, M_NOWAIT); 293 if (ap == NULL) 294 return ENOMEM; 295 i = 0; 296 ACL_LOCK(as); 297 TAILQ_FOREACH(acl, &as->as_list, acl_list) { 298 IEEE80211_ADDR_COPY(ap[i].ml_macaddr, acl->acl_macaddr); 299 i++; 300 } 301 ACL_UNLOCK(as); 302 if (ireq->i_len >= space) { 303 error = copyout(ap, ireq->i_data, space); 304 ireq->i_len = space; 305 } else 306 error = copyout(ap, ireq->i_data, ireq->i_len); 307 FREE(ap, M_TEMP); 308 return error; 309 } 310 return EINVAL; 311} 312 |
313static const struct ieee80211_aclator mac = { 314 .iac_name = "mac", 315 .iac_attach = acl_attach, 316 .iac_detach = acl_detach, 317 .iac_check = acl_check, 318 .iac_add = acl_add, 319 .iac_remove = acl_remove, 320 .iac_flush = acl_free_all, 321 .iac_setpolicy = acl_setpolicy, 322 .iac_getpolicy = acl_getpolicy, |
323 .iac_setioctl = acl_setioctl, 324 .iac_getioctl = acl_getioctl, |
325}; 326 327/* 328 * Module glue. 329 */ 330static int 331wlan_acl_modevent(module_t mod, int type, void *unused) 332{ --- 21 unchanged lines hidden --- |