ОБЗОР
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
ОПИСАНИЕ
Данная функция преобразует строку символов src в структуру сетевого
адреса сетевого семейства адресов af, а затем копирует полученную
структуру по адресу dst. Значение аргумента af должно быть равно
AF_INET или AF_INET6.
В настоящее время поддерживаются следующие семейства адресов:
AF_INET Значение src указывает на строку символов, содержащую сетевой адрес IPv4 в точечном формате «ddd.ddd.ddd.ddd», где ddd — десятичное число в диапазоне от 0 до 255, состоящее максимум из трёх цифр. Адрес преобразуется в struct in_addr и копируется в dst, размер которой должен быть равен sizeof(struct in_addr) (4) байтам (32 бита).
AF_INET6 Значение src указывает на строку символов, содержащую сетевой адрес IPv6. Адрес преобразуется в struct in6_addr и копируется в dst, размер которой должен быть равен sizeof(struct in6_addr) (16) байтам (128 бит). Допустимые форматы адресов IPv6:
1. Предпочтительный формат — x:x:x:x:x:x:x:x. Он состоит из восьми шестнадцатеричных чисел, каждое из которых представляет 16-битное значение (т. е., каждый x может содержать до 4 шестнадцатеричных цифр).
2. Серия непрерывных нулевых значений в предпочтительном формате может сокращённо записываться как ::. В адресе допускается только одно появление ::. Например, адрес интерфейса обратной петли 0:0:0:0:0:0:0:1 может быть сокращён до ::1. Шаблонный адрес, состоящий из всех нулей, может быть записан как ::.
3. Альтернативный формат — полезен для записи IPv4-отображённых адресов IPv6. Этот формат имеет вид x:x:x:x:x:x:d.d.d.d, где шесть начальных x представляют собой шестнадцатеричные значения, которые определяют шесть наиболее значимых 16-битных частей адреса (т. е., 96 бит), а символами d выражается значение в точечно-десятичном формате, которое определяет наименее значимые 32 бита адреса. Пример адреса: ::FFFF:204.152.189.116. Дополнительную информацию о представлении адресов IPv6 смотрите в RFC 2373.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении функция inet_pton() возвращает 1 (адрес
преобразован). Функция возвращает 0, если src не содержит строку
символов, представляющую правильный сетевой адрес для указанного семейства
адресов. Если af не содержит допустимого значения семейства адресов, то
возвращается -1 и errno присваивается значение EAFNOSUPPORT.
АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс Атрибут Значение
inet_pton()
безвредность в потоках: безвредно (MT-Safe locale)
СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.
ЗАМЕЧАНИЯ
В отличие от inet_aton(3) и inet_addr(3), inet_pton() поддерживает
адреса IPv6. Но стоит отметить, что inet_pton() работает только с
адресами IPv4 в точечно-десятичном формате, в то время как inet_aton(3) и
inet_addr(3) поддерживают более распространённый формат чисел-с-точками
(numbers-and-dots notation) (шестнадцатеричный и восьмеричный формат чисел,
и форматы, которые не требуют явного указания всех четырёх
байт). Программный интерфейс, который понимает одновременно адреса и IPv6, и
IPv4 в формате чисел-с-точками, смотрите getaddrinfo(3).
ДЕФЕКТЫ
При AF_INET6 не распознаются адреса IPv4. В этом случае в src должен указываться IPv4-отображённый адрес IPv6.
ПРИМЕР
Представленная ниже программа показывает использование inet_pton() и
inet_ntop(3). Пример работы программы:
$ ./a.out i6 0:0:0:0:0:0:0:0 :: $ ./a.out i6 1:0:0:0:0:0:0:8 1::8 $ ./a.out i6 0:0:0:0:0:FFFF:204.152.189.116 ::ffff:204.152.189.116
Исходный код программы
#include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { unsigned char buf[sizeof(struct in6_addr)]; int domain, s; char str[INET6_ADDRSTRLEN]; if (argc != 3) { fprintf(stderr, "Использование: %s {i4|i6|<число>} строка\n", argv[0]); exit(EXIT_FAILURE); } domain = (strcmp(argv[1], "i4") == 0) ? AF_INET : (strcmp(argv[1], "i6") == 0) ? AF_INET6 : atoi(argv[1]); s = inet_pton(domain, argv[2], buf); if (s <= 0) { if (s == 0) fprintf(stderr, "Неверный формат представления"); else perror("inet_pton"); exit(EXIT_FAILURE); } if (inet_ntop(domain, buf, str, INET6_ADDRSTRLEN) == NULL) { perror("inet_ntop"); exit(EXIT_FAILURE); } printf("%s\n", str); exit(EXIT_SUCCESS); }