Перейти к содержанию
    

STM32F107+uIP ICMP request

Доброго времени суток!

 

Суть проблемы: пытаюсь пропинговать с контроллера обычный комп в сети, использую uIP v 1.0

Сам стэк работает, все примеры нормально бегают, и вебсервер и телнет и.д.

Железяка пингуется со стороны компа. На компе ICMP разрешён, другие компы его пингуют.

При попытке отправить ICMP request с железяки Wireshark видит пакет, но комп не отвечает.

Вот скрин с Wireshark: post-7964-1387463067_thumb.png

 

Как отправляю - заполняю все поля в буфере (uip_buf) и пинаю:

 

uip_arp_out();

vSendMACData( uip_len ); //это функция отправки данных драйвера Ethernet для STM32F107

 

В Wireshark вижу, что сначала уходит ARP запрос и на него приходит нормальный ответ от компа, с МАС-ами и IP соответствующими железкам. А вот затем вижу ушедший ICMP request и.... никакого ответа.

 

В чём может быть засада?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Контрольную сумму (CRC) проверьте.

 

Да!!! Спасибо большое, 4 часа протупил, сумма в заголовке ICMP была не правильной.

Ответ пошёл.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да!!! Спасибо большое, 4 часа протупил, сумма в заголовке ICMP была не правильной.

Ответ пошёл.

 

Да,в IP пакетах надо CRC всегда считать...кстати STM аппаратно считает CRC этих пакетов установкой битов в дескрипторе передачи TDES0.CIC = 3

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кому надо, делается это вот так:

        // Составляем IP заголовок
        ICMPBUF->vhl = 0x45;
        ICMPBUF->tos = 0;
        uint16_t    len = sizeof(struct uip_icmpip_hdr);    // длина будет равна заголовку ip + icmp
        ICMPBUF->len[0] = len >> 8;
        ICMPBUF->len[1] = len & 0xff;
        uint16_t    ipid = 0;
        ICMPBUF->ipid[0] = ipid >> 8;
        ICMPBUF->ipid[1] = ipid & 0xff;
        ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
        ICMPBUF->ttl = UIP_TTL;
        ICMPBUF->proto = UIP_PROTO_ICMP;
        // указываем свой ip и ip удаленного устройства.
        uip_gethostaddr(ICMPBUF->srcipaddr);
        uip_ipaddr(&ICMPBUF->destipaddr, 192,168,1,101);

        ICMPBUF->ipchksum = 0;
        ICMPBUF->ipchksum = ~(uip_ipchksum());

        ICMPBUF->type = ICMP_ECHO;
        ICMPBUF->icode = 0;
        ICMPBUF->icmpchksum = 0;
        ICMPBUF->icmpchksum = uip_chksum((uint16_t*)&ICMPBUF->type, 8);
        ICMPBUF->icmpchksum = ~((ICMPBUF->icmpchksum == 0) ? 0xffff : ICMPBUF->icmpchksum);

        printf("type %d, code %d, icmpchksum %d\r\n", ICMPBUF->type, ICMPBUF->icode, ICMPBUF->icmpchksum);

        uip_len = UIP_IPH_LEN + 8;    // длина равна заголовку ip + заголовку icmp

        uip_arp_out();
        enc28j60_send_packet((uint8_t *) uip_buf, uip_len);

Данный код подходит как для пинга внутренней сети, так и внешней.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...