mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-02-22 03:53:02 -05:00
VLAN: Add per-STA vif option
This allows the stations to be assigned to their own vif. It does not need dynamic_vlan to be set. Make hostapd call ap_sta_set_vlan even if !vlan_desc.notempty, so vlan_id can be assigned regardless. Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
This commit is contained in:
parent
d0bdc96bdd
commit
8be640b780
@ -2769,6 +2769,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
|||||||
#ifndef CONFIG_NO_VLAN
|
#ifndef CONFIG_NO_VLAN
|
||||||
} else if (os_strcmp(buf, "dynamic_vlan") == 0) {
|
} else if (os_strcmp(buf, "dynamic_vlan") == 0) {
|
||||||
bss->ssid.dynamic_vlan = atoi(pos);
|
bss->ssid.dynamic_vlan = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "per_sta_vif") == 0) {
|
||||||
|
bss->ssid.per_sta_vif = atoi(pos);
|
||||||
} else if (os_strcmp(buf, "vlan_file") == 0) {
|
} else if (os_strcmp(buf, "vlan_file") == 0) {
|
||||||
if (hostapd_config_read_vlan_file(bss, pos)) {
|
if (hostapd_config_read_vlan_file(bss, pos)) {
|
||||||
wpa_printf(MSG_ERROR, "Line %d: failed to read VLAN file '%s'",
|
wpa_printf(MSG_ERROR, "Line %d: failed to read VLAN file '%s'",
|
||||||
|
@ -978,6 +978,17 @@ own_ip_addr=127.0.0.1
|
|||||||
# 2 = required; reject authentication if RADIUS server does not include VLAN ID
|
# 2 = required; reject authentication if RADIUS server does not include VLAN ID
|
||||||
#dynamic_vlan=0
|
#dynamic_vlan=0
|
||||||
|
|
||||||
|
# Per-Station AP_VLAN interface mode
|
||||||
|
# If enabled, each station is assigned its own AP_VLAN interface.
|
||||||
|
# This implies per-station group keying and ebtables filtering of inter-STA
|
||||||
|
# traffic (when passed through the AP).
|
||||||
|
# If the sta is not assigned to any VLAN, then its AP_VLAN interface will be
|
||||||
|
# added to the bridge given by the "bridge" configuration option (see above).
|
||||||
|
# Otherwise, it will be added to the per-VLAN bridge.
|
||||||
|
# 0 = disabled (default)
|
||||||
|
# 1 = enabled
|
||||||
|
#per_sta_vif=0
|
||||||
|
|
||||||
# VLAN interface list for dynamic VLAN mode is read from a separate text file.
|
# VLAN interface list for dynamic VLAN mode is read from a separate text file.
|
||||||
# This list is used to map VLAN ID from the RADIUS server to a network
|
# This list is used to map VLAN ID from the RADIUS server to a network
|
||||||
# interface. Each station is bound to one interface in the same way as with
|
# interface. Each station is bound to one interface in the same way as with
|
||||||
|
@ -104,6 +104,7 @@ struct hostapd_ssid {
|
|||||||
#define DYNAMIC_VLAN_NAMING_WITH_DEVICE 1
|
#define DYNAMIC_VLAN_NAMING_WITH_DEVICE 1
|
||||||
#define DYNAMIC_VLAN_NAMING_END 2
|
#define DYNAMIC_VLAN_NAMING_END 2
|
||||||
int vlan_naming;
|
int vlan_naming;
|
||||||
|
int per_sta_vif;
|
||||||
#ifdef CONFIG_FULL_DYNAMIC_VLAN
|
#ifdef CONFIG_FULL_DYNAMIC_VLAN
|
||||||
char *vlan_tagged_interface;
|
char *vlan_tagged_interface;
|
||||||
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
||||||
|
@ -1097,8 +1097,8 @@ static void handle_auth(struct hostapd_data *hapd,
|
|||||||
sta->last_seq_ctrl = seq_ctrl;
|
sta->last_seq_ctrl = seq_ctrl;
|
||||||
sta->last_subtype = WLAN_FC_STYPE_AUTH;
|
sta->last_subtype = WLAN_FC_STYPE_AUTH;
|
||||||
|
|
||||||
if (vlan_id.notempty) {
|
if (vlan_id.notempty &&
|
||||||
if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_id)) {
|
!hostapd_vlan_valid(hapd->conf->vlan, &vlan_id)) {
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
|
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
|
||||||
HOSTAPD_LEVEL_INFO,
|
HOSTAPD_LEVEL_INFO,
|
||||||
"Invalid VLAN %d%s received from RADIUS server",
|
"Invalid VLAN %d%s received from RADIUS server",
|
||||||
@ -1111,9 +1111,9 @@ static void handle_auth(struct hostapd_data *hapd,
|
|||||||
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
if (sta->vlan_id)
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
|
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
|
||||||
HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
|
HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
|
||||||
}
|
|
||||||
|
|
||||||
hostapd_free_psk_list(sta->psk);
|
hostapd_free_psk_list(sta->psk);
|
||||||
if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
|
if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
|
||||||
|
@ -831,11 +831,35 @@ int ap_sta_set_vlan(struct hostapd_data *hapd, struct sta_info *sta,
|
|||||||
vlan_desc = NULL;
|
vlan_desc = NULL;
|
||||||
|
|
||||||
/* Check if there is something to do */
|
/* Check if there is something to do */
|
||||||
if (!vlan_compare(vlan_desc, sta->vlan_desc))
|
if (hapd->conf->ssid.per_sta_vif && !sta->vlan_id) {
|
||||||
|
/* This sta is lacking its own vif */
|
||||||
|
} else if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_DISABLED &&
|
||||||
|
!hapd->conf->ssid.per_sta_vif && sta->vlan_id) {
|
||||||
|
/* sta->vlan_id needs to be reset */
|
||||||
|
} else if (!vlan_compare(vlan_desc, sta->vlan_desc)) {
|
||||||
return 0; /* nothing to change */
|
return 0; /* nothing to change */
|
||||||
|
}
|
||||||
|
|
||||||
/* Now the real VLAN changed or the STA just needs its own vif */
|
/* Now the real VLAN changed or the STA just needs its own vif */
|
||||||
if (vlan_desc->notempty) {
|
if (hapd->conf->ssid.per_sta_vif) {
|
||||||
|
/* Assign a new vif, always */
|
||||||
|
/* find a free vlan_id sufficiently big */
|
||||||
|
vlan_id = ap_sta_get_free_vlan_id(hapd);
|
||||||
|
/* Get wildcard VLAN */
|
||||||
|
for (vlan = hapd->conf->vlan; vlan; vlan = vlan->next) {
|
||||||
|
if (vlan->vlan_id == VLAN_ID_WILDCARD)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!vlan) {
|
||||||
|
hostapd_logger(hapd, sta->addr,
|
||||||
|
HOSTAPD_MODULE_IEEE80211,
|
||||||
|
HOSTAPD_LEVEL_DEBUG,
|
||||||
|
"per_sta_vif missing wildcard");
|
||||||
|
vlan_id = 0;
|
||||||
|
ret = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
} else if (vlan_desc && vlan_desc->notempty) {
|
||||||
for (vlan = hapd->conf->vlan; vlan; vlan = vlan->next) {
|
for (vlan = hapd->conf->vlan; vlan; vlan = vlan->next) {
|
||||||
if (!vlan_compare(&vlan->vlan_desc, vlan_desc))
|
if (!vlan_compare(&vlan->vlan_desc, vlan_desc))
|
||||||
break;
|
break;
|
||||||
|
@ -686,7 +686,7 @@ static void vlan_newlink(const char *ifname, struct hostapd_data *hapd)
|
|||||||
{
|
{
|
||||||
char br_name[IFNAMSIZ];
|
char br_name[IFNAMSIZ];
|
||||||
struct hostapd_vlan *vlan;
|
struct hostapd_vlan *vlan;
|
||||||
int untagged, *tagged, i;
|
int untagged, *tagged, i, notempty;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname);
|
wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname);
|
||||||
|
|
||||||
@ -701,10 +701,16 @@ static void vlan_newlink(const char *ifname, struct hostapd_data *hapd)
|
|||||||
|
|
||||||
vlan->configured = 1;
|
vlan->configured = 1;
|
||||||
|
|
||||||
|
notempty = vlan->vlan_desc.notempty;
|
||||||
untagged = vlan->vlan_desc.untagged;
|
untagged = vlan->vlan_desc.untagged;
|
||||||
tagged = vlan->vlan_desc.tagged;
|
tagged = vlan->vlan_desc.tagged;
|
||||||
|
|
||||||
if (untagged > 0 && untagged <= MAX_VLAN_ID) {
|
if (!notempty) {
|
||||||
|
/* Non-VLAN STA */
|
||||||
|
if (hapd->conf->bridge[0] &&
|
||||||
|
!br_addif(hapd->conf->bridge, ifname))
|
||||||
|
vlan->clean |= DVLAN_CLEAN_WLAN_PORT;
|
||||||
|
} else if (untagged > 0 && untagged <= MAX_VLAN_ID) {
|
||||||
vlan_bridge_name(br_name, hapd, untagged);
|
vlan_bridge_name(br_name, hapd, untagged);
|
||||||
|
|
||||||
vlan_get_bridge(br_name, hapd, untagged);
|
vlan_get_bridge(br_name, hapd, untagged);
|
||||||
@ -792,6 +798,7 @@ static void vlan_dellink(const char *ifname, struct hostapd_data *hapd)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (vlan->configured) {
|
if (vlan->configured) {
|
||||||
|
int notempty = vlan->vlan_desc.notempty;
|
||||||
int untagged = vlan->vlan_desc.untagged;
|
int untagged = vlan->vlan_desc.untagged;
|
||||||
int *tagged = vlan->vlan_desc.tagged;
|
int *tagged = vlan->vlan_desc.tagged;
|
||||||
char br_name[IFNAMSIZ];
|
char br_name[IFNAMSIZ];
|
||||||
@ -808,7 +815,12 @@ static void vlan_dellink(const char *ifname, struct hostapd_data *hapd)
|
|||||||
vlan_put_bridge(br_name, hapd, tagged[i]);
|
vlan_put_bridge(br_name, hapd, tagged[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (untagged > 0 && untagged <= MAX_VLAN_ID) {
|
if (!notempty) {
|
||||||
|
/* Non-VLAN STA */
|
||||||
|
if (hapd->conf->bridge[0] &&
|
||||||
|
(vlan->clean & DVLAN_CLEAN_WLAN_PORT))
|
||||||
|
br_delif(hapd->conf->bridge, ifname);
|
||||||
|
} else if (untagged > 0 && untagged <= MAX_VLAN_ID) {
|
||||||
vlan_bridge_name(br_name, hapd, untagged);
|
vlan_bridge_name(br_name, hapd, untagged);
|
||||||
|
|
||||||
if (vlan->clean & DVLAN_CLEAN_WLAN_PORT)
|
if (vlan->clean & DVLAN_CLEAN_WLAN_PORT)
|
||||||
@ -1064,7 +1076,8 @@ int vlan_init(struct hostapd_data *hapd)
|
|||||||
hapd->full_dynamic_vlan = full_dynamic_vlan_init(hapd);
|
hapd->full_dynamic_vlan = full_dynamic_vlan_init(hapd);
|
||||||
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
||||||
|
|
||||||
if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED &&
|
if ((hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED ||
|
||||||
|
hapd->conf->ssid.per_sta_vif) &&
|
||||||
!hapd->conf->vlan) {
|
!hapd->conf->vlan) {
|
||||||
/* dynamic vlans enabled but no (or empty) vlan_file given */
|
/* dynamic vlans enabled but no (or empty) vlan_file given */
|
||||||
struct hostapd_vlan *vlan;
|
struct hostapd_vlan *vlan;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user