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).
This commit is contained in:
parent
fd630bc183
commit
271d2830ff
7 changed files with 55 additions and 20 deletions
|
@ -7,6 +7,9 @@ ChangeLog for hostapd
|
||||||
identity lengths)
|
identity lengths)
|
||||||
* fixed internal TLSv1 implementation for abbreviated handshake (used
|
* fixed internal TLSv1 implementation for abbreviated handshake (used
|
||||||
by EAP-FAST server)
|
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
|
2008-08-10 - v0.6.4
|
||||||
* added peer identity into EAP-FAST PAC-Opaque and skip Phase 2
|
* 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,
|
static int hostapd_acl_comp(const void *a, const void *b)
|
||||||
int *num)
|
{
|
||||||
|
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;
|
FILE *f;
|
||||||
char buf[128], *pos;
|
char buf[128], *pos;
|
||||||
int line = 0;
|
int line = 0;
|
||||||
u8 addr[ETH_ALEN];
|
u8 addr[ETH_ALEN];
|
||||||
macaddr *newacl;
|
struct mac_acl_entry *newacl;
|
||||||
|
int vlan_id;
|
||||||
|
|
||||||
if (!fname)
|
if (!fname)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -311,7 +320,16 @@ static int hostapd_config_read_maclist(const char *fname, macaddr **acl,
|
||||||
return -1;
|
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) {
|
if (newacl == NULL) {
|
||||||
printf("MAC list reallocation failed\n");
|
printf("MAC list reallocation failed\n");
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -319,13 +337,14 @@ static int hostapd_config_read_maclist(const char *fname, macaddr **acl,
|
||||||
}
|
}
|
||||||
|
|
||||||
*acl = newacl;
|
*acl = newacl;
|
||||||
os_memcpy((*acl)[*num], addr, ETH_ALEN);
|
os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
|
||||||
|
(*acl)[*num].vlan_id = vlan_id;
|
||||||
(*num)++;
|
(*num)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
qsort(*acl, *num, sizeof(macaddr), hostapd_mac_comp);
|
qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
|
||||||
|
|
||||||
return 0;
|
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.
|
/* 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. */
|
* 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;
|
int start, end, middle, res;
|
||||||
|
|
||||||
|
@ -2176,9 +2196,12 @@ int hostapd_maclist_found(macaddr *list, int num_entries, const u8 *addr)
|
||||||
|
|
||||||
while (start <= end) {
|
while (start <= end) {
|
||||||
middle = (start + end) / 2;
|
middle = (start + end) / 2;
|
||||||
res = os_memcmp(list[middle], addr, ETH_ALEN);
|
res = os_memcmp(list[middle].addr, addr, ETH_ALEN);
|
||||||
if (res == 0)
|
if (res == 0) {
|
||||||
|
if (vlan_id)
|
||||||
|
*vlan_id = list[middle].vlan_id;
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
start = middle + 1;
|
start = middle + 1;
|
||||||
else
|
else
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
|
|
||||||
typedef u8 macaddr[ETH_ALEN];
|
typedef u8 macaddr[ETH_ALEN];
|
||||||
|
|
||||||
|
struct mac_acl_entry {
|
||||||
|
macaddr addr;
|
||||||
|
int vlan_id;
|
||||||
|
};
|
||||||
|
|
||||||
struct hostapd_radius_servers;
|
struct hostapd_radius_servers;
|
||||||
struct ft_remote_r0kh;
|
struct ft_remote_r0kh;
|
||||||
struct ft_remote_r1kh;
|
struct ft_remote_r1kh;
|
||||||
|
@ -192,9 +197,9 @@ struct hostapd_bss_config {
|
||||||
DENY_UNLESS_ACCEPTED = 1,
|
DENY_UNLESS_ACCEPTED = 1,
|
||||||
USE_EXTERNAL_RADIUS_AUTH = 2
|
USE_EXTERNAL_RADIUS_AUTH = 2
|
||||||
} macaddr_acl;
|
} macaddr_acl;
|
||||||
macaddr *accept_mac;
|
struct mac_acl_entry *accept_mac;
|
||||||
int num_accept_mac;
|
int num_accept_mac;
|
||||||
macaddr *deny_mac;
|
struct mac_acl_entry *deny_mac;
|
||||||
int num_deny_mac;
|
int num_deny_mac;
|
||||||
|
|
||||||
int auth_algs; /* bitfield of allowed IEEE 802.11 authentication
|
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);
|
int hostapd_mac_comp_empty(const void *a);
|
||||||
struct hostapd_config * hostapd_config_read(const char *fname);
|
struct hostapd_config * hostapd_config_read(const char *fname);
|
||||||
void hostapd_config_free(struct hostapd_config *conf);
|
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_rate_found(int *list, int rate);
|
||||||
int hostapd_wep_key_cmp(struct hostapd_wep_keys *a,
|
int hostapd_wep_key_cmp(struct hostapd_wep_keys *a,
|
||||||
struct hostapd_wep_keys *b);
|
struct hostapd_wep_keys *b);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# List of MAC addresses that are allowed to authenticate (IEEE 802.11)
|
# 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:11:22:33:44:55
|
||||||
00:66:77:88:99:aa
|
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),
|
# 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
|
# 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
|
# 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)
|
# 0 = disabled (default)
|
||||||
# 1 = option; use default interface if RADIUS server does not include VLAN ID
|
# 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
|
# 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;
|
*vlan_id = 0;
|
||||||
|
|
||||||
if (hostapd_maclist_found(hapd->conf->accept_mac,
|
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;
|
return HOSTAPD_ACL_ACCEPT;
|
||||||
|
|
||||||
if (hostapd_maclist_found(hapd->conf->deny_mac,
|
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;
|
return HOSTAPD_ACL_REJECT;
|
||||||
|
|
||||||
if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED)
|
if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED)
|
||||||
|
|
|
@ -211,13 +211,14 @@ static int hostapd_acl_diff(struct hostapd_bss_config *a,
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (i = 0; i < a->num_accept_mac; i++) {
|
for (i = 0; i < a->num_accept_mac; i++) {
|
||||||
if (os_memcmp(a->accept_mac[i], b->accept_mac[i], ETH_ALEN) !=
|
if (os_memcmp(a->accept_mac[i].addr, b->accept_mac[i].addr,
|
||||||
0)
|
ETH_ALEN) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < a->num_deny_mac; i++) {
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue