Элементы, исключенные из вывода буферного массива после заданной структуры (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. Это:

  1. 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)

  2. struct RxControl rx_ctrl;, under struct SnifferPacket

    а. Комментирование: Все 12 элементов появляются в выходных данных snifferPacket (10100010 10000 11100110 1010000 0 0 0 0 0 0 1 0)

Таким образом, ясно, что существует связь между определением атрибутов и их исключением из выходных данных снифферПакета.

Обратите внимание, что ведущие 0 являются частью элемента, которые игнорируются и являются частью вывода. Например:

 - 0100 = 100
 - 0000 = 0
 - 1000 = 1000

Итак, мои вопросы таковы:

  1. Что представляет собой каждый из этих 12 элементов?
  2. Почему существует разница в выходных данных между выходными данными необработанного буфера и снифферПакета?
  3. Почему только определенные атрибуты влияют на вывод snifferPacket?
  4. Почему комментирование большего числа атрибутов приводит к появлению большего числа элементов, независимо от того, какие атрибуты комментируются?

Заранее спасибо.

, 👍1

Обсуждение

https://en.cppreference.com/w/cpp/language/bit_field, @Majenko


1 ответ


Лучший ответ:

1

Что представляет собой каждый из 12 элементов?

Вещи в заголовке. Здесь это не по теме.

Почему существует разница в выводе между выводом необработанного буфера и snifferPacket?

snifferPacket накладывается поверх входящего буфера. Это включает в себя буфер "данных", который вы печатаете. Буфер данных-это только часть снифферПакета.

Почему только определенные атрибуты влияют на выход snifferPacket?

Это битовые поля, и они упакованы в байты или слова. Количество и размер битовых полей влияют на количество байтов, необходимых для их содержания, и, следовательно, на то, откуда в структуре берется массив данных.

Почему комментирование большего числа атрибутов приводит к появлению большего числа элементов, независимо от того, какие атрибуты комментируются?

См.выше. Кроме того, атрибуты должны быть там. Удаление их будет означать, что другие атрибуты не указывают на нужные биты в памяти.

Вы должны узнать, как работают битовые поля Си. Вы можете прочитать больше в справочнике по C++ здесь.

,