Use driver event, EVENT_EAPOL_RX, for EAPOL frame indication
authorJouni Malinen <j@w1.fi>
Sun, 3 Jan 2010 15:44:40 +0000 (17:44 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 3 Jan 2010 15:44:40 +0000 (17:44 +0200)
15 files changed:
src/ap/drv_callbacks.c
src/drivers/driver.h
src/drivers/driver_atheros.c
src/drivers/driver_bsd.c
src/drivers/driver_hostap.c
src/drivers/driver_madwifi.c
src/drivers/driver_nl80211.c
src/drivers/driver_privsep.c
src/drivers/driver_roboswitch.c
src/drivers/driver_test.c
src/drivers/driver_wired.c
wpa_supplicant/ap.c
wpa_supplicant/events.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 09d4b1d..b03a541 100644 (file)
 #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)
 {
@@ -166,29 +145,6 @@ 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)
-{
-       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
@@ -343,6 +299,44 @@ static int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa,
 }
 
 
+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)
 {
@@ -396,7 +390,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                     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;
index d467eb2..77263b5 100644 (file)
@@ -795,9 +795,9 @@ struct wpa_driver_ops {
         * 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);
@@ -1882,7 +1882,17 @@ enum wpa_event_type {
         * 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
 };
 
 
@@ -2210,6 +2220,15 @@ union wpa_event_data {
        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;
 };
 
 /**
@@ -2225,23 +2244,6 @@ union wpa_event_data {
 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);
@@ -2256,10 +2258,5 @@ void wpa_scan_sort_results(struct wpa_scan_results *res);
 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 */
index 58834b4..e3a7e7d 100644 (file)
@@ -1073,9 +1073,12 @@ static void
 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 *
index 2b83618..5b232fd 100644 (file)
@@ -736,9 +736,12 @@ 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
index c0f36b8..1aa52e8 100644 (file)
@@ -112,7 +112,11 @@ static void handle_data(struct hostap_driver_data *drv, u8 *buf, size_t len,
        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:
index 02852fe..5c25ee3 100644 (file)
@@ -1143,9 +1143,12 @@ static void
 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 *
index 24e5b5c..5a36cf8 100644 (file)
@@ -4234,11 +4234,12 @@ static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
        }
 
        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);
        }
 }
 
index d9911e9..223695a 100644 (file)
@@ -321,7 +321,8 @@ static int wpa_driver_privsep_disassociate(void *priv, const u8 *addr,
 }
 
 
-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;
@@ -431,10 +432,16 @@ static void wpa_driver_privsep_event_ft_response(void *ctx, u8 *buf,
 
 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);
 }
 
 
index aab6bc0..fe63bc1 100644 (file)
@@ -180,8 +180,12 @@ static void wpa_driver_roboswitch_receive(void *priv, const u8 *src_addr,
 
        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);
        }
 }
 
index 205744e..c61535e 100644 (file)
@@ -652,6 +652,8 @@ static void test_driver_eapol(struct wpa_driver_test_data *drv,
        struct test_client_socket *cli;
 #endif /* HOSTAPD */
        const u8 *src = NULL;
+       union wpa_event_data event;
+       void *ctx;
 
        if (datalen > 14) {
                /* Skip Ethernet header */
@@ -663,19 +665,30 @@ static void test_driver_eapol(struct wpa_driver_test_data *drv,
                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);
 }
 
 
@@ -1803,6 +1816,7 @@ static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv,
                                  const u8 *data, size_t data_len)
 {
        const u8 *src = drv->bssid;
+       union wpa_event_data event;
 
        if (data_len > 14) {
                /* Skip Ethernet header */
@@ -1810,9 +1824,12 @@ static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv,
                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);
 }
 
 
index 4a596a1..ba6ae00 100644 (file)
@@ -141,7 +141,11 @@ static void handle_data(void *ctx, unsigned char *buf, size_t len)
                        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:
index 0f89aaa..ff07d60 100644 (file)
@@ -22,6 +22,7 @@
 #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"
@@ -289,7 +290,7 @@ void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok)
 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);
 }
 
 
index 4bd9da8..050ca1e 100644 (file)
@@ -1515,7 +1515,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                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;
index fc42d29..7e56bb7 100644 (file)
@@ -1722,6 +1722,20 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
 }
 
 
+/**
+ * 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)
 {
index f86a172..677925f 100644 (file)
@@ -487,6 +487,8 @@ void wpa_supplicant_deinit(struct wpa_global *global);
 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);