[PATCH] Added hostapd/hostapd_cli support for adding/removing a STA from the deny/accept ACL
Kevin Mahoney
k.mahoney at cablelabs.com
Wed Sep 28 14:01:12 PDT 2016
This patch provides the ability to manage the deny and accept ACLs dynamically without having to reload the configuration.
Signed-off-by: Kevin Mahoney <k.mahoney at cablelabs.com>
---
hostapd/ctrl_iface.c | 6 +++
hostapd/hostapd_cli.c | 32 ++++++++++++
src/ap/ctrl_iface_ap.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++
src/ap/ctrl_iface_ap.h | 4 ++
4 files changed, 178 insertions(+)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index d7db4a7..fbdc8a8 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -2361,6 +2361,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
} else if (os_strncmp(buf, "NEW_STA ", 8) == 0) {
if (hostapd_ctrl_iface_new_sta(hapd, buf + 8))
reply_len = -1;
+ } else if (os_strncmp(buf, "DENY_STA ", 9) == 0) {
+ if (hostapd_ctrl_iface_deny_sta(hapd, buf + 9, reply, reply_size))
+ reply_len = -1;
+ } else if (os_strncmp(buf, "ACCEPT_STA ", 11) == 0) {
+ if (hostapd_ctrl_iface_accept_sta(hapd, buf + 11, reply, reply_size))
+ reply_len = -1;
} else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) {
if (hostapd_ctrl_iface_deauthenticate(hapd, buf + 15))
reply_len = -1;
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index 5e62542..103ee7a 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -300,6 +300,34 @@ static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
}
+static int hostapd_cli_cmd_deny_sta(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char buf[64];
+ if (argc != 1) {
+ printf("Invalid 'deny_sta' command - exactly one argument, STA "
+ "address, is required.\n");
+ return -1;
+ }
+ snprintf(buf, sizeof(buf), "DENY_STA %s", argv[0]);
+ return wpa_ctrl_command(ctrl, buf);
+}
+
+
+static int hostapd_cli_cmd_accept_sta(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char buf[64];
+ if (argc != 1) {
+ printf("Invalid 'accept_sta' command - exactly one argument, STA "
+ "address, is required.\n");
+ return -1;
+ }
+ snprintf(buf, sizeof(buf), "ACCEPT_STA %s", argv[0]);
+ return wpa_ctrl_command(ctrl, buf);
+}
+
+
static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
@@ -1281,6 +1309,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
"= get MIB variables for all stations" },
{ "new_sta", hostapd_cli_cmd_new_sta, NULL,
"<addr> = add a new station" },
+ { "deny_sta", hostapd_cli_cmd_deny_sta, NULL,
+ "<addr> = add a station to the deny ACL" },
+ { "accept_sta", hostapd_cli_cmd_accept_sta, NULL,
+ "<addr> = add a station to the accept ACL" },
{ "deauthenticate", hostapd_cli_cmd_deauthenticate,
hostapd_complete_deauthenticate,
"<addr> = deauthenticate a station" },
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index 3680fda..58abb93 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -251,6 +251,142 @@ int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr,
}
+static int hostapd_acl_comp(const void *a, const void *b)
+{
+ const struct mac_acl_entry *aa = a;
+ const struct mac_acl_entry *bb = b;
+ return os_memcmp(aa->addr, bb->addr, sizeof(macaddr));
+}
+
+
+int hostapd_ctrl_iface_deny_sta(struct hostapd_data *hapd, const char *txtaddr,
+ char *buf, size_t buflen)
+{
+ u8 addr[ETH_ALEN];
+ struct mac_acl_entry **acl = &hapd->conf->deny_mac;
+ struct mac_acl_entry *newacl;
+ int *num = &hapd->conf->num_deny_mac;
+ int vlan_id = 0; /* TODO: Add VLAN support */
+ int rem = 0;
+ int ret;
+
+ wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "DENY_STA: %s", txtaddr);
+
+ if (txtaddr[0] == '-') {
+ rem = 1;
+ txtaddr++;
+ }
+ else if (txtaddr[0] == '+') {
+ rem = 0;
+ txtaddr++;
+ }
+
+ if (hwaddr_aton(txtaddr, addr)) {
+ ret = os_snprintf(buf, buflen, "BAD_ADDR\n");
+ if (os_snprintf_error(buflen, ret))
+ return 0;
+ return ret;
+ }
+
+ if (rem) {
+ int i = 0;
+ while (i < *num) {
+ if (os_memcmp((*acl)[i].addr, addr, ETH_ALEN) == 0) {
+ os_remove_in_array(*acl, *num, sizeof(**acl), i);
+ (*num)--;
+ } else
+ i++;
+ }
+ }
+ else {
+ newacl = os_realloc_array(*acl, *num + 1, sizeof(**acl));
+ if (newacl == NULL) {
+ ret = os_snprintf(buf, buflen, "NO_MEM\n");
+ if (os_snprintf_error(buflen, ret))
+ return 0;
+ return ret;
+ }
+
+ *acl = newacl;
+ os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
+ os_memset(&(*acl)[*num].vlan_id, 0,
+ sizeof((*acl)[*num].vlan_id));
+ (*acl)[*num].vlan_id.untagged = vlan_id;
+ (*acl)[*num].vlan_id.notempty = !!vlan_id;
+ (*num)++;
+ }
+
+ qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
+
+ return 0;
+
+}
+
+
+int hostapd_ctrl_iface_accept_sta(struct hostapd_data *hapd, const char *txtaddr,
+ char *buf, size_t buflen)
+{
+ u8 addr[ETH_ALEN];
+ struct mac_acl_entry **acl = &hapd->conf->accept_mac;
+ struct mac_acl_entry *newacl;
+ int *num = &hapd->conf->num_accept_mac;
+ int vlan_id = 0; /* TODO: Add VLAN support */
+ int rem = 0;
+ int ret;
+
+ wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "ACCEPT_STA: %s", txtaddr);
+
+ if (txtaddr[0] == '-') {
+ rem = 1;
+ txtaddr++;
+ }
+ else if (txtaddr[0] == '+') {
+ rem = 0;
+ txtaddr++;
+ }
+
+ if (hwaddr_aton(txtaddr, addr)) {
+ ret = os_snprintf(buf, buflen, "BAD_ADDR\n");
+ if (os_snprintf_error(buflen, ret))
+ return 0;
+ return ret;
+ }
+
+ if (rem) {
+ int i = 0;
+ while (i < *num) {
+ if (os_memcmp((*acl)[i].addr, addr, ETH_ALEN) == 0) {
+ os_remove_in_array(*acl, *num, sizeof(**acl), i);
+ (*num)--;
+ } else
+ i++;
+ }
+ }
+ else {
+ newacl = os_realloc_array(*acl, *num + 1, sizeof(**acl));
+ if (newacl == NULL) {
+ ret = os_snprintf(buf, buflen, "NO_MEM\n");
+ if (os_snprintf_error(buflen, ret))
+ return 0;
+ return ret;
+ }
+
+ *acl = newacl;
+ os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
+ os_memset(&(*acl)[*num].vlan_id, 0,
+ sizeof((*acl)[*num].vlan_id));
+ (*acl)[*num].vlan_id.untagged = vlan_id;
+ (*acl)[*num].vlan_id.notempty = !!vlan_id;
+ (*num)++;
+ }
+
+ qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
+
+ return 0;
+
+}
+
+
#ifdef CONFIG_P2P_MANAGER
static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
u8 minor_reason_code, const u8 *addr)
diff --git a/src/ap/ctrl_iface_ap.h b/src/ap/ctrl_iface_ap.h
index 4f99680..b662922 100644
--- a/src/ap/ctrl_iface_ap.h
+++ b/src/ap/ctrl_iface_ap.h
@@ -15,6 +15,10 @@ int hostapd_ctrl_iface_sta(struct hostapd_data *hapd, const char *txtaddr,
char *buf, size_t buflen);
int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr,
char *buf, size_t buflen);
+int hostapd_ctrl_iface_deny_sta(struct hostapd_data *hapd, const char *txtaddr,
+ char *buf, size_t buflen);
+int hostapd_ctrl_iface_accept_sta(struct hostapd_data *hapd, const char *txtaddr,
+ char *buf, size_t buflen);
int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
const char *txtaddr);
int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
--
2.7.4
More information about the Hostap
mailing list