From: Felix Fietkau Date: Tue, 6 Aug 2013 17:59:12 +0000 (+0000) Subject: hostapd: Fix WDS/WEP usage X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=91f0b411f4aa8b5e0bcb7388141bf85586b82976;p=librecmc%2Flibrecmc.git hostapd: Fix WDS/WEP usage WEP in WDS is currently broken in hostapd. Add a patch to fix the issue. Signed-off-by: Sujith Manoharan SVN-Revision: 37733 --- diff --git a/package/network/services/hostapd/patches/710-wds-wep-fix.patch b/package/network/services/hostapd/patches/710-wds-wep-fix.patch new file mode 100644 index 0000000000..1411d1fc65 --- /dev/null +++ b/package/network/services/hostapd/patches/710-wds-wep-fix.patch @@ -0,0 +1,156 @@ +--- a/src/ap/ap_drv_ops.c ++++ b/src/ap/ap_drv_ops.c +@@ -296,19 +296,19 @@ int hostapd_vlan_if_remove(struct hostap + } + + +-int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr, int aid, +- int val) ++int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds, ++ const u8 *addr, int aid, int val) + { + const char *bridge = NULL; + + if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL) +- return 0; ++ return -1; + if (hapd->conf->wds_bridge[0]) + bridge = hapd->conf->wds_bridge; + else if (hapd->conf->bridge[0]) + bridge = hapd->conf->bridge; + return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val, +- bridge); ++ bridge, ifname_wds); + } + + +--- a/src/ap/ap_drv_ops.h ++++ b/src/ap/ap_drv_ops.h +@@ -31,8 +31,8 @@ int hostapd_set_drv_ieee8021x(struct hos + int enabled); + int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname); + int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname); +-int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr, int aid, +- int val); ++int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds, ++ const u8 *addr, int aid, int val); + int hostapd_sta_add(struct hostapd_data *hapd, + const u8 *addr, u16 aid, u16 capability, + const u8 *supp_rates, size_t supp_rates_len, +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c +@@ -1846,6 +1846,29 @@ static void handle_auth_cb(struct hostap + } + } + ++static void hostapd_set_wds_encryption(struct hostapd_data *hapd, ++ struct sta_info *sta, ++ char *ifname_wds) ++{ ++ int i, idx; ++ struct hostapd_ssid *ssid = sta->ssid; ++ ++ if (hapd->conf->ieee802_1x || hapd->conf->wpa) ++ return; ++ ++ for (i = 0; i < 4; i++) { ++ if (ssid->wep.key[i] && ++ hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i, ++ i == ssid->wep.idx, NULL, 0, ++ ssid->wep.key[i], ++ ssid->wep.len[i])) { ++ wpa_printf(MSG_WARNING, ++ "Could not set WEP keys for WDS interface; %s", ++ ifname_wds); ++ break; ++ } ++ } ++} + + static void handle_assoc_cb(struct hostapd_data *hapd, + const struct ieee80211_mgmt *mgmt, +@@ -1949,8 +1972,15 @@ static void handle_assoc_cb(struct hosta + goto fail; + } + +- if (sta->flags & WLAN_STA_WDS) +- hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 1); ++ if (sta->flags & WLAN_STA_WDS) { ++ int ret; ++ char ifname_wds[IFNAMSIZ + 1]; ++ ++ ret = hostapd_set_wds_sta(hapd, ifname_wds, sta->addr, ++ sta->aid, 1); ++ if (!ret) ++ hostapd_set_wds_encryption(hapd, sta, ifname_wds); ++ } + + if (sta->eapol_sm == NULL) { + /* +@@ -2191,11 +2221,18 @@ void ieee802_11_rx_from_unknown(struct h + return; + + if (wds && !(sta->flags & WLAN_STA_WDS)) { ++ int ret; ++ char ifname_wds[IFNAMSIZ + 1]; ++ + wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for " + "STA " MACSTR " (aid %u)", + MAC2STR(sta->addr), sta->aid); + sta->flags |= WLAN_STA_WDS; +- hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 1); ++ ret = hostapd_set_wds_sta(hapd, ifname_wds, ++ sta->addr, sta->aid, 1); ++ if (!ret) ++ hostapd_set_wds_encryption(hapd, sta, ++ ifname_wds); + } + return; + } +--- a/src/ap/sta_info.c ++++ b/src/ap/sta_info.c +@@ -129,7 +129,7 @@ void ap_free_sta(struct hostapd_data *ha + ap_sta_set_authorized(hapd, sta, 0); + + if (sta->flags & WLAN_STA_WDS) +- hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 0); ++ hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0); + + if (!(sta->flags & WLAN_STA_PREAUTH)) + hostapd_drv_sta_remove(hapd, sta->addr); +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -2057,10 +2057,12 @@ struct wpa_driver_ops { + * @val: 1 = bind to 4-address WDS; 0 = unbind + * @bridge_ifname: Bridge interface to use for the WDS station or %NULL + * to indicate that bridge is not to be used ++ * @ifname_wds: Buffer to return the interface name for the new WDS ++ * station. + * Returns: 0 on success, -1 on failure + */ + int (*set_wds_sta)(void *priv, const u8 *addr, int aid, int val, +- const char *bridge_ifname); ++ const char *bridge_ifname, char *ifname_wds); + + /** + * send_action - Transmit an Action frame +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -8744,13 +8744,16 @@ static int have_ifidx(struct wpa_driver_ + + + static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val, +- const char *bridge_ifname) ++ const char *bridge_ifname, char *ifname_wds) + { + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + char name[IFNAMSIZ + 1]; + + os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid); ++ if (ifname_wds) ++ os_strlcpy(ifname_wds, name, IFNAMSIZ + 1); ++ + wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR + " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name); + if (val) {