Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
esp32 promiscuous mode and packet injection experiments
// Espressif ESP32 promiscuous mode and packet injection experiments
// by brainstorm at nopcode org
#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_wifi_internal.h"
#include "lwip/err.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
uint8_t HEX_COLSIZE = 7;
esp_err_t event_handler(void *ctx, system_event_t *event)
return ESP_OK;
void process_promisc(void* buf, uint16_t len)
char* buflen = (char*) buf + len;
uint8_t hexdump_cols = 0;
uint8_t offset = 0;
// RAW packet
for (char* ptr = buf; ptr < buflen; ptr++) printf("%c", *ptr);
// Hexdump (wireshark-friendly)
for (char* ptr = buf; ptr < buflen; ptr+=HEX_COLSIZE) {
// print offset
printf(" %06X ", offset);
for (hexdump_cols=0; hexdump_cols < HEX_COLSIZE; hexdump_cols++)
printf(" %02X", *(ptr+hexdump_cols*sizeof(char)));
offset = offset + HEX_COLSIZE;
void send_packet(esp_interface_t iface, void* buf, uint8_t len)
printf("Sending actual packet via driver...\n");
switch(esp_wifi_internal_tx(iface, buf, len))
case ERR_OK:
printf("Packet in the air!\n");
case ERR_IF:
printf("WiFi driver error\n");
printf("Some other error I don't want to control now\n");
void app_main(void)
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_interface_t wifi_if;
void* wifi_eth = NULL;
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
printf("Setting up wifi\n");
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
//printf("Promiscuous mode callback\n");
ESP_ERROR_CHECK( esp_wifi_start() );
// Borrowed from the original esp8266 injection example:
uint8_t packet[128] = { 0x80, 0x00, 0x00, 0x00,
/*4*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/*10*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
/*16*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
/*22*/ 0xc0, 0x6c,
/*24*/ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00,
/*32*/ 0x64, 0x00,
/*34*/ 0x01, 0x04,
/* SSID */
/*36*/ 0x00, 0x06, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
0x01, 0x08, 0x82, 0x84,
0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01,
/*56*/ 0x04};
wifi_if = tcpip_adapter_get_esp_if(wifi_eth);
printf("About to send packets every 200ms\n");
send_packet(wifi_if, (void*)packet, sizeof(packet));
vTaskDelay(200 / portTICK_RATE_MS);
Copy link

nissimzur commented Apr 15, 2017

Hi brainstorm,
Can I hire you to small work on esp32 promiscuous?
Please email me to or call my Skype nissim.text
Thank you

Copy link

dsiganos commented Jun 17, 2017

It appears that Espressif will be imminently releasing a feature to inject 802.11 data frames (but not management frames):

It is probably the function esp_wifi_80211_tx() introduced by this commit:

Copy link

Staubgeborener commented Jun 24, 2017

Another approach is to get the whole frame by casting the buffer and greb the playload with casted_buffer->payload. Also the length is in sig_len (see With this variant, i'll also get nearly all of the packets. Though i also have the same problem with malformed packets.

a possibility could be:

// get length of packet
 for (i = 0; i < casted_buffer->rx_ctrl.sig_len; i++) {
// print payload
printf(" %02X", casted_buffer->payload[i]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment