Málokterá síťová aplikace pro IPv4 se asi obejde bez použití systému DNS a tím i funkce gethostbyname(). V kontextu IPv6 je ale tato funkce nepoužitelná. Každý uzel Internetu podporující IPv6 totiž bude mít kromě jedné nebo více adres IPv6 obvykle také adresu IPv4. Obě verze adres mohou být v DNS přiřazeny stejnému doménovému jménu - adresu IPv4 najdeme v záznamu typu A a adresu IPv6 v záznamu typu AAAA. Funkce gethostbyname() neumožňuje říci, který z obou typů záznamu chceme, popřípadě zda chceme oba. RFC 2553 proto zavedlo nové funkce getipnodebyname() a getipnodebyaddr() pro převod jména na adresu a obráceně. Bohužel i tyto funkce se ukázaly jako nedostatečné, neboť nepodporují dosahy adres //(address scopes)//. V novějších verzích API byly proto také zavrženy. Pro převod jména na adresu tak zbyla jediná, protokolově nezávislá funkce - getaddrinfo(), jež má svůj původ ve standardu IEEE POSIX 1003.1g. Kromě gethostbyname() plně nahrazuje i funkci getservbyname(). Prototyp vypadá takto:
int *getaddrinfo(const char *nodename, const char *servname,
const struct addrinfo *hints, struct addrinfo **res);
Funkce vrací buď nulu v případě úspěchu anebo různé chybové kódy. Skutečný výsledek je předán prostřednictvím argumentu ''res'', který je ukazatelem na jednosměrný seznam struktur typu ''addrinfo'' definovaného v //netdb.h//:
struct addrinfo
{
int ai_flags; /* Input flags. */
int ai_family; /* Protocol family for socket. */
int ai_socktype; /* Socket type. */
int ai_protocol; /* Protocol for socket. */
socklen_t ai_addrlen; /* Length of socket address. */
struct sockaddr *ai_addr; /* Socket address for socket. */
char *ai_canonname; /* Canonical name. */
struct addrinfo *ai_next; /* Pointer to next in list. */
};
Položka ''ai_next'' ukazuje na následující prvek seznamu, poslední prvek seznamu pak zde má NULL. Paměť pro seznam musí být alokována dynamicky, a proto musíme (alespoň v C) pamatovat na řádné uvolnění této paměti po použití. K tomu slouží funkce freeaddrinfo().
Každý z prvků seznamu obsahuje položky, které můžeme přímo použít jako argumenty pro funkci socket(): ''ai_family'' (v našem případě ''PF_INET'' či ''PF_INET6'', ''ai_socktype'' (obvykle ''SOCK_STREAM'' nebo ''SOCK_DGRAM'') a ''ai_protocol'' (obvykle ''IPPROTO_TCP'' nebo ''SOCK_UDP''). Položka ''ai_addr'' pak ukazuje na adresu soketu, jejíž délku specifikuje položka ''ai_addrlen''.
Argument ''nodename'' by měl obsahovat doménové jméno, o které nám jde, popřípadě obvyklý textový zápis adresy IPv4 nebo IPv6. Pokud chceme, můžeme vyplnit i argument ''servname'' a to buď jménem služby podle ///etc/services// anebo dekadickým číslem portu ve formě řetězce.
Argument ''hints'' umožňuje stanovit, o jaký typ dat máme zájem. Jeho typem je opět ''struct addrinfo'', v níž ovšem smějí být vyplněny jen tyto položky: ''ai_flags'', ''ai_family'', ''ai_socktype'' a ''ai_protocol''. Ostatní položky musí být vynulovány. V případě, že v některé kategorii jsme připraveni přijmout cokoli, nastavíme hodnoty podle následující tabulky. Nemáme-li preference v žádné kategorii, stačí předat NULL na místě argumentu ''hints''.
^ **Kritérium**^ **Položka**^ **Nastavení** |
| Libovolná adresová rodina| ''ai_family''| ''AF_UNSPEC'' |
| Libovolný typ soketu| ''ai_socktype''| 0 |
| Libovolný protokol| ''ai_protocol''| 0 |
Položka ''ai_flags'' v argumentu ''hints'' hints obsahuje příznaky //(flags)//, kterými můžeme své požadavky specifikovat ještě detailněji. Jak je obvyklé, jednotlivé příznaky můžeme kombinovat pomocí operace bitového OR (''|''). K dispozici jsou tyto příznaky:
** ''AI_PASSIVE''
**\\ Tento příznak hraje roli jen v případě, že je na místě argumentu ''nodename'' předána hodnota NULL. Příznak nastavíme, pokud chceme výstup funkce getaddrinfo() použít pro funkci bind(), tj. na lokální straně soketu. Adresa soketu se v tom případě vyplní s ''INADDR_ANY'' pro IPv4 nebo ''IN6ADDR_ANY_INIT'' pro IPv6 (viz oddíl [[bsd_sockets_-_zakladni_funkce|Základní funkce]]). Pokud chceme výstup funkce getaddrinfo() použít pro vzdálenou stranu soketu, tedy např. ve funkcích connect() či sendto(), pak tento příznak nenastavíme. Dostaneme pak adresu soketu s ''INADDR_LOOPBACK'' pro IPv4 nebo ''IN6ADDR_LOOPBACK_INIT'' pro IPv6.
** ''AI_CANONNAME''
**\\ Nastavíme-li tento příznak a argument ''nodename'' není NULL, funkce getaddrinfo() se pokusí též vyhledat //kanonické doménové jméno// uzlu. To se hodí třeba tehdy, když známe DNS alias a chceme zjistit kanonické jméno.
** ''AI_NUMERICHOST''
**\\ Pokud je tento příznak nastaven, musí být argument ''nodename'' řetězcem reprezentujícím adresu IPv4 nebo IPv6. Funkce getaddrinfo() pak vůbec nepoužívá DNS.
** ''AI_NUMERICSERV''
**\\ Tento příznak nastavíme, pokud chceme jako argument ''servname'' použít řetězec s dekadickým číslem portu.
** ''AI_V4MAPPED''
**\\ Tento příznak má smysl jen pro ''AF_INET6'' v položce ''ai_family'' argumentu ''hints''. Pokud je nastaven a funkce getaddrinfo() nenalezne pro zadané ''nodename'' v DNS žádné záznamy typu AAAA, poskytne jako výsledek obsah záznamů typu A (pokud takové existují) ve formě IPv4-mapovaných adres IPv6 //(IPv4-mapped IPv6 addresses)//.
** ''AI_ALL''
**\\ Je-li tento příznak nastaven zároveň s ''AI_V4MAPPED'' a ''hints.ai_family'' je ''AF_INET6'', pak funkce getaddrinfo() vrátí adresové údaje ze //všech// záznamů DNS typu AAAA i A, přičemž posledně jmenované budou opět ve formě IPv4-mapovaných adres IPv6. V případě, že adresová rodina není specifikována, tj. ''hints.ai_family==AF_UNSPEC'' anebo ''hints==NULL'', bere se nastavení příznaků ''AI_V4MAPPED'' a ''AI_ALL'' v úvahu jen tehdy, je-li na hostitelském počítači podporováno IPv6.
** ''AI_ADDRCONFIG''
**\\ Nastavení tohoto příznaku vede k tomu, že funkce getaddrinfo() vrátí adresy IPv4 jen tehdy, je-li na hostitelském počítači zkonfigurována nějaká lokální adresa IPv4 a podobně vrátí adresy IPv6 jen tehdy, je-li zkonfigurována aspoň jedna lokální adresa IPv6 (v obou případech se nepočítá adresa zpětné smyčky).
V jistém smyslu inverzní funkcí ke getaddrinfo() je tato funkce:
int getnameinfo(const struct sockaddr *sa, socklen_t salen,
char *node, socklen_t nodelen, char *service,
socklen_t servicelen, int flags);
Jejím úkolem je převod obsahu adresy soketu na doménové jméno uzlu a/nebo jméno služby. Návratová hodnota je opět buď nula v případě úspěchu nebo příslušný chybový kód.
Struktura typu ''sockaddr'', na niž ukazuje argument ''sa'', může obsahovat adresu IPv6 s vnořenou adresou IPv4, tedy buď IPv4-mapovanou nebo IPv4-kompatibilní adresu. V takovém pádu se vnořená adresa IPv4 extrahuje a nadále se pokračuje tak, jako by byla předložena struktura s adresou IPv4.
Výsledky převodu funkce getnameinfo zapisuje do bufferů, na které ukazují argumenty ''node'' a ''service''. Tyto buffery musí mít dopředu přidělenu paměť a argumenty ''nodelen'' a ''servicelen'' udávají jejich délku. Je-li některý z argumentů ''node'' a ''service'' předán jako nulový ukazatel, příslušná hodnota se nevrací.
Poslední argument ''flags'' specifikuje následující příznaky, které mohou být opět kombinovány pomocí bitového OR:
** ''NI_NOFQDN''
**\\ Při nastavení tohoto příznaku se pro lokální uzel vrátí jen jeho samotné jméno, tedy bez domény.
** ''NI_NUMERICHOST''
**\\ Při jeho nastavení se do ''*node'' zapíše řetězec reprezentující numerickou adresu. Pokud je to adresa IPv6, může v ní být vyznačena i zóna adresy //(address scope)//, například ''"fe80::1%eth0"''.
** ''NI_NUMERICSCOPE''
**\\ Je-li nastaven tento příznak společně s předchozím, pak se zóna v textové reprezentaci adresy IPv6 zapíše jako číslo (např. index rozhraní) a nikoli symbolické jméno (např. ''eth0'').
** ''NI_NUMERICSERV''
**\\ Obdobně při nastavení tohoto příznaku se do ''*service'' zapíše řetězec s dekadickým číslem portu.
** ''NI_NAMEREQD''
**\\ Pokud je příznak nastaven a doménové jméno uzlu nemůže být nalezeno, vrátí funkce getnameinfo nenulový chybový kód.
** ''NI_DGRAM''
**\\ Nastavení tohoto příznaku naznačuje, že se jedná o nespojovanou službu (''SOCK_DGRAM''). Implicitně se předpokládá spojovaná služba (''SOCK_STREAM'').