Сетевое программирование в Linux: getaddrinfo () дает неверный результат - PullRequest
1 голос
/ 11 марта 2012

Это простая программа, я пишу ее, чтобы узнать все A record.

домена

Я заканчиваю и не получаю ни ошибок, ни предупреждений.

Затем я запускаю его, я обнаружил, что он дает неправильный IP, например:

. / A.out www.google.com

2.0.0.0

2.0.0.0

Это мой код:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(int argc, char *argv[])
{
    struct addrinfo addrC;
    struct addrinfo *addrL;
    struct addrinfo *temp;

    memset(&addrC, 0, sizeof(addrC));
    addrC.ai_family = AF_INET;
    addrC.ai_socktype = SOCK_STREAM;
    addrC.ai_protocol = IPPROTO_TCP;

    if (getaddrinfo(argv[1], "http", &addrC, &addrL) != 0)
    {
        perror("getaddrinfo!");
        exit(1);
    }

    for (temp = addrL; temp != NULL; temp = temp->ai_next)
    {
        char addrBuf[BUFSIZ];
        void *addrCount = &((struct sockaddr_in*)temp)->sin_addr;
        inet_ntop(temp->ai_addr->sa_family, addrCount, addrBuf, sizeof(addrBuf));
        printf("%s\n", addrBuf);
    }
    for (temp = addrL; temp != NULL; temp = addrL)
    {
        addrL = temp->ai_next;
        free(temp);
    }
    return 0;
}

Почему? и как это исправить?

Ответы [ 2 ]

1 голос
/ 11 марта 2012

Другой ответ правильный, но я бы рекомендовал использовать getnameinfo (используя NI_NUMERICHOST) вместо inet_ntop. Тогда у вас не было бы этой ошибки.

Кроме того, вы не должны зацикливать и освобождать результат от getaddrinfo. Вы вызываете freeaddrinfo, чтобы освободить весь массив.

1 голос
/ 11 марта 2012

У вас есть ошибка в приведении указателя внутри цикла, оно должно быть:

void *addrCount = &((struct sockaddr_in*)temp->ai_addr)->sin_addr;

В противном случае вы читаете мусор и передаете этот мусор в inet_ntop, поэтому в результате вы получаете мусор:)

...