mirror of
https://github.com/SpacehuhnTech/esp8266_deauther.git
synced 2025-12-23 15:10:06 +01:00
Version 2.0
This commit is contained in:
398
esp8266_deauther/Scan.cpp
Normal file
398
esp8266_deauther/Scan.cpp
Normal file
@@ -0,0 +1,398 @@
|
||||
#include "Scan.h"
|
||||
|
||||
Scan::Scan() {
|
||||
list = new LinkedList<uint16_t>;
|
||||
}
|
||||
|
||||
void Scan::sniffer(uint8_t* buf, uint16_t len) {
|
||||
if (!isSniffing()) return;
|
||||
|
||||
packets++;
|
||||
|
||||
if (len < 28) return; // drop frames that are too short to have a valid MAC header
|
||||
|
||||
if (buf[12] == 0xc0 || buf[12] == 0xa0) {
|
||||
tmpDeauths++;
|
||||
return;
|
||||
}
|
||||
|
||||
// drop beacon frames, probe requests/responses and deauth/disassociation frames
|
||||
if (buf[12] == 0x80 || buf[12] == 0x40 || buf[12] == 0x50/* || buf[12] == 0xc0 || buf[12] == 0xa0*/) return;
|
||||
|
||||
// only allow data frames
|
||||
// if(buf[12] != 0x08 && buf[12] != 0x88) return;
|
||||
|
||||
uint8_t* macTo = &buf[16];
|
||||
uint8_t* macFrom = &buf[22];
|
||||
|
||||
if (macBroadcast(macTo) || macBroadcast(macFrom) || !macValid(macTo) || !macValid(macFrom) || macMulticast(macTo) || macMulticast(macFrom)) return;
|
||||
|
||||
int16_t accesspointNum = findAccesspoint(macFrom);
|
||||
if (accesspointNum >= 0) {
|
||||
stations.add(macTo, accesspointNum);
|
||||
} else {
|
||||
accesspointNum = findAccesspoint(macTo);
|
||||
if (accesspointNum >= 0) {
|
||||
stations.add(macFrom, accesspointNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Scan::findAccesspoint(uint8_t* mac) {
|
||||
for (int i = 0; i < accesspoints.count(); i++) {
|
||||
if (memcmp(accesspoints.getMac(i), mac, 6) == 0) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Scan::start(uint8_t mode) {
|
||||
start(mode, sniffTime, scan_continue_mode, continueTime, channelHop, wifi_channel);
|
||||
}
|
||||
|
||||
void Scan::start(uint8_t mode, uint32_t time, uint8_t nextmode, uint32_t continueTime, bool channelHop, uint8_t channel) {
|
||||
if(mode != SCAN_MODE_OFF) stop();
|
||||
|
||||
setWifiChannel(channel);
|
||||
Scan::continueStartTime = currentTime;
|
||||
Scan::snifferPacketTime = continueStartTime;
|
||||
Scan::snifferOutputTime = continueStartTime;
|
||||
Scan::continueTime = continueTime;
|
||||
Scan::sniffTime = time;
|
||||
Scan::channelHop = channelHop;
|
||||
Scan::scanMode = mode;
|
||||
Scan::scan_continue_mode = nextmode;
|
||||
|
||||
if(sniffTime > 0 && sniffTime < 1000) sniffTime = 1000;
|
||||
|
||||
// Serial.printf("mode: %u, time: %u, continue-mode: %u, continueTime: %u, channelHop: %u, channel: %u\r\n", mode, time, scan_continue_mode, continueTime, channelHop, channel);
|
||||
|
||||
/* AP Scan */
|
||||
if (mode == SCAN_MODE_APS || mode == SCAN_MODE_ALL) {
|
||||
// remove old results
|
||||
accesspoints.removeAll();
|
||||
stations.removeAll();
|
||||
// start AP scan
|
||||
prntln(SC_START_AP);
|
||||
WiFi.scanNetworks(true, true);
|
||||
}
|
||||
|
||||
/* Station Scan */
|
||||
else if (mode == SCAN_MODE_STATIONS) {
|
||||
// start station scan
|
||||
if (accesspoints.count() < 1) {
|
||||
start(SCAN_MODE_ALL);
|
||||
//Serial.println(str(SC_ERROR_NO_AP));
|
||||
return;
|
||||
}
|
||||
snifferStartTime = currentTime;
|
||||
prnt(SC_START_CLIENT);
|
||||
if (sniffTime > 0) prnt(String(sniffTime / 1000) + S);
|
||||
else prnt(SC_INFINITELY);
|
||||
if(!channelHop){
|
||||
prnt(SC_ON_CHANNEL);
|
||||
prnt(wifi_channel);
|
||||
}
|
||||
prntln();
|
||||
|
||||
// enable sniffer
|
||||
stopAP();
|
||||
wifi_promiscuous_enable(true);
|
||||
}
|
||||
|
||||
else if (mode == SCAN_MODE_SNIFFER) {
|
||||
deauths = tmpDeauths;
|
||||
tmpDeauths = 0;
|
||||
snifferStartTime = currentTime;
|
||||
prnt(SS_START_SNIFFER);
|
||||
if (sniffTime > 0) prnt(String(sniffTime / 1000) + S);
|
||||
else prnt(SC_INFINITELY);
|
||||
prnt(SC_ON_CHANNEL);
|
||||
prntln(channelHop ? str(SC_ONE_TO) +(String)settings.getMaxCh() : (String)wifi_channel);
|
||||
|
||||
// enable sniffer
|
||||
stopAP();
|
||||
wifi_promiscuous_enable(true);
|
||||
}
|
||||
|
||||
/* Stop scan */
|
||||
else if (mode == SCAN_MODE_OFF) {
|
||||
wifi_promiscuous_enable(false);
|
||||
if(settings.getWebInterface()) resumeAP();
|
||||
prntln(SC_STOPPED);
|
||||
save(true);
|
||||
if (scan_continue_mode != SCAN_MODE_OFF) {
|
||||
prnt(SC_RESTART);
|
||||
prnt(int(continueTime / 1000));
|
||||
prntln(SC_CONTINUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* ERROR */
|
||||
else {
|
||||
prnt(SC_ERROR_MODE);
|
||||
prntln(mode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Scan::update() {
|
||||
if (scanMode == SCAN_MODE_OFF) {
|
||||
// restart scan if it is continuous
|
||||
if (scan_continue_mode != SCAN_MODE_OFF) {
|
||||
if (currentTime - continueStartTime > continueTime) start(scan_continue_mode);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// sniffer
|
||||
if(isSniffing()){
|
||||
// update packet list every 1s
|
||||
if(currentTime - snifferPacketTime > 1000){
|
||||
snifferPacketTime = currentTime;
|
||||
list->add(packets);
|
||||
if(list->size() > SCAN_PACKET_LIST_SIZE) list->remove(0);
|
||||
deauths = tmpDeauths;
|
||||
tmpDeauths = 0;
|
||||
packets = 0;
|
||||
}
|
||||
|
||||
// print status every 3s
|
||||
if (currentTime - snifferOutputTime > 3000) {
|
||||
char s[100];
|
||||
if(sniffTime > 0){
|
||||
sprintf(s,str(SC_OUTPUT_A).c_str(), getPercentage(), packets, stations.count(), deauths);
|
||||
} else{
|
||||
sprintf(s,str(SC_OUTPUT_B).c_str(), packets, stations.count(), deauths);
|
||||
}
|
||||
prnt(String(s));
|
||||
snifferOutputTime = currentTime;
|
||||
}
|
||||
|
||||
// channel hopping
|
||||
if(channelHop && currentTime - snifferChannelTime > settings.getChTime()) {
|
||||
snifferChannelTime = currentTime;
|
||||
if(scanMode == SCAN_MODE_STATIONS) nextChannel(); // go to next channel an AP is on
|
||||
else setChannel(wifi_channel + 1); // go to next channel
|
||||
}
|
||||
}
|
||||
|
||||
// APs
|
||||
if (scanMode == SCAN_MODE_APS || scanMode == SCAN_MODE_ALL) {
|
||||
int16_t results = WiFi.scanComplete();
|
||||
if (results >= 0) {
|
||||
for (int16_t i = 0; i < results && i < 256; i++) {
|
||||
if(channelHop || WiFi.channel(i) == wifi_channel) accesspoints.add(i, false);
|
||||
}
|
||||
accesspoints.sort();
|
||||
accesspoints.printAll();
|
||||
if (scanMode == SCAN_MODE_ALL){
|
||||
delay(30);
|
||||
start(SCAN_MODE_STATIONS);
|
||||
}
|
||||
else start(SCAN_MODE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
// Stations
|
||||
else if (sniffTime > 0 && currentTime > snifferStartTime + sniffTime) {
|
||||
wifi_promiscuous_enable(false);
|
||||
if(scanMode == SCAN_MODE_STATIONS){
|
||||
stations.sort();
|
||||
stations.printAll();
|
||||
}
|
||||
start(SCAN_MODE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
void Scan::setup(){
|
||||
save(true);
|
||||
}
|
||||
|
||||
void Scan::stop() {
|
||||
scan_continue_mode = SCAN_MODE_OFF;
|
||||
start(SCAN_MODE_OFF);
|
||||
}
|
||||
|
||||
void Scan::setChannel(uint8_t ch) {
|
||||
if (ch > settings.getMaxCh()) ch = 1;
|
||||
else if (ch < 1) ch = settings.getMaxCh();
|
||||
|
||||
wifi_promiscuous_enable(0);
|
||||
setWifiChannel(ch);
|
||||
wifi_promiscuous_enable(1);
|
||||
}
|
||||
|
||||
void Scan::nextChannel() {
|
||||
if (accesspoints.count() > 1) {
|
||||
uint8_t ch = wifi_channel;
|
||||
do {
|
||||
ch++;
|
||||
if (ch > settings.getMaxCh()) ch = 1;
|
||||
} while (!apWithChannel(ch));
|
||||
setChannel(ch);
|
||||
}
|
||||
}
|
||||
|
||||
bool Scan::apWithChannel(uint8_t ch) {
|
||||
for (int i = 0; i < accesspoints.count(); i++)
|
||||
if (accesspoints.getCh(i) == ch) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Scan::save(bool force, String filePath){
|
||||
String tmp = FILE_PATH;
|
||||
FILE_PATH = filePath;
|
||||
save(true);
|
||||
FILE_PATH = tmp;
|
||||
}
|
||||
|
||||
void Scan::save(bool force) {
|
||||
if(!(accesspoints.changed || stations.changed) && !force) return;
|
||||
|
||||
// Accesspoints
|
||||
String buf = String(OPEN_CURLY_BRACKET) + String(DOUBLEQUOTES) + str(SC_JSON_APS) + String(DOUBLEQUOTES) + String(DOUBLEPOINT) + String(OPEN_BRACKET); // {"aps":[
|
||||
|
||||
if(!writeFile(FILE_PATH, buf)) { // overwrite old file
|
||||
prnt(SC_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = String(); // clear buffer
|
||||
uint32_t apCount = accesspoints.count();
|
||||
|
||||
for (int i = 0; i < apCount; i++) {
|
||||
buf += String(OPEN_BRACKET) + String(DOUBLEQUOTES) + escape(accesspoints.getSSID(i)) + String(DOUBLEQUOTES) + String(COMMA); // ["ssid",
|
||||
buf += String(DOUBLEQUOTES) + escape(accesspoints.getNameStr(i)) + String(DOUBLEQUOTES) + String(COMMA); // "name",
|
||||
buf += String(accesspoints.getCh(i)) + String(COMMA); // 1,
|
||||
buf += String(accesspoints.getRSSI(i)) + String(COMMA); // -30,
|
||||
buf += String(DOUBLEQUOTES) + accesspoints.getEncStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "wpa2",
|
||||
buf += String(DOUBLEQUOTES) + accesspoints.getMacStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "00:11:22:00:11:22",
|
||||
buf += String(DOUBLEQUOTES) + accesspoints.getVendorStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "vendor",
|
||||
buf += b2s(accesspoints.getSelected(i)) + String(CLOSE_BRACKET); // false]
|
||||
if(i < apCount - 1) buf += String(COMMA); // ,
|
||||
|
||||
if(buf.length() >= 1024){
|
||||
if(!appendFile(FILE_PATH, buf)) {
|
||||
prnt(SC_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = String(); // clear buffer
|
||||
}
|
||||
}
|
||||
|
||||
// Stations
|
||||
buf += String(CLOSE_BRACKET) + String(COMMA) + String(DOUBLEQUOTES) + str(SC_JSON_STATIONS) + String(DOUBLEQUOTES) + String(DOUBLEPOINT) + String(OPEN_BRACKET); // ],"stations":[;
|
||||
uint32_t stationCount = stations.count();
|
||||
|
||||
for (int i = 0; i < stationCount; i++) {
|
||||
buf += String(OPEN_BRACKET) + String(DOUBLEQUOTES) + stations.getMacStr(i) + String(DOUBLEQUOTES) + String(COMMA); // ["00:11:22:00:11:22",
|
||||
buf += String(stations.getCh(i)) + String(COMMA); // 1,
|
||||
buf += String(DOUBLEQUOTES) + stations.getNameStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "name",
|
||||
buf += String(DOUBLEQUOTES) + stations.getVendorStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "vendor",
|
||||
buf += String(*stations.getPkts(i)) + String(COMMA); // 123,
|
||||
buf += String(stations.getAP(i)) + String(COMMA); // 0,
|
||||
buf += String(DOUBLEQUOTES) + stations.getTimeStr(i) + String(DOUBLEQUOTES) + String(COMMA); // "<1min",
|
||||
buf += b2s(stations.getSelected(i)) + String(CLOSE_BRACKET); // false]
|
||||
if(i < stationCount - 1) buf += String(COMMA); // ,
|
||||
|
||||
if(buf.length() >= 1024){
|
||||
if(!appendFile(FILE_PATH, buf)) {
|
||||
prnt(SC_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = String(); // clear buffer
|
||||
}
|
||||
}
|
||||
|
||||
buf += String(CLOSE_BRACKET) + String(CLOSE_CURLY_BRACKET); // ]}
|
||||
|
||||
if(!appendFile(FILE_PATH, buf)) {
|
||||
prnt(SC_ERROR_SAVING);
|
||||
prntln(FILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
accesspoints.changed = false;
|
||||
stations.changed = false;
|
||||
prnt(SC_SAVED_IN);
|
||||
prntln(FILE_PATH);
|
||||
}
|
||||
|
||||
uint32_t Scan::countSelected() {
|
||||
return (accesspoints.selected() + stations.selected() + names.selected());
|
||||
}
|
||||
|
||||
uint32_t Scan::countAll() {
|
||||
return (accesspoints.count() + stations.count() + names.count());
|
||||
}
|
||||
|
||||
bool Scan::isScanning() {
|
||||
return scanMode != SCAN_MODE_OFF;
|
||||
}
|
||||
|
||||
bool Scan::isSniffing() {
|
||||
return scanMode == SCAN_MODE_STATIONS || scanMode == SCAN_MODE_SNIFFER;
|
||||
}
|
||||
|
||||
uint8_t Scan::getPercentage(){
|
||||
if(!isSniffing()) return 0;
|
||||
return (currentTime - snifferStartTime) / (sniffTime / 100);
|
||||
}
|
||||
|
||||
void Scan::selectAll() {
|
||||
accesspoints.selectAll();
|
||||
stations.selectAll();
|
||||
names.selectAll();
|
||||
}
|
||||
|
||||
void Scan::deselectAll() {
|
||||
accesspoints.deselectAll();
|
||||
stations.deselectAll();
|
||||
names.deselectAll();
|
||||
}
|
||||
|
||||
void Scan::printAll() {
|
||||
accesspoints.printAll();
|
||||
stations.printAll();
|
||||
names.printAll();
|
||||
ssids.printAll();
|
||||
}
|
||||
|
||||
void Scan::printSelected() {
|
||||
accesspoints.printSelected();
|
||||
stations.printSelected();
|
||||
names.printSelected();
|
||||
}
|
||||
|
||||
uint32_t Scan::getPackets(int i){
|
||||
if(list->size() < SCAN_PACKET_LIST_SIZE){
|
||||
uint8_t translatedNum = SCAN_PACKET_LIST_SIZE - list->size();
|
||||
if(i >= translatedNum) return list->get(i-translatedNum);
|
||||
return 0;
|
||||
} else {
|
||||
return list->get(i);
|
||||
}
|
||||
}
|
||||
|
||||
double Scan::getScaleFactor(uint8_t height){
|
||||
return (double)height/(double)getMaxPacket();
|
||||
}
|
||||
|
||||
uint32_t Scan::getMaxPacket(){
|
||||
uint16_t max = 0;
|
||||
for(uint8_t i=0;i<list->size();i++){
|
||||
if(list->get(i) > max) max = list->get(i);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
uint32_t Scan::getPacketRate(){
|
||||
return list->get(list->size()-1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user