#include <net80211/ieee80211_crypto.h>
#include <net80211/ieee80211_ioctl.h>
+#ifdef CONFIG_WPS
+#ifdef IEEE80211_IOCTL_FILTERFRAME
+#include <netpacket/packet.h>
+
+#ifndef ETH_P_80211_RAW
+#define ETH_P_80211_RAW 0x0019
+#endif
+#endif /* IEEE80211_IOCTL_FILTERFRAME */
+#endif /* CONFIG_WPS */
+
/*
* Avoid conflicts with hostapd definitions by undefining couple of defines
* from madwifi header files.
#include "hostapd.h"
#include "driver.h"
-#include "ieee802_1x.h"
#include "eloop.h"
#include "priv_netlink.h"
-#include "sta_info.h"
#include "l2_packet/l2_packet.h"
-#include "wpa.h"
-#include "radius/radius.h"
-#include "ieee802_11.h"
-#include "accounting.h"
#include "common.h"
+#include "wps_hostapd.h"
+#include "ieee802_11_defs.h"
struct madwifi_driver_data {
return 0;
}
+#ifndef CONFIG_NO_STDOUT_DEBUG
static const char *
ether_sprintf(const u8 *addr)
{
snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
return buf;
}
+#endif /* CONFIG_NO_STDOUT_DEBUG */
/*
* Configure WPA parameters.
return ret;
}
+#ifdef CONFIG_WPS
+#ifdef IEEE80211_IOCTL_FILTERFRAME
+static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
+ size_t len)
+{
+ struct madwifi_driver_data *drv = ctx;
+ const struct ieee80211_mgmt *mgmt;
+ const u8 *end, *ie;
+ u16 fc;
+ size_t ie_len;
+
+ /* Send Probe Request information to WPS processing */
+
+ if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
+ return;
+ mgmt = (const struct ieee80211_mgmt *) buf;
+
+ fc = le_to_host16(mgmt->frame_control);
+ if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
+ WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ)
+ return;
+
+ end = buf + len;
+ ie = mgmt->u.probe_req.variable;
+ ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
+
+ hostapd_wps_probe_req_rx(drv->hapd, mgmt->sa, ie, ie_len);
+}
+#endif /* IEEE80211_IOCTL_FILTERFRAME */
+#endif /* CONFIG_WPS */
+
+static int madwifi_receive_probe_req(struct madwifi_driver_data *drv)
+{
+ int ret = 0;
+#ifdef CONFIG_WPS
+#ifdef IEEE80211_IOCTL_FILTERFRAME
+ struct ieee80211req_set_filter filt;
+
+ wpa_printf(MSG_DEBUG, "%s Enter", __func__);
+ filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ;
+
+ ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt,
+ sizeof(struct ieee80211req_set_filter));
+ if (ret)
+ return ret;
+
+ drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW,
+ madwifi_raw_receive, drv, 1);
+ if (drv->sock_raw == NULL)
+ return -1;
+#endif /* IEEE80211_IOCTL_FILTERFRAME */
+#endif /* CONFIG_WPS */
+ return ret;
+}
+
+#ifdef CONFIG_WPS
static int
-madwifi_del_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
+madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype)
{
- struct hostapd_data *hapd = drv->hapd;
- struct sta_info *sta;
-
- hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_INFO, "disassociated");
-
- sta = ap_get_sta(hapd, addr);
- if (sta != NULL) {
- sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
- wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
- sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
- ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
- ap_free_sta(hapd, sta);
- }
- return 0;
+ struct madwifi_driver_data *drv = priv;
+ u8 buf[256];
+ struct ieee80211req_getset_appiebuf *beac_ie;
+
+ wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__,
+ (unsigned long) len);
+
+ beac_ie = (struct ieee80211req_getset_appiebuf *) buf;
+ beac_ie->app_frmtype = frametype;
+ beac_ie->app_buflen = len;
+ memcpy(&(beac_ie->app_buf[0]), ie, len);
+
+ return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie,
+ sizeof(struct ieee80211req_getset_appiebuf) + len);
}
static int
-madwifi_process_wpa_ie(struct madwifi_driver_data *drv, struct sta_info *sta)
+madwifi_set_wps_beacon_ie(const char *ifname, void *priv, const u8 *ie,
+ size_t len)
+{
+ return madwifi_set_wps_ie(priv, ie, len, IEEE80211_APPIE_FRAME_BEACON);
+}
+
+static int
+madwifi_set_wps_probe_resp_ie(const char *ifname, void *priv, const u8 *ie,
+ size_t len)
+{
+ return madwifi_set_wps_ie(priv, ie, len,
+ IEEE80211_APPIE_FRAME_PROBE_RESP);
+}
+#else /* CONFIG_WPS */
+#define madwifi_set_wps_beacon_ie NULL
+#define madwifi_set_wps_probe_resp_ie NULL
+#endif /* CONFIG_WPS */
+
+static int
+madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
{
struct hostapd_data *hapd = drv->hapd;
struct ieee80211req_wpaie ie;
- int ielen, res;
- u8 *iebuf;
+ int ielen = 0, res;
+ u8 *iebuf = NULL;
/*
* Fetch negotiated WPA/RSN parameters from the system.
*/
memset(&ie, 0, sizeof(ie));
- memcpy(ie.wpa_macaddr, sta->addr, IEEE80211_ADDR_LEN);
+ memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) {
- wpa_printf(MSG_ERROR, "%s: Failed to get WPA/RSN IE",
+ wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE",
__func__);
- printf("Failed to get WPA/RSN information element.\n");
- return -1; /* XXX not right */
+ goto no_ie;
}
wpa_hexdump(MSG_MSGDUMP, "madwifi req WPA IE",
ie.wpa_ie, IEEE80211_MAX_OPT_IE);
iebuf[1] = 0;
}
#endif /* MADWIFI_NG */
- ielen = iebuf[1];
- if (ielen == 0) {
- printf("No WPA/RSN information element for station!?\n");
- return -1; /* XXX not right */
- }
- ielen += 2;
- if (sta->wpa_sm == NULL)
- sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr);
- if (sta->wpa_sm == NULL) {
- printf("Failed to initialize WPA state machine\n");
- return -1;
- }
- res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
- iebuf, ielen, NULL, 0);
- if (res != WPA_IE_OK) {
- printf("WPA/RSN information element rejected? (res %u)\n", res);
- return -1;
- }
- return 0;
-}
-
-static int
-madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
-{
- struct hostapd_data *hapd = drv->hapd;
- struct sta_info *sta;
- int new_assoc;
- hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_INFO, "associated");
+ ielen = iebuf[1];
+ if (ielen == 0)
+ iebuf = NULL;
+ else
+ ielen += 2;
- sta = ap_get_sta(hapd, addr);
- if (sta) {
- accounting_sta_stop(hapd, sta);
- } else {
- sta = ap_sta_add(hapd, addr);
- if (sta == NULL)
- return -1;
- }
+no_ie:
+ res = hostapd_notif_assoc(hapd, addr, iebuf, ielen);
if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
/* Cached accounting data is not valid anymore. */
memset(drv->acct_mac, 0, ETH_ALEN);
memset(&drv->acct_data, 0, sizeof(drv->acct_data));
}
- accounting_sta_get_id(hapd, sta);
-
- if (hapd->conf->wpa) {
- if (madwifi_process_wpa_ie(drv, sta))
- return -1;
- }
- /*
- * Now that the internal station state is setup
- * kick the authenticator into action.
- */
- new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
- sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
- wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
- hostapd_new_assoc_sta(hapd, sta, !new_assoc);
- ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
- return 0;
+ return res;
}
static void
}
pos += 5;
if (hwaddr_aton(pos, addr) == 0) {
- ieee80211_michael_mic_failure(drv->hapd, addr, 1);
+ hostapd_michael_mic_failure(drv->hapd, addr);
} else {
wpa_printf(MSG_DEBUG,
"MLME-MICHAELMICFAILURE.indication "
switch (iwe->cmd) {
case IWEVEXPIRED:
- madwifi_del_sta(drv, (u8 *) iwe->u.addr.sa_data);
+ hostapd_notif_disassoc(drv->hapd,
+ (u8 *) iwe->u.addr.sa_data);
break;
case IWEVREGISTERED:
madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data);
eth = (struct l2_ethhdr *) bp;
memcpy(eth->h_dest, addr, ETH_ALEN);
memcpy(eth->h_source, own_addr, ETH_ALEN);
- eth->h_proto = htons(ETH_P_EAPOL);
+ eth->h_proto = host_to_be16(ETH_P_EAPOL);
memcpy(eth+1, data, data_len);
wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
{
struct madwifi_driver_data *drv = ctx;
- struct hostapd_data *hapd = drv->hapd;
- struct sta_info *sta;
-
- sta = ap_get_sta(hapd, src_addr);
- if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
- printf("Data frame from not associated STA %s\n",
- ether_sprintf(src_addr));
- /* XXX cannot happen */
- return;
- }
- ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr),
- len - sizeof(struct l2_ethhdr));
+ hostapd_eapol_receive(drv->hapd, src_addr,
+ buf + sizeof(struct l2_ethhdr),
+ len - sizeof(struct l2_ethhdr));
}
static void *
madwifi_set_iface_flags(drv, 0); /* mark down during setup */
madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */
+ madwifi_receive_probe_req(drv);
+
return drv;
bad:
if (drv->sock_xmit != NULL)
.set_countermeasures = madwifi_set_countermeasures,
.sta_clear_stats = madwifi_sta_clear_stats,
.commit = madwifi_commit,
+ .set_wps_beacon_ie = madwifi_set_wps_beacon_ie,
+ .set_wps_probe_resp_ie = madwifi_set_wps_probe_resp_ie,
};