GETNAMEINFO(3) Podręcznik programisty Linuksa GETNAMEINFO(3)

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

#include <sys/socket.h>
#include <netdb.h>
int getnameinfo(const struct sockaddr *restrict addr, socklen_t addrlen,
                char *restrict host, socklen_t hostlen,
                char *restrict serv, socklen_t servlen, int flags);
Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)):

getnameinfo():


Since glibc 2.22:
_POSIX_C_SOURCE >= 200112L
Glibc 2.21 and earlier:
_POSIX_C_SOURCE

Funkcja getnameinfo() jest odwrotnością funkcji getaddrinfo(3): tłumaczy, w sposób niezależny od protokołu, adres gniazda na odpowiadające mu nazwę komputera i usługi. Łączy w sobie funkcjonalność funkcji gethostbyaddr(3) oraz getservbyport(3), ale w przeciwieństwie do nich getnameinfo() jest bezpieczna dla wątków i pozwala programowi wyeliminować zależności od IPv4-kontra-IPv6.

Argument addr jest wskaźnikiem do ogólnej struktury adresu gniazda (typu sockaddr_in lub sockaddr_in6) o rozmiarze addrlen, która przechowuje wejściowy adres IP i numer portu. Argumenty host i port są wskaźnikami do zaalokowanych przez program wywołujący tę funkcję buforów (odpowiednio o rozmiarach hostlen i servlen), w których getnameinfo() umieści zakończone NULL-em łańcuchy znaków zawierające odpowiednio nazwę komputera i nazwy usług.

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 zmienia zachowanie getnameinfo() w następujący sposób:

Jeśli ustawiono, to w razie nieznalezienia nazwy komputera zwracany jest błąd.
Jeżeli ustawiono, to serwis jest oparty raczej na datagramach (UDP) niż na strumieniach (TCP). Jest to wymagane dla kilku portów (512\n514), które mają przypisane inne serwisy dla UDP niż dla TCP.
Jeżeli ustawiono, to zwracana jest tylko lokalna część nazwy komputera, a nie jego pełną domenowa nazwa sieciowa.
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).
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).

Począwszy do wersji 2.3.4 biblioteki glibc, getnameinfo() został rozszerzony i pozwala na przezroczystą konwersję nazw komputerów do i z formatu międzynarodowych nazw domenowych (Internationalized Domain Name — IDN; patrz RFC 3490, Internationalizing Domain Names in Applications (IDNA)). Zostały zdefiniowane trzy nowe flagi:

Jeśli użyto tego znacznika, to nazwa znaleziona przez proces wyszukiwania jest konwertowana z formatu IDN na kodowanie zgodne z bieżącymi ustawieniami językowymi. Nazwy składające się wyłącznie ze znaków ASCII nie są zmieniane, co pozwala na bezproblemowe używanie tego znacznika w istniejących programach i środowiskach.
Ustawienie tych znaczników włączy odpowiednio znaczniki IDNA_ALLOW_UNASSIGNED (zezwala na używanie nieprzypisanych znaków Unikodu) i IDNA_USE_STD3_ASCII_RULES (upewnia się, że zwracana nazwa komputera jest zgodna ze standardem STD3), które będą używane podczas obsługi IDNA.

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 NULL-em. 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:

Obecnie nie można znaleźć nazwy. Proszę spróbować później.
Argument flags ma niepoprawną wartość.
Wystąpił błąd krytyczny.
Nieznana rodzina adresów lub długość adresu nie jest odpowiednia dla podanej rodziny.
Brak pamięci.
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.
Bufor, na który wskazywał parametr host lub serv, był za mały.
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.

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

getnameinfo() jest dostarczane przez glibc od wersji 2.1.

Informacje o pojęciach używanych w tym rozdziale można znaleźć w podręczniku attributes(7).

Interfejs Atrybut Wartość
getnameinfo() Bezpieczeństwo wątkowe MT-Safe env locale

POSIX.1-2001, POSIX.1-2008, RFC 2553.

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

Od glibc 2.8 powyższe definicje są dostępne, jeśli zdefiniowano odpowiednie makro, mianowicie: _GNU_SOURCE, _DEFAULT_SOURCE (od glibc 2.19) lub (w wersjach glibc do 2.19 włącznie) _BSD_SOURCE lub _SVID_SOURCE.

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).

Przed glibc w wersji 2.2 argumenty hostlen i servlen były wprowadzane jako size_t.

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 *addr;     /* wejście */
socklen_t addrlen;         /* wejście */
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
if (getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), sbuf,

sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);

Następująca wersja sprawdza, czy adres gniazda ma odwrotne mapowanie adresu.


struct sockaddr *addr;     /* wejście */
socklen_t addrlen;         /* wejście */
char hbuf[NI_MAXHOST];
if (getnameinfo(addr, addrlen, hbuf, sizeof(hbuf),

NULL, 0, NI_NAMEREQD))
printf("nie można znaleźć nazwy komputera"); else
printf("komputer=%s\n", hbuf);

Przykładowy program używający getnameinfo() można znaleźć w getaddrinfo(3).

accept(2), getpeername(2), getsockname(2), recvfrom(2), socket(2), getaddrinfo(3), gethostbyaddr(3), getservbyname(3), getservbyport(3), inet_ntop(3), hosts(5), services(5), hostname(7), named(8)

R. Gilligan, S. Thomson, J. Bound and 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.

Angielska wersja tej strony pochodzi z wydania 5.13 projektu Linux man-pages. Opis projektu, informacje dotyczące zgłaszania błędów oraz najnowszą wersję oryginału można znaleźć pod adresem https://www.kernel.org/doc/man-pages/.

Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Robert Luberda <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>

Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.

Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres manpages-pl-list@lists.sourceforge.net.

22 marca 2021 r. GNU