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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user