Code: Select all
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include "./functions.h"
#define disable 0
#define enable 1
#define ACTIVITYLED 13 // GPIO13/D7
#define SWITCHPIN 0 // GPIO00/D3
unsigned int channel = 1;
const char *ssid = "ORANGE-Tom";
const char *password = "xyzzy3585";
IPAddress ip(192, 168, 1, 254);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WiFiServer webServer (80);
char mode; //s - sniff, h - html
int currentSwitchState; // the current reading from the switch pin
int lastSwitchState = LOW; // the previous reading from the switch pin
//=========================================================================================================================
void setup() {
Serial.begin(57600);
delay(100);
////////////////Temporary//////////////////////////////
{ uint8_t whoStation[] = {0xD4,0xCA,0x94,0x8D,0xC3,0x6A}; // E0-CA-94-8D-C3-6A
uint8_t whoName[] = {'B','i','k','k','e','y','-','P','C',' ',' ',' ',' ',' ',' '};
registerWho(whoStation, whoName);
}
{ uint8_t whoStation[] = {0x5c,0xcf,0x7f,0x81,0x05,0x96};
uint8_t whoName[] = {'T','o','m','-','e','s','p','8','2','6','6','S','N','I','F'};
registerWho(whoStation, whoName);
}
{ uint8_t whoStation[] = {0xd4,0x7b,0xb0,0x77,0xe5,0x73};
uint8_t whoName[] = {'0','0','0','-','e','s','p','8','2','6','6','S','N','I','F'};
registerWho(whoStation, whoName);
}
////////////End Temporary//////////////////////////////
pinMode(SWITCHPIN, INPUT);
pinMode(SWITCHPIN, INPUT);
if (switchState() == 1) {
disableSnifferEnableWebServer ();
} else {
disableWebServerEnableSniffer ();
}
Serial.println(F("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"));
Serial.printf("\n\nSDK version:%s\n\r", system_get_sdk_version());
Serial.println(F("------------------------------------------Activity-(c - Clients, b - Beacons, w = who-------------------------"));
Serial.println(F("/Type:/ /-------MAC------/Dir/ /----WiFi Access Point SSID-----/ /-------MAC------/ Chnl RSSI /----Who--------/"));
pinMode(ACTIVITYLED, OUTPUT); //Declare GPIO13/D7 as output
}
//=========================================================================================================================
void disableSnifferEnableWebServer () {
mode = 'h';
// Sniffer - Disable
wifi_promiscuous_enable(disable);
// Web Server - Enable
Serial.println("");
webServer.on ( "/", handleRoot );
webServer.on ( "/clients", handleClients );
webServer.on ( "/beacons", handleBeacons );
webServer.on ( "/who", handleWho );
webServer.on ( "/deletewho", handleDeleteWho);
webServer.begin();
WiFi.config(ip, gateway,subnet);
WiFi.begin ( ssid, password );
while ( WiFi.status() != WL_CONNECTED ) {
delay (500);
Serial.print ( "." );
}
Serial.print ( "HTTP server started with" );
uint8_t macaddr[6];
wifi_get_macaddr(0x00, macaddr);
Serial.printf("\nMAC: %02x:%02x:%02x:%02x:%02x:%02x\r\n", macaddr[0],macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]);
Serial.println ("");
}
//=========================================================================================================================
void disableWebServerEnableSniffer () {
mode = 's';
// Web Server - Disable
///////////////////////////////////////////////webServer.stop();
// Sniffer - Enable
Serial.println("");
wifi_set_opmode(STATION_MODE); // Promiscuous works only with station mode
wifi_promiscuous_enable(disable);
wifi_set_promiscuous_rx_cb(promisc_cb); // Set up promiscuous callback
wifi_promiscuous_enable(enable);
}
//=========================================================================================================================
int switchState () {
unsigned long debounceDelay = 50; // the debounce time
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
int reading = digitalRead(SWITCHPIN); // read the state of the switch
if (reading != lastSwitchState) { // If the switch changed, due to noise or pressing:
lastDebounceTime = millis(); // reset the debouncing timer
}
if ((millis() - lastDebounceTime) > debounceDelay) {
currentSwitchState = reading;
}
lastSwitchState = reading; // save the reading. Next time through the loop, it'll be the lastButtonState:
return currentSwitchState;
}
//=========================================================================================================================
void loop() {
char commandChar = ' ';
if (mode == 's' and switchState() == 1) {
disableSnifferEnableWebServer ();
} else if (mode == 'h' and switchState() == 0) {
disableWebServerEnableSniffer ();
}
Serial.print(mode);
webServer.handleClient();
delay(1000);
unsigned int saveChannel = wifi_get_channel();
channel = 0;
if (mode == 's') {
wifi_set_channel(channel);
while (channel < 14) {
if (foundOne == 'y') {
foundOne = 'n';
blink();
}
channel++;
if (mode == 's') {
wifi_set_channel(channel);
delay(100); // critical processing timeslice for NON-OS SDK (non-OS vs RTOS)! No delay(0) yield()
}
if (Serial.available() > 0) {
commandChar = Serial.read();
while (Serial.available()) {
Serial.read();
}
}
if (commandChar == 'c') { // List Clients
Serial.println(F("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"));
Serial.println(F("----------------------------------------Clients-------------------------------------------------------------"));
Serial.println(F("/Type:/ /-------MAC------/Dir/ /----WiFi Access Point SSID-----/ /-------MAC------/ Chnl RSSI /----Who--------/"));
for (int u = 0; u < clientsKnownCount; u++) printClient(clientsKnown[u]);
Serial.println(F("--------------------------------Activity-(c - Clients, b - Beacons, w = who)-----------------"));
}
if (commandChar == 'b') { // List Beacons
Serial.println(F("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"));
Serial.println(F("----------------------------------------Beacons-------------------------------------------------------------"));
Serial.println(F("/Type:/ /Dir//----WiFi Access Point SSID------/ /------MAC------/ Chnl RSSI") );
for (int u = 0; u < apsKnownCount; u++) printBeacon(apsKnown[u]);
Serial.println(F("--------------------------------Activity-(c - Clients, b - Beacons, w = who)-----------------"));
}
if (commandChar == 'w') { // List who
Serial.println(F("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"));
Serial.println(F("-------------------------------------------Who--------------------------------------------------------------"));
Serial.println(F("/-------Who-----/ /-----MAC-------/"));
for (int u = 0; u < whosCount; u++) printWho(whosKnown[u]);
Serial.println(F("--------------------------------Activity-(c - Clients, b - Beacons, w = who)-----------------"));
}
if (commandChar == 's') { // Sniffer
disableWebServerEnableSniffer();
}
if (commandChar == 'h') { // HTML
disableSnifferEnableWebServer();
}
}
}
if (Serial.available() > 0) {
commandChar = Serial.read();
while (Serial.available()) {
Serial.read();
}
}
if (commandChar == 'c') { // List Clients
Serial.println(F("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"));
Serial.println(F("----------------------------------------Clients-------------------------------------------------------------"));
Serial.println(F("/Type:/ /-------MAC------/Dir/ /----WiFi Access Point SSID-----/ /-------MAC------/ Chnl RSSI /----Who--------/"));
for (int u = 0; u < clientsKnownCount; u++) printClient(clientsKnown[u]);
Serial.println(F("--------------------------------Activity-(c - Clients, b - Beacons, w = who)-----------------"));
}
if (commandChar == 'b') { // List Beacons
Serial.println(F("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"));
Serial.println(F("----------------------------------------Beacons-------------------------------------------------------------"));
Serial.println(F("/Type:/ /Dir//----WiFi Access Point SSID------/ /------MAC------/ Chnl RSSI") );
for (int u = 0; u < apsKnownCount; u++) printBeacon(apsKnown[u]);
Serial.println(F("--------------------------------Activity-(c - Clients, b - Beacons, w = who)-----------------"));
}
if (commandChar == 'w') { // List who
Serial.println(F("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"));
Serial.println(F("-------------------------------------------Who--------------------------------------------------------------"));
Serial.println(F("/-------Who-----/ /-----MAC-------/"));
for (int u = 0; u < whosCount; u++) printWho(whosKnown[u]);
Serial.println(F("--------------------------------Activity-(c - Clients, b - Beacons, w = who)-----------------"));
}
if (commandChar == 's') { // Sniffer
disableWebServerEnableSniffer();
}
if (commandChar == 'h') { // HTML
disableSnifferEnableWebServer();
}
if(mode == 'h') {
wifi_set_channel(saveChannel);
}
}
//=========================================================================================================================
void handleRoot() {
Serial.println("\n-------------------------------------------------------handleRoot");
htmlReply("home");
}
//=========================================================================================================================
void handleClients() {
Serial.println("\n-------------------------------------------------------handleClients");
htmlReply("clients");
}
//=========================================================================================================================
void handleBeacons() {
Serial.println("\n-------------------------------------------------------handleBeacons");
htmlReply("beacons");
}
//=========================================================================================================================
void handleWho() {
Serial.println("\n-------------------------------------------------------handleWho");
htmlReply("who");
}
void handleDeleteWho() {
int sequence;
Serial.println("\n-------------------------------------------------------handleDeleteWho");
if (webServer.arg("Sequence") != "" &&+ webServer.arg("Sequence").toInt() != 0) {
sequence = webServer.arg("Sequence").toInt();
if (sequence <= whosCount) {
for (int i = sequence - 1;i < whosCount; i++) {
whosKnown[i] = whosKnown[i + 1];
}
whosCount = whosCount - 1;
}
}
htmlReply("who");
}
//=========================================================================================================================
void handleWhoAdd() {
Serial.println("\n-------------------------------------------------------handleWhoAdd");
htmlReply("who");
}
//=========================================================================================================================
void htmlReply(String type) {
///************************************
int hrSinceBoot;
int minSinceBoot;
int secSinceBoot;
String x = "<html>\n"; //---------------------------------Common
x = x
+ "<head width=100% align=center>\n"
//+ "<meta http-equiv='refresh' content='5;url=/'/>\n"
+ "<title width=100% align=center>ESP8266 - Sniffer Data Access</title>\n"
+ "<style>\n"
+ "body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\n"
+ "</style>\n"
+ "</head>\n"
+ "<body width=100%>\n"
+ "<style>\n"
+ " section {\n"
+ "background: white;\n"
+ "color: black;\n"
+ "border-radius: 1em;\n"
+ "padding: 1em;\n"
+ "position: absolute;\n"
+ "top: 50%;\n"
+ "left: 50%;\n"
+ "margin-right: -50%;\n"
+ "transform: translate(-50%, -50%) }\n"
+ "table {align:center}\n"
+ "table, th, td {border: 1px solid black;border-collapse: collapse;}\n"
+ "th, td {padding: 1px;text-align: center;}\n"
+ "</style>\n"
+ "<h1 align:center width=100%><p>ArduinoEPS8266 - WiFi Sniffer</p></h1>\n"
+ "<div style=\"width: 725px;\">\n"
+ "<table style=\"width: 725px; table-layout: fixed;\">\n"
+ "<tr style=\"width: 725px;\">\n"
+ "<table style=\"width: 725px; table-layout: fixed;\">\n"
+ "<tr>\n"
+ "<td width=25%> <form name='onForm' action='/who' method='post'>\n"
+ "<div align='center'>\n"
+ "<br><input type='submit' value='Who' style=\"width: 70px; height: 25px; background-color: #00FF00; color: #FFFFFF; font-weight: bold;\"><br>\n"
+ "</div>\n"
+ "</form>\n"
+ "</td>\n"
+ "<td width=25%> <form name='onForm' action='/clients' method='post'>\n"
+ "<div align='center'>\n"
+ "<br><input type='submit' value='Clients' style=\"width: 70px; height: 25px; background-color: #00FF00; color: #FFFFFF; font-weight: bold;\"><br>\n"
+ "</div>\n"
+ "</form>\n"
+ "</td>\n"
+ "<td width=25%> <form name='onForm' action='/beacons' method='post'>\n"
+ "<div align='center'>\n"
+ "<br><input type='submit' value='Beacons' style=\"width: 70px; height: 25px; background-color: #00FF00; color: #FFFFFF; font-weight: bold;\"><br>\n"
+ "</div>\n"
+ "</form>\n"
+ "</td>\n"
+ "<td width=25%> <form name='onForm' action='/' method='post'>\n"
+ "<div align='center'>\n"
+ "<br><input type='submit' value='Home' style=\"width: 70px; height: 25px; background-color: #00FF00; color: #FFFFFF; font-weight: bold;\"><br>\n"
+ "</div>\n"
+ "</form>\n"
+ "</td>\n"
+ "</tr>\n"
+ "</table>\n"
+ "</tr>\n"
+ "<tr>\n";
if (type == "home") { //---------------------------------home
x = x + "<br><br>";
x = x + "<table style=\"width: 725px; table-layout: fixed;\">\n";
x = x + "<thead>\n";
x = x + "<tr>"
+ "<td><p style=\"font-weight:bold\"> Notes on Use</p></td>"
+ "</tr>";
x = x + "</thead>";
x = x + "<tbody>\n";
x = x + "<tr>"
+ "<td>"
+ "<font size=\"2\">"
+ "<p> by Tom Meyers November 2017 Santiago DR</p>"
+ "</font>"
+ "</td>"
+ "</tr>";
x = x + "</tbody>\n";
x = x + "</table>";
x = x + "<div style=\"width:725px; height:50px; overflow: auto;\" >\n"
+ "Example of using div for scrolling"
+ "text text (Description of sniffer) text text "
+ "text text text text text text text text text "
+ "text text text text text text text text text "
+ "text text text text text text text text text "
+ "text text text text text text text text text "
+ "text text text text text text text text text "
+ "text text text text text text text text text "
+ "text text text text text text text text text "
+ "</div>\n";
}
if (type == "who") { //---------------------------------Who
x = x + "<br><br>";
x = x + "<table style=\"width: 725px; table-layout: fixed;\">\n";
x = x + "<thead>\n";
x = x + "<tr><th> Who do I know </th></tr>"
+ "</thead>\n"
+ "</table>";
x = x + "<table style=\"width: 725px; table-layout: fixed;\">\n";
x = x + "<thead>\n";
x = x + "<tr>"
+ "<th>Sequence</th>"
+ "<th>Name</th>"
+ "<th>MAC</th>"
+ "</tr>";
x = x + "</thead>";
x = x + "<tbody>\n";
for (int i = 0; i < whosCount ; i++) {
x = x
+ "<tr>\n"
+ "<td>"
+ (i + 1)
+ "</td>"
+ "<td>";
for (int j = 0; j < 15 ; j++) {
x = x + (char) whosKnown[i].whoName[0];
}
x = x
+ "</td>"
+ "<td>"
+ macToString(whosKnown[i].whoStation)
+ "</td>"
+ "</tr>\n";
}
x = x + "</tbody>\n";
x = x + "</table><br><br> \n";
x = x + "<table style=\"width: 725px;\"><tbody>";
x = x + "<tr colspan=\"2\"><td>"
+ "<form action=\"/deletewho\">"
+ " Sequence: <input type=\"text\" name=\"Sequence\" pattern=\"[0-9]+\" title=\"Sequence Number\">"
+ " <input name=\"Delete\" type=\"submit\" value=\"Delete\">"
+ "</form>"
+ "<td></tr>\n";
x = x + "<tr colspan=\"2\"><td>"
+ "<form action=\"/addwho\">"
+ "MAC: <input type=\"text\" name=\"MAC\" pattern=\"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$\" title=\"XX:XX:XX:XX:XX:XX\">"
+ " Name: <input type=\"text\" name=\"Name\" title=\"Descripive Name\">"
+ " <input name = \"Add\" type=\"submit\">"
+ "</form>"
+ "<td></tr>\n";
x = x + "</tbody></table>";
}
/*
* uint8_t bssid[ETH_MAC_LEN];
uint8_t bssidWhoName[15]; // who this is from table of known whos
uint8_t station[ETH_MAC_LEN];
uint8_t StationWhoName[15]; // who this is from table of known whos
uint8_t ap[ETH_MAC_LEN];
uint8_t apWhoName[15]; // who this is from table of known whos
int channel;
int err;
signed rssi;
uint16_t seq_n;
*/
if (type == "clients") { //---------------------------------Client
updateClientNames();
x = x + "<br><br>";
x = x + "<table style=\"width: 725px; table-layout: fixed;\">\n";
x = x + "<thead>\n";
x = x + "<tr><th> Clients Found </th></tr>";
x = x + "</thead>";
x = x + "</table>";
x = x + "<table style=\"width: 725px; table-layout: fixed;font-size:10px\">\n";
x = x + "<thead>\n";
x = x + "<tr>"
+ "<th>Name</th>"
+ "<th>bssid</th>"
+ "<th>Station</th>"
+ "<th>AP</th>"
+ "<th>Channel</th>"
+ "<th>err</th>"
+ "<th>rssi</th>"
+ "<th>SEQ_N</th>"
+ "</tr>";
x = x + "</thead>";
x = x + "<tbody>\n";
for (int i = 0; i < clientsKnownCount ; i++) {
x = x
+ "<tr>\n"
+ "<td>"; //Name
for (int j = 0; j < 10 ; j++) {
x = x + "*"; /////////////////////// x = x + (char) clientsKnown[i].whoName[0];
}
x = x
+ "</td>"
+ "<td>" //bssid
+ macToString(clientsKnown[i].bssid)
+ "<br>" + clientsKnown[i].bssidWhoName[0]
+ "</td>"
+ "<td>" //Station
+ macToString(clientsKnown[i].station)
+ "</td>"
+ "<td>" //AP
+ macToString(clientsKnown[i].ap)
+ "</td>"
//////////////////////////////////////
+ "<td>" //Channel
+ clientsKnown[i].channel
+ "</td>"
+ "<td>" //err
+ clientsKnown[i].err
+ "</td>"
+ "<td>" //rssi
+ clientsKnown[i].rssi
+ "</td>"
+ "<td>" //SEQ_N
+ clientsKnown[i].seq_n
+ "</td>"
+ "</tr>\n";
}
x = x + "</tbody>\n";
x = x + "</table> \n";
}
///*
/* beaconInfo apsKnown[MAX_APS_TRACKED]; // Array to save MACs of known APs
int apsKnownCount = 0; // Number of known APs
struct beaconInfo {
uint8_t bssid[ETH_MAC_LEN];
uint8_t ssid[33];
int ssid_len;
int channel;
int err;
signed rssi;
uint8_t capa[2];
};
//*/
if (type == "beacons") { //---------------------------------Beacon
x = x + "<br><br>";
x = x + "<table style=\"width: 725px; table-layout: fixed;\">\n";
x = x + "<thead>\n";
x = x + "<tr><th>Beacons Found </th></tr>";
x = x + "</thead> </table>";
x = x + "<table style=\"width: 725px; table-layout: fixed;font-size:10px\">\n";
x = x + "<tr>"
+ "<th>bssid</th>"
+ "<th>ssid</th>"
+ "<th>ssid_len</th>"
+ "<th>Channel</th>"
+ "<th>err</th>"
+ "<th>rssi</th>"
+ "<th>capa[0] capa[1]</th>"
+ "</tr>";
x = x + "</thead>";
x = x + "<tbody>\n";
for (int i = 0; i < apsKnownCount ; i++) {
x = x
+ "<tr>\n"
+ "<td>"
+ macToString(apsKnown[i].bssid)
+ "</td>"
+ "<td>";
for (int j = 0; j < apsKnown[i].ssid_len ; j++) {
x = x + (char) apsKnown[i].ssid[0];
}
x = x
+ "<td>"
+ apsKnown[i].ssid_len
+ "</td>"
+ "<td>"
+ apsKnown[i].channel
+ "</td>"
+ "<td>"
+ apsKnown[i].err
+ "</td>"
+ "<td>"
+ apsKnown[i].rssi
+ "</td>"
+ "<td>"
+ apsKnown[i].capa[0]
+ "/"
+ apsKnown[i].capa[0]
+ "</td>"
+ "</tr>\n";
}
x = x + "</tbody>\n";
x = x + "</table> \n";
}
x = x + "</tr>"
+ "</table>\n"
+ "</div>\n"
+ "</body>\n" //---------------------------------More Common
+ "</html>\n";
// hrSinceBoot, minSinceBoot, secSinceBoot, hrSinceOn, minSinceOn, secSinceOn, hrSinceOff, minSinceOff, secSinceOff );
webServer.send ( 200, "text/html", x);
//************************************************************************/
}
//=========================================================================================================================
void blink() {
digitalWrite(13, HIGH); // turn the LED on
delay(1000); // Wait 1 second
digitalWrite(13, LOW); // turn the LED off
delay(1000); // wait 1 second
}
//=========================================================================================================================
String macToString(uint8_t MAC[ETH_MAC_LEN]) {
String formatedMAC;
formatedMAC = "";
for (int i = 0; i < ETH_MAC_LEN; i++) {
if ( i == ETH_MAC_LEN - 1) {
formatedMAC = formatedMAC + format("%02x", MAC[i]);
} else {
formatedMAC = formatedMAC + format("%02x:", MAC[i]);
}
}
return formatedMAC;
}
//=========================================================================================================================
String xformat(char formatString[], int formatData){ // hold-----------------
char charFormatted[100];
sprintf(charFormatted, formatString, formatData);
return (String) charFormatted;
}
//=========================================================================================================================
String format(char formatString[], char formatData){ // format a single char
char charFormatted[100];
sprintf(charFormatted, formatString, formatData);
return (String) charFormatted;
}
//clientInfo clientsKnown[MAX_CLIENTS_TRACKED]; // Array to save MACs of known CLIENTs
//int clientsKnownCount = 0; // Number of known CLIENTs
//whoInfo whosKnown[MAX_KNOWN_TRACKED]; // Identified MAC addresses
//int whosCount = 0;
void updateClientNames() {
for (int i = 0; i < clientsKnownCount; i++) {
for(int j = 0; j < whosCount; j++) {
Serial.println(macToString(clientsKnown[i].bssid) + "/"+ macToString(whosKnown[i].whoStation));
if(memcmp(clientsKnown[i].station,whosKnown[j].whoStation,ETH_MAC_LEN)) {
Serial.println("equal station");
for(int k = 0; k < 15;k++) {clientsKnown[i].stationWhoName[k] = whosKnown[i].whoName[k];}
}
if(memcmp(clientsKnown[i].bssid,whosKnown[j].whoStation,ETH_MAC_LEN)) {
Serial.println("equal bssid");
for(int k = 0; k < 15;k++) {clientsKnown[i].bssidWhoName[k] = whosKnown[i].whoName[k];}
}
if(memcmp(clientsKnown[i].ap,whosKnown[j].whoStation,ETH_MAC_LEN)) {
Serial.println("equal ap");
for(int k = 0; k < 15;k++) {clientsKnown[i].apWhoName[k] = whosKnown[i].whoName[k];}
}
}
}
}