IvanPletnev 0 26 декабря, 2019 Опубликовано 26 декабря, 2019 · Жалоба Уважаемые коллеги, здравствуйте! Столкнулся с такой проблемой. STM32F429, стек LWIP v.2.0.3, FreeRTOS. Пытаюсь создать сокет SOCK_RAW для периодического пинга подключенного клиента, он не создаётся. Причем, похоже, задача виснет, потому что диагностические сообщение не выводятся. При этом сокеты SOCK_STREAM и SOCK_DGRAM создаются без проблем. Кто-нибудь подскажет, куда копнуть? if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) { puts("PING socket error"); return; } printf("Socket No %u created\r\n", s); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IvanPletnev 0 27 декабря, 2019 Опубликовано 27 декабря, 2019 · Жалоба Похоже, я нашел причину. В отладчике Atollic TrueStudio я обратил внимание на то, что задача виснет, когда в стеке находятся функции, отправляющие сообщения в очередь. Начал копать LWIP и обнаружил, что DEFAULT_RAW_RECVMBOX_SIZE в файле opt.h равен 0. Поэтому, наверное, задача и виснет. Пока не пробовал, но должно помочь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ksv198 0 27 декабря, 2019 Опубликовано 27 декабря, 2019 · Жалоба 2 hours ago, IvanPletnev said: Похоже, я нашел причину. В отладчике Atollic TrueStudio я обратил внимание на то, что задача виснет, когда в стеке находятся функции, отправляющие сообщения в очередь. Начал копать LWIP и обнаружил, что DEFAULT_RAW_RECVMBOX_SIZE в файле opt.h равен 0. Поэтому, наверное, задача и виснет. Пока не пробовал, но должно помочь. Да, в файле lwipopts.h должно быть определено #define DEFAULT_RAW_RECVMBOX_SIZE 3 //need for RAW sockets (например) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IvanPletnev 0 28 декабря, 2019 Опубликовано 28 декабря, 2019 · Жалоба Так, кое-что заработало. Теперь у меня отправляется один ICMP пакет тык. Но вылезла очередная проблема. Вот моя функция подготовки пакета: static void ping_prepare_echo(struct icmp_echo_hdr *iecho, u16_t len) { size_t i; size_t data_len = len - sizeof(struct icmp_echo_hdr); ICMPH_TYPE_SET(iecho, ICMP_ECHO); ICMPH_CODE_SET(iecho, 0); iecho->chksum = 0; iecho->id = PING_ID; iecho->seqno = htons(++ping_seq_num); /* fill the additional data buffer with some data */ for (i = 0; i < data_len; i++) { ((char*) iecho)[sizeof(struct icmp_echo_hdr) + i] = (char) i; } iecho->chksum = inet_chksum(iecho, len); } Wireshark говорит мне, что некорректная контрольная сумма. 0x0000 вместо 0x574e тык. Хотя контрольная сумма считается правильно и заносится в заголовок ICMP пакета тык. Все остальные поля структуры передаются правильно, а контрольная сумма при передаче куда-то исчезает. Видимо поэтому, когда я пытаюсь пинговать windows компьютер, он на этот пакет ничего не отвечает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 28 декабря, 2019 Опубликовано 28 декабря, 2019 · Жалоба 5 часов назад, IvanPletnev сказал: Хотя контрольная сумма считается правильно и заносится в заголовок ICMP пакета А не включен ли у вас аппаратный подсчет контрольных сумм? Возможно, он при отправке учитывает и рассчитанное вами значение и получает в итоге ноль. Там в lwIP была куча #define включения программного подсчета CRC для разных типов пакетов (CHECKSUM_GEN_XXX и CHECKSUM_CHECK_XXX), при использоавании аппаратного подсчета они все должны быть равны нулю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IvanPletnev 0 29 декабря, 2019 Опубликовано 29 декабря, 2019 · Жалоба 10 hours ago, Сергей Борщ said: А не включен ли у вас аппаратный подсчет контрольных сумм? Возможно, он при отправке учитывает и рассчитанное вами значение и получает в итоге ноль. Там в lwIP была куча #define включения программного подсчета CRC для разных типов пакетов (CHECKSUM_GEN_XXX и CHECKSUM_CHECK_XXX), при использоавании аппаратного подсчета они все должны быть равны нулю. Точно! Вы правы! У меня включен аппаратный расчет контрольных сумм. Я просто закомментировал функцию расчета контрольной суммы iecho->chksum = inet_chksum(iecho, len); и всё заработало!!!! Спасибо огромное!. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться