[PATCH 4/4] hostapd: add support for pre-auth rx over driver event

Markus Theil <[email protected]>
Newsgroups gmane.linux.drivers.hostap
Message-ID <[email protected]>
This patch enables hostapd to receive pre-auth frames over nl80211.

Signed-off-by: Markus Theil <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.