From 271d2830ff1f74156b3fe296b9e851e7cbb52e69 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 28 Aug 2008 18:43:26 +0300 Subject: [PATCH] Added support for setting VLAN ID for STAs based on local MAC ACL This allows the accept_mac_file to be used as an alternative for RADIUS server-based configuration. This is mainly to ease VLAN testing (i.e., no need to set up RADIUS server for this anymore). --- hostapd/ChangeLog | 3 +++ hostapd/config.c | 41 ++++++++++++++++++++++++++++++--------- hostapd/config.h | 12 +++++++++--- hostapd/hostapd.accept | 5 +++-- hostapd/hostapd.conf | 3 ++- hostapd/ieee802_11_auth.c | 4 ++-- hostapd/reconfig.c | 7 ++++--- 7 files changed, 55 insertions(+), 20 deletions(-) diff --git a/hostapd/ChangeLog b/hostapd/ChangeLog index 2db46b845..e249ad73f 100644 --- a/hostapd/ChangeLog +++ b/hostapd/ChangeLog @@ -7,6 +7,9 @@ ChangeLog for hostapd identity lengths) * fixed internal TLSv1 implementation for abbreviated handshake (used by EAP-FAST server) + * added support for setting VLAN ID for STAs based on local MAC ACL + (accept_mac_file) as an alternative for RADIUS server-based + configuration 2008-08-10 - v0.6.4 * added peer identity into EAP-FAST PAC-Opaque and skip Phase 2 diff --git a/hostapd/config.c b/hostapd/config.c index 7ec3594fe..eb247a3f1 100644 --- a/hostapd/config.c +++ b/hostapd/config.c @@ -270,14 +270,23 @@ int hostapd_mac_comp_empty(const void *a) } -static int hostapd_config_read_maclist(const char *fname, macaddr **acl, - int *num) +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)); +} + + +static int hostapd_config_read_maclist(const char *fname, + struct mac_acl_entry **acl, int *num) { FILE *f; char buf[128], *pos; int line = 0; u8 addr[ETH_ALEN]; - macaddr *newacl; + struct mac_acl_entry *newacl; + int vlan_id; if (!fname) return 0; @@ -311,7 +320,16 @@ static int hostapd_config_read_maclist(const char *fname, macaddr **acl, return -1; } - newacl = os_realloc(*acl, (*num + 1) * ETH_ALEN); + vlan_id = 0; + pos = buf; + while (*pos != '\0' && *pos != ' ' && *pos != '\t') + pos++; + while (*pos == ' ' || *pos == '\t') + pos++; + if (*pos != '\0') + vlan_id = atoi(pos); + + newacl = os_realloc(*acl, (*num + 1) * sizeof(**acl)); if (newacl == NULL) { printf("MAC list reallocation failed\n"); fclose(f); @@ -319,13 +337,14 @@ static int hostapd_config_read_maclist(const char *fname, macaddr **acl, } *acl = newacl; - os_memcpy((*acl)[*num], addr, ETH_ALEN); + os_memcpy((*acl)[*num].addr, addr, ETH_ALEN); + (*acl)[*num].vlan_id = vlan_id; (*num)++; } fclose(f); - qsort(*acl, *num, sizeof(macaddr), hostapd_mac_comp); + qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp); return 0; } @@ -2167,7 +2186,8 @@ void hostapd_config_free(struct hostapd_config *conf) /* Perform a binary search for given MAC address from a pre-sorted list. * Returns 1 if address is in the list or 0 if not. */ -int hostapd_maclist_found(macaddr *list, int num_entries, const u8 *addr) +int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries, + const u8 *addr, int *vlan_id) { int start, end, middle, res; @@ -2176,9 +2196,12 @@ int hostapd_maclist_found(macaddr *list, int num_entries, const u8 *addr) while (start <= end) { middle = (start + end) / 2; - res = os_memcmp(list[middle], addr, ETH_ALEN); - if (res == 0) + res = os_memcmp(list[middle].addr, addr, ETH_ALEN); + if (res == 0) { + if (vlan_id) + *vlan_id = list[middle].vlan_id; return 1; + } if (res < 0) start = middle + 1; else diff --git a/hostapd/config.h b/hostapd/config.h index 971350362..f92ea84c4 100644 --- a/hostapd/config.h +++ b/hostapd/config.h @@ -26,6 +26,11 @@ typedef u8 macaddr[ETH_ALEN]; +struct mac_acl_entry { + macaddr addr; + int vlan_id; +}; + struct hostapd_radius_servers; struct ft_remote_r0kh; struct ft_remote_r1kh; @@ -192,9 +197,9 @@ struct hostapd_bss_config { DENY_UNLESS_ACCEPTED = 1, USE_EXTERNAL_RADIUS_AUTH = 2 } macaddr_acl; - macaddr *accept_mac; + struct mac_acl_entry *accept_mac; int num_accept_mac; - macaddr *deny_mac; + struct mac_acl_entry *deny_mac; int num_deny_mac; int auth_algs; /* bitfield of allowed IEEE 802.11 authentication @@ -359,7 +364,8 @@ int hostapd_mac_comp(const void *a, const void *b); int hostapd_mac_comp_empty(const void *a); struct hostapd_config * hostapd_config_read(const char *fname); void hostapd_config_free(struct hostapd_config *conf); -int hostapd_maclist_found(macaddr *list, int num_entries, const u8 *addr); +int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries, + const u8 *addr, int *vlan_id); int hostapd_rate_found(int *list, int rate); int hostapd_wep_key_cmp(struct hostapd_wep_keys *a, struct hostapd_wep_keys *b); diff --git a/hostapd/hostapd.accept b/hostapd/hostapd.accept index 57122b663..2d2a0a27e 100644 --- a/hostapd/hostapd.accept +++ b/hostapd/hostapd.accept @@ -1,5 +1,6 @@ # List of MAC addresses that are allowed to authenticate (IEEE 802.11) -# with the AP. +# with the AP. Optional VLAN ID can be assigned for clients based on the +# MAC address if dynamic VLANs (hostapd.conf dynamic_vlan option) are used. 00:11:22:33:44:55 00:66:77:88:99:aa -00:00:22:33:44:55 +00:00:22:33:44:55 1 diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 4665ad61b..2e4b71c52 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -583,7 +583,8 @@ own_ip_addr=127.0.0.1 # attributes based on RFC 3580 and RFC 2868: Tunnel-Type (value 13 = VLAN), # Tunnel-Medium-Type (value 6 = IEEE 802), Tunnel-Private-Group-ID (value # VLANID as a string). vlan_file option below must be configured if dynamic -# VLANs are used. +# VLANs are used. Optionally, the local MAC ACL list (accept_mac_file) can be +# used to set static client MAC address to VLAN ID mapping. # 0 = disabled (default) # 1 = option; use default interface if RADIUS server does not include VLAN ID # 2 = required; reject authentication if RADIUS server does not include VLAN ID diff --git a/hostapd/ieee802_11_auth.c b/hostapd/ieee802_11_auth.c index 86f71b397..2d63ff17e 100644 --- a/hostapd/ieee802_11_auth.c +++ b/hostapd/ieee802_11_auth.c @@ -205,11 +205,11 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, *vlan_id = 0; if (hostapd_maclist_found(hapd->conf->accept_mac, - hapd->conf->num_accept_mac, addr)) + hapd->conf->num_accept_mac, addr, vlan_id)) return HOSTAPD_ACL_ACCEPT; if (hostapd_maclist_found(hapd->conf->deny_mac, - hapd->conf->num_deny_mac, addr)) + hapd->conf->num_deny_mac, addr, vlan_id)) return HOSTAPD_ACL_REJECT; if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED) diff --git a/hostapd/reconfig.c b/hostapd/reconfig.c index 3e46edd4c..5783eda88 100644 --- a/hostapd/reconfig.c +++ b/hostapd/reconfig.c @@ -211,13 +211,14 @@ static int hostapd_acl_diff(struct hostapd_bss_config *a, return 1; for (i = 0; i < a->num_accept_mac; i++) { - if (os_memcmp(a->accept_mac[i], b->accept_mac[i], ETH_ALEN) != - 0) + if (os_memcmp(a->accept_mac[i].addr, b->accept_mac[i].addr, + ETH_ALEN) != 0) return 1; } for (i = 0; i < a->num_deny_mac; i++) { - if (os_memcmp(a->deny_mac[i], b->deny_mac[i], ETH_ALEN) != 0) + if (os_memcmp(a->deny_mac[i].addr, b->deny_mac[i].addr, + ETH_ALEN) != 0) return 1; }