🇮🇷 Iran Proxy | https://www.wikipedia.org/wiki/Getaddrinfo
Jump to content

getaddrinfo

From Wikipedia, the free encyclopedia

In C programming, the functions getaddrinfo() and getnameinfo() convert domain names, hostnames, and IP addresses between human-readable text representations and structured binary formats for the operating system's networking API. Both functions are contained in the POSIX standard application programming interface (API).[1]

getaddrinfo and getnameinfo are inverse functions of each other. They are network protocol agnostic, and support both IPv4 and 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 (DNS). The 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.[2]

addrinfo

[edit]

The C 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:[3][note 1]

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;
};

The structure contains a member ai_family and a member ai_addr pointing to a struct sockaddr object with its own sa_family field. These are set to the same value when the structure is created with function getaddrinfo() in some implementations.[citation needed]

getaddrinfo

[edit]

getaddrinfo() converts human-readable text strings representing hostnames or IP addresses into a list of struct addrinfo structures. The function prototype is:[1]

int getaddrinfo(const char *restrict hostname,
       const char *restrict service,
       const struct addrinfo *restrict hints,
       struct addrinfo **restrict res);
hostname
can be either a domain name, such as "example.com", an address string, such as "127.0.0.1", or NULL, in which case the address 0.0.0.0 or 127.0.0.1 is assigned depending on the hints flags.
service
can be a port number passed as string, such as "80", or a service name, e.g. "echo". In the latter case a typical implementation uses getservbyname() to query the file /etc/services to resolve the service to a port number.
hints
can be either NULL or an addrinfo structure with the type of service requested.
res
is a pointer that will be assigned to point to a new dynamically allocated linked list of addrinfo structures with the information requested after successful completion of the function, to be freed with freeaddrinfo().[5]

The function returns 0 upon success and non-zero error value if it fails,[1] which can be mapped to a human-readable string using gai_strerror()[6]

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

freeaddrinfo

[edit]

The function freeaddrinfo() frees the memory allocated by function getaddrinfo(). Given a linked list of struct addrinfo objects starting at ai, yielded by getaddrinfo(..., &ai), freeaddrinfo(ai) frees every struct addrinfo object in that list.

void freeaddrinfo(struct addrinfo *ai);

getnameinfo

[edit]

The function getnameinfo() converts the internal binary representation of an IP address in the form of a pointer to a 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:

int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,
       char *restrict host, socklen_t hostlen,
       char *restrict service, socklen_t servicelen,
       int flags);

Example

[edit]

The following example uses getaddrinfo() to resolve the domain name www.example.com into its list of addresses and then calls getnameinfo() on each result to return the canonical name for the address. In general, this produces the original 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.

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

#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif

int main(void) {
    struct addrinfo *result, *ai;
    int error;

    // resolve the domain name into a list of addresses
    error = getaddrinfo("www.example.com", NULL, NULL, &result);
    if (error != 0) {   
        if (error == EAI_SYSTEM) {
            perror("getaddrinfo");
        } else {
            fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error));
        }   
        return EXIT_FAILURE;
    }

    // loop over all returned results and do inverse lookup
    for (ai = result; ai != NULL; ai = ai->ai_next) {   
        char hostname[NI_MAXHOST];
        error = getnameinfo(ai->ai_addr, ai->ai_addrlen,
            hostname, sizeof(hostname), NULL, 0, 0); 
        if (error != 0) {
            fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(error));
            continue;
        }
        if (*hostname != '\0') {
            printf("hostname: %s\n", hostname);
        }
    }

    freeaddrinfo(result);
    return 0;
}

See also

[edit]

Notes

[edit]
  1. ^ In some older systems the type of ai_addrlen is size_t instead of socklen_t. Most socket functions, such as accept() and getpeername(), require the parameter to have type socklen_t * and programmers often pass the address to the ai_addrlen element of the addrinfo structure. If the types are incompatible, e.g., on a 64-bit Solaris 9 system where size_t is 8 bytes and socklen_t is 4 bytes, then run-time errors may result.[4]

References

[edit]
  1. ^ a b c "freeaddrinfo, getaddrinfo — get address information". The Open Group Base Specifications Issue 8 (POSIX.1-2024 ed.). The Open Group. Archived from the original on 2025-08-14. Retrieved 2025-12-07.
  2. ^ "nss - man pages section 5: File Formats". docs.oracle.com.
  3. ^ "netdb.h — definitions for network database operations". The Open Group Base Specifications Issue 8, IEEE Std. 1003.1-2024 (POSIX.1-2024 ed.). The Open Group. Archived from the original on 2025-06-16. Retrieved 2025-12-07.
  4. ^ "man pages Section 3: Networking Library Functions, getaddrinfo(3SOCKET)". Solaris 9 12/02 Reference Manual Collection. Sun Microsystems. December 2002. Archived from the original on 2025-12-07. Retrieved 2025-12-07.
  5. ^ 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
  6. ^ "gai_strerror — address and name information error description". The Open Group Base Specifications Issue 8, IEEE Std. 1003.1-2024 (POSIX.1-2024 ed.). The Open Group. Archived from the original on 2025-05-19. Retrieved 2025-12-07.
[edit]