# Getaddrinfo

> Mediated Wiki article. Canonical URL: https://mediated.wiki/source/Getaddrinfo
> Markdown URL: https://mediated.wiki/source/Getaddrinfo.md
> Source: https://en.wikipedia.org/wiki/Getaddrinfo
> Source revision: 1339371567
> License: Creative Commons Attribution-ShareAlike 4.0 International (https://creativecommons.org/licenses/by-sa/4.0/)

{{lowercase title}}
{{short description|C programming function}}
In [C programming](/source/C_(programming_language)), the  [function](/source/function_(computer_science))s '''{{code|getaddrinfo()}}''' and '''{{code|getnameinfo()}}'''  convert [domain name](/source/domain_name)s, [hostname](/source/hostname)s, and [IP address](/source/IP_address)es between human-readable text representations and structured binary formats for the [operating system](/source/operating_system)'s networking API. Both functions are contained in the [POSIX](/source/POSIX) standard [application programming interface](/source/application_programming_interface) (API).<ref name="posix-function-spec">{{cite web
|url=https://pubs.opengroup.org/onlinepubs/9799919799/functions/getaddrinfo.html
|title=freeaddrinfo, getaddrinfo — get address information
|work=The Open Group Base Specifications Issue 8
|edition=POSIX.1-2024
|publisher=[The Open Group](/source/The_Open_Group)
|access-date=2025-12-07
|url-status=live
|archive-url=https://web.archive.org/web/20250814074405/https://pubs.opengroup.org/onlinepubs/9799919799/functions/getaddrinfo.html
|archive-date=2025-08-14
}}</ref>

getaddrinfo and getnameinfo are inverse functions of each other. They are network protocol agnostic, and support both [IPv4](/source/IPv4) and [IPv6](/source/IPv6). It is the recommended interface for name resolution in building protocol independent applications and for transitioning legacy IPv4 code to the IPv6 Internet.

Internally, the functions may use a variety of resolution methods not limited to the [Domain Name System](/source/Domain_Name_System) (DNS). The [Name Service Switch](/source/Name_Service_Switch) is commonly used on Unix-like systems and affects most implementation of this pair as it did with [their BSD-socket era predecessors](/source/Berkeley_sockets).<ref>{{cite web |title=nss - man pages section 5: File Formats |url=https://docs.oracle.com/cd/E88353_01/html/E37852/nss-5.html |website=docs.oracle.com}}</ref>

=={{mono|addrinfo}}==
The [C](/source/C_(programming_language)) data structure used to represent results of address address information queries for use in the networking API might be defined as follows, possibly with members in another order or additional members:<ref name="posix-netdb.h">{{cite web
|title=netdb.h — definitions for network database operations
|url=https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netdb.h.html
|access-date=2025-12-07
|url-status=live
|archive-url=https://web.archive.org/web/20250616191423/https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netdb.h.html
|archive-date=2025-06-16
|work=The Open Group Base Specifications Issue 8, IEEE Std. 1003.1-2024
|edition=POSIX.1-2024
|publisher=[The Open Group](/source/The_Open_Group)
}}</ref>{{refn|group=note|In some older systems the type of {{code|ai_addrlen}} is {{code|size_t}} instead of {{code|socklen_t}}. Most socket functions, such as {{code|accept()}} and {{code|getpeername()}}, require the parameter to have type {{code|socklen_t *}} and programmers often pass the address to the {{code|ai_addrlen}} element of the {{code|addrinfo}} structure. If the types are incompatible, e.g., on a 64-bit [Solaris 9](/source/Solaris_9) system where {{code|size_t}} is 8 bytes and {{code|socklen_t}} is 4 bytes, then run-time errors may result.<ref name="solaris9getaddrinfo3">{{cite book
|title=Solaris 9 12/02 Reference Manual Collection
|date=December 2002
|publisher=[Sun Microsystems](/source/Sun_Microsystems)
|chapter=man pages Section 3: Networking Library Functions, getaddrinfo(3SOCKET)
|chapter-url=https://docs.oracle.com/cd/E19683-01/816-5216/6mbchamap/index.html
|access-date=2025-12-07
|url-status=live
|archive-url=https://web.archive.org/web/20251207174922/https://docs.oracle.com/cd/E19683-01/816-5216/6mbchamap/index.html
|archive-date=2025-12-07
}}</ref>}}

<syntaxhighlight lang="c">
struct addrinfo {
    int ai_flags;
    int ai_family;
    int ai_socktype;
    int ai_protocol;
    socklen_t ai_addrlen;
    struct sockaddr *ai_addr;
    char *ai_canonname;
    struct addrinfo *ai_next;
};
</syntaxhighlight>

The structure contains a member {{code|ai_family}} and a member {{code|ai_addr}} pointing to a {{code|struct sockaddr}} object with its own {{code|sa_family}} field. These are set to the same value when the structure is created with function {{code|getaddrinfo()}} in some implementations.{{cn|date=December 2025}}

=={{mono|getaddrinfo}}==
{{code|getaddrinfo()}} converts human-readable text strings representing [hostname](/source/hostname)s or [IP address](/source/IP_address)es into a list of struct addrinfo structures.
The [function prototype](/source/function_prototype) is:<ref name="posix-function-spec"/>

<syntaxhighlight lang="c">
int getaddrinfo(const char *restrict hostname,
       const char *restrict service,
       const struct addrinfo *restrict hints,
       struct addrinfo **restrict res);
</syntaxhighlight>

; ''{{mono|hostname}}''
: can be either a domain name, such as "[example.com](/source/example.com)", an address string, such as "{{IPaddr|127.0.0.1}}", or {{code|NULL}}, in which case the address {{IPaddr|0.0.0.0}} or {{IPaddr|127.0.0.1}} is assigned depending on the hints flags.
; ''{{mono|service}}''
: can be a port number passed as string, such as {{mono|"80"}}, or a service name, e.g. {{mono|"echo"}}. In the latter case a typical implementation uses {{code|getservbyname()}} to query the file {{mono|/etc/services}} to resolve the service to a port number.
; ''{{mono|hints}}''
: can be either {{code|NULL}} or an {{code|addrinfo}} structure with the type of service requested.
; ''{{mono|res}}''
: is a pointer that will be assigned to point to a new [dynamically allocated](/source/Dynamic_memory_allocation) [linked list](/source/linked_list) of {{code|addrinfo}} structures with the information requested after successful completion of the function, to be freed with {{code|freeaddrinfo()}}.<ref>Stevens R., Fenner, Rudoff [2003] UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking API. Publisher: Addison-Wesley Professional. Pub. Date: November 14, 2003 p. 256</ref>

The function returns 0 upon success and non-zero error value if it fails,<ref name="posix-function-spec" /> which can be mapped to a human-readable string using {{code|gai_strerror()}}<ref name="posix-gai_strerror">{{cite web
|title=gai_strerror — address and name information error description
|url=https://pubs.opengroup.org/onlinepubs/9799919799/functions/gai_strerror.html
|access-date=2025-12-07
|url-status=live
|archive-url=https://web.archive.org/web/20250519052537/https://pubs.opengroup.org/onlinepubs/9799919799/functions/gai_strerror.html
|archive-date=2025-05-19
|work=The Open Group Base Specifications Issue 8, IEEE Std. 1003.1-2024
|edition=POSIX.1-2024
|publisher=[The Open Group](/source/The_Open_Group)
}}</ref>

Implementations vary among platforms, but often the function will look up hostnames in the [DNS](/source/Domain_Name_System) if not, and look up services among a [well-known service database](/source/List_of_TCP_and_UDP_port_numbers).
The exact set of sources queried for hostname and service resolution is often controlled by the system's [Name Service Switch](/source/Name_Service_Switch) configuration.

=={{mono|freeaddrinfo}}==
The function {{code|freeaddrinfo()}} frees the memory allocated by function {{code|getaddrinfo()}}. Given a linked list of {{code|struct addrinfo}} objects starting at ''{{mono|ai}}'', yielded by <code>getaddrinfo(..., &''ai'')</code>, <code>freeaddrinfo(''ai'')</code> frees every {{code|struct addrinfo}} object in that list.
<syntaxhighlight lang="c">
void freeaddrinfo(struct addrinfo *ai);
</syntaxhighlight>

=={{mono|getnameinfo}}==
The function {{code|getnameinfo()}} converts the internal binary representation of an IP address in the form of a pointer to a {{code|struct sockaddr}} into text strings consisting of the hostname or, if the address cannot be resolved into a name, a textual IP address representation, as well as the service port name or number. The function prototype is specified as follows:
<syntaxhighlight lang="c">
int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,
       char *restrict host, socklen_t hostlen,
       char *restrict service, socklen_t servicelen,
       int flags);
</syntaxhighlight>

==Example==
The following example uses {{code|getaddrinfo()}} to resolve the domain name {{mono|www.example.com}} into its list of addresses and then calls {{code|getnameinfo()}} on each result to return the canonical name for the address. In general, this produces the original [hostname](/source/hostname), unless the particular address has multiple names, in which case the ''canonical'' name is returned. In this example, the domain name is printed three times, once for each of the three results obtained.
<syntaxhighlight lang="c">
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>

#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif

int main(void) {
    const char query_host[] = "www.example.com";
    struct addrinfo *result;

    struct addrinfo hints = {
        .ai_family = AF_UNSPEC,
        .ai_socktype = SOCK_STREAM
    };

    // Resolve the domain name into a list of addresses
    int gai_rc = getaddrinfo(query_host, NULL, &hints, &result);
    switch (gai_rc) {
        case 0:
            break;
        case EAI_SYSTEM:
            fprintf(stderr, "Failed to resolve server address '%s': system error %s\n",
                query_host, strerror(errno));
            return EXIT_FAILURE;
        default:
            fprintf(stderr, "Failed to resolve server address '%s': %s\n",
                query_host, gai_strerror(gai_rc));
            return EXIT_FAILURE;
    }

    // Perform reverse DNS lookup for each resolved address
    for (const struct addrinfo *ai = result; ai != NULL; ai = ai->ai_next) {
        char hostname[NI_MAXHOST];
        char addr[NI_MAXHOST];

        int gni_rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
            sizeof(addr), NULL, 0, NI_NUMERICHOST);
        if (gni_rc != 0) {
            fprintf(stderr, "Failed to format address: %s\n", gai_strerror(gni_rc));
            continue;
        }

        gni_rc = getnameinfo(ai->ai_addr, ai->ai_addrlen,
            hostname, sizeof(hostname), NULL, 0, 0);
        switch (gni_rc) {
            case 0:
                printf("Hostname for %s: %s\n", addr, hostname);
                break;
            case EAI_SYSTEM:
                fprintf(stderr, "Reverse DNS lookup for %s: system error %s\n",
                    addr, strerror(errno));
                break;
            default:
                fprintf(stderr, "Reverse DNS lookup failed for %s: %s\n",
                    addr, gai_strerror(gni_rc));
        }
    }

    freeaddrinfo(result);
    return 0;
}
</syntaxhighlight>

==See also==
*[Network address](/source/Network_address)

==Notes==
{{reflist|group=note}}

==References==
{{reflist}}

==External links==
* [https://pubs.opengroup.org/onlinepubs/9799919799/functions/getaddrinfo.html freeaddrinfo and getaddrinfo specifications in POSIX.1-2024]. ''The Open Group Base Specifications Issue 8, 2024 edition''
* [https://datatracker.ietf.org/doc/html/rfc3493 RFC 3493, Basic Socket Interface Extensions for IPv6]

Category:Internet Protocol
Category:Network addressing
Category:Domain Name System
Category:C POSIX library
Category:Articles with example C code

---
Adapted from the Wikipedia article [Getaddrinfo](https://en.wikipedia.org/wiki/Getaddrinfo) by Wikipedia contributors ([contributor history](https://en.wikipedia.org/wiki/Getaddrinfo?action=history)). Available under [Creative Commons Attribution-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/). Changes may have been made.
