#ifndef WIFIRAW_H #define WIFIRAW_H #include "MAC.h" #if IS_ESP8266 extern "C" { #include "esp_wifi.h" } #endif // ifconfig wlp0s26u1u2u1 down && iw dev wlp0s26u1u2u1 set monitor none && ifconfig wlp0s26u1u2u1 up && iw dev wlp0s26u1u2u1 set channel 3 // ifconfig wlp0s26u1u2u1 down && iw dev wlp0s26u1u2u1 set monitor none && ifconfig wlp0s26u1u2u1 up iwconfig wlp0s26u1u2u1 channel 3 // https://supportforums.cisco.com/document/52391/80211-frames-starter-guide-learn-wireless-sniffer-traces namespace WiFiRaw { /** frame type */ enum Type { MANAGEMENT = 0b00, CONTROL = 0b01, DATA = 0b10, RESERVED = 0b11, }; /** frame sub-type */ enum SubType { DATA_DATA = 0b0000, DATA_DATA_CF_ACK = 0b0001, DATA_DATA_CF_POLL = 0b0010, DATA_DATA_CF_ACK_POLL = 0b0011, DATA_NULL = 0b0100, DATA_QOS = 0b1000, MGMT_ASSOC_REQUEST = 0b0000, MGMT_PROBE_REQUEST = 0b0100, MGMT_BEACON = 0b1000, MGMT_DISASSOCIATION = 0b1010, }; /** * 2 byte segment and fragment number. * usually set by the ESP itself */ struct Fragment { uint8_t data[2]; /** empty ctor */ Fragment() : data() {;} /** ctor with values */ Fragment(const uint8_t fragNr, const uint16_t seqNr) { data[1] = seqNr >> 4; data[0] = seqNr << 4 | fragNr; } }; // /** // * 4 byte checksum. // * usually set by the ESP itself // */ // struct FCS { // uint8_t data[4]; // FCS() : data() {;} // }; struct Header { uint8_t version : 2; // always 0 uint8_t type : 2; // see enum uint8_t subType : 4; // see enum struct Flags { uint8_t toDS : 1; // always 0 uint8_t fromDS : 1; // unencrypted: 0 uint8_t moreFragments : 1; // no more data: 0 , more data: 1 uint8_t retransmission : 1; // no retransmission: 0, retransmission: 1 uint8_t powerManagement : 1; // i am fully active: 0, tell AP that i safe power: 1, uint8_t moreData : 1; // ? uint8_t protectedPkt : 1; // 1 = encrypted, 0 = unencrypted uint8_t strictlyOrdered : 1; // 0 = not strictly ordered Flags() : toDS(0), fromDS(0), moreFragments(0), retransmission(0), powerManagement(0), moreData(0), protectedPkt(0), strictlyOrdered(0) {;} } flags; uint16_t duration; // ?? Header(Type type, SubType subType) : version(0), type(type), subType(subType), duration(0) { ; } }; struct Timestamp { uint8_t data[8]; Timestamp() : data() {;} }; struct BeaconInterval { uint8_t data[2]; BeaconInterval() { data[0] = 0x64; data[1] = 0x00; } }; struct Capabilities { uint8_t isSTA : 1; uint16_t empty : 15; Capabilities() : isSTA(1), empty(0) {;} }; /** base-struct for management frames */ struct ManagementFrame { Timestamp ts; BeaconInterval interval; Capabilities capa; ManagementFrame() : ts(), interval(), capa() {;} }; struct UnknownPkt { Header header; WiFiRaw::MACAddress destination; WiFiRaw::MACAddress transmitter; WiFiRaw::MACAddress bssid; }; /** beacon packet */ template struct BeaconPkt { Header header; WiFiRaw::MACAddress destination; // usually broadcast ff:ff:ff:ff:ff:ff WiFiRaw::MACAddress transmitter; // usually the AP's MAC WiFiRaw::MACAddress bssid; // the AP's MAC Fragment frag; ManagementFrame mgmt; T data; //FCS fcs; BeaconPkt(const WiFiRaw::MACAddress myMAC) : header(MANAGEMENT, MGMT_BEACON), destination(0xFF,0xFF,0xFF,0xFF,0xFF,0xFF), transmitter(myMAC), bssid(myMAC) { ; } }; /** data packet */ template struct DataPkt { Header header; WiFiRaw::MACAddress bssid; // the AP's mac WiFiRaw::MACAddress transmitter; // my mac WiFiRaw::MACAddress destination; // the receiver's mac Fragment frag; uint8_t data[size]; //FCS fcs; DataPkt(const WiFiRaw::MACAddress& mine, const WiFiRaw::MACAddress& receiver, const WiFiRaw::MACAddress& bssid) : header(DATA, DATA_DATA_CF_ACK), bssid(bssid), transmitter(mine), destination(receiver) { header.flags.toDS = 1; } }; #if IS_ESP8266 WiFiRaw::MACAddress getMyMAC() { WiFiRaw::MACAddress mine; esp_wifi_get_mac(ESP_IF_WIFI_STA, (uint8_t*)&mine); return mine; } #endif #if IS_ESP32 WiFiRaw::MACAddress getMyMAC() { WiFiRaw::MACAddress mine; esp_wifi_get_mac(ESP_IF_WIFI_STA, (uint8_t*)&mine); return mine; } #endif }; #endif // WIFIRAW_H