Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * PROJECT: WATCHTOWER v10 (STABLE)
- * SUBJECT: ASYNC LOGGING & STICKY LOCK
- * FIX: Prevents Serial Overflow crashes during high-volume attacks.
- */
- #include <ESP8266WiFi.h>
- // --- Configuration ---
- #define LED_PIN 2
- #define SERIAL_BAUD 115200
- #define LOCK_TIMEOUT 5000 // Stay on channel for 5s after last packet
- // --- Globals ---
- unsigned long lastHopTime = 0;
- unsigned long lockTimer = 0;
- unsigned long lastLedToggle = 0;
- int currentChannel = 1;
- // --- State Flags ---
- volatile bool hasNewThreat = false; // Flag to tell Loop to print
- volatile int threatRSSI = 0;
- volatile int threatChannel = 0;
- volatile bool isDeauth = false;
- volatile bool isBeacon = false;
- String threatSrc = ""; // String isn't volatile-safe usually, but we manage via flag
- String threatDst = "";
- String threatSSID = "";
- // --- Hardware Structs ---
- struct RxControl {
- signed char rssi;
- unsigned char rate;
- unsigned int legacy_length:12;
- unsigned int damatch0:1;
- unsigned int damatch1:1;
- unsigned int bssidmatch0:1;
- unsigned int bssidmatch1:1;
- unsigned int MCS:7;
- unsigned int CWB:1;
- unsigned int HT_length:16;
- unsigned int Smoothing:1;
- unsigned int Not_Sounding:1;
- unsigned int Aggregation:1;
- unsigned int STBC:2;
- unsigned int FEC_CODING:1;
- unsigned int SGI:1;
- unsigned int rxend_state:8;
- unsigned int ampdu_cnt:8;
- unsigned int channel:4;
- unsigned int :12;
- };
- struct SnifferPacket {
- struct RxControl rx_ctrl;
- uint8_t data[128];
- uint16_t cnt;
- uint16_t len;
- };
- // Helper to format MAC safely
- String formatMac(uint8_t* mac) {
- char buf[18];
- snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
- return String(buf);
- }
- // --- Sniffer Callback (INTERRUPT CONTEXT - KEEP FAST) ---
- void sniffer(uint8_t *buf, uint16_t len) {
- struct SnifferPacket *snifferPacket = (struct SnifferPacket*) buf;
- uint8_t frame_control = snifferPacket->data[0];
- // Filter: Deauth (0xC0), Disassoc (0xA0), Beacon (0x80)
- bool d = (frame_control == 0xC0 || frame_control == 0xA0);
- bool b = (frame_control == 0x80);
- if (!d && !b) return; // Ignore everything else
- // RSSI Filter (Ignore weak noise)
- int rssi = snifferPacket->rx_ctrl.rssi;
- if (rssi < -85) return;
- // --- LOGIC: Only process Beacons if they look like SPAM (optional check) ---
- // For now, we capture them to show output as requested.
- // Update Global Shared Variables (If loop has finished printing previous)
- if (!hasNewThreat) {
- threatRSSI = rssi;
- threatChannel = currentChannel; // Use global current channel
- isDeauth = d;
- isBeacon = b;
- // Extract MACs
- // 802.11 Header: [FC][Dur][Dst][Src]
- threatDst = formatMac(&snifferPacket->data[4]);
- threatSrc = formatMac(&snifferPacket->data[10]);
- // Extract SSID if Beacon
- if (b && len > 38) {
- int pos = 36;
- uint8_t tag_id = snifferPacket->data[pos];
- uint8_t tag_len = snifferPacket->data[pos+1];
- if (tag_id == 0 && pos + tag_len + 2 < len) {
- if (tag_len > 32) tag_len = 32;
- char ssidBuf[33];
- memset(ssidBuf, 0, 33);
- memcpy(ssidBuf, &snifferPacket->data[pos+2], tag_len);
- threatSSID = String(ssidBuf);
- } else {
- threatSSID = "";
- }
- } else {
- threatSSID = "";
- }
- // Set Flag
- hasNewThreat = true;
- }
- }
- void setup() {
- Serial.begin(SERIAL_BAUD);
- pinMode(LED_PIN, OUTPUT);
- digitalWrite(LED_PIN, HIGH);
- WiFi.mode(WIFI_STA);
- WiFi.disconnect();
- Serial.println("\n--- WATCHTOWER v10 STABLE ---");
- Serial.println("Mode: Async Logging (No Crashes)");
- Serial.println("Lock: 5 Seconds per detection");
- wifi_set_opmode(STATION_MODE);
- wifi_set_promiscuous_rx_cb(sniffer);
- wifi_promiscuous_enable(1);
- }
- void loop() {
- unsigned long currentMillis = millis();
- // --- 1. PRINTING ENGINE (Main Loop Context) ---
- if (hasNewThreat) {
- // Extend Lock Timer
- lockTimer = currentMillis + LOCK_TIMEOUT;
- // Visual Strobe (Toggle LED)
- digitalWrite(LED_PIN, !digitalRead(LED_PIN));
- // Print Data
- if (isDeauth) {
- Serial.print(">>> DEAUTH | CH:");
- Serial.print(threatChannel);
- Serial.print(" | RSSI:");
- Serial.print(threatRSSI);
- Serial.print(" | SRC: ");
- Serial.println(threatSrc);
- }
- else if (isBeacon) {
- // Only print if it looks suspicious (simple noise filter)
- // or print all if you want to see the spam flow
- Serial.print("--- BEACON | CH:");
- Serial.print(threatChannel);
- Serial.print(" | RSSI:");
- Serial.print(threatRSSI);
- Serial.print(" | SSID: ");
- Serial.println(threatSSID);
- }
- // Clear Flag (Ready for next packet)
- hasNewThreat = false;
- }
- // --- 2. LED MANAGEMENT ---
- // If locked, we rely on the packet arrival to toggle the LED (above).
- // If idle (no packets for > 5s), we do the slow heartbeat.
- if (currentMillis > lockTimer) {
- // Idle Mode
- if (currentMillis - lastLedToggle > 2000) {
- lastLedToggle = currentMillis;
- digitalWrite(LED_PIN, LOW); // Blink
- delay(20);
- digitalWrite(LED_PIN, HIGH);
- }
- }
- // --- 3. CHANNEL HOPPING ---
- // CRITICAL: Do NOT hop if locked
- if (currentMillis > lockTimer) {
- if (currentMillis - lastHopTime > 200) {
- lastHopTime = currentMillis;
- currentChannel++;
- if (currentChannel > 14) currentChannel = 1;
- wifi_set_channel(currentChannel);
- }
- }
- }
Advertisement