Заголовок полученного IP-пакета отличается от wireshark

#c #network-programming #ip #ping #icmp

#c #сетевое программирование #ip #ping #icmp

Вопрос:

Я пытаюсь перекодировать команду ping на C в образовательных целях. Отправка ICMP кажется нормальной (я сравнил ее с оригинальным ping на wireshark), но при приеме IP-пакетов у меня возникает следующая проблема:

16 бит общей длины в заголовке IP отличаются от того, что я вижу на wireshark. Я использую функцию recvmsg() для получения данных в буфере, как показано ниже.

ОБНОВЛЕНИЕ: у меня есть такое поведение на macos, но не на виртуальной машине Linux

     struct msghdr msg;
    struct iovec iov[1];
    char databuf[1000];
    char datacontrol[1000];

    bzero(amp;(msg), sizeof(msg));
    bzero(amp;(iov), sizeof(iov));
    bzero(amp;(databuf), sizeof(databuf));
    bzero(amp;(datacontrol), sizeof(datacontrol));


    msg.msg_name = env->addr->ai_addr;
    msg.msg_namelen = env->addr->ai_addrlen;
    iov[0].iov_base = amp;(databuf[0]);
    iov[0].iov_len = sizeof(databuf);
    msg.msg_iov = iov;
    msg.msg_iovlen = 1;
    msg.msg_control = amp;(datacontrol[0]);
    msg.msg_controllen = sizeof(datacontrol);
    msg.msg_flags = 0;

    int retrecv = recvmsg(env.sockfd, amp;(msg), MSG_WAITALL);

 

Когда я отображаю данные, которые я получаю в databuf, как показано ниже:

     for (int i = 0; i < 20; i  )
    {
        for (int j = 7; j >= 0; j--)
            printf("%d", ((databuf[i] >> j) amp; 1));
        printf("  ");
        if (i == 7 || i == 15)
            printf("n");
    }

 

У меня это как результат:

 01000101  00000000  01000000  00000000  00000000  00000000  00000000  00000000
01110100  00000001  11010111  00110011  11011000  00111010  11010101  01001110  
11000000  10101000  00000001  01000100
 

когда в настоящее время на wireshark у меня:

 01000101  00000000  00000000  01010100  00000000  00000000  00000000  00000000
01110100  00000001  11010111  00110011  11011000  00111010  11010101  01001110  
11000000  10101000  00000001  01000100
 

Все биты одинаковы, кроме 3-го и 4-го (общая длина IP-пакета). Я знаю о проблеме малого / большого конца, но я не понимаю, в чем разница.

Спасибо!

Комментарии:

1. Не имеет отношения к вашей проблеме, но семантически ваше использование оператора address-of amp; для массивов неверно. Вы должны передать указатель на первый элемент, а не указатель на массив. Например, plain databuf сам по себе будет распадаться на указатель на его первый элемент, amp;databuf[0] т. Е. Имеющий тип char * . При использовании amp;databuf вы получаете указатель на сам массив, который имеет тип char (*)[1000] . Вам повезло, что оба указывают на одно и то же местоположение, но, как я уже сказал, они семантически отличаются из-за разницы в типе.

2. Верно! Я не заметил, но я изменил его. Спасибо!