For example, when using the DNS, queries are made for both AAAA
records and A records, and getaddrinfo() returns the combined
results of both queries. Any IPv4 addresses found are returned as
IPv4-mapped IPv6 addresses.
The AI_ALL flag without the AI_V4MAPPED flag is ignored.
Note:
When ai_family is not specified (AF_UNSPEC), AI_V4MAPPED and
AI_ALL flags will only be used if AF_INET6 is supported.
If the AI_ADDRCONFIG flag is specified, IPv4 addresses shall be
returned only if an IPv4 address is configured on the local system,
and IPv6 addresses shall be returned only if an IPv6 address is
configured on the local system. The loopback address is not
considered for this case as valid as a configured address.
For example, when using the DNS, a query for AAAA records should
occur only if the node has at least one IPv6 address configured
(other than IPv6 loopback) and a query for A records should occur
only if the node has at least one IPv4 address configured (other
than the IPv4 loopback).
The ai_socktype field to which argument hints points specifies the
socket type for the service, as defined for socket(). If a specific
socket type is not given (for example, a value of zero) and the
service name could be interpreted as valid with multiple supported
socket types, the implementation shall attempt to resolve the service
name for all supported socket types and, in the absence of errors,
all possible results shall be returned. A non-zero socket type value
shall limit the returned information to values with the specified
socket type.
If the ai_family field to which hints points has the value AF_UNSPEC,
addresses shall be returned for use with any address family that can
be used with the specified nodename and/or servname. Otherwise,
addresses shall be returned for use only with the specified address
family. If ai_family is not AF_UNSPEC and ai_protocol is not zero,
then addresses are returned for use only with the specified address
family and protocol; the value of ai_protocol shall be interpreted as
in a call to the socket() function with the corresponding values of
ai_family and ai_protocol.
The freeaddrinfo() function frees one or more addrinfo structures
returned by getaddrinfo(), along with any additional storage
associated with those structures (for example, storage pointed to by
the ai_canonname and ai_addr fields; an application must not
reference this storage after the associated addrinfo structure has
been freed). If the ai_next field of the structure is not null, the
entire list of structures is freed. The freeaddrinfo() function must
support the freeing of arbitrary sublists of an addrinfo list
originally returned by getaddrinfo().
Functions getaddrinfo() and freeaddrinfo() must be thread-safe.
A zero return value for getaddrinfo() indicates successful
completion; a non-zero return value indicates failure. The possible
values for the failures are listed below under Error Return Values.
Upon successful return of getaddrinfo(), the location to which res
points shall refer to a linked list of addrinfo structures, each of
which shall specify a socket address and information for use in
creating a socket with which to use that socket address. The list
shall include at least one addrinfo structure. The ai_next field of
each structure contains a pointer to the next structure on the list,
or a null pointer if it is the last structure on the list. Each
structure on the list shall include values for use with a call to the
socket() function, and a socket address for use with the connect()
function or, if the AI_PASSIVE flag was specified, for use with the
bind() function. The fields ai_family, ai_socktype, and ai_protocol
shall be usable as the arguments to the socket() function to create a
socket suitable for use with the returned address. The fields
ai_addr and ai_addrlen are usable as the arguments to the connect()
or bind() functions with such a socket, according to the AI_PASSIVE
flag.
If nodename is not null, and if requested by the AI_CANONNAME flag,
the ai_canonname field of the first returned addrinfo structure shall
point to a null-terminated string containing the canonical name
corresponding to the input nodename; if the canonical name is not
available, then ai_canonname shall refer to the nodename argument or
a string with the same contents. The contents of the ai_flags field
of the returned structures are undefined.
All fields in socket address structures returned by getaddrinfo()
that are not filled in through an explicit argument (for example,
sin6_flowinfo) shall be set to zero.
Note: This makes it easier to compare socket address structures.
Error Return Values:
The getaddrinfo() function shall fail and return the corresponding
value if:
[EAI_AGAIN] The name could not be resolved at this time. Future
attempts may succeed.
[EAI_BADFLAGS] The flags parameter had an invalid value.
[EAI_FAIL] A non-recoverable error occurred when attempting to
resolve the name.
[EAI_FAMILY] The address family was not recognized.
[EAI_MEMORY] There was a memory allocation failure when trying to
allocate storage for the return value.
[EAI_NONAME] The name does not resolve for the supplied
parameters. Neither nodename nor servname were
supplied. At least one of these must be supplied.
[EAI_SERVICE] The service passed was not recognized for the
specified socket type.
[EAI_SOCKTYPE] The intended socket type was not recognized.
[EAI_SYSTEM] A system error occurred; the error code can be found
in errno.
The gai_strerror() function provides a descriptive text string
corresponding to an EAI_xxx error value.
#include <netdb.h>
const char *gai_strerror(int ecode);
The argument is one of the EAI_xxx values defined for the
getaddrinfo() and getnameinfo() functions. The return value points
to a string describing the error. If the argument is not one of the
EAI_xxx values, the function still returns a pointer to a string
whose contents indicate an unknown error.
6.2 Socket Address Structure to Node Name and Service Name
The getnameinfo() function is used to translate the contents of a
socket address structure to a node name and/or service name.
#include <sys/socket.h>
#include <netdb.h>
int getnameinfo(const struct sockaddr *sa, socklen_t salen,
char *node, socklen_t nodelen,
char *service, socklen_t servicelen,
int flags);
The getnameinfo() function shall translate a socket address to a node
name and service location, all of which are defined as in
getaddrinfo().
The sa argument points to a socket address structure to be
translated.
The salen argument holds the size of the socket address structure
pointed to by sa.
If the socket address structure contains an IPv4-mapped IPv6 address
or an IPv4-compatible IPv6 address, the implementation shall extract
the embedded IPv4 address and lookup the node name for that IPv4
address.
Note: The IPv6 unspecified address ("::") and the IPv6 loopback
address ("::1") are not IPv4-compatible addresses. If the address
is the IPv6 unspecified address ("::"), a lookup is not performed,
and the [EAI_NONAME] error is returned.
If the node argument is non-NULL and the nodelen argument is nonzero,
then the node argument points to a buffer able to contain up to
nodelen characters that receives the node name as a null-terminated
string. If the node argument is NULL or the nodelen argument is
zero, the node name shall not be returned. If the node's name cannot
be located, the numeric form of the node's address is returned
instead of its name.
If the service argument is non-NULL and the servicelen argument is
non-zero, then the service argument points to a buffer able to
contain up to servicelen bytes that receives the service name as a
null-terminated string. If the service argument is NULL or the
servicelen argument is zero, the service name shall not be returned.
If the service's name cannot be located, the numeric form of the
service address (for example, its port number) shall be returned
instead of its name.
The arguments node and service cannot both be NULL.
The flags argument is a flag that changes the default actions of the
function. By default the fully-qualified domain name (FQDN) for the
host shall be returned, but:
- If the flag bit NI_NOFQDN is set, only the node name portion of
the FQDN shall be returned for local hosts.
- If the flag bit NI_NUMERICHOST is set, the numeric form of the
host's address shall be returned instead of its name, under all
circumstances.
- If the flag bit NI_NAMEREQD is set, an error shall be returned if
the host's name cannot be located.
- If the flag bit NI_NUMERICSERV is set, the numeric form of the
service address shall be returned (for example, its port number)
instead of its name, under all circumstances.
- If the flag bit NI_DGRAM is set, this indicates that the service
is a datagram service (SOCK_DGRAM). The default behavior shall
assume that the service is a stream service (SOCK_STREAM).
Note:
1. The NI_NUMERICxxx flags are required to support the "-n" flags
that many commands provide.
2. The NI_DGRAM flag is required for the few AF_INET and AF_INET6
port numbers (for example, [512,514]) that represent different
services for UDP and TCP.
The getnameinfo() function shall be thread safe.
A zero return value for getnameinfo() indicates successful
completion; a non-zero return value indicates failure.
Upon successful completion, getnameinfo() shall return the node and
service names, if requested, in the buffers provided. The returned
names are always null-terminated strings.
Error Return Values:
The getnameinfo() function shall fail and return the corresponding
value if:
[EAI_AGAIN] The name could not be resolved at this time.
Future attempts may succeed.
[EAI_BADFLAGS] The flags had an invalid value.
[EAI_FAIL] A non-recoverable error occurred.
[EAI_FAMILY] The address family was not recognized or the address
length was invalid for the specified family.
[EAI_MEMORY] There was a memory allocation failure.
[EAI_NONAME] The name does not resolve for the supplied parameters.
NI_NAMEREQD is set and the host's name cannot be
located, or both nodename and servname were null.
[EAI_OVERFLOW] An argument buffer overflowed.
[EAI_SYSTEM] A system error occurred. The error code can be found
in errno.
6.3 Address Conversion Functions
The two IPv4 functions inet_addr() and inet_ntoa() convert an IPv4
address between binary and text form. IPv6 applications need similar
functions. The following two functions convert both IPv6 and IPv4
addresses:
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src,
char *dst, socklen_t size);
The inet_pton() function shall convert an address in its standard
text presentation form into its numeric binary form. The af argument
shall specify the family of the address. The AF_INET and AF_INET6
address families shall be supported. The src argument points to the
string being passed in. The dst argument points to a buffer into
which the function stores the numeric address; this shall be large
enough to hold the numeric address (32 bits for AF_INET, 128 bits for
AF_INET6). The inet_pton() function shall return 1 if the conversion
succeeds, with the address pointed to by dst in network byte order.
It shall return 0 if the input is not a valid IPv4 dotted-decimal
string or a valid IPv6 address string, or -1 with errno set to
EAFNOSUPPORT if the af argument is unknown.
If the af argument of inet_pton() is AF_INET, the src string shall be
in the standard IPv4 dotted-decimal form:
ddd.ddd.ddd.ddd
where "ddd" is a one to three digit decimal number between 0 and 255.
The inet_pton() function does not accept other formats (such as the
octal numbers, hexadecimal numbers, and fewer than four numbers that
inet_addr() accepts).
If the af argument of inet_pton() is AF_INET6, the src string shall
be in one of the standard IPv6 text forms defined in Section 2.2 of
the addressing architecture specification [2].
The inet_ntop() function shall convert a numeric address into a text
string suitable for presentation. The af argument shall specify the
family of the address. This can be AF_INET or AF_INET6. The src
argument points to a buffer holding an IPv4 address if the af
argument is AF_INET, or an IPv6 address if the af argument is
AF_INET6; the address must be in network byte order. The dst
argument points to a buffer where the function stores the resulting
text string; it shall not be NULL. The size argument specifies the
size of this buffer, which shall be large enough to hold the text
string (INET_ADDRSTRLEN characters for IPv4, INET6_ADDRSTRLEN
characters for IPv6).
In order to allow applications to easily declare buffers of the
proper size to store IPv4 and IPv6 addresses in string form, the
following two constants are defined in <netinet/in.h>:
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
The inet_ntop() function shall return a pointer to the buffer
containing the text string if the conversion succeeds, and NULL
otherwise. Upon failure, errno is set to EAFNOSUPPORT if the af
argument is invalid or ENOSPC if the size of the result buffer is
inadequate.
6.4 Address Testing Macros
The following macros can be used to test for special IPv6 addresses.
#include <netinet/in.h>
int IN6_IS_ADDR_UNSPECIFIED (const struct in6_addr *);
int IN6_IS_ADDR_LOOPBACK (const struct in6_addr *);
int IN6_IS_ADDR_MULTICAST (const struct in6_addr *);
int IN6_IS_ADDR_LINKLOCAL (const struct in6_addr *);
int IN6_IS_ADDR_SITELOCAL (const struct in6_addr *);
int IN6_IS_ADDR_V4MAPPED (const struct in6_addr *);
int IN6_IS_ADDR_V4COMPAT (const struct in6_addr *);
int IN6_IS_ADDR_MC_NODELOCAL(const struct in6_addr *);
int IN6_IS_ADDR_MC_LINKLOCAL(const struct in6_addr *);
int IN6_IS_ADDR_MC_SITELOCAL(const struct in6_addr *);
int IN6_IS_ADDR_MC_ORGLOCAL (const struct in6_addr *);
int IN6_IS_ADDR_MC_GLOBAL (const struct in6_addr *);
The first seven macros return true if the address is of the specified
type, or false otherwise. The last five test the scope of a
multicast address and return true if the address is a multicast
address of the specified scope or false if the address is either not
a multicast address or not of the specified scope.
Note that IN6_IS_ADDR_LINKLOCAL and IN6_IS_ADDR_SITELOCAL return true
only for the two types of local-use IPv6 unicast addresses (Link-
Local and Site-Local) defined in [2], and that by this definition,
the IN6_IS_ADDR_LINKLOCAL macro returns false for the IPv6 loopback
address (::1). These two macros do not return true for IPv6
multicast addresses of either link-local scope or site-local scope.
7. Summary of New Definitions
The following list summarizes the constants, structure, and extern
definitions discussed in this memo, sorted by header.
<net/if.h> IF_NAMESIZE
<net/if.h> struct if_nameindex{};
<netdb.h> AI_ADDRCONFIG
<netdb.h> AI_ALL
<netdb.h> AI_CANONNAME
<netdb.h> AI_NUMERICHOST
<netdb.h> AI_NUMERICSERV
<netdb.h> AI_PASSIVE
<netdb.h> AI_V4MAPPED
<netdb.h> EAI_AGAIN
<netdb.h> EAI_BADFLAGS
<netdb.h> EAI_FAIL
<netdb.h> EAI_FAMILY
<netdb.h> EAI_MEMORY
<netdb.h> EAI_NONAME
<netdb.h> EAI_OVERFLOW
<netdb.h> EAI_SERVICE
<netdb.h> EAI_SOCKTYPE
<netdb.h> EAI_SYSTEM
<netdb.h> NI_DGRAM
<netdb.h> NI_NAMEREQD
<netdb.h> NI_NOFQDN
<netdb.h> NI_NUMERICHOST
<netdb.h> NI_NUMERICSERV
<netdb.h> struct addrinfo{};
<netinet/in.h> IN6ADDR_ANY_INIT
<netinet/in.h> IN6ADDR_LOOPBACK_INIT
<netinet/in.h> INET6_ADDRSTRLEN
<netinet/in.h> INET_ADDRSTRLEN
<netinet/in.h> IPPROTO_IPV6
<netinet/in.h> IPV6_JOIN_GROUP
<netinet/in.h> IPV6_LEAVE_GROUP
<netinet/in.h> IPV6_MULTICAST_HOPS
<netinet/in.h> IPV6_MULTICAST_IF
<netinet/in.h> IPV6_MULTICAST_LOOP
<netinet/in.h> IPV6_UNICAST_HOPS
<netinet/in.h> IPV6_V6ONLY
<netinet/in.h> SIN6_LEN
<netinet/in.h> extern const struct in6_addr in6addr_any;
<netinet/in.h> extern const struct in6_addr in6addr_loopback;
<netinet/in.h> struct in6_addr{};
<netinet/in.h> struct ipv6_mreq{};
<netinet/in.h> struct sockaddr_in6{};
<sys/socket.h> AF_INET6
<sys/socket.h> PF_INET6
<sys/socket.h> struct sockaddr_storage;
The following list summarizes the function and macro prototypes
discussed in this memo, sorted by header.
<arpa/inet.h> int inet_pton(int, const char *, void *);
<arpa/inet.h> const char *inet_ntop(int, const void *,
char *, socklen_t);
<net/if.h> char *if_indextoname(unsigned int, char *);
<net/if.h> unsigned int if_nametoindex(const char *);
<net/if.h> void if_freenameindex(struct if_nameindex *);
<net/if.h> struct if_nameindex *if_nameindex(void);
<netdb.h> int getaddrinfo(const char *, const char *,
const struct addrinfo *,
struct addrinfo **);
<netdb.h> int getnameinfo(const struct sockaddr *, socklen_t,
char *, socklen_t, char *, socklen_t, int);
<netdb.h> void freeaddrinfo(struct addrinfo *);
<netdb.h> const char *gai_strerror(int);
<netinet/in.h> int IN6_IS_ADDR_LINKLOCAL(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_LOOPBACK(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_MC_GLOBAL(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_MC_LINKLOCAL(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_MC_NODELOCAL(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_MC_ORGLOCAL(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_MC_SITELOCAL(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_MULTICAST(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_SITELOCAL(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_V4COMPAT(const struct in6_addr *);
<netinet/in.h> int IN6_IS_ADDR_V4MAPPED(const struct in6_addr *);
8. Security Considerations
IPv6 provides a number of new security mechanisms, many of which need
to be accessible to applications. Companion memos detailing the
extensions to the socket interfaces to support IPv6 security are
being written.
9. Changes from RFC2553
1. Add brief description of the history of this API and its relation
to the Open Group/IEEE/ISO standards.
2. Alignments with [3].
3. Removed all references to getipnodebyname() and getipnodebyaddr(),
which are deprecated in favor of getaddrinfo() and getnameinfo().
4. Added IPV6_V6ONLY IP level socket option to permit nodes to not
process IPv4 packets as IPv4 Mapped addresses in implementations.
5. Added SIIT to references and added new contributors.
6. In previous versions of this specification, the sin6_flowinfo
field was associated with the IPv6 traffic class and flow label,
but its usage was not completely specified. The complete
definition of the sin6_flowinfo field, including its association
with the traffic class or flow label, is now deferred to a future
specification.
10. Acknowledgments
This specification's evolution and completeness were significantly
influenced by the efforts of Richard Stevens, who has passed on.
Richard's wisdom and talent made the specification what it is today.
The co-authors will long think of Richard with great respect.
Thanks to the many people who made suggestions and provided feedback
to this document, including:
Werner Almesberger, Ran Atkinson, Fred Baker, Dave Borman, Andrew
Cherenson, Alex Conta, Alan Cox, Steve Deering, Richard Draves,
Francis Dupont, Robert Elz, Brian Haberman, Jun-ichiro itojun Hagino,
Marc Hasson, Tom Herbert, Bob Hinden, Wan-Yen Hsu, Christian Huitema,
Koji Imada, Markus Jork, Ron Lee, Alan Lloyd, Charles Lynn, Dan
McDonald, Dave Mitton, Finnbarr Murphy, Thomas Narten, Josh Osborne,
Craig Partridge, Jean-Luc Richier, Bill Sommerfield, Erik Scoredos,
Keith Sklower, JINMEI Tatuya, Dave Thaler, Matt Thomas, Harvey
Thompson, Dean D. Throop, Karen Tracey, Glenn Trewitt, Paul Vixie,
David Waitzman, Carl Williams, Kazu Yamamoto, Vlad Yasevich, Stig
Venaas, and Brian Zill.
The getaddrinfo() and getnameinfo() functions are taken from an
earlier document by Keith Sklower. As noted in that document,
William Durst, Steven Wise, Michael Karels, and Eric Allman provided
many useful discussions on the subject of protocol-independent name-
to-address translation, and reviewed early versions of Keith
Sklower's original proposal. Eric Allman implemented the first
prototype of getaddrinfo(). The observation that specifying the pair
of name and service would suffice for connecting to a service
independent of protocol details was made by Marshall Rose in a
proposal to X/Open for a "Uniform Network Interface".
Craig Metz, Jack McCann, Erik Nordmark, Tim Hartrick, and Mukesh
Kacker made many contributions to this document. Ramesh Govindan
made a number of contributions and co-authored an earlier version of
this memo.
11. References
[1] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6)
Specification", RFC2460, December 1998.
[2] Hinden, R. and S. Deering, "IP Version 6 Addressing
Architecture", RFC2373, July 1998.
[3] IEEE Std. 1003.1-2001 Standard for Information Technology --
Portable Operating System Interface (POSIX). Open Group
Technical Standard: Base Specifications, Issue 6, December 2001.
ISO/IEC 9945:2002. http://www.opengroup.org/austin
[4] Stevens, W. and M. Thomas, "Advanced Sockets API for IPv6", RFC
2292, February 1998.
[5] Nordmark, E., "Stateless IP/ICMP Translation Algorithm (SIIT)",
RFC2765, February 2000.
[6] The Open Group Base Working Group
http://www.opengroup.org/platform/base.html
12. Authors' Addresses
Bob Gilligan
Intransa, Inc.
2870 Zanker Rd.
San Jose, CA 95134
Phone: 408-678-8647
EMail: gilligan@intransa.com
Susan Thomson
Cisco Systems
499 Thornall Street, 8th floor
Edison, NJ 08837
Phone: 732-635-3086
EMail: sethomso@cisco.com
Jim Bound
Hewlett-Packard Company
110 Spitbrook Road ZKO3-3/W20
Nashua, NH 03062
Phone: 603-884-0062
EMail: Jim.Bound@hp.com
Jack McCann
Hewlett-Packard Company
110 Spitbrook Road ZKO3-3/W20
Nashua, NH 03062
Phone: 603-884-2608
EMail: Jack.McCann@hp.com
13. Full Copyright Statement
Copyright (C) The Internet Society (2003). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Acknowledgement
Funding for the RFCEditor function is currently provided by the
Internet Society.