Page 1 of 1

请问ESP32-C5手动构造发送5G的Probe request报文,实际无法抓到对应报文

Posted: Tue Jan 07, 2025 2:03 am
by JialingChen

Code: Untitled.c Select all


/* 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