getnameinfo(3)

НАЗВАНИЕ
getnameinfo - перевод сетевого адреса в имя машины (способ действия не зависит от протокола)

СИНТАКСИС
#include <sys/socket.h>
#include <netdb.h>

int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                char *host, size_t hostlen,
                char *serv, size_t servlen, int flags);

ОПИСАНИЕ
Функция getnameinfo(3) предназначена для перевода сетевого адреса в имя машины, способом, который не зависит от сетевого протокола. Она сочетает в себе действия функций gethostbyaddr(3) и getservbyport(3), и является функцией обратной функции getaddrinfo(3). Аргумент sa - это указатель на структуру адреса сокета (типа sockaddr_in или sockaddr_in6) размером salen, которая содержит IP-адрес и номер порта. Аргументы host и serv указывают на буферы (размером hostlen и servlen соответственно), которые будут содержать возвращаемые значения. Если при вызове не требуется определять имя машины (или имя сервиса), тогда аргумент host (или serv) должен указывает на NULL или параметр hostlen (или servlen) должен быть равен нулю. Однако, по крайней мере один параметр, имя машины или имя сервиса, должно быть запрошено. Аргумент flags меняет поведение функции getnameinfo(3) следующим образом:

NI_NOFQDN
    Если этот флаг установлен, то возвращается только имени машины части полностью определенного имени домена (FQDN) для локальных машин.

NI_NUMERICHOST
    Если этот флаг установлен, то имя машины возвращается в числовой форме. (Если этот флаг не установлен, в этом случае имя узла не будет найдено.)

NI_NAMEREQD
    Если этот флаг установлен, тогда возвращается ошибка, если имя машины не может быть определено.

NI_NUMERICSERV
    Если этот флаг установлен, тогда имя сервиса возвращается в числовой форме, например по номеру его порта.

NI_DGRAM
    Если этот флаг установлен, тогда предпочтительнее имя сервиса основанного на протоколе UDP, чем имя сервиса основанного на протоколе TCP. Это требуется для немногих портов (512-514), которые имеют различные сервисы для UDP и TCP.

ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
При успешном завершении возвращается 0, имя узла и имя сервиса. Возможно сокращение имен в буфере до указанной длины. При ошибке возвращается ненулевое значение, а глобальная переменная errno устанавливается в соответствующее значение.

НАЙДЕННЫЕ ОШИБКИ

EAI_AGAIN
    Имя не может быть определено в настоящий момент. Попробуйте повторить попытку позже.

EAI_BADFLAGS
    Параметр flags имеет неверное значение.

EAI_FAIL
    Произошла непоправимая ошибка.

EAI_FAMILY
    Не распознано семейство адресов, или длина адреса была указана неверно для данного семейства.

EAI_MEMORY
    Недостаточно памяти.

EAI_NONAME
    Имя не может быть определено для указанных параметров. Установлен флаг NI_NAMEREQD и имя машины не может быть определено, или имя машины и имя сервиса не были запрошены.

EAI_SYSTEM
    Произошла системная ошибка. Код системной ошибки может быть получен из переменной errno.

ФАЙЛЫ
/etc/hosts
/etc/nsswitch.conf
/etc/resolv.conf

ЗАМЕЧАНИЯ
В файле <netdb.h> определены константы, которые надлежащим образом могут помочь программисту в выборе размеров для буферов:
    # define NI_MAXHOST      1025
    # define NI_MAXSERV      32
Константа MAXDNAME находится в файле последней версии BIND <arpa/nameser.h>. Списки сервисов находятся в соответствующих RFC.

ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ
Следующий код пытается получить имя машины и сервиса в числовой форме, для данного адреса сокета. Обратите внимание, что здесь нет прямых упоминаний на особое семейство адресов.
      struct sockaddr *sa;    /* ввод */
      char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
      if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf,
          sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0)
              printf("host=%s, serv=%s\n", hbuf, sbuf);
Следующая версия проверяет, если адрес сокета имеет обратное отображение адресов.
      struct sockaddr *sa; /* ввод */
      char hbuf[NI_MAXHOST];
      if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf),
          NULL, 0, NI_NAMEREQD))
             printf("невозможно определить имя машины");
      else
             printf("имя машины=%s\n", hbuf);

СООТВЕТСТВИЕ СТАНДАРТАМ
RFC 2553. (См. также XNS, 5.2.)

СМ. ТАКЖЕ
getaddrinfo(3), gethostbyaddr(3), getservbyname(3), getservbyport(3), inet_ntop(3), socket(3), hosts(5), services(5), hostname(7), named(8)

R. Gilligan, S. Thomson, J. Bound и W. Stevens, Basic Socket Interface Extensions for IPv6, RFC 2553, Март 1999.

Tatsuya Jinmei и Atsushi Onoe, An Extension of Format for IPv6 Scoped Addresses, черновик, находится в стадии написания. ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipngwg-scopedaddr-format-02.txt

Craig Metz, Protocol Independence Using the Sockets API, Продолжение темы 2000 USENIX ежегодной технической конференции, Июнь 2000. http://www.usenix.org/publications/library/proceedings/usenix2000/freenix/metzprotocol.html