2.然而如果要在wireshark情況下分析也需要了解.pcapng檔格式,下方程式內也都包含了.pcapng開頭結尾檔格式。
這部分是混雜模式下開頭檔格式
對稱1為Section Header Block (SHB)
0x0000001C(Hex)為28(Dec),所以表示從0x0A0D0D0A到0x0000001C總共有28byte
對稱2為Interface Description Block (IDB)
程式1:
serialwrite_32(0x0A0D0D0A);
serialwrite_32(0x0000001C); //對稱1--
serialwrite_32(0x1A2B3C4D);
serialwrite_32(0x00000001);
serialwrite_32(0xFFFFFFFF);
serialwrite_32(0xFFFFFFFF);
serialwrite_32(0x0000001C); //對稱1--
serialwrite_32(0x00000001);
serialwrite_32(0x00000014); //對稱2--
serialwrite_32(105);
serialwrite_32(0x0000FFFF);
serialwrite_32(0x00000014); //對稱2--
我需要確保這個funtion回傳的len是要4的倍數。
程式2:
if (len / 4 != 0)
{
len += 4 - (len % 4);
}
對稱3為Enhanced Packet Block (EPB)
當esp8266從空中抓到任何封包轉成.pcapng格式需要頭尾格式,再來就是格式裡面有一個重要需要注意的(Packet Data variable length, padded to 32 bits),收到的資料不管是127還是多少,都需要補足到132。
其中一定會好奇為什麼我會多打入兩組0x00000000,這是固定需要補足的地方,上面程式2是捕到4的倍數,但這是需要補到132byte,wireshark才有辦法做分析
程式3:
serialwrite_32(0x00000006);
serialwrite_32(len + 36); //對稱3--
serialwrite_32(0x00000000);
serialwrite_32(timestamp);
serialwrite_32(microseconds);
serialwrite_32(incl_len);
serialwrite_32(orig_len);
char bufStr[1] = { 0 };
char *zero = 0;
for (int i = 12 ; i <= len ; i++)
{
sprintf(bufStr, "%02X ", buf[i]);
Serial.print(bufStr);
if ((len / 4) != 0 && i == len)
{
for (int k = 1 ; k <(4 - (len % 4)) ; k++)
{
sprintf(bufStr, "%02X ", zero);
Serial.print(bufStr);
}
}
}
serialwrite_32(0x00000000);
serialwrite_32(0x00000000);
serialwrite_32(orig_len);
serialwrite_32(len + 36); //對稱3--
以下是完整程式碼
#include <ESP8266WiFi.h>
unsigned long time_ = 0;
#define HOP_INTERVAL 214
#define MAX_CHANNEL 11
#define CHANNEL 1
unsigned long lastChannelChange = 0;
int ch = CHANNEL;
char macStr[18] = { 0 };
int input_need_catch_count , count_number = 0;
bool CHANNEL_HOPPING = true;
void sniffer(uint8_t *buf, uint16_t len)
{
uint32_t timestamp = 0;
uint32_t microseconds = (unsigned int)(micros() - millis() * 1000); //micro seconds offset (0 - 999)
if (len / 4 != 0)
{
len += 4 - (len % 4);
}
uint32_t orig_len = len;
uint32_t incl_len = len;
serialwrite_32(0x00000006);
serialwrite_32(len + 36);
serialwrite_32(0x00000000);
serialwrite_32(timestamp);
serialwrite_32(microseconds);
serialwrite_32(incl_len);
serialwrite_32(orig_len);
char bufStr[1] = { 0 };
char *zero = 0;
for (int i = 12 ; i <= len ; i++)
{
sprintf(bufStr, "%02X ", buf[i]);
Serial.print(bufStr);
if ((len / 4) != 0 && i == len)
{
for (int k = 1 ; k <(4 - (len % 4)) ; k++)
{
sprintf(bufStr, "%02X ", zero);
Serial.print(bufStr);
}
}
}
serialwrite_32(0x00000000);
serialwrite_32(0x00000000);
serialwrite_32(orig_len);
serialwrite_32(len + 36);
++count_number;
if (count_number == input_need_catch_count)
{
CHANNEL_HOPPING = false;
wifi_promiscuous_enable(0);
}
}
void setup()
{
uint8_t mac[6];
Serial.begin(115200);
wifi_set_opmode(STATION_MODE);
WiFi.begin("Fan", "66666663");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.println(WiFi.hostname());
Serial.print("\n inpute need catch count:");
while(input_need_catch_count <= 1)
{
input_need_catch_count = Serial.parseInt();
}
Serial.println(input_need_catch_count);
Serial.println("\n -> WiFi Sniffer");
Serial.println(" -> Initializing!");
wifi_promiscuous_enable(0);
wifi_station_disconnect();
wifi_set_promiscuous_rx_cb(sniffer);
wifi_promiscuous_enable(1);
Serial.println(" -> Init finished!\n");
time_ = millis();
Serial.println("-----");
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]);
Serial.println(String(macStr));
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]);
Serial.println(String(macStr));
Serial.println("-----");
serialwrite_32(0x0A0D0D0A);
serialwrite_32(0x0000001C);
serialwrite_32(0x1A2B3C4D);
serialwrite_32(0x00000001);
serialwrite_32(0xFFFFFFFF);
serialwrite_32(0xFFFFFFFF);
serialwrite_32(0x0000001C);
serialwrite_32(0x00000001);
serialwrite_32(0x00000014);
serialwrite_32(105);
serialwrite_32(0x0000FFFF);
serialwrite_32(0x00000014);
}
void loop()
{
if(CHANNEL_HOPPING)
{
unsigned long currentTime = millis();
if(currentTime - lastChannelChange >= HOP_INTERVAL){
lastChannelChange = currentTime;
ch++; //increase channel
if(ch > MAX_CHANNEL) ch = 1;
wifi_set_channel(ch); //switch to new channel
}
}
}
void escape32(uint32_t n, uint8_t* buf)
{
buf[0] = n;
buf[1] = n >> 8;
buf[2] = n >> 16;
buf[3] = n >> 24;
}
void serialwrite_32(uint32_t n)
{
uint8_t _buf[4];
char bufStr[4];
escape32(n, _buf);
sprintf(bufStr, "%02X %02X %02X %02X ", _buf[0], _buf[1], _buf[2], _buf[3]);
Serial.print(bufStr);
// Serial.write(_buf, 4);
}
最後我會直接輸入需要抓幾個封包,但通常很容易都會多抓
上述如果有錯誤或是更好的方法,提醒和交流我會非常感激。
沒有留言:
張貼留言