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).
master
Jouni Malinen 16 years ago committed by Jouni Malinen
parent fd630bc183
commit 271d2830ff

@ -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

@ -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

@ -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);

@ -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

@ -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

@ -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)

@ -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;
}

Loading…
Cancel
Save