getnameinfo(3)

NAZWA
getnameinfo - tłumaczenie adresu na nazwę w sposób niezależny od protokołu

SKŁADNIA
#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);

OPIS
Funkcja getnameinfo(3) obsługuje niezależne od protokołu tłumaczenie adresu do nazwy komputera. Łączy w sobie funkcjonalność funkcji gethostbyaddr(3) oraz getservbyport(3) i jest odwrotnością getaddrinfo(3). Argument sa jest wskaźnikiem do ogólnej struktury adresu gniazda (typu sockaddr_in lub sockaddr_in6) o rozmiarze salen, która przechowuje wejściowy adres IP i numer portu. Argumenty host i port są wskaźnikami do buforów (odpowiednio o rozmiarach hostlen i servlen), w których zapisane będą zwrócone wartości. Funkcja wywołująca może określić, że nazwa komputera (lub nazwa serwisu) nie jest potrzebna, przez przekazanie wartości NULL w argumencie host (lub serv) albo przez podanie 0 w parametrze hostlen (lub servlen). Jednakże co najmniej jeden z podanych parametrów (nazwa komputera lub nazwa serwisu) musi być ustawiony. Argument flags w następujący sposób zmienia zachowanie getnameinfo(3):

NI_NOFQDN
    Jeżeli ustawiono, to dla lokalnych komputerów zwraca tylko ich nazwy, a nie pełną domenową nazwę sieciową (FQDN).

NI_NUMERICHOST
    Jeśli ustawiono, to nazwa komputera jest zwracana w formie numerycznej. (Może się to również zdarzyć wtedy, gdy nie ustawiono tej flagi i nie można znaleźć nazwy komputera).

NI_NAMEREQD
    Jeśli ustawiono, to w razie nieznalezienia nazwy komputera zwracany jest błąd.

NI_NUMERICSERV
    Jeżeli ustawiono, to zwracany jest adres serwisu w postaci numerycznej, na przykład jako numer portu.

NI_DGRAM
    Jeżeli ustawiono, to serwis jest oparty raczej na datagramach (UDP) niż na strumieniach (TCP). Jest to wymagane dla kilku portów (512-514), które mają przypisane inne serwisy dla UDP niż dla TCP.

WARTOŚĆ ZWRACANA
W przypadku powodzenia zwracane jest 0, a nazwy komputera i usług, jeśli ich zażądano, są wypełniane łańcuchami znaków zakończonymi nullem. Nazwy te mogą zostać obcięte, tak aby zmieściły się w podanych długościach bufora. W razie błędu zwracany jest jeden z poniższych niezerowych kodów błędu:

EAI_AGAIN
    Obecnie nie można znaleźć nazwy, Proszę spróbować później.

EAI_BADFLAGS
    Parametr flags ma niepoprawną wartość.

EAI_FAIL
    Wystąpił błąd krytyczny.

EAI_FAMILY
    Nieznana rodzina adresów lub długość adresu nie jest odpowiednia dla podanej rodziny.

EAI_MEMORY
    Brak pamięci.

EAI_NONAME
    Nie można rozwinąć nazwy dla podanych parametrów. Ustawiono NI_NAMEREQD, a nie można znaleźć nazwy komputera albo nie zażądano ani nazwy komputera, ani nazwy serwisu.

EAI_OVERFLOW
    Bufor, na który wskazywał parametr host lub serv, był za mały.

EAI_SYSTEM
    Wystąpił błąd systemowy. Numer błędu można znaleźć w zmiennej errno.

Funkcja gai_strerror(3) przekształca te kody błędów w komunikat zrozumiały dla człowieka, więc jest odpowiednia do raportowania błędów.

PLIKI
/etc/hosts
/etc/nsswitch.conf
/etc/resolv.conf

UWAGA
Aby pomóc programiście w wyborze odpowiedniego rozmiaru buforów, w <netdb.h> zdefiniowano stałe
    # define NI_MAXHOST      1025
    # define NI_MAXSERV      32
Pierwsza z nich jest stałą MAXDNAME zdefiniowaną w pliku nagłówkowym <arpa/nameser.h> z nowszych wersji BIND-a. Druga jest zgadywaniem opartym na liście serwisów w bieżącym RFC dotyczącym przypisanych numerów (Assigned Numbers RFC).

PRZYKŁAD
Następujący kod próbuje pobrać numeryczną nazwę komputera i nazwę usługi dla podanego adresu gniazda. Proszę zauważyć, że nie ustawiono na sztywno żadnej rodziny adresów.
      struct sockaddr *sa;    /* wejście */
      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("komputer=%s, serwis=%s\n", hbuf, sbuf);
Następująca wersja sprawdza, czy adres gniazda ma odwrotne mapowanie adresu.
      struct sockaddr *sa; /* wejście */
      char hbuf[NI_MAXHOST];
      if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf),
          NULL, 0, NI_NAMEREQD))
             printf("nie można znaleźć nazwy komputera");
      else
             printf("komputer=%s\n", hbuf);

ZGODNE Z
RFC 2553 (Patrz także XNS, temat 5.2).

ZOBACZ TAKŻE
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 i W. Stevens, Basic Socket Interface Extensions for IPv6, RFC 2553, marzec 1999.

Tatsuya Jinmei i Atsushi Onoe, An Extension of Format for IPv6 Scoped Addresses, szkic internetowy, prace trwają. ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipngwg-scopedaddr-format-02.txt

Craig Metz, Protocol Independence Using the Sockets API, Proceedings of the freenix track: Coroczna techniczna konferencja USENIX 2000, czerwiec 2000. http://www.usenix.org/publications/library/proceedings/usenix2000/freenix/metzprotocol.html