aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorSam Leffler <sam@FreeBSD.org>2005-08-13 17:31:48 +0000
committerSam Leffler <sam@FreeBSD.org>2005-08-13 17:31:48 +0000
commit188757f54c844f7a1c7d8cd03afd8af160fc3ed1 (patch)
treef0d9a9b4254830aeaf4b80f482f49834bcdafc54 /sys
parentd958d0d5dc653eb82feb9017e5fa12a1a17b2d0c (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211_acl.c54
-rw-r--r--sys/net80211/ieee80211_ioctl.c20
-rw-r--r--sys/net80211/ieee80211_ioctl.h6
-rw-r--r--sys/net80211/ieee80211_proto.h3
4 files changed, 79 insertions, 4 deletions
diff --git a/sys/net80211/ieee80211_acl.c b/sys/net80211/ieee80211_acl.c
index ccd0c2b8b281..2dadff99c730 100644
--- a/sys/net80211/ieee80211_acl.c
+++ b/sys/net80211/ieee80211_acl.c
@@ -75,6 +75,7 @@ struct acl {
struct aclstate {
acl_lock_t as_lock;
int as_policy;
+ int as_nacls;
TAILQ_HEAD(, acl) as_list; /* list of all ACL's */
LIST_HEAD(, acl) as_hash[ACL_HASHSIZE];
struct ieee80211com *as_ic;
@@ -94,7 +95,7 @@ acl_attach(struct ieee80211com *ic)
struct aclstate *as;
MALLOC(as, struct aclstate *, sizeof(struct aclstate),
- M_DEVBUF, M_NOWAIT | M_ZERO);
+ M_80211_ACL, M_NOWAIT | M_ZERO);
if (as == NULL)
return 0;
ACL_LOCK_INIT(as, "acl");
@@ -138,6 +139,7 @@ _acl_free(struct aclstate *as, struct acl *acl)
TAILQ_REMOVE(&as->as_list, acl, acl_list);
LIST_REMOVE(acl, acl_hash);
FREE(acl, M_80211_ACL);
+ as->as_nacls--;
}
static int
@@ -186,6 +188,7 @@ acl_add(struct ieee80211com *ic, const u_int8_t mac[IEEE80211_ADDR_LEN])
IEEE80211_ADDR_COPY(new->acl_macaddr, mac);
TAILQ_INSERT_TAIL(&as->as_list, new, acl_list);
LIST_INSERT_HEAD(&as->as_hash[hash], new, acl_hash);
+ as->as_nacls++;
ACL_UNLOCK(as);
IEEE80211_DPRINTF(ic, IEEE80211_MSG_ACL,
@@ -260,6 +263,53 @@ acl_getpolicy(struct ieee80211com *ic)
return as->as_policy;
}
+static int
+acl_setioctl(struct ieee80211com *ic, struct ieee80211req *ireq)
+{
+
+ return EINVAL;
+}
+
+static int
+acl_getioctl(struct ieee80211com *ic, struct ieee80211req *ireq)
+{
+ struct aclstate *as = ic->ic_as;
+ struct acl *acl;
+ struct ieee80211req_maclist *ap;
+ int error, space, i;
+
+ switch (ireq->i_val) {
+ case IEEE80211_MACCMD_POLICY:
+ ireq->i_val = as->as_policy;
+ return 0;
+ case IEEE80211_MACCMD_LIST:
+ space = as->as_nacls * IEEE80211_ADDR_LEN;
+ if (ireq->i_len == 0) {
+ ireq->i_len = space; /* return required space */
+ return 0; /* NB: must not error */
+ }
+ MALLOC(ap, struct ieee80211req_maclist *, space,
+ M_TEMP, M_NOWAIT);
+ if (ap == NULL)
+ return ENOMEM;
+ i = 0;
+ ACL_LOCK(as);
+ TAILQ_FOREACH(acl, &as->as_list, acl_list) {
+ IEEE80211_ADDR_COPY(ap[i].ml_macaddr, acl->acl_macaddr);
+ i++;
+ }
+ ACL_UNLOCK(as);
+ if (ireq->i_len >= space) {
+ error = copyout(ap, ireq->i_data, space);
+ ireq->i_len = space;
+ } else
+ error = copyout(ap, ireq->i_data, ireq->i_len);
+ FREE(ap, M_TEMP);
+ return error;
+ }
+ return EINVAL;
+}
+
static const struct ieee80211_aclator mac = {
.iac_name = "mac",
.iac_attach = acl_attach,
@@ -270,6 +320,8 @@ static const struct ieee80211_aclator mac = {
.iac_flush = acl_free_all,
.iac_setpolicy = acl_setpolicy,
.iac_getpolicy = acl_getpolicy,
+ .iac_setioctl = acl_setioctl,
+ .iac_getioctl = acl_getioctl,
};
/*
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index e8cf5c4e4f17..9d5a28579fcf 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -1242,6 +1242,14 @@ ieee80211_ioctl_getwmeparam(struct ieee80211com *ic, struct ieee80211req *ireq)
return 0;
}
+static int
+ieee80211_ioctl_getmaccmd(struct ieee80211com *ic, struct ieee80211req *ireq)
+{
+ const struct ieee80211_aclator *acl = ic->ic_acl;
+
+ return (acl == NULL ? EINVAL : acl->iac_getioctl(ic, ireq));
+}
+
/*
* When building the kernel with -O2 on the i386 architecture, gcc
* seems to want to inline this function into ieee80211_ioctl()
@@ -1475,6 +1483,9 @@ ieee80211_ioctl_get80211(struct ieee80211com *ic, u_long cmd, struct ieee80211re
case IEEE80211_IOC_FRAGTHRESHOLD:
ireq->i_val = ic->ic_fragthreshold;
break;
+ case IEEE80211_IOC_MACCMD:
+ error = ieee80211_ioctl_getmaccmd(ic, ireq);
+ break;
default:
error = EINVAL;
break;
@@ -1740,7 +1751,7 @@ ieee80211_ioctl_macmac(struct ieee80211com *ic, struct ieee80211req *ireq)
}
static int
-ieee80211_ioctl_maccmd(struct ieee80211com *ic, struct ieee80211req *ireq)
+ieee80211_ioctl_setmaccmd(struct ieee80211com *ic, struct ieee80211req *ireq)
{
const struct ieee80211_aclator *acl = ic->ic_acl;
@@ -1768,7 +1779,10 @@ ieee80211_ioctl_maccmd(struct ieee80211com *ic, struct ieee80211req *ireq)
}
break;
default:
- return EINVAL;
+ if (acl == NULL)
+ return EINVAL;
+ else
+ return acl->iac_setioctl(ic, ireq);
}
return 0;
}
@@ -2302,7 +2316,7 @@ ieee80211_ioctl_set80211(struct ieee80211com *ic, u_long cmd, struct ieee80211re
error = ieee80211_ioctl_macmac(ic, ireq);
break;
case IEEE80211_IOC_MACCMD:
- error = ieee80211_ioctl_maccmd(ic, ireq);
+ error = ieee80211_ioctl_setmaccmd(ic, ireq);
break;
case IEEE80211_IOC_STA_TXPOW:
error = ieee80211_ioctl_setstatxpow(ic, ireq);
diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h
index 83ff1182199c..8c3b2abbb2f4 100644
--- a/sys/net80211/ieee80211_ioctl.h
+++ b/sys/net80211/ieee80211_ioctl.h
@@ -252,6 +252,12 @@ enum {
IEEE80211_MACCMD_POLICY_DENY = 2, /* set policy: deny traffic */
IEEE80211_MACCMD_FLUSH = 3, /* flush ACL database */
IEEE80211_MACCMD_DETACH = 4, /* detach ACL policy */
+ IEEE80211_MACCMD_POLICY = 5, /* get ACL policy */
+ IEEE80211_MACCMD_LIST = 6, /* get ACL database */
+};
+
+struct ieee80211req_maclist {
+ u_int8_t ml_macaddr[IEEE80211_ADDR_LEN];
};
/*
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 45fe1641e715..694eff5b6b2d 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -144,6 +144,7 @@ void ieee80211_authenticator_register(int type,
void ieee80211_authenticator_unregister(int type);
const struct ieee80211_authenticator *ieee80211_authenticator_get(int auth);
+struct ieee80211req;
/*
* Template for an MAC ACL policy module. Such modules
* register with the protocol code and are passed the sender's
@@ -162,6 +163,8 @@ struct ieee80211_aclator {
int (*iac_flush)(struct ieee80211com *);
int (*iac_setpolicy)(struct ieee80211com *, int);
int (*iac_getpolicy)(struct ieee80211com *);
+ int (*iac_setioctl)(struct ieee80211com *, struct ieee80211req *);
+ int (*iac_getioctl)(struct ieee80211com *, struct ieee80211req *);
};
void ieee80211_aclator_register(const struct ieee80211_aclator *);
void ieee80211_aclator_unregister(const struct ieee80211_aclator *);