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@xxxxxxxxxxxxx> --- 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 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap