Сообщите, является ли текстовая строка адресом IPv6 или IPv4 с использованием стандартного API-интерфейса сокетов C - PullRequest
9 голосов
/ 17 сентября 2010

У меня есть программа, в которой внешний компонент передает мне строку, содержащую IP-адрес.Затем мне нужно превратить его в URI.Для IPv4 это легко;Я добавляю http: // и добавляю /.Однако для IPv6 мне также необходимо заключить его в квадратные скобки [].

Существует ли стандартный вызов API сокетов для определения семейства адресов этого адреса?

Ответы [ 2 ]

20 голосов
/ 17 сентября 2010

Вид. Вы можете использовать inet_pton(), чтобы попытаться проанализировать строку сначала как IPv4 (AF_INET), а затем IPv6 (AF_INET6). Код возврата сообщит вам, если функция выполнена успешно, и, таким образом, строка содержит адрес типа попытки.

Например:

#include <arpa/inet.h>
#include <stdio.h>

static int
ip_version(const char *src) {
    char buf[16];
    if (inet_pton(AF_INET, src, buf)) {
        return 4;
    } else if (inet_pton(AF_INET6, src, buf)) {
        return 6;
    }
    return -1;
}

int
main(int argc, char *argv[]) {
    for (int i = 1; i < argc; ++i) {
        printf("%s\t%d\n", argv[i], ip_version(argv[i]));
    }

    return 0;
}
13 голосов
/ 17 сентября 2010

Используйте getaddrinfo () и установите флаг подсказки AI_NUMERICHOST, семейство AF_UNSPEC, после успешного возврата из getaddrinfo результирующий член struct addrinfo .ai_family будет либо AF_INET, либо AF_INET6.

РЕДАКТИРОВАТЬ, маленький пример

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>

int main(int argc, char *argv[])
{
    struct addrinfo hint, *res = NULL;
    int ret;

    memset(&hint, '\0', sizeof hint);

    hint.ai_family = PF_UNSPEC;
    hint.ai_flags = AI_NUMERICHOST;

    ret = getaddrinfo(argv[1], NULL, &hint, &res);
    if (ret) {
        puts("Invalid address");
        puts(gai_strerror(ret));
        return 1;
    }
    if(res->ai_family == AF_INET) {
        printf("%s is an ipv4 address\n",argv[1]);
    } else if (res->ai_family == AF_INET6) {
        printf("%s is an ipv6 address\n",argv[1]);
    } else {
        printf("%s is an is unknown address format %d\n",argv[1],res->ai_family);
    }

   freeaddrinfo(res);
   return 0;
}

$ ./a.out 127.0.0.1
127.0.0.1 is an ipv4 address
$ ./a.out ff01::01
ff01::01 is an ipv6 address
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...