firmware&dashboard changes
This commit is contained in:
@@ -28,12 +28,12 @@ This is a learning/research project covering distributed systems, event-driven a
|
||||
|
||||
### Active nodes
|
||||
|
||||
| node_id | MAC | Location / Port |
|
||||
|----------|-------------------|------------------------|
|
||||
| F68D6E30 | 44:1b:f6:8d:6e:30 | desk /dev/ttyACM0 |
|
||||
| A1D658D4 | e0:72:a1:d6:58:d4 | desk /dev/ttyACM1 |
|
||||
| A1D700C4 | e0:72:a1:d7:00:c4 | desk /dev/ttyACM2 |
|
||||
| A1D6F190 | e0:72:a1:d6:f1:90 | deployed (another room)|
|
||||
| node_id | MAC | Location |
|
||||
|----------|-------------------|-------------------------|
|
||||
| F68D6E30 | 44:1b:f6:8d:6e:30 | room 1 (permanent) |
|
||||
| A1D658D4 | e0:72:a1:d6:58:d4 | room 2 (permanent) |
|
||||
| A1D700C4 | e0:72:a1:d7:00:c4 | dev machine /dev/ttyACM2|
|
||||
| A1D6F190 | e0:72:a1:d6:f1:90 | dev machine /dev/ttyACM1|
|
||||
|
||||
---
|
||||
|
||||
@@ -124,10 +124,15 @@ esp32_cluster/
|
||||
Each node:
|
||||
- Connects to WiFi `sandbox`
|
||||
- Scans for nearby APs every 15 seconds (active scan, includes hidden SSIDs)
|
||||
- Hops across all 13 2.4 GHz channels (300ms dwell per channel) while sniffing
|
||||
- Captures probe request frames passively (promiscuous mode) between scans
|
||||
- Sends a heartbeat packet every 10 seconds (uptime, free heap, WiFi RSSI to router)
|
||||
- Sends beacon, probe, and heartbeat events as UDP JSON packets to the coordinator
|
||||
- Captures deauth and disassoc frames (0xC0 / 0xA0)
|
||||
- Captures association and reassociation request frames (0x00 / 0x20) with SSID IE parsing
|
||||
- Sends a heartbeat packet every 10 seconds (uptime, free heap, WiFi RSSI to router, queue drop counters)
|
||||
- Sends all events as UDP JSON packets to the coordinator
|
||||
- `node_id` is derived from bytes 2–5 of the ESP32's base MAC address
|
||||
- Events are buffered in FreeRTOS queues and flushed once per scan cycle when back on the home channel
|
||||
- If a deauth with reason code 2 is seen at RSSI ≥ -60 dBm, an alert flag triggers an immediate flush on the home channel without waiting for the next scan
|
||||
|
||||
### Event formats
|
||||
|
||||
@@ -179,17 +184,37 @@ Each node:
|
||||
- `reason` is the 802.11 reason code (7 = class 3 frame received from non-associated station, common in attack tools)
|
||||
- Captured passively in the same promiscuous callback as probe requests, flushed to coordinator after each scan cycle
|
||||
|
||||
**Assoc / Reassoc event** (client joining a network):
|
||||
```json
|
||||
{
|
||||
"node_id": "F68D6E30",
|
||||
"ts": 12345,
|
||||
"type": "assoc",
|
||||
"src": "AA:BB:CC:DD:EE:FF",
|
||||
"bssid": "11:22:33:44:55:66",
|
||||
"ssid": "NetworkName",
|
||||
"rssi": -55
|
||||
}
|
||||
```
|
||||
- `type` is `assoc` (0x00) or `reassoc` (0x20)
|
||||
- SSID is parsed from the first Information Element in the frame body (IE tag 0x00)
|
||||
- Captures real client→AP join events, not just passive probe searches
|
||||
|
||||
**Heartbeat event** (node health, sent every 10 seconds):
|
||||
```json
|
||||
{
|
||||
"node_id": "F68D6E30",
|
||||
"ts": 12345,
|
||||
"type": "heartbeat",
|
||||
"uptime_ms": 123456,
|
||||
"free_heap": 245000,
|
||||
"wifi_rssi": -62
|
||||
"node_id": "F68D6E30",
|
||||
"ts": 12345,
|
||||
"type": "heartbeat",
|
||||
"uptime_ms": 123456,
|
||||
"free_heap": 245000,
|
||||
"wifi_rssi": -62,
|
||||
"probe_drops": 0,
|
||||
"deauth_drops": 0,
|
||||
"assoc_drops": 0
|
||||
}
|
||||
```
|
||||
- `probe_drops`, `deauth_drops`, `assoc_drops` count events lost due to queue overflow since boot. Non-zero values indicate the node is seeing more traffic than the queue sizes can absorb.
|
||||
|
||||
- `imp`: `high` if RSSI >= -50, `low` if <= -80, else `normal`
|
||||
- `ssid` in probe events is the network the device is searching for — empty means wildcard (any network)
|
||||
@@ -216,16 +241,21 @@ The same binary works on every node — `node_id` is auto-derived from the MAC,
|
||||
|
||||
### config.h reference
|
||||
|
||||
| Constant | Default | Purpose |
|
||||
|--------------------|------------------|-------------------------------------------|
|
||||
| `WIFI_SSID` | `sandbox` | WiFi network to connect to |
|
||||
| `COORDINATOR_IP` | `192.168.1.133` | Orange Pi address |
|
||||
| `COORDINATOR_PORT` | `5005` | UDP port |
|
||||
| `SCAN_INTERVAL_MS` | `15000` | How often to run a beacon scan (ms) |
|
||||
| `PROBE_SNIFF` | `1` | Enable/disable probe sniffing (1/0) |
|
||||
| `PROBE_DEDUP_SECS` | `30` | Suppress duplicate probe MAC+SSID (secs) |
|
||||
| `PROBE_QUEUE_SIZE` | `32` | Max probe events buffered between scans |
|
||||
| `DEAUTH_QUEUE_SIZE`| `32` | Max deauth/disassoc events buffered |
|
||||
| Constant | Default | Purpose |
|
||||
|-------------------------|-----------|----------------------------------------------------------------|
|
||||
| `WIFI_SSID` | `sandbox` | WiFi network to connect to |
|
||||
| `COORDINATOR_IP` | `192.168.1.133` | Orange Pi address |
|
||||
| `COORDINATOR_PORT` | `5005` | UDP port |
|
||||
| `SCAN_INTERVAL_MS` | `15000` | How often to run a beacon scan (ms) |
|
||||
| `HEARTBEAT_INTERVAL_MS` | `10000` | How often to send a heartbeat (ms) |
|
||||
| `PROBE_SNIFF` | `1` | Enable/disable probe/deauth/assoc sniffing (1/0) |
|
||||
| `PROBE_DEDUP_SECS` | `30` | Suppress duplicate probe MAC+SSID (secs) |
|
||||
| `DEDUP_CACHE_SIZE` | `64` | Number of MAC+SSID pairs tracked for dedup |
|
||||
| `PROBE_QUEUE_SIZE` | `128` | Max probe events buffered between flushes |
|
||||
| `DEAUTH_QUEUE_SIZE` | `128` | Max deauth/disassoc events buffered |
|
||||
| `ASSOC_QUEUE_SIZE` | `32` | Max assoc/reassoc events buffered |
|
||||
| `HOP_DWELL_MS` | `300` | Ms to dwell on each channel while hopping (13ch × 300ms ≈ 4s) |
|
||||
| `RSSI_ALERT_THRESHOLD` | `-60` | RSSI floor for immediate-flush deauth alert (dBm) |
|
||||
|
||||
---
|
||||
|
||||
@@ -327,21 +357,28 @@ The `oui.txt` file is the IEEE public OUI database (39,171 entries as of downloa
|
||||
- [x] Node firmware: beacon scan + probe sniffing
|
||||
- [x] Four ESP32-S3 nodes flashed and running
|
||||
- [x] UDP ingestor (`udp_ingest.py`) — beacon + probe routing with field validation
|
||||
- [x] Web dashboard: Feed, Networks, Cross-node, Clients, Node detail views
|
||||
- [x] OUI vendor lookup in Clients view
|
||||
- [x] Web dashboard: Feed, Networks, Cross-node, Clients, Alerts, Search, Presence, Node detail
|
||||
- [x] OUI vendor lookup in Clients view (vendor grouping + randomized MAC detection)
|
||||
- [x] Dashboard split into HTML / CSS / JS (no monolithic file)
|
||||
- [x] Deployed to Orange Pi as systemd services (runs 24/7)
|
||||
- [x] All four nodes sending to Orange Pi, confirmed live
|
||||
- [x] Node heartbeat every 10s — uptime, free heap, AP signal, drives online/offline status
|
||||
- [x] RSSI history chart per network (canvas, per-node coloured lines, 1h/2h/6h/24h range)
|
||||
- [x] Presence tab — Present Now, New Arrivals, Regulars
|
||||
- [x] Presence tab — Present Now, New Arrivals, Regulars (fixed key mismatch bug)
|
||||
- [x] Deauth/disassoc frame detection — burst detection with multi-node confirmation, Alerts tab
|
||||
- [x] Alerts tab — most impersonated networks, most targeted devices, burst detection, raw feed
|
||||
- [x] Search tab — cross-table lookup by MAC, SSID, BSSID, or vendor name
|
||||
- [x] Node detail view — 2×5 stat cards with animated border, fixed alphabetical sidebar order
|
||||
- [x] Channel hopping — 13 channels at 300ms dwell, flush on homeChannel pass
|
||||
- [x] Assoc/reassoc frame capture — client join events with SSID IE parsing
|
||||
- [x] RSSI-triggered alert flush — immediate homeChannel flush on close-range deauth attack signature
|
||||
- [x] Queue drop counters — tracked per queue in firmware, reported in heartbeat, stored in DB
|
||||
- [x] SQLite indexes — received_at, node_id, bssid, src_mac, src, dst across all event tables
|
||||
- [x] Dashboard query caps — 300-row limits on Clients, Networks, Cross-node to keep UI responsive
|
||||
- [ ] Attack session reconstruction — group deauth events into discrete sessions by source/time
|
||||
- [ ] Scan interval control from dashboard
|
||||
- [ ] Surface assoc events in dashboard (Sessions tab or Search results)
|
||||
- [ ] DB pruning / retention policy (events.db grows indefinitely)
|
||||
- [ ] Scan interval control from dashboard
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user