Browse Source

hostapd: Add wpa_msg_ctrl() to report Probe Request frames from STA

This allows external applications to get event indication for Probe
Request frames. Extend ctrl iface cmd "ATTACH" to enable this event on
per-request basis. For example, user has to send ctrl iface cmd "ATTACH
probe_rx_events=1" to enable the Probe Request frame events.

Signed-off-by: bhagavathi perumal s <bperumal@qti.qualcomm.com>
bhagavathi perumal s 7 years ago
parent
commit
cc79e06f00

+ 29 - 7
hostapd/ctrl_iface.c

@@ -30,6 +30,7 @@
 #include "common/ieee802_11_defs.h"
 #include "common/ctrl_iface_common.h"
 #include "common/dpp.h"
+#include "common/wpa_ctrl.h"
 #include "crypto/tls.h"
 #include "drivers/driver.h"
 #include "eapol_auth/eapol_auth_sm.h"
@@ -78,9 +79,9 @@ static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
 
 static int hostapd_ctrl_iface_attach(struct hostapd_data *hapd,
 				     struct sockaddr_storage *from,
-				     socklen_t fromlen)
+				     socklen_t fromlen, const char *input)
 {
-	return ctrl_iface_attach(&hapd->ctrl_dst, from, fromlen);
+	return ctrl_iface_attach(&hapd->ctrl_dst, from, fromlen, input);
 }
 
 
@@ -2746,7 +2747,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
 		reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply,
 							reply_size);
 	} else if (os_strcmp(buf, "ATTACH") == 0) {
-		if (hostapd_ctrl_iface_attach(hapd, from, fromlen))
+		if (hostapd_ctrl_iface_attach(hapd, from, fromlen, NULL))
+			reply_len = -1;
+	} else if (os_strncmp(buf, "ATTACH ", 7) == 0) {
+		if (hostapd_ctrl_iface_attach(hapd, from, fromlen, buf + 7))
 			reply_len = -1;
 	} else if (os_strcmp(buf, "DETACH") == 0) {
 		if (hostapd_ctrl_iface_detach(hapd, from, fromlen))
@@ -3499,9 +3503,10 @@ static int hostapd_ctrl_iface_remove(struct hapd_interfaces *interfaces,
 
 static int hostapd_global_ctrl_iface_attach(struct hapd_interfaces *interfaces,
 					    struct sockaddr_storage *from,
-					    socklen_t fromlen)
+					    socklen_t fromlen, char *input)
 {
-	return ctrl_iface_attach(&interfaces->global_ctrl_dst, from, fromlen);
+	return ctrl_iface_attach(&interfaces->global_ctrl_dst, from, fromlen,
+				 input);
 }
 
 
@@ -3878,7 +3883,11 @@ static void hostapd_global_ctrl_iface_receive(int sock, void *eloop_ctx,
 			reply_len = -1;
 	} else if (os_strcmp(buf, "ATTACH") == 0) {
 		if (hostapd_global_ctrl_iface_attach(interfaces, &from,
-						     fromlen))
+						     fromlen, NULL))
+			reply_len = -1;
+	} else if (os_strncmp(buf, "ATTACH ", 7) == 0) {
+		if (hostapd_global_ctrl_iface_attach(interfaces, &from,
+						     fromlen, buf + 7))
 			reply_len = -1;
 	} else if (os_strcmp(buf, "DETACH") == 0) {
 		if (hostapd_global_ctrl_iface_detach(interfaces, &from,
@@ -4194,6 +4203,18 @@ void hostapd_global_ctrl_iface_deinit(struct hapd_interfaces *interfaces)
 }
 
 
+static int hostapd_ctrl_check_event_enabled(struct wpa_ctrl_dst *dst,
+					    const char *buf)
+{
+	/* Enable Probe Request events based on explicit request.
+	 * Other events are enabled by default.
+	 */
+	if (str_starts(buf, RX_PROBE_REQUEST))
+		return !!(dst->events & WPA_EVENT_RX_PROBE_REQUEST);
+	return 1;
+}
+
+
 static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
 				    enum wpa_msg_type type,
 				    const char *buf, size_t len)
@@ -4228,7 +4249,8 @@ static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
 
 	idx = 0;
 	dl_list_for_each_safe(dst, next, ctrl_dst, struct wpa_ctrl_dst, list) {
-		if (level >= dst->debug_level) {
+		if ((level >= dst->debug_level) &&
+		     hostapd_ctrl_check_event_enabled(dst, buf)) {
 			sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor send",
 				       &dst->addr, dst->addrlen);
 			msg.msg_name = &dst->addr;

+ 4 - 0
src/ap/beacon.c

@@ -16,6 +16,7 @@
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
 #include "common/hw_features_common.h"
+#include "common/wpa_ctrl.h"
 #include "wps/wps_defs.h"
 #include "p2p/p2p.h"
 #include "hostapd.h"
@@ -993,6 +994,9 @@ void handle_probe_req(struct hostapd_data *hapd,
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
+	wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, RX_PROBE_REQUEST "sa=" MACSTR
+		     " signal=%d", MAC2STR(mgmt->sa), ssi_signal);
+
 	resp = hostapd_gen_probe_resp(hapd, mgmt, elems.p2p != NULL,
 				      &resp_len);
 	if (resp == NULL)

+ 37 - 1
src/common/ctrl_iface_common.c

@@ -113,17 +113,53 @@ void sockaddr_print(int level, const char *msg, struct sockaddr_storage *sock,
 }
 
 
+static int ctrl_set_events(struct wpa_ctrl_dst *dst, const char *input)
+{
+	const char *value;
+	int val;
+
+	if (!input)
+		return 0;
+
+	value = os_strchr(input, '=');
+	if (!value)
+		return -1;
+	value++;
+	val = atoi(value);
+	if (val < 0 || val > 1)
+		return -1;
+
+	if (str_starts(input, "probe_rx_events=")) {
+		if (val)
+			dst->events |= WPA_EVENT_RX_PROBE_REQUEST;
+		else
+			dst->events &= ~WPA_EVENT_RX_PROBE_REQUEST;
+	}
+
+	return 0;
+}
+
+
 int ctrl_iface_attach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
-		      socklen_t fromlen)
+		      socklen_t fromlen, const char *input)
 {
 	struct wpa_ctrl_dst *dst;
 
+	/* Update event registration if already attached */
+	dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
+		if (!sockaddr_compare(from, fromlen,
+				      &dst->addr, dst->addrlen))
+			return ctrl_set_events(dst, input);
+	}
+
+	/* New attachment */
 	dst = os_zalloc(sizeof(*dst));
 	if (dst == NULL)
 		return -1;
 	os_memcpy(&dst->addr, from, fromlen);
 	dst->addrlen = fromlen;
 	dst->debug_level = MSG_INFO;
+	ctrl_set_events(dst, input);
 	dl_list_add(ctrl_dst, &dst->list);
 
 	sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor attached", from, fromlen);

+ 5 - 1
src/common/ctrl_iface_common.h

@@ -11,6 +11,9 @@
 
 #include "utils/list.h"
 
+/* Events enable bits (wpa_ctrl_dst::events) */
+#define WPA_EVENT_RX_PROBE_REQUEST BIT(0)
+
 /**
  * struct wpa_ctrl_dst - Data structure of control interface monitors
  *
@@ -23,13 +26,14 @@ struct wpa_ctrl_dst {
 	socklen_t addrlen;
 	int debug_level;
 	int errors;
+	u32 events; /* WPA_EVENT_* bitmap */
 };
 
 void sockaddr_print(int level, const char *msg, struct sockaddr_storage *sock,
 		    socklen_t socklen);
 
 int ctrl_iface_attach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
-		       socklen_t fromlen);
+		       socklen_t fromlen, const char *input);
 int ctrl_iface_detach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
 		      socklen_t fromlen);
 int ctrl_iface_level(struct dl_list *ctrl_dst, struct sockaddr_storage *from,

+ 4 - 0
src/common/wpa_ctrl.h

@@ -339,6 +339,10 @@ extern "C" {
  */
 #define FILS_HLP_RX "FILS-HLP-RX "
 
+/* Event to indicate Probe Request frame;
+ * parameters: sa=<STA MAC address> signal=<signal> */
+#define RX_PROBE_REQUEST "RX-PROBE-REQUEST "
+
 /* BSS command information masks */
 
 #define WPA_BSS_MASK_ALL		0xFFFDFFFF

+ 1 - 1
wpa_supplicant/ctrl_iface_unix.c

@@ -103,7 +103,7 @@ static int wpa_supplicant_ctrl_iface_attach(struct dl_list *ctrl_dst,
 					    struct sockaddr_storage *from,
 					    socklen_t fromlen, int global)
 {
-	return ctrl_iface_attach(ctrl_dst, from, fromlen);
+	return ctrl_iface_attach(ctrl_dst, from, fromlen, NULL);
 }