This patch enables hostapd to receive pre-auth frames over nl80211. Signed-off-by: Markus Theil <markus.theil@xxxxxxxxxxxxx> --- src/ap/drv_callbacks.c | 32 ++++++++++++++++++++++++++++++++ src/ap/preauth_auth.c | 29 +++++++++++++++++++++++++++++ src/ap/preauth_auth.h | 13 +++++++++++++ 3 files changed, 74 insertions(+) diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index fdd845573..4c0ea80c4 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -42,6 +42,7 @@ #include "dpp_hostapd.h" #include "fils_hlp.h" #include "neighbor_db.h" +#include "preauth_auth.h" #ifdef CONFIG_FILS @@ -1424,6 +1425,30 @@ static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, ieee802_1x_receive(hapd, src, data, data_len); } + +static void hostapd_event_rsn_preauth_rx(struct hostapd_data *hapd, + const u8 *src, const u8 *dst, + const u8 *data, size_t data_len) +{ + if (!hapd->preauth_iface) { + wpa_printf(MSG_DEBUG, "Received pre-auth frame from " MACSTR + " without preauth_iface created", + MAC2STR(src)); + return; + } + + if (!dst) { + wpa_printf(MSG_DEBUG, "Received pre-auth frame from " MACSTR + " without destination MAC set, maybe your kernel " + "is too old for nl80211 control port rx", + MAC2STR(src)); + return; + } + + rsn_preauth_receive_or_forward(hapd, src, dst, data, data_len); +} + + #endif /* HOSTAPD */ @@ -1797,6 +1822,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, data->eapol_rx.data, data->eapol_rx.data_len); break; + case EVENT_RSN_PREAUTH_RX: + hostapd_event_rsn_preauth_rx(hapd, + data->rsn_preauth_rx.src, + data->rsn_preauth_rx.dst, + data->rsn_preauth_rx.data, + data->rsn_preauth_rx.data_len); + break; case EVENT_ASSOC: if (!data) return; diff --git a/src/ap/preauth_auth.c b/src/ap/preauth_auth.c index 3e0c8000d..a367b5e19 100644 --- a/src/ap/preauth_auth.c +++ b/src/ap/preauth_auth.c @@ -270,4 +270,33 @@ void rsn_preauth_free_station(struct hostapd_data *hapd, struct sta_info *sta) eloop_cancel_timeout(rsn_preauth_finished_cb, hapd, sta); } +void rsn_preauth_receive_or_forward(struct hostapd_data *hapd, + const u8 *src_addr, + const u8 *dst_addr, + const u8 *buf, size_t len) +{ + struct l2_ethhdr *ethhdr; + + ethhdr = os_malloc(sizeof(*ethhdr) + len); + if (ethhdr == NULL) + return; + + if (os_memcmp(dst_addr, hapd->own_addr, ETH_ALEN) != 0) { + os_memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); + os_memcpy(ethhdr->h_source, src_addr, ETH_ALEN); + ethhdr->h_proto = host_to_be16(ETH_P_PREAUTH); + os_memcpy(ethhdr + 1, buf, len); + + if (l2_packet_send(hapd->preauth_iface->l2, dst_addr, ETH_P_PREAUTH, (u8 *) ethhdr, + sizeof(*ethhdr) + len) < 0) { + wpa_printf(MSG_ERROR, "Failed to forward preauth packet using " + "l2_packet_send\n"); + } + } else { + rsn_preauth_receive(hapd->preauth_iface, src_addr, buf, len); + } + + os_free(ethhdr); +} + #endif /* CONFIG_RSN_PREAUTH */ diff --git a/src/ap/preauth_auth.h b/src/ap/preauth_auth.h index 69fb3566e..d6ae1b72d 100644 --- a/src/ap/preauth_auth.h +++ b/src/ap/preauth_auth.h @@ -19,6 +19,11 @@ void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta, u8 *buf, size_t len); void rsn_preauth_free_station(struct hostapd_data *hapd, struct sta_info *sta); +void rsn_preauth_receive_or_forward(struct hostapd_data *hapd, + const u8 *src_addr, + const u8 *dst_addr, + const u8 *buf, size_t len); + #else /* CONFIG_RSN_PREAUTH */ static inline int rsn_preauth_iface_init(struct hostapd_data *hapd) @@ -47,6 +52,14 @@ static inline void rsn_preauth_free_station(struct hostapd_data *hapd, { } +static inline void rsn_preauth_receive_or_forward(struct hostapd_data *hapd, + const u8 *src_addr, + const u8 *dst_addr, + const u8 *buf, size_t len) +{ +} + + #endif /* CONFIG_RSN_PREAUTH */ #endif /* PREAUTH_H */ -- 2.17.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap