Created
February 14, 2018 15:56
-
-
Save Ynn/35e1e3145b23958a84880be51b094cec to your computer and use it in GitHub Desktop.
esp8266 : sniff, send in udp, then sniff another channel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Arduino.h> | |
#ifdef ESP8266 | |
extern "C" { | |
#include "user_interface.h" //to gain access to promiscuous mode | |
} | |
#endif | |
#include <ESP8266WiFi.h> | |
#include <WiFiClient.h> | |
#include <WiFiUdp.h> | |
#define DATA_LENGTH 112 | |
#define TYPE_MANAGEMENT 0x00 | |
#define TYPE_CONTROL 0x01 | |
#define TYPE_DATA 0x02 | |
#define SUBTYPE_ASSOC_REQUEST 0x00 | |
#define SUBTYPE_ASSOC_RESP 0x01 | |
#define SUBTYPE_REASSOC 0x02 | |
#define SUBTYPE_REASSOC_RESP 0x03 | |
#define SUBTYPE_PROBE_REQUEST 0x04 | |
#define SUBTYPE_PROBE_RESPONSE 0x05 | |
#define SUBTYPE_BEACON 0x08 | |
#define SUBTYPE_ATIM 0x09 | |
#define SUBTYPE_DISAC 0x0A | |
#define SUBTYPE_AUTH 0x0B | |
#define SUBTYPE_DEAUTH 0x0C | |
#define DISABLE 0 | |
#define ENABLE 1 | |
#include <set> | |
#define WIFI_SSID "" //SSID must not be hidden by the AP! | |
#define WIFI_PASSWORD "" //actually not necessary for clock sync | |
IPAddress ip(172, 24, 1, 91); | |
int port = 8888; | |
std::set<std::string> macs; | |
struct RxControl { | |
signed rssi: 8; | |
unsigned rate: 4; | |
unsigned is_group: 1; | |
unsigned: 1; | |
unsigned sig_mode: 2; | |
unsigned legacy_length: 12; | |
unsigned damatch0: 1; | |
unsigned damatch1: 1; | |
unsigned bssidmatch0: 1; | |
unsigned bssidmatch1: 1; | |
unsigned MCS: 7; | |
unsigned CWB: 1; | |
unsigned HT_length: 16; | |
unsigned Smoothing: 1; | |
unsigned Not_Sounding: 1; | |
unsigned: 1; | |
unsigned Aggregation: 1; | |
unsigned STBC: 2; | |
unsigned FEC_CODING: 1; | |
unsigned SGI: 1; | |
unsigned rxend_state: 8; | |
unsigned ampdu_cnt: 8; | |
unsigned channel: 4; | |
unsigned: 12; | |
}; | |
struct SnifferPacket { | |
struct RxControl rx_ctrl; | |
uint8_t data[112]; | |
uint16_t cnt; | |
uint16_t len; | |
}; | |
WiFiUDP Udp; | |
static void getMAC(char *addr, uint8_t* data, uint16_t offset) { | |
sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", data[offset+0], data[offset+1], data[offset+2], data[offset+3], data[offset+4], data[offset+5]); | |
} | |
static void showMetadata(SnifferPacket *snifferPacket) { | |
unsigned int frameControl = ((unsigned int)snifferPacket->data[1] << 8) + snifferPacket->data[0]; | |
uint8_t version = (frameControl & 0b0000000000000011) >> 0; | |
uint8_t frameType = (frameControl & 0b0000000000001100) >> 2; | |
uint8_t frameSubType = (frameControl & 0b0000000011110000) >> 4; | |
uint8_t toDS = (frameControl & 0b0000000100000000) >> 8; | |
uint8_t fromDS = (frameControl & 0b0000001000000000) >> 9; | |
//Only look for non beacon packets | |
// if (frameType == TYPE_MANAGEMENT && frameSubType == SUBTYPE_BEACON) | |
// return; | |
switch (frameType) { | |
case TYPE_MANAGEMENT: Serial.print("[M]"); | |
switch(frameSubType){ | |
case SUBTYPE_PROBE_REQUEST : Serial.print("[PROBE]"); break; | |
case SUBTYPE_BEACON: Serial.print("[BEACON]"); break; | |
case SUBTYPE_ASSOC_REQUEST : Serial.print("[<ASSOC]"); break; | |
case SUBTYPE_ASSOC_RESP : Serial.print("[>ASSOC]"); break; | |
case SUBTYPE_AUTH : Serial.print("[>AUTH]"); break; | |
case SUBTYPE_DEAUTH : Serial.print("[<AUTH]"); break; | |
} | |
break; | |
case TYPE_CONTROL : Serial.print("[C]"); break; | |
case TYPE_DATA : Serial.print("[D]"); break; | |
} | |
Serial.printf("[%02x]",frameType,frameSubType); | |
Serial.print("RSSI: "); | |
Serial.print(snifferPacket->rx_ctrl.rssi, DEC); | |
Serial.print(" Ch: "); | |
Serial.print(wifi_get_channel()); | |
char addr[] = "00:00:00:00:00:00"; | |
getMAC(addr, snifferPacket->data, 10); | |
Serial.print(" Peer MAC: "); | |
Serial.print(addr); | |
macs.insert(addr); | |
// uint8_t SSID_length = snifferPacket->data[25]; | |
// Serial.print(" SSID: "); | |
// printDataSpan(26, SSID_length, snifferPacket->data); | |
Serial.println(); | |
} | |
void setup() { | |
Serial.begin(115200); | |
} | |
/** | |
* Callback for promiscuous mode | |
*/ | |
static void ICACHE_FLASH_ATTR sniffer_callback(uint8_t *buffer, uint16_t length) { | |
struct SnifferPacket *snifferPacket = (struct SnifferPacket*) buffer; | |
showMetadata(snifferPacket); | |
} | |
void loop() { | |
int channel = 1; | |
Serial.print("start sniffing channel :");Serial.println(channel); | |
wifi_set_opmode(STATION_MODE);delay(10); | |
wifi_set_channel(channel);delay(10); | |
wifi_promiscuous_enable(0);delay(10); | |
wifi_set_promiscuous_rx_cb(sniffer_callback);delay(10); | |
wifi_promiscuous_enable(1);delay(10); | |
delay(5000); | |
Serial.println("stop sniffing"); | |
wifi_promiscuous_enable(0); | |
wifi_set_promiscuous_rx_cb(0); | |
wifi_promiscuous_enable(1); | |
wifi_promiscuous_enable(0); | |
delay(500); | |
Serial.println("Set AP"); | |
WiFi.mode(WIFI_STA); | |
WiFi.begin(WIFI_SSID, WIFI_PASSWORD); | |
// Wait for connection | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.print("Connected to "); | |
Serial.println(WIFI_SSID); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
for(auto mac : macs){ | |
mac = mac+"\n"; | |
Serial.println("Send packet"); | |
Udp.beginPacket(ip, port); | |
Udp.write(mac.c_str()); | |
Udp.endPacket(); | |
} | |
delay(3000); | |
channel++; | |
if(channel == 14){ | |
channel = 1; | |
} | |
macs.clear(); | |
} |
Improve channel scanning :
#include <Arduino.h>
#ifdef ESP8266
extern "C" {
#include "user_interface.h" //to gain access to promiscuous mode
}
#endif
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
#define DATA_LENGTH 112
#define TYPE_MANAGEMENT 0x00
#define TYPE_CONTROL 0x01
#define TYPE_DATA 0x02
#define SUBTYPE_ASSOC_REQUEST 0x00
#define SUBTYPE_ASSOC_RESP 0x01
#define SUBTYPE_REASSOC 0x02
#define SUBTYPE_REASSOC_RESP 0x03
#define SUBTYPE_PROBE_REQUEST 0x04
#define SUBTYPE_PROBE_RESPONSE 0x05
#define SUBTYPE_BEACON 0x08
#define SUBTYPE_ATIM 0x09
#define SUBTYPE_DISAC 0x0A
#define SUBTYPE_AUTH 0x0B
#define SUBTYPE_DEAUTH 0x0C
#define DISABLE 0
#define ENABLE 1
#include <set>
#define WIFI_SSID "a3G" //SSID must not be hidden by the AP!
#define WIFI_PASSWORD "cee" //actually not necessary for clock sync
#define mqtt_server "m23.cloudmqtt.com"
#define mqtt_user "nxkhl"
#define mqtt_password "Pda2uKd"
#define mqtt_port 1235
//UDP
IPAddress ip(172, 24, 1, 91);
int port = 8888;
//MQTT
WiFiClient espClient;
PubSubClient client(espClient);
std::set<std::string> macs;
struct RxControl {
signed rssi: 8;
unsigned rate: 4;
unsigned is_group: 1;
unsigned: 1;
unsigned sig_mode: 2;
unsigned legacy_length: 12;
unsigned damatch0: 1;
unsigned damatch1: 1;
unsigned bssidmatch0: 1;
unsigned bssidmatch1: 1;
unsigned MCS: 7;
unsigned CWB: 1;
unsigned HT_length: 16;
unsigned Smoothing: 1;
unsigned Not_Sounding: 1;
unsigned: 1;
unsigned Aggregation: 1;
unsigned STBC: 2;
unsigned FEC_CODING: 1;
unsigned SGI: 1;
unsigned rxend_state: 8;
unsigned ampdu_cnt: 8;
unsigned channel: 4;
unsigned: 12;
};
struct SnifferPacket {
struct RxControl rx_ctrl;
uint8_t data[112];
uint16_t cnt;
uint16_t len;
};
WiFiUDP Udp;
static void getMAC(char *addr, uint8_t* data, uint16_t offset) {
sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", data[offset+0], data[offset+1], data[offset+2], data[offset+3], data[offset+4], data[offset+5]);
}
static void showMetadata(SnifferPacket *snifferPacket) {
unsigned int frameControl = ((unsigned int)snifferPacket->data[1] << 8) + snifferPacket->data[0];
uint8_t version = (frameControl & 0b0000000000000011) >> 0;
uint8_t frameType = (frameControl & 0b0000000000001100) >> 2;
uint8_t frameSubType = (frameControl & 0b0000000011110000) >> 4;
uint8_t toDS = (frameControl & 0b0000000100000000) >> 8;
uint8_t fromDS = (frameControl & 0b0000001000000000) >> 9;
//Only look for non beacon packets
if (frameType == TYPE_MANAGEMENT && frameSubType == SUBTYPE_BEACON)
return;
switch (frameType) {
case TYPE_MANAGEMENT: Serial.print("[M]");
switch(frameSubType){
case SUBTYPE_PROBE_REQUEST : Serial.print("[PROBE]"); break;
case SUBTYPE_BEACON: Serial.print("[BEACON]"); break;
case SUBTYPE_ASSOC_REQUEST : Serial.print("[<ASSOC]"); break;
case SUBTYPE_ASSOC_RESP : Serial.print("[>ASSOC]"); break;
case SUBTYPE_AUTH : Serial.print("[>AUTH]"); break;
case SUBTYPE_DEAUTH : Serial.print("[<AUTH]"); break;
}
break;
case TYPE_CONTROL : Serial.print("[C]"); break;
case TYPE_DATA : Serial.print("[D]"); break;
}
Serial.printf("[%02x]",frameType,frameSubType);
Serial.print("RSSI: ");
Serial.print(snifferPacket->rx_ctrl.rssi, DEC);
Serial.print(" Ch: ");
Serial.print(wifi_get_channel());
char addr[] = "00:00:00:00:00:00";
getMAC(addr, snifferPacket->data, 10);
Serial.print(" Peer MAC: ");
Serial.print(addr);
macs.insert(addr);
// uint8_t SSID_length = snifferPacket->data[25];
// Serial.print(" SSID: ");
// printDataSpan(26, SSID_length, snifferPacket->data);
Serial.println();
}
void setup() {
Serial.begin(115200);
client.setServer(mqtt_server, mqtt_port);
}
/**
* Callback for promiscuous mode
*/
static void ICACHE_FLASH_ATTR sniffer_callback(uint8_t *buffer, uint16_t length) {
struct SnifferPacket *snifferPacket = (struct SnifferPacket*) buffer;
showMetadata(snifferPacket);
}
void sendMQTT() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str(), mqtt_user, mqtt_password)) {
Serial.println("connected");
//SEND UDP
for(auto mac : macs){
mac = mac+"\n";
Serial.print("Send mqtt >");Serial.print(mac.c_str());
client.publish("mac", mac.c_str());
delay(100);
}
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 1 seconds");
// Wait 5 seconds before retrying
delay(1000);
}
}
}
void loop() {
int channel = 1;
Serial.print("start sniffing channel :");Serial.println(channel);
wifi_set_opmode(STATION_MODE);delay(10);
wifi_set_channel(channel);delay(10);
wifi_promiscuous_enable(0);delay(10);
wifi_set_promiscuous_rx_cb(sniffer_callback);delay(10);
wifi_promiscuous_enable(1);delay(10);
for (size_t i = 1; i < 14; i++) {
wifi_set_channel(channel++);delay(10);
Serial.print("start sniffing channel :");Serial.println(channel);
delay(1000);
}
Serial.println("stop sniffing");
wifi_promiscuous_enable(0);
wifi_set_promiscuous_rx_cb(0);
wifi_promiscuous_enable(1);
wifi_promiscuous_enable(0);
delay(500);
Serial.println("Set AP");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(WIFI_SSID);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
sendMQTT();
//SEND UDP
for(auto mac : macs){
mac = mac+"\n";
Serial.print("Send udp >");Serial.print(mac.c_str());
Udp.beginPacket(ip, port);
Udp.write(mac.c_str());
Udp.endPacket();
delay(100);
}
macs.clear();
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Same with MQTT support. You have to adjust scanning times in the loop.