feat: Add deauth/disassoc frame detection via promiscuous mode

Enable WiFi promiscuous mode (MGMT filter only) to detect deauth and
disassociation frames. Sends ALERT_DATA packets via UDP with sender MAC,
target MAC, and RSSI. Coexists with CSI via separate callback path.
This commit is contained in:
user
2026-02-04 18:21:45 +01:00
parent a917a5ea02
commit 2554e11a0e

View File

@@ -679,6 +679,73 @@ static void ota_task(void *arg)
vTaskDelete(NULL);
}
/* --- Promiscuous mode: deauth/disassoc detection --- */
typedef struct {
uint16_t frame_ctrl;
uint16_t duration;
uint8_t addr1[6]; /* destination */
uint8_t addr2[6]; /* source */
uint8_t addr3[6]; /* BSSID */
uint16_t seq_ctrl;
} __attribute__((packed)) wifi_ieee80211_mac_hdr_t;
static void wifi_promiscuous_cb(void *buf, wifi_promiscuous_pkt_type_t type)
{
if (type != WIFI_PKT_MGMT) return;
const wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf;
const wifi_ieee80211_mac_hdr_t *hdr = (wifi_ieee80211_mac_hdr_t *)pkt->payload;
uint8_t subtype = (hdr->frame_ctrl >> 4) & 0x0F;
const char *type_str = NULL;
if (subtype == 0x0C) {
type_str = "deauth";
} else if (subtype == 0x0A) {
type_str = "disassoc";
} else {
return;
}
char alert[160];
int len = snprintf(alert, sizeof(alert),
"ALERT_DATA,%s,%s,"
"%02x:%02x:%02x:%02x:%02x:%02x,"
"%02x:%02x:%02x:%02x:%02x:%02x,"
"%d\n",
CONFIG_CSI_HOSTNAME, type_str,
hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
hdr->addr1[3], hdr->addr1[4], hdr->addr1[5],
pkt->rx_ctrl.rssi);
if (s_udp_socket >= 0) {
sendto(s_udp_socket, alert, len, 0,
(struct sockaddr *)&s_dest_addr, sizeof(s_dest_addr));
}
ESP_LOGW(TAG, "ALERT: %s from " MACSTR " -> " MACSTR " rssi=%d",
type_str,
hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
hdr->addr1[3], hdr->addr1[4], hdr->addr1[5],
pkt->rx_ctrl.rssi);
}
static void wifi_promiscuous_init(void)
{
wifi_promiscuous_filter_t filt = {
.filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT,
};
ESP_ERROR_CHECK(esp_wifi_set_promiscuous_filter(&filt));
ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb));
ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true));
ESP_LOGI(TAG, "Promiscuous mode: deauth/disassoc detection enabled");
}
/* --- Command handler --- */
static void reboot_after_delay(void *arg)
@@ -1060,6 +1127,7 @@ void app_main()
udp_socket_init();
wifi_csi_init();
wifi_promiscuous_init();
wifi_ping_router_start();
xTaskCreate(cmd_task, "cmd_task", 4096, NULL, 5, NULL);