Элементы, исключенные из вывода буферного массива после заданной структуры (ESP8266 WifiSniffer) (snifferPacket)
В настоящее время я пытаюсь определить, как работает программа ESP8266 WifiSniffer от Kalanda.
Вот исходный код:
#include <Arduino.h>
extern "C" {
#include <user_interface.h>
}
#define DATA_LENGTH 112
#define TYPE_MANAGEMENT 0x00
#define TYPE_CONTROL 0x01
#define TYPE_DATA 0x02
#define SUBTYPE_PROBE_REQUEST 0x04
struct RxControl {
//THESE HAVE AN EFFECT
// signed rssi:8; // signal intensity of packet
// unsigned rate:4;
// unsigned is_group:1;
// unsigned:1;
// unsigned legacy_length:12; // if not 11n packet, shows length of packet. NOT THIS
// unsigned MCS:7; // if is 11n packet, shows the modulation and code used (range from 0 to 76)
// unsigned Smoothing:1;
// unsigned Not_Sounding:1;
// unsigned:1;
// unsigned Aggregation:1;
// unsigned STBC:2;
// unsigned rxend_state:8;
// unsigned ampdu_cnt:8;
// unsigned channel:4; //which channel this packet in.
//THESE HAVE NO EFFECT
// unsigned sig_mode:2; // 0:is 11n packet; 1:is not 11n packet;
// unsigned damatch0:1;
// unsigned damatch1:1;
// unsigned bssidmatch0:1;
// unsigned bssidmatch1:1;
// unsigned CWB:1; // if is 11n packet, shows if is HT40 packet or not
// unsigned HT_length:16;// if is 11n packet, shows length of packet. NOT THIS
//unsigned FEC_CODING:1; // if is 11n packet, shows if is LDPC packet or not.
//unsigned SGI:1;
//unsigned:12; //HAS NO EFFECT
};
struct SnifferPacket{
struct RxControl rx_ctrl; //RxControl is just a name, can be named anything (as long as you change other things)
uint8_t data[DATA_LENGTH]; //DOES NOT HAVE EFFECT
// uint16_t cnt; //THIS HAS NO EFFECT
// uint16_t len; //THIS HAS NO EFFECT
};
// Declare each custom function (excluding built-in, such as setup and loop) before it will be called.
// https://docs.platformio.org/en/latest/faq.html#convert-arduino-file-to-c-manually
//static void showMetadata(SnifferPacket *snifferPacket);
//static void sniffer_callback(uint8_t *buffer, uint16_t length);
static void printDataSpan(uint16_t start, uint16_t size, uint8_t* data);
static void getMAC(char *addr, uint8_t* data, uint16_t offset);
void channelHop();
/**
* Callback for promiscuous mode
*/
static void sniffer_callback(uint8_t *buffer, uint16_t length) {
struct SnifferPacket *snifferPacket;
snifferPacket = (struct SnifferPacket*) buffer;
Serial.print("buffer size: ");
Serial.print(sizeof(buffer));
Serial.print(" length size: ");
Serial.print(sizeof(length));
Serial.print(" snifferPacket size: ");
Serial.print(sizeof(snifferPacket));
Serial.print(" START OF BUFFER OG: ");
for (int i = 0; i < 20; i++){
Serial.print((unsigned int) buffer[i], BIN);
Serial.print(" ");
}
Serial.print(" END OF BUFFER OG ");
showMetadata(snifferPacket);
}
static void showMetadata(SnifferPacket *snifferPacket) {
unsigned int frameControl = ((unsigned int)snifferPacket->data[1] << 8) + snifferPacket->data[0];
uint8_t version = (frameControl & 0b0000000000000011) >> 0;
uint8_t frameType = (frameControl & 0b0000000000001100) >> 2;
uint8_t frameSubType = (frameControl & 0b0000000011110000) >> 4;
uint8_t toDS = (frameControl & 0b0000000100000000) >> 8;
uint8_t fromDS = (frameControl & 0b0000001000000000) >> 9;
uint8_t moreFragments = (frameControl & 0b0000010000000000) >> 10;
uint8_t retry = (frameControl & 0b0000100000000000) >> 11;
uint8_t powerMgmt = (frameControl & 0b0001000000000000) >> 12;
uint8_t moreData = (frameControl & 0b0010000000000000) >> 13;
uint8_t protectedFrame = (frameControl & 0b0100000000000000) >> 14;
uint8_t htcOrder = (frameControl & 0b1000000000000000) >> 15;
Serial.print(" START OF BUFFER: ");
for (int i = 0; i < 20; i++){
Serial.print((unsigned int)snifferPacket->data[i], BIN);
Serial.print(" ");
}
Serial.print(" END OF BUFFER ");
Serial.print(" DATASPAN START: ");
printDataSpan;
Serial.print(" DATASPAN END ");
Serial.print(" frameControl: ");
Serial.print(frameControl);
Serial.print(" version: ");
Serial.print(version);
Serial.print(" Type: ");
Serial.print(frameType);
Serial.print(" frameSubType: ");
Serial.print(frameSubType);
Serial.print(" toDS: ");
Serial.print(toDS);
Serial.print(" fromDS: ");
Serial.print(fromDS);
Serial.print(" moreFragments: ");
Serial.print(moreFragments);
Serial.print(" retry: ");
Serial.print(retry);
Serial.print(" powerMgmt: ");
Serial.print(powerMgmt);
Serial.print(" moreData: ");
Serial.print(moreData);
Serial.print(" protectedFrame: ");
Serial.print(protectedFrame);
Serial.print(" htcOrder: ");
Serial.print(htcOrder);
Serial.print(" Ch: ");
Serial.print(wifi_get_channel());
// Serial.print(" rssi: ");
// Serial.print(snifferPacket->rx_ctrl.rssi, BIN);
// Serial.print(" RSSI: ");
// Serial.print(snifferPacket->rx_ctrl.rssi, DEC);
//Only look for probe request packets
// if (frameType != TYPE_MANAGEMENT ||
// frameSubType != SUBTYPE_PROBE_REQUEST)
// //Serial.println();
// return;
// Serial.print(" RSSI: ");
// Serial.print(snifferPacket->rx_ctrl.rssi, DEC);
Serial.print(" Ch: ");
Serial.print(wifi_get_channel());
char addr[] = "00:00:00:00:00:00";
getMAC(addr, snifferPacket->data, 10);
Serial.print(" Peer MAC: ");
Serial.print(addr);
// uint8_t SSID_length = snifferPacket->data[25];
// Serial.print(" SSID: ");printDataSpan
// printDataSpan(26, SSID_length, snifferPacket->data);
Serial.println();
}
static void printDataSpan(uint16_t start, uint16_t size, uint8_t* data) {
for(uint16_t x = start; x < DATA_LENGTH && x < start+size; x++) {
Serial.print(data[x]);
//Serial.write(data[x]);
}
}
static void getMAC(char *addr, uint8_t* data, uint16_t offset) {
sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", data[offset+0], data[offset+1], data[offset+2], data[offset+3], data[offset+4], data[offset+5]);
}
#define CHANNEL_HOP_INTERVAL_MS 100
static os_timer_t channelHop_timer;
/**
* Callback for channel hoping
*/
void channelHop()
{
// hoping channels 1-13
uint8 new_channel = wifi_get_channel() + 1;
if (new_channel > 13) {
new_channel = 1;
}
wifi_set_channel(new_channel);
}
#define DISABLE 0
#define ENABLE 1
void setup() {
// set the WiFi chip to "promiscuous" mode aka monitor mode
Serial.begin(115200);
//delay(10);
wifi_set_opmode(STATION_MODE);
wifi_set_channel(1);
wifi_promiscuous_enable(DISABLE);
//delay(10);
wifi_set_promiscuous_rx_cb(sniffer_callback);
//delay(10);
wifi_promiscuous_enable(ENABLE);
// setup the channel hoping callback timer
//os_timer_disarm(&channelHop_timer);
//os_timer_setfn(&channelHop_timer, (os_timer_func_t *) channelHop, NULL);
//os_timer_arm(&channelHop_timer, CHANNEL_HOP_INTERVAL_MS, 1);
}
void loop() {
//delay(10);
}
Я заметил, что вывод Serial.print
непосредственно из буфера
отличается от вывода Serial.print
для переменной snifferPacket,
которая задана атрибутами структуры RxControl
.
Когда код настроен как обычный, выход необработанного буфера (BUFFER OG) имеет 12 дополнительных элементов по сравнению с выходом snifferPacket (BUFFER). Вот пример:
buffer size: 4 length size: 2 snifferPacket size: 4 START OF BUFFER OG: 10100010 10000 11100110 1010000 0 0 0 0 0 0 1 0 10000000 0 0 0 11111111 11111111 11111111 11111111 END OF BUFFER OG START OF BUFFER: 10000000 0 0 0 11111111 11111111 11111111 11111111 11111111 11111111 11011000 111 10110110 11010 10100010 1000001 11011000 111 10110110 11010 END OF BUFFER DATASPAN START: DATASPAN END frameControl: 128 version: 0 Type: 0 frameSubType: 8 toDS: 0 fromDS: 0 moreFragments: 0 retry: 0 powerMgmt: 0 moreData: 0 protectedFrame: 0 htcOrder: 0 Ch: 1 Ch: 1 Peer MAC: d8:07:b6:1a:a2:41
Сравнение только двух буферных выходов:
- BUFFER OG: 10100010 10000 11100110 1010000 0 0 0 0 0 0 1 0 10000000 0
0 0 11111111 11111111 11111111 11111111
- BUFFER: 10000000 0 0 0 11111111 11111111 11111111 11111111...
Я смог идентифицировать части первых 12 элементов:
1. 10100010 -> RCPI (RSSI) in two's complement format
2. 10000 -> Unknown
3. 11100110 -> Unknown
4. 1010000 -> Unknown
5. 0 -> Unknown, but constant
6. 0 -> Unknown, but constant
7. 0 -> Unknown, but constant
8. 0 -> Unknown, but constant
9. 0 -> Unknown, but constant
10. 0 -> Unknown, but constant
11. 1 -> Wi-Fi channel (in this example it's channel 1)
12. 0 -> Unknown, but constant
Эти 12 элементов приходят перед пакетом 802.11 (начиная с заголовка кадра, который начинается с 10000000)
Методом проб и ошибок мне удалось идентифицировать части кода, которые влияют на вывод snifferPacket. Это:
14 атрибутов в
структуре RxControl, названных ТАК, как
ОНИ ИМЕЮТ ЭФФЕКТ
.а. Комментирование между 1-8 любыми атрибутами: Последние 4 элемента появляются на
выходе snifferPacket (
0 0 1 0
)б. Комментирование между 9-13 любыми атрибутами: Последние 8 элементов появляются в
выходных данных snifferPacket (
0 0 0 0 0 0 1 0
)в) Комментирование всех 14 атрибутов: Последние 11 элементов появляются в выходных данных snifferPacket (
10000 11100110 1010000 0 0 0 0 0 0 1 0
)struct RxControl rx_ctrl;
, understruct SnifferPacket
а. Комментирование: Все 12 элементов появляются в выходных данных snifferPacket (
10100010 10000 11100110 1010000 0 0 0 0 0 0 1 0
)
Таким образом, ясно, что существует связь между определением атрибутов и их исключением из выходных данных снифферПакета.
Обратите внимание, что ведущие 0 являются частью элемента, которые игнорируются и являются частью вывода. Например:
- 0100 = 100
- 0000 = 0
- 1000 = 1000
Итак, мои вопросы таковы:
- Что представляет собой каждый из этих 12 элементов?
- Почему существует разница в выходных данных между выходными данными необработанного
буфера
иснифферПакета
? - Почему только определенные атрибуты влияют на вывод
snifferPacket
? - Почему комментирование большего числа атрибутов приводит к появлению большего числа элементов, независимо от того, какие атрибуты комментируются?
Заранее спасибо.
1 ответ
Лучший ответ:
Что представляет собой каждый из 12 элементов?
Вещи в заголовке. Здесь это не по теме.
Почему существует разница в выводе между выводом необработанного буфера и snifferPacket?
snifferPacket накладывается поверх входящего буфера. Это включает в себя буфер "данных", который вы печатаете. Буфер данных-это только часть снифферПакета.
Почему только определенные атрибуты влияют на выход snifferPacket?
Это битовые поля, и они упакованы в байты или слова. Количество и размер битовых полей влияют на количество байтов, необходимых для их содержания, и, следовательно, на то, откуда в структуре берется массив данных.
Почему комментирование большего числа атрибутов приводит к появлению большего числа элементов, независимо от того, какие атрибуты комментируются?
См.выше. Кроме того, атрибуты должны быть там. Удаление их будет означать, что другие атрибуты не указывают на нужные биты в памяти.
Вы должны узнать, как работают битовые поля Си. Вы можете прочитать больше в справочнике по C++ здесь.
- Почему мы используем client.flush() в коде, когда мы подключаем Esp8266 к Интернету или серверу?
- Какой максимальный размер статического документа Json в Arduino JSON?
- Использование ESP8266-01 с Arduino uno R3
- Ручное TCP-соединение с использованием неправильно набранной команды модуля WiFi ESP8266
- ESP-01 не посылает данных по последовательному каналу, как только он подключен к Wi-Fi-маршрутизатору
- ESP8266 не подключается к Wi-Fi
- AT-команда не отвечает на последовательный монитор
- Как подключить Wi-Fi Shield ESP-12E-ESP8266-UART-WIFI-Wireless-Shield к Arduino
https://en.cppreference.com/w/cpp/language/bit_field, @Majenko