具体的东西有网文可以查看。这个东西网上已经出来比较久了,今天只是偶然看到,代码总体比较简单。
ESP32实现设备的MAC地址获取,输出到串口。使用其它设备(PC或另一块ESP32)来处理获取到的信息,比如MAC对应的公司或人。当然,也可以加个TF卡,白天扫,晚上来处理数据。
据说苹果是随机MAC的,这个对它不产生作用。不过苹果的用户量不小。
感觉可以用在判断家人是否回家:当他的手机MAC出现时,表示已来到搜索范围。
#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_wifi_types.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
//RSSI: -30~-120
#define LED_GPIO_PIN 2
#define WIFI_CHANNEL_SWITCH_INTERVAL (500)
#define WIFI_CHANNEL_MAX (13)
uint8_t level = 0, channel = 1;
static wifi_country_t wifi_country = {.cc="CN", .schan = 1, .nchan = 13}; //Most recent esp32 library struct
typedef struct {
unsigned frame_ctrl:16;
unsigned duration_id:16;
uint8_t addr1[6]; /* receiver address */
uint8_t addr2[6]; /* sender address */
uint8_t addr3[6]; /* filtering address */
unsigned sequence_ctrl:16;
uint8_t addr4[6]; /* optional */
} wifi_ieee80211_mac_hdr_t;
typedef struct {
wifi_ieee80211_mac_hdr_t hdr;
uint8_t payload[0]; /* network data ended with 4 bytes csum (CRC32) */
} wifi_ieee80211_packet_t;
static esp_err_t event_handler(void *ctx, system_event_t *event);
static void wifi_sniffer_init(void);
static void wifi_sniffer_set_channel(uint8_t channel);
static const char *wifi_sniffer_packet_type2str(wifi_promiscuous_pkt_type_t type);
static void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type);
esp_err_t event_handler(void *ctx, system_event_t *event)
{
return ESP_OK;
}
void wifi_sniffer_init(void) {
nvs_flash_init();
tcpip_adapter_init();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_country(&wifi_country) ); /* set country for channel range [1, 13] */
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) );
ESP_ERROR_CHECK( esp_wifi_start() );
esp_wifi_set_promiscuous(true);
esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler);
}
void wifi_sniffer_set_channel(uint8_t channel) {
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
}
const char * wifi_sniffer_packet_type2str(wifi_promiscuous_pkt_type_t type) {
switch(type) {
case WIFI_PKT_MGMT: return "MGMT";
case WIFI_PKT_DATA: return "DATA";
default:
case WIFI_PKT_MISC: return "MISC";
}
}
void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type) {
if (type != WIFI_PKT_MGMT)
return;
const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload;
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
printf("PACKET TYPE=%s, CHAN=%02d, RSSI=%02d,"
" ADDR1=%02x:%02x:%02x:%02x:%02x:%02x,"
" ADDR2=%02x:%02x:%02x:%02x:%02x:%02x,"
" ADDR3=%02x:%02x:%02x:%02x:%02x:%02x\n",
wifi_sniffer_packet_type2str(type),
ppkt->rx_ctrl.channel,
ppkt->rx_ctrl.rssi,
/* ADDR1 */
hdr->addr1[0],hdr->addr1[1],hdr->addr1[2],
hdr->addr1[3],hdr->addr1[4],hdr->addr1[5],
/* ADDR2 */
hdr->addr2[0],hdr->addr2[1],hdr->addr2[2],
hdr->addr2[3],hdr->addr2[4],hdr->addr2[5],
/* ADDR3 */
hdr->addr3[0],hdr->addr3[1],hdr->addr3[2],
hdr->addr3[3],hdr->addr3[4],hdr->addr3[5]
);
}
void setup() {
Serial.begin(115200); delay(10);
wifi_sniffer_init();
pinMode(LED_GPIO_PIN, OUTPUT);
}
void loop() {
delay(1000); // wait for a second
if (digitalRead(LED_GPIO_PIN) == LOW)
digitalWrite(LED_GPIO_PIN, HIGH);
else
digitalWrite(LED_GPIO_PIN, LOW);
vTaskDelay(WIFI_CHANNEL_SWITCH_INTERVAL / portTICK_PERIOD_MS); //告诉操作系统,现在无任务在做,请告诉kernel将时间分配给其他任务,并在某个时间点将该任务唤醒
wifi_sniffer_set_channel(channel);
channel = (channel % WIFI_CHANNEL_MAX) + 1;
}
2020.9.26
将其升级了一下:一会儿收集MAC,一会儿发送收集到的MAC给服务器。 :)
EPS32自带的存储有限,所以必须存一些就发给服务器。若扩展了TF卡存储,那就能带身上出去玩了…
放阳台上一个小时,收集到323个MAC。
Shenzhen Pulier Tech CO.,Ltd 深圳水星通信技术公司
这是小区的安全产品?23个
SICHUAN TIANYI COMHEART TELECOMCO 四川天邑康和通信股份有限公司
这是什么?8个
最多的就是 Tp-Link 设备了。华为和小米也有一点。
为什么不有发现我的手机?时机不对?