• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос Генерация ARP и ICMP пакетов

vasimv

New member
Взял скетч "метеостанции" с DHT22, запускается и работает. Но через какое-то время теряется связь с модулем. Похоже, что-то не так с обработкой ARP-запросов в модуле, если постоянно пинговать адрес модуля с другого хоста, то все работает прекрасно. Можно конечно просто резетить или переподсоединяться к WiFi , но не хотелось бы.

Поэтому и вопрос - а есть ли готовая библиотека для Arduino IDE с отсылкой ICMP-пакетов (пингов)? Или может какой-то генератор RAW-пакетов, чтобы я мог сам периодически посылать ARP-анонсы с MAC-адресом модуля?

Нашел только ICMP-библиотеку для шилда W5100 и еще одну, для голого SDK, но не пойму как ее к Arduino IDE прикрутить. :(
 

vasimv

New member
Ok, разобрался сам. Добавил в библиотеку ESP8266WiFi.cpp метод forceARP() и дергаю его каждые две секунды. Он рассылает по всем сетевым интерфейсам gratuitous ARP анонс со своими MAC/IP, так что больше никто модуль не теряет в сети. Дергаю этот метод каждую секунду.

Код:
extern "C" {
#include "lwip/netif.h"

err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr)ICACHE_FLASH_ATTR;
}

void ESP8266WiFiClass::forceARP() {
   struct netif *netif = netif_list;
   while (netif)
   {
      etharp_request((netif), &(netif)->ip_addr);
      netif = netif->next;
   }

}

Ну или более кривой вариант, зато без изменения библиотек (обычная функция в любом месте скетча). Может перестать работать, если сильно поменяется сетевой стек:

Код:
extern "C" {
char *netif_list;
uint8_t etharp_request(char *, char *);
}

void forceARP() {
  char *netif = netif_list;

  while (netif)
   {
      etharp_request((netif), (netif+4));
      netif = *((char **) netif);
   }
}
 
Последнее редактирование:
Ok, разобрался сам. Добавил в библиотеку ESP8266WiFi.cpp метод forceARP() и дергаю его каждые две секунды. Он рассылает по всем сетевым интерфейсам gratuitous ARP анонс со своими MAC/IP, так что больше никто модуль не теряет в сети. Дергаю этот метод каждую секунду.

Код:
extern "C" {
#include "lwip/netif.h"

err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr)ICACHE_FLASH_ATTR;
}

void ESP8266WiFiClass::forceARP() {
   struct netif *netif = netif_list;
   while (netif)
   {
      etharp_request((netif), &(netif)->ip_addr);
      netif = netif->next;
   }

}

Ну или более кривой вариант, зато без изменения библиотек (обычная функция в любом месте скетча). Может перестать работать, если сильно поменяется сетевой стек:

Код:
extern "C" {
char *netif_list;
uint8_t etharp_request(char *, char *);
}

void forceARP() {
  char *netif = netif_list;

  while (netif)
   {
      etharp_request((netif), (netif+4));
      netif = *((char **) netif);
   }
}
Спасибо за раскрытие темы. Действительно есть такая проблема. Теряется связь. По поводу изменения библиотеки - это всё что вы изменили? Не надо ничего добавлять в файле *.h ?
 
почему то не видит IDE моих изменений. Странно. Добавил и в cpp и в h. А при компиляции выдает что нет такого члена в классе.
 

vasimv

New member
почему то не видит IDE моих изменений. Странно. Добавил и в cpp и в h. А при компиляции выдает что нет такого члена в классе.
Даты файлов поменялись? CTRL-R попробуйте, может просто закэшировались скомпилированные версии. Или просто не те файлы меняли (копия неиспользуемая) - мои лежали в C:\Documents and Settings\vasim\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\2.0.0-rc2\libraries\ESP8266WiFi\src\
 
Даты файлов поменялись? CTRL-R попробуйте, может просто закэшировались скомпилированные версии. Или просто не те файлы меняли (копия неиспользуемая) - мои лежали в C:\Documents and Settings\vasim\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\2.0.0-rc2\libraries\ESP8266WiFi\src\
C этим разобрался. Просто у меня 2 пользователя и я не там менял. Но всё равно при компиляции выдает неизвестную ошибку когда доходит до библиотеки WiFi. Может я не правильно подставил код.
тут я правильно подставил в библиотеке? extern "C" уже был так я в него вписал две строчки.
extern "C" {
[HASHTAG]#include[/HASHTAG] "lwip/netif.h"
[HASHTAG]#include[/HASHTAG] "c_types.h"
[HASHTAG]#include[/HASHTAG] "ets_sys.h"
[HASHTAG]#include[/HASHTAG] "os_type.h"
[HASHTAG]#include[/HASHTAG] "osapi.h"
[HASHTAG]#include[/HASHTAG] "mem.h"
[HASHTAG]#include[/HASHTAG] "user_interface.h"
[HASHTAG]#include[/HASHTAG] "smartconfig.h"
[HASHTAG]#include[/HASHTAG] "lwip/opt.h"
[HASHTAG]#include[/HASHTAG] "lwip/err.h"
[HASHTAG]#include[/HASHTAG] "lwip/dns.h"
err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr)ICACHE_FLASH_ATTR;
}
Ну а дальше то понятно. Добавил класс force() и в файле *.h добавил void.
 

vasimv

New member
C этим разобрался. Просто у меня 2 пользователя и я не там менял. Но всё равно при компиляции выдает неизвестную ошибку когда доходит до библиотеки WiFi. Может я не правильно подставил код.
тут я правильно подставил в библиотеке? extern "C" уже был так я в него вписал две строчки.
extern "C" {
[HASHTAG]#include[/HASHTAG] "lwip/netif.h"
[HASHTAG]#include[/HASHTAG] "c_types.h"
[HASHTAG]#include[/HASHTAG] "ets_sys.h"
[HASHTAG]#include[/HASHTAG] "os_type.h"
[HASHTAG]#include[/HASHTAG] "osapi.h"
[HASHTAG]#include[/HASHTAG] "mem.h"
[HASHTAG]#include[/HASHTAG] "user_interface.h"
[HASHTAG]#include[/HASHTAG] "smartconfig.h"
[HASHTAG]#include[/HASHTAG] "lwip/opt.h"
[HASHTAG]#include[/HASHTAG] "lwip/err.h"
[HASHTAG]#include[/HASHTAG] "lwip/dns.h"
err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr)ICACHE_FLASH_ATTR;
}
Ну а дальше то понятно. Добавил класс force() и в файле *.h добавил void.
Да вроде верно. А что за ошибка? Попробуйте второй вариант, с кодом прямо в конечном скетче, все равно вероятность того, что там все сильно поменяется - практически нулевая.
 
Да вроде верно. А что за ошибка? Попробуйте второй вариант, с кодом прямо в конечном скетче, все равно вероятность того, что там все сильно поменяется - практически нулевая.
Ошибка типа 1 Exit и всё. Ошибка компиляции.
Если в скетче напрямую, то компиляция успешная.
А есть вообще разница?
И что вы имели ввиду написав, что может не работать? Это в случае,если в скетче прописывать или в обоих вариантах может быть сбой?
 

vasimv

New member
Ошибка типа 1 Exit и всё. Ошибка компиляции.
Если в скетче напрямую, то компиляция успешная.
А есть вообще разница?
И что вы имели ввиду написав, что может не работать? Это в случае,если в скетче прописывать или в обоих вариантах может быть сбой?
С точки зрения конечного результата - разницы не какой (главное не забывать ее дергать периодически). Но может перестать работать, если они в sdk поменяют функцию etharp_request (почти нулевая вероятность, так как эта функция не собственность китайцев, а из библиотеки LWIP).
 
Большое спасибо!!!
Долго не мог ничего найти. Действительно у есп есть такая байда, что если долго не общаться с ним, то потом он как бы отваливается от роутера, но сам он думает что подключен. Надеюсь ваше предложение поможет. Странно, что никто не поднимает этот вопрос.
 
Сверху Снизу