-
-
Notifications
You must be signed in to change notification settings - Fork 112
/
main.c
132 lines (111 loc) · 3.5 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* Copyright (c) 2017, Łukasz Marcin Podkalicki <lpodkalicki@gmail.com>
* ESP32/016
* WiFi Sniffer.
*/
#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"
#define LED_GPIO_PIN GPIO_NUM_4
#define WIFI_CHANNEL_MAX (13)
#define WIFI_CHANNEL_SWITCH_INTERVAL (500)
static wifi_country_t wifi_country = {.cc="CN", .schan=1, .nchan=13, .policy=WIFI_COUNTRY_POLICY_AUTO};
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);
void
app_main(void)
{
uint8_t level = 0, channel = 1;
/* setup */
wifi_sniffer_init();
gpio_set_direction(LED_GPIO_PIN, GPIO_MODE_OUTPUT);
/* loop */
while (true) {
gpio_set_level(LED_GPIO_PIN, level ^= 1);
vTaskDelay(WIFI_CHANNEL_SWITCH_INTERVAL / portTICK_PERIOD_MS);
wifi_sniffer_set_channel(channel);
channel = (channel % WIFI_CHANNEL_MAX) + 1;
}
}
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]
);
}