Получение IP-адреса из struct sockaddr не работает для 32-битной компиляции - PullRequest
1 голос
/ 11 мая 2011

У меня есть небольшое клиент-серверное приложение, которое отправляет / получает пакеты обнаружения UDP. Когда получен пакет UDP, я хочу отобразить исходный IP. Код клиент / сервер основан на примере UDP от Beej: https://beej.us/guide/bgnet/html/multi/clientserver.html

Когда я компилирую для 64-битной версии, IP отображается так, как ожидалось, но когда я компилирую для 32-битной версии (опция -m32), он вообще не получает правильного значения.

Фрагмент кода:

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

...

printf("listener: waiting to recvfrom...\n");
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
    (struct sockaddr *)their_addr, &addr_len)) == -1) {
    perror("recvfrom");
    exit(1);
}

printf("listener: got packet from %s\n",
    inet_ntop(their_addr->sa_family,
        get_in_addr((struct sockaddr *)their_addr),
        s, sizeof s));

printf("Sockaddr: ");
for (i=0; i<sizeof(struct sockaddr_in); i++)
    printf("%x ", ((char *)their_addr)[i]);
printf("\n");

Правильный вывод при компиляции для 64 бит:

    listener: waiting to recvfrom...
    listener: got packet from 192.168.20.6
    Sockaddr: 2 0 ffffff80 19 ffffffc0 ffffffa8 14 6 64 2e 40 0 0 0 0 0 

Неверный вывод при компиляции с -m32:

    listener: waiting to recvfrom...
    listener: got packet from 168.32.140.255
    Sockaddr: 2 0 ffffff80 19 ffffffa8 20 ffffff8c ffffffff 50 ffffffdd 7d fffffff7 4 0 0 0 

Я не очень понимаю, почему возникает проблема с использованием get_in_addr или inet_ntop при компиляции для 32-битного?

Ответы [ 3 ]

3 голосов
/ 11 мая 2011

addr_len должен быть установлен на размер структуры адреса, а не на размер указателя (это работает в 64-битном режиме, потому что указатели в этом режиме в два раза больше). Так и должно быть:

addr_len = sizeof *their_addr;

Кстати, как инициализируется their_addr? Там должна быть реальная структура, на которую можно указать.

2 голосов
/ 11 мая 2011

Помимо ошибок, это неправильный способ обработки IP-адресов.Вы должны использовать getnameinfo с флагом NI_NUMERICHOST для получения презентабельных форм адресов.Тогда вам не нужно заботиться о том, v4 или v6, или даже v7 или v8.

0 голосов
/ 11 мая 2011

get_in_addr не является стандартной функцией.Скорее всего, ваша реализация делает это неправильно.Покажите код.

...