- /* WiFi station Example
- This example code is in the Public Domain (or CC0 licensed, at your option.)
- Unless required by applicable law or agreed to in writing, this
- software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, either express or implied.
- */
- #include <string.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/event_groups.h"
- #include "esp_system.h"
- #include "esp_wifi.h"
- #include "esp_event.h"
- #include "esp_log.h"
- #include "nvs_flash.h"
- #include "lwip/err.h"
- #include "lwip/sys.h"
- #define SCAN_CHANNEL_1 1
- #define SCAN_CHANNEL_13 13
- #define SCAN_CHANNEL_36 36 // 5G信道
- #define SCAN_CHANNEL_48 48 // 5G信道
- #define PROBE_COUNT 3
- #define SCAN_INTERVAL_MS 5000
- #define PROBE_REQ_HEAD_LEN 24
- #define SSID_IE_LEN 2
- #define SUPPORTED_RATES_LEN 8
- #define DS_PARAM_LEN 3
- #define FRAME_CONTROL_PROBE_REQ 0x0040 // 正确的 Probe Request 帧控制值
- static const char *TAG = "wifi station";
- static void send_probe_req_task(void *pvParameters)
- {
- uint8_t probe_req_frame_2g[200] = {0};
- uint8_t probe_req_frame_5g[200] = {0};
- int cur_len_2g = 0;
- int cur_len_5g = 0;
- // 构造2.4G probe request基本帧
- // Frame Control
- probe_req_frame_2g[cur_len_2g++] = 0x40; // 帧控制字段
- probe_req_frame_2g[cur_len_2g++] = 0x00;
- // Duration
- probe_req_frame_2g[cur_len_2g++] = 0x00;
- probe_req_frame_2g[cur_len_2g++] = 0x00;
- // Destination Address (broadcast)
- memset(&probe_req_frame_2g[cur_len_2g], 0xFF, 6);
- cur_len_2g += 6;
- // Source Address
- uint8_t mac_addr[6];
- esp_wifi_get_mac(WIFI_IF_STA, mac_addr);
- memcpy(&probe_req_frame_2g[cur_len_2g], mac_addr, 6);
- cur_len_2g += 6;
- // BSSID
- memset(&probe_req_frame_2g[cur_len_2g], 0xFF, 6);
- cur_len_2g += 6;
- // Sequence Control
- probe_req_frame_2g[cur_len_2g++] = 0x00;
- probe_req_frame_2g[cur_len_2g++] = 0x00;
- // 2.4G SSID
- probe_req_frame_2g[cur_len_2g++] = 0x00;
- probe_req_frame_2g[cur_len_2g++] = 0x00;
- // 2.4G Supported rates
- probe_req_frame_2g[cur_len_2g++] = 0x01;
- probe_req_frame_2g[cur_len_2g++] = 0x04;
- probe_req_frame_2g[cur_len_2g++] = 0x82; // 1 Mbps
- probe_req_frame_2g[cur_len_2g++] = 0x84; // 2 Mbps
- probe_req_frame_2g[cur_len_2g++] = 0x8B; // 5.5 Mbps
- probe_req_frame_2g[cur_len_2g++] = 0x96; // 11 Mbps
- int total_len_2g = cur_len_2g;
- // Frame Control
- probe_req_frame_5g[cur_len_5g++] = 0x40; // 帧控制字段
- probe_req_frame_5g[cur_len_5g++] = 0x00;
- // Duration
- probe_req_frame_5g[cur_len_5g++] = 0x00;
- probe_req_frame_5g[cur_len_5g++] = 0x00;
- // Destination Address (broadcast)
- memset(&probe_req_frame_5g[cur_len_5g], 0xFF, 6);
- cur_len_5g += 6;
- memcpy(&probe_req_frame_5g[cur_len_5g], mac_addr, 6);
- cur_len_5g += 6;
- // BSSID (broadcast)
- memset(&probe_req_frame_5g[cur_len_5g], 0xFF, 6);
- cur_len_5g += 6;
- // Sequence Control
- probe_req_frame_5g[cur_len_5g++] = 0x00;
- probe_req_frame_5g[cur_len_5g++] = 0x00;
- // SSID
- probe_req_frame_5g[cur_len_5g++] = 0x00; // Element ID: SSID
- probe_req_frame_5g[cur_len_5g++] = 0x00; // Length: 0 (Broadcast)
- // Supported Rates (5G基本速率)
- probe_req_frame_5g[cur_len_5g++] = 0x01; // Element ID: Supported Rates
- probe_req_frame_5g[cur_len_5g++] = 0x08; // Length
- probe_req_frame_5g[cur_len_5g++] = 0x0C; // 6 Mbps
- probe_req_frame_5g[cur_len_5g++] = 0x18; // 9 Mbps
- probe_req_frame_5g[cur_len_5g++] = 0x30; // 12 Mbps
- probe_req_frame_5g[cur_len_5g++] = 0x60; // 18 Mbps
- probe_req_frame_5g[cur_len_5g++] = 0x6c; // 24 Mbps
- probe_req_frame_5g[cur_len_5g++] = 0x12; // 36 Mbps
- probe_req_frame_5g[cur_len_5g++] = 0x24; // 48 Mbps
- probe_req_frame_5g[cur_len_5g++] = 0x48; // 54 Mbps
- int total_len_5g = cur_len_5g;
- while (1) {
- // 2.4G 信道1发送
- ESP_ERROR_CHECK(esp_wifi_set_channel(SCAN_CHANNEL_1, WIFI_SECOND_CHAN_NONE));
- vTaskDelay(pdMS_TO_TICKS(20));
- for (int i = 0; i < PROBE_COUNT; i++) {
- esp_err_t err = esp_wifi_80211_tx(WIFI_IF_STA, probe_req_frame_2g, total_len_2g, false);
- if (err == ESP_OK) {
- ESP_LOGI(TAG, "Successfully sent 2.4G probe request %d/%d on channel 1", i + 1, PROBE_COUNT);
- }
- vTaskDelay(pdMS_TO_TICKS(100));
- }
- // 5G 信道36发送
- ESP_ERROR_CHECK(esp_wifi_set_channel(SCAN_CHANNEL_36, WIFI_SECOND_CHAN_NONE));
- vTaskDelay(pdMS_TO_TICKS(20));
- uint8_t primary;
- wifi_second_chan_t second;
- ESP_ERROR_CHECK(esp_wifi_get_channel(&primary, &second));
- ESP_LOGI(TAG, "Current channel: primary=%d, secondary=%d", primary, second);
- for (int i = 0; i < PROBE_COUNT; i++) {
- esp_err_t err = esp_wifi_80211_tx(WIFI_IF_STA, probe_req_frame_5g, total_len_5g, false);
- if (err == ESP_OK) {
- ESP_LOGI(TAG, "Successfully sent 5G probe request %d/%d on channel 36", i + 1, PROBE_COUNT);
- }
- vTaskDelay(pdMS_TO_TICKS(100));
- }
- // ... 其他信道的发送逻辑类似 ...
- vTaskDelay(pdMS_TO_TICKS(SCAN_INTERVAL_MS));
- }
- }
- static void wifi_init_sta(void)
- {
- ESP_ERROR_CHECK(esp_netif_init());
- ESP_ERROR_CHECK(esp_event_loop_create_default());
- esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
- assert(sta_netif);
- wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
- ESP_ERROR_CHECK(esp_wifi_init(&cfg));
- // 简化 WiFi 配置
- wifi_config_t wifi_config = {
- .sta = {
- .scan_method = WIFI_FAST_SCAN,
- .bssid_set = 0,
- .listen_interval = 0,
- },
- };
- ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
- // 设置 WiFi 模式并启动
- ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
- ESP_ERROR_CHECK(esp_wifi_start());
- // 禁用省电模式
- ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
- // 确保监控模式正确设置
- wifi_promiscuous_filter_t filter = {
- .filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT // 只过滤管理帧
- };
- ESP_ERROR_CHECK(esp_wifi_set_promiscuous_filter(&filter));
- ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // 启用混杂模式
- // 设置发送功率
- int8_t power = 8; // 设置适中的发送功率
- ESP_ERROR_CHECK(esp_wifi_set_max_tx_power(power));
- // // 确保在信道 1
- // ESP_ERROR_CHECK(esp_wifi_set_channel(SCAN_CHANNEL_1, WIFI_SECOND_CHAN_NONE));
- // 查看当前WiFi频段模式
- wifi_band_mode_t mode;
- ESP_ERROR_CHECK(esp_wifi_get_band_mode(&mode));
- ESP_LOGI(TAG, "Current WiFi band mode: %d", mode);
- // 如果需要指定频段,可以这样设置:
- // ESP_ERROR_CHECK(esp_wifi_set_band_mode(WIFI_BAND_MODE_2G)); // 仅2.4G
- // ESP_ERROR_CHECK(esp_wifi_set_band_mode(WIFI_BAND_MODE_5G)); // 仅5G
- // ESP_ERROR_CHECK(esp_wifi_set_band_mode(WIFI_BAND_MODE_AUTO)); // 自动(默认)
- // 创建发送任务
- xTaskCreate(send_probe_req_task, "probe_req_task", 4096, NULL, 5, NULL);
- }
- void app_main(void)
- {
- //Initialize NVS
- esp_err_t ret = nvs_flash_init();
- if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
- ESP_ERROR_CHECK(nvs_flash_erase());
- ret = nvs_flash_init();
- }
- ESP_ERROR_CHECK(ret);
- ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
- wifi_init_sta();
- }
如上是程序源代码,其中2G的报文能够正常抓取到,5G的报文无法正常抓取。5G的probe request报文是根据芯片自身扫描行为发送的报文构造的相同报文。
ESP-IDF版本为v5.4.0