#include "ap_config.h"
-static int hostapd_notif_new_sta(struct hostapd_data *hapd, const u8 *addr)
-{
- struct sta_info *sta = ap_get_sta(hapd, addr);
- if (sta)
- return 0;
-
- wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
- " - adding a new STA", MAC2STR(addr));
- sta = ap_sta_add(hapd, addr);
- if (sta) {
- hostapd_new_assoc_sta(hapd, sta, 0);
- } else {
- wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
- MAC2STR(addr));
- return -1;
- }
-
- return 0;
-}
-
-
int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
const u8 *ie, size_t ielen)
{
}
-void hostapd_eapol_receive(struct hostapd_data *hapd, const u8 *sa,
- const u8 *buf, size_t len)
-{
- ieee802_1x_receive(hapd, sa, buf, len);
-}
-
-
-struct hostapd_data * hostapd_sta_get_bss(struct hostapd_data *hapd,
- const u8 *addr)
-{
- struct hostapd_iface *iface = hapd->iface;
- size_t j;
-
- for (j = 0; j < iface->num_bss; j++) {
- hapd = iface->bss[j];
- if (ap_get_sta(hapd, addr))
- return hapd;
- }
-
- return NULL;
-}
-
-
#ifdef HOSTAPD
#ifdef NEED_AP_MLME
}
+static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
+{
+ struct sta_info *sta = ap_get_sta(hapd, addr);
+ if (sta)
+ return 0;
+
+ wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
+ " - adding a new STA", MAC2STR(addr));
+ sta = ap_sta_add(hapd, addr);
+ if (sta) {
+ hostapd_new_assoc_sta(hapd, sta, 0);
+ } else {
+ wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
+ MAC2STR(addr));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
+ const u8 *data, size_t data_len)
+{
+ struct hostapd_iface *iface = hapd->iface;
+ size_t j;
+
+ for (j = 0; j < iface->num_bss; j++) {
+ if (ap_get_sta(iface->bss[j], src)) {
+ hapd = iface->bss[j];
+ break;
+ }
+ }
+
+ ieee802_1x_receive(hapd, src, data, data_len);
+}
+
+
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
union wpa_event_data *data)
{
data->rx_probe_req.ie_len);
break;
case EVENT_NEW_STA:
- hostapd_notif_new_sta(hapd, data->new_sta.addr);
+ hostapd_event_new_sta(hapd, data->new_sta.addr);
+ break;
+ case EVENT_EAPOL_RX:
+ hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
+ data->eapol_rx.data,
+ data->eapol_rx.data_len);
+ break;
default:
wpa_printf(MSG_DEBUG, "Unknown event %d", event);
break;
* with driver specific functionality. If this function pointer is set,
* l2_packet module is not used at all and the driver interface code is
* responsible for receiving and sending all EAPOL packets. The
- * received EAPOL packets are sent to core code by calling
- * wpa_supplicant_rx_eapol(). The driver interface is required to
- * implement get_mac_addr() handler if send_eapol() is used.
+ * received EAPOL packets are sent to core code with EVENT_EAPOL_RX
+ * event. The driver interface is required to implement get_mac_addr()
+ * handler if send_eapol() is used.
*/
int (*send_eapol)(void *priv, const u8 *dest, u16 proto,
const u8 *data, size_t data_len);
* authenticator when receiving a frame from a device. The address of
* the device is included in union wpa_event_data::new_sta.
*/
- EVENT_NEW_STA
+ EVENT_NEW_STA,
+
+ /**
+ * EVENT_EAPOL_RX - Report received EAPOL frame
+ *
+ * When in AP mode with hostapd, this event is required to be used to
+ * deliver the receive EAPOL frames from the driver. With
+ * %wpa_supplicant, this event is used only if the send_eapol() handler
+ * is used to override the use of l2_packet for EAPOL frame TX.
+ */
+ EVENT_EAPOL_RX
};
struct new_sta {
const u8 *addr;
} new_sta;
+
+ /**
+ * struct eapol_rx - Data for EVENT_EAPOL_RX events
+ */
+ struct eapol_rx {
+ const u8 *src;
+ const u8 *data;
+ size_t data_len;
+ } eapol_rx;
};
/**
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
union wpa_event_data *data);
-/**
- * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
- * @ctx: Context pointer (wpa_s); this is the ctx variable registered
- * with struct wpa_driver_ops::init()
- * @src_addr: Source address of the EAPOL frame
- * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
- * @len: Length of the EAPOL data
- *
- * This function is called for each received EAPOL frame. Most driver
- * interfaces rely on more generic OS mechanism for receiving frames through
- * l2_packet, but if such a mechanism is not available, the driver wrapper may
- * take care of received EAPOL frames and deliver them to the core supplicant
- * code by calling this function.
- */
-void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
- const u8 *buf, size_t len);
-
const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie);
const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
u32 vendor_type);
int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
const u8 *ie, size_t ielen);
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr);
-void hostapd_eapol_receive(struct hostapd_data *hapd, const u8 *sa,
- const u8 *buf, size_t len);
-
-struct hostapd_data * hostapd_sta_get_bss(struct hostapd_data *hapd,
- const u8 *addr);
#endif /* DRIVER_H */
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
{
struct madwifi_driver_data *drv = ctx;
- hostapd_eapol_receive(drv->hapd, src_addr,
- buf + sizeof(struct l2_ethhdr),
- len - sizeof(struct l2_ethhdr));
+ union wpa_event_data event;
+ os_memset(&event, 0, sizeof(event));
+ event.eapol_rx.src = src_addr;
+ event.eapol_rx.data = buf + sizeof(struct l2_ethhdr);
+ event.eapol_rx.data_len = len - sizeof(struct l2_ethhdr);
+ wpa_supplicant_event(drv->hapd, EVENT_EAPOL_RX, &event);
}
static void *
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
{
struct bsd_driver_data *drv = ctx;
- hostapd_eapol_receive(drv->hapd, src_addr,
- buf + sizeof(struct l2_ethhdr),
- len - sizeof(struct l2_ethhdr));
+ union wpa_event_data event;
+ os_memset(&event, 0, sizeof(event));
+ event.eapol_rx.src = src_addr;
+ event.eapol_rx.data = buf + sizeof(struct l2_ethhdr);
+ event.eapol_rx.data_len = len - sizeof(struct l2_ethhdr);
+ wpa_supplicant_event(drv->hapd, EVENT_EAPOL_RX, &event);
}
static int
left -= 2;
switch (ethertype) {
case ETH_P_PAE:
- hostapd_eapol_receive(drv->hapd, sa, pos, left);
+ os_memset(&event, 0, sizeof(event));
+ event.eapol_rx.src = sa;
+ event.eapol_rx.data = pos;
+ event.eapol_rx.data_len = left;
+ wpa_supplicant_event(drv->hapd, EVENT_EAPOL_RX, &event);
break;
default:
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
{
struct madwifi_driver_data *drv = ctx;
- hostapd_eapol_receive(drv->hapd, src_addr,
- buf + sizeof(struct l2_ethhdr),
- len - sizeof(struct l2_ethhdr));
+ union wpa_event_data event;
+ os_memset(&event, 0, sizeof(event));
+ event.eapol_rx.src = src_addr;
+ event.eapol_rx.data = buf + sizeof(struct l2_ethhdr);
+ event.eapol_rx.data_len = len - sizeof(struct l2_ethhdr);
+ wpa_supplicant_event(drv->hapd, EVENT_EAPOL_RX, &event);
}
static void *
}
if (have_ifidx(drv, lladdr.sll_ifindex)) {
- void *ctx;
- ctx = hostapd_sta_get_bss(drv->ctx, lladdr.sll_addr);
- if (!ctx)
- return;
- hostapd_eapol_receive(ctx, lladdr.sll_addr, buf, len);
+ union wpa_event_data event;
+ os_memset(&event, 0, sizeof(event));
+ event.eapol_rx.src = lladdr.sll_addr;
+ event.eapol_rx.data = buf;
+ event.eapol_rx.data_len = len;
+ wpa_supplicant_event(drv->ctx, EVENT_EAPOL_RX, &event);
}
}
}
-static void wpa_driver_privsep_event_assoc(void *ctx, wpa_event_type event,
+static void wpa_driver_privsep_event_assoc(void *ctx,
+ enum wpa_event_type event,
u8 *buf, size_t len)
{
union wpa_event_data data;
static void wpa_driver_privsep_event_rx_eapol(void *ctx, u8 *buf, size_t len)
{
+ union wpa_event_data event;
+
if (len < ETH_ALEN)
return;
- wpa_supplicant_rx_eapol(ctx, buf, buf + ETH_ALEN, len - ETH_ALEN);
+ os_memset(&event, 0, sizeof(event));
+ event.eapol_rx.src = buf;
+ event.eapol_rx.data = buf + ETH_ALEN;
+ event.eapol_rx.data_len = len - ETH_ALEN;
+ wpa_supplicant_event(ctx, EVENT_EAPOL_RX, &event);
}
if (len > 14 && WPA_GET_BE16(buf + 12) == ETH_P_EAPOL &&
os_memcmp(buf, drv->own_addr, ETH_ALEN) == 0) {
- wpa_supplicant_rx_eapol(drv->ctx, src_addr, buf + 14,
- len - 14);
+ union wpa_event_data event;
+ os_memset(&event, 0, sizeof(event));
+ event.eapol_rx.src = src_addr;
+ event.eapol_rx.data = buf + 14;
+ event.eapol_rx.data_len = len - 14;
+ wpa_supplicant_event(drv->ctx, EVENT_EAPOL_RX, &event);
}
}
struct test_client_socket *cli;
#endif /* HOSTAPD */
const u8 *src = NULL;
+ union wpa_event_data event;
+ void *ctx;
if (datalen > 14) {
/* Skip Ethernet header */
data += 14;
datalen -= 14;
}
+
+ os_memset(&event, 0, sizeof(event));
+ event.eapol_rx.data = data;
+ event.eapol_rx.data_len = datalen;
+
#ifdef HOSTAPD
cli = test_driver_get_cli(drv, from, fromlen);
if (cli) {
- hostapd_eapol_receive(cli->bss->bss_ctx, cli->addr, data,
- datalen);
+ event.eapol_rx.src = cli->addr;
+ ctx = cli->bss->bss_ctx;
} else {
wpa_printf(MSG_DEBUG, "test_socket: EAPOL from unknown "
"client");
+ return;
}
#else /* HOSTAPD */
- if (src)
- wpa_supplicant_rx_eapol(drv->ctx, src, data, datalen);
+ if (src) {
+ event.eapol_rx.src = src;
+ ctx = drv->ctx;
+ } else
+ return;
#endif /* HOSTAPD */
+
+ wpa_supplicant_event(ctx, EVENT_EAPOL_RX, &event);
}
const u8 *data, size_t data_len)
{
const u8 *src = drv->bssid;
+ union wpa_event_data event;
if (data_len > 14) {
/* Skip Ethernet header */
data += 14;
data_len -= 14;
}
-#ifndef HOSTAPD
- wpa_supplicant_rx_eapol(drv->ctx, src, data, data_len);
-#endif /* HOSTAPD */
+
+ os_memset(&event, 0, sizeof(event));
+ event.eapol_rx.src = src;
+ event.eapol_rx.data = data;
+ event.eapol_rx.data_len = data_len;
+ wpa_supplicant_event(drv->ctx, EVENT_EAPOL_RX, &event);
}
pos = (u8 *) (hdr + 1);
left = len - sizeof(*hdr);
- hostapd_eapol_receive(ctx, sa, pos, left);
+ os_memset(&event, 0, sizeof(event));
+ event.eapol_rx.src = sa;
+ event.eapol_rx.data = pos;
+ event.eapol_rx.data_len = left;
+ wpa_supplicant_event(ctx, EVENT_EAPOL_RX, &event);
break;
default:
#ifdef NEED_AP_MLME
#include "ap/ieee802_11.h"
#endif /* NEED_AP_MLME */
+#include "ap/ieee802_1x.h"
#include "ap/wps_hostapd.h"
#include "ap/ctrl_iface_ap.h"
#include "eap_common/eap_defs.h"
void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
const u8 *src_addr, const u8 *buf, size_t len)
{
- hostapd_eapol_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
+ ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
}
break;
}
#endif /* CONFIG_CLIENT_MLME */
-
+ case EVENT_EAPOL_RX:
+ wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src,
+ data->eapol_rx.data,
+ data->eapol_rx.data_len);
+ break;
default:
wpa_printf(MSG_INFO, "Unknown event %d", event);
break;
}
+/**
+ * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
+ * @ctx: Context pointer (wpa_s); this is the ctx variable registered
+ * with struct wpa_driver_ops::init()
+ * @src_addr: Source address of the EAPOL frame
+ * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
+ * @len: Length of the EAPOL data
+ *
+ * This function is called for each received EAPOL frame. Most driver
+ * interfaces rely on more generic OS mechanism for receiving frames through
+ * l2_packet, but if such a mechanism is not available, the driver wrapper may
+ * take care of received EAPOL frames and deliver them to the core supplicant
+ * code by calling this function.
+ */
void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
const u8 *buf, size_t len)
{
int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
void wpa_supplicant_terminate_proc(struct wpa_global *global);
+void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
+ const u8 *buf, size_t len);
/* scan.c */
int wpa_supplicant_enabled_networks(struct wpa_config *conf);