diff mbox series

Return the mac addresses of overlapping stations when wps overlap is detected by the AP

Message ID PR0P264MB1147D4F5534533E6E1730E179F309@PR0P264MB1147.FRAP264.PROD.OUTLOOK.COM
State New
Headers show
Series Return the mac addresses of overlapping stations when wps overlap is detected by the AP | expand

Commit Message

Jef MAERIEN June 15, 2021, 12:11 p.m. UTC
Report the MAC Addresses that cause WPS overlap, when detected by AP.
This allows to identify potential misbehaving or conflicting stations. 

Signed-off-by: Jef Maerien <jef.maerien_at_softathome.com>
---
 src/ap/wps_hostapd.c    | 24 +++++++++++++++++++++++-
 src/wps/wps.h           | 14 ++++++++++++++
 src/wps/wps_common.c    | 14 ++++++++++++++
 src/wps/wps_i.h         |  1 +
 src/wps/wps_registrar.c | 40 +++++++++++++++++++++-------------------
 5 files changed, 73 insertions(+), 20 deletions(-)

--
2.17.1
diff mbox series

Patch

diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index e97dbf996..1b16364ae 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -905,7 +905,29 @@  static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
 		break;
 	case WPS_EV_PBC_OVERLAP:
 		hostapd_wps_event_pbc_overlap(hapd);
-		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_OVERLAP);
+		u8 size = (data->overlap_pbc_session.count-1)*18+1;
+		char* str_mac = os_zalloc(size); //18:xx:xx:xx:xx:xx:xx,
+		if(str_mac) {
+			int ret;
+			char *pos, *end;
+			struct wps_pbc_session *pbc;
+			pos = str_mac;
+			end = str_mac + size;
+			for (pbc = data->overlap_pbc_session.pbc_session; pbc; pbc = pbc->next) {
+				if(pbc->overlap){
+					ret = os_snprintf(pos, end - pos, MACSTR",", MAC2STR(pbc->addr));
+					pos += ret;
+				}
+			}
+			*(pos-1) = '\0';
+		}
+		if(data->overlap_pbc_session.addr){
+			wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_OVERLAP MACSTR",%s",MAC2STR(data->overlap_pbc_session.addr), str_mac);
+		} else {
+			wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_OVERLAP "null,%s", str_mac);
+		}
+		os_free(str_mac);
+		str_mac = NULL;
 		break;
 	case WPS_EV_PBC_TIMEOUT:
 		hostapd_wps_event_pbc_timeout(hapd);
diff --git a/src/wps/wps.h b/src/wps/wps.h
index 6a12255c8..51cdd8d15 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -520,6 +520,14 @@  enum wps_event {
 	WPS_EV_AP_PIN_SUCCESS
 };

+struct wps_pbc_session {
+	struct wps_pbc_session *next;
+	u8 addr[ETH_ALEN];
+	u8 uuid_e[WPS_UUID_LEN];
+	u8 overlap;
+	struct os_reltime timestamp;
+};
+
 /**
  * union wps_event_data - WPS event data
  */
@@ -611,6 +619,12 @@  union wps_event_data {
 			WPS_ER_SET_SEL_REG_FAILED
 		} state;
 	} set_sel_reg;
+
+	struct wps_event_overlap_pbc_session {
+		int count;
+		u8 *addr;
+		struct wps_pbc_session *pbc_session;
+	} overlap_pbc_session;
 };

 /**
diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c
index 747dc4710..953abc8bf 100644
--- a/src/wps/wps_common.c
+++ b/src/wps/wps_common.c
@@ -323,6 +323,20 @@  void wps_pbc_overlap_event(struct wps_context *wps)
 	wps->event_cb(wps->cb_ctx, WPS_EV_PBC_OVERLAP, NULL);
 }

+void wps_pbc_vap_overlap_event(struct wps_context *wps, int count, u8 *addr, struct wps_pbc_session *pbc)
+{
+	union wps_event_data data;
+
+	if (wps->event_cb == NULL)
+		return;
+
+	os_memset(&data, 0, sizeof(data));
+	data.overlap_pbc_session.count = count;
+	data.overlap_pbc_session.addr = addr;
+	data.overlap_pbc_session.pbc_session = pbc;
+	wps->event_cb(wps->cb_ctx, WPS_EV_PBC_OVERLAP, &data);
+}
+

 void wps_pbc_timeout_event(struct wps_context *wps)
 {
diff --git a/src/wps/wps_i.h b/src/wps/wps_i.h
index 2cf22d4b7..ce629f360 100644
--- a/src/wps/wps_i.h
+++ b/src/wps/wps_i.h
@@ -144,6 +144,7 @@  void wps_success_event(struct wps_context *wps, const u8 *mac_addr);
 void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part,
 			     const u8 *mac_addr);
 void wps_pbc_overlap_event(struct wps_context *wps);
+void wps_pbc_vap_overlap_event(struct wps_context *wps, int count, u8 *addr, struct wps_pbc_session *pbc);
 void wps_pbc_timeout_event(struct wps_context *wps);
 void wps_pbc_active_event(struct wps_context *wps);
 void wps_pbc_disable_event(struct wps_context *wps);
diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c
index 45f7e947e..696a51602 100644
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -111,15 +111,6 @@  static void wps_free_pins(struct dl_list *pins)
 		wps_remove_pin(pin);
 }

-
-struct wps_pbc_session {
-	struct wps_pbc_session *next;
-	u8 addr[ETH_ALEN];
-	u8 uuid_e[WPS_UUID_LEN];
-	struct os_reltime timestamp;
-};
-
-
 static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
 {
 	struct wps_pbc_session *prev;
@@ -425,7 +416,15 @@  static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
 	}
 }

-
+static void wps_pbc_raise_overlap_event(struct wps_context *wps, int count, u8 *addr, struct wps_pbc_session *pbc)
+{
+	wps_pbc_vap_overlap_event(wps, count, addr, pbc);
+	//clear overlap flag
+	struct wps_pbc_session *itr;
+	for (itr = pbc; itr; itr = itr->next) {
+		itr->overlap = 0;
+	}
+}
 int wps_registrar_pbc_overlap(struct wps_registrar *reg,
 			      const u8 *addr, const u8 *uuid_e)
 {
@@ -464,6 +463,7 @@  int wps_registrar_pbc_overlap(struct wps_registrar *reg,
 		    os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN)) {
 			wpa_printf(MSG_DEBUG, "WPS: New Enrollee");
 			count++;
+			pbc->overlap = 1;
 		}
 		if (first == NULL)
 			first = pbc;
@@ -471,7 +471,7 @@  int wps_registrar_pbc_overlap(struct wps_registrar *reg,

 	wpa_printf(MSG_DEBUG, "WPS: %u active PBC session(s) found", count);

-	return count > 1 ? 1 : 0;
+	return count > 1 ? count : 0;
 }


@@ -1046,11 +1046,12 @@  static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
 int wps_registrar_button_pushed(struct wps_registrar *reg,
 				const u8 *p2p_dev_addr)
 {
+	int count;
 	if (p2p_dev_addr == NULL &&
-	    wps_registrar_pbc_overlap(reg, NULL, NULL)) {
+	    (count=wps_registrar_pbc_overlap(reg, NULL, NULL))) {
 		wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
 			   "mode");
-		wps_pbc_overlap_event(reg->wps);
+		wps_pbc_raise_overlap_event(reg->wps, count, NULL, reg->pbc_sessions);
 		return -2;
 	}
 	wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
@@ -1150,6 +1151,7 @@  void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
 {
 	struct wps_parse_attr attr;
 	int skip_add = 0;
+	int count = 0;

 	wpa_hexdump_buf(MSG_MSGDUMP,
 			"WPS: Probe Request with WPS data received",
@@ -1219,10 +1221,10 @@  void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,

 	if (!skip_add)
 		wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
-	if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
+	if ((count=wps_registrar_pbc_overlap(reg, addr, attr.uuid_e))) {
 		wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
 		reg->force_pbc_overlap = 1;
-		wps_pbc_overlap_event(reg->wps);
+		wps_pbc_raise_overlap_event(reg->wps, count, (u8*) addr, reg->pbc_sessions);
 	}
 }

@@ -2728,18 +2730,18 @@  static enum wps_process_res wps_process_m1(struct wps_data *wps,
 		}
 	}
 #endif /* CONFIG_WPS_NFC */
-
+	int count = 0;
 	if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
 		if ((wps->wps->registrar->force_pbc_overlap ||
-		     wps_registrar_pbc_overlap(wps->wps->registrar,
-					       wps->mac_addr_e, wps->uuid_e) ||
+		     (count=wps_registrar_pbc_overlap(wps->wps->registrar,
+					       wps->mac_addr_e, wps->uuid_e)) ||
 		     !wps_registrar_p2p_dev_addr_match(wps)) &&
 		    !wps_registrar_skip_overlap(wps)) {
 			wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
 				   "negotiation");
 			wps->state = SEND_M2D;
 			wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
-			wps_pbc_overlap_event(wps->wps);
+			wps_pbc_raise_overlap_event(wps->wps, count, wps->mac_addr_e, wps->wps->registrar->pbc_sessions);
 			wps_fail_event(wps->wps, WPS_M1,
 				       WPS_CFG_MULTIPLE_PBC_DETECTED,
 				       WPS_EI_NO_ERROR, wps->mac_addr_e);