diff options
author | Thomas Voss <mail@thomasvoss.com> | 2024-11-27 20:54:24 +0100 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2024-11-27 20:54:24 +0100 |
commit | 4bfd864f10b68b71482b35c818559068ef8d5797 (patch) | |
tree | e3989f47a7994642eb325063d46e8f08ffa681dc /doc/rfc/rfc3493.txt | |
parent | ea76e11061bda059ae9f9ad130a9895cc85607db (diff) |
doc: Add RFC documents
Diffstat (limited to 'doc/rfc/rfc3493.txt')
-rw-r--r-- | doc/rfc/rfc3493.txt | 2187 |
1 files changed, 2187 insertions, 0 deletions
diff --git a/doc/rfc/rfc3493.txt b/doc/rfc/rfc3493.txt new file mode 100644 index 0000000..5fea6c1 --- /dev/null +++ b/doc/rfc/rfc3493.txt @@ -0,0 +1,2187 @@ + + + + + + +Network Working Group R. Gilligan +Request for Comments: 3493 Intransa, Inc. +Obsoletes: 2553 S. Thomson +Category: Informational Cisco + J. Bound + J. McCann + Hewlett-Packard + W. Stevens + February 2003 + + + Basic Socket Interface Extensions for IPv6 + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2003). All Rights Reserved. + +Abstract + + The de facto standard Application Program Interface (API) for TCP/IP + applications is the "sockets" interface. Although this API was + developed for Unix in the early 1980s it has also been implemented on + a wide variety of non-Unix systems. TCP/IP applications written + using the sockets API have in the past enjoyed a high degree of + portability and we would like the same portability with IPv6 + applications. But changes are required to the sockets API to support + IPv6 and this memo describes these changes. These include a new + socket address structure to carry IPv6 addresses, new address + conversion functions, and some new socket options. These extensions + are designed to provide access to the basic IPv6 features required by + TCP and UDP applications, including multicasting, while introducing a + minimum of change into the system and providing complete + compatibility for existing IPv4 applications. Additional extensions + for advanced IPv6 features (raw sockets and access to the IPv6 + extension headers) are defined in another document. + + + + + + + + + + +Gilligan, et al. Informational [Page 1] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +Table of Contents + + 1. Introduction................................................3 + 2. Design Considerations.......................................4 + 2.1 What Needs to be Changed...............................4 + 2.2 Data Types.............................................6 + 2.3 Headers................................................6 + 2.4 Structures.............................................6 + 3. Socket Interface............................................6 + 3.1 IPv6 Address Family and Protocol Family................6 + 3.2 IPv6 Address Structure.................................7 + 3.3 Socket Address Structure for 4.3BSD-Based Systems......7 + 3.4 Socket Address Structure for 4.4BSD-Based Systems......9 + 3.5 The Socket Functions...................................9 + 3.6 Compatibility with IPv4 Applications..................10 + 3.7 Compatibility with IPv4 Nodes.........................11 + 3.8 IPv6 Wildcard Address.................................11 + 3.9 IPv6 Loopback Address.................................13 + 3.10 Portability Additions.................................14 + 4. Interface Identification...................................16 + 4.1 Name-to-Index.........................................17 + 4.2 Index-to-Name.........................................17 + 4.3 Return All Interface Names and Indexes................18 + 4.4 Free Memory...........................................18 + 5. Socket Options.............................................18 + 5.1 Unicast Hop Limit.....................................19 + 5.2 Sending and Receiving Multicast Packets...............19 + 5.3 IPV6_V6ONLY option for AF_INET6 Sockets...............22 + 6. Library Functions..........................................22 + 6.1 Protocol-Independent Nodename and + Service Name Translation..............................23 + 6.2 Socket Address Structure to Node Name + and Service Name......................................28 + 6.3 Address Conversion Functions..........................31 + 6.4 Address Testing Macros................................33 + 7. Summary of New Definitions.................................33 + 8. Security Considerations....................................35 + 9. Changes from RFC 2553......................................35 + 10. Acknowledgments............................................36 + 11. References.................................................37 + 12. Authors' Addresses.........................................38 + 13. Full Copyright Statement...................................39 + + + + + + + + + +Gilligan, et al. Informational [Page 2] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +1. Introduction + + While IPv4 addresses are 32 bits long, IPv6 addresses are 128 bits + long. The socket interface makes the size of an IP address quite + visible to an application; virtually all TCP/IP applications for + BSD-based systems have knowledge of the size of an IP address. Those + parts of the API that expose the addresses must be changed to + accommodate the larger IPv6 address size. IPv6 also introduces new + features, some of which must be made visible to applications via the + API. This memo defines a set of extensions to the socket interface + to support the larger address size and new features of IPv6. It + defines "basic" extensions that are of use to a broad range of + applications. A companion document, the "advanced" API [4], covers + extensions that are of use to more specialized applications, examples + of which include routing daemons, and the "ping" and "traceroute" + utilities. + + The development of this API was started in 1994 in the IETF IPng + working group. The API has evolved over the years, published first + in RFC 2133, then again in RFC 2553, and reaching its final form in + this document. + + As the API matured and stabilized, it was incorporated into the Open + Group's Networking Services (XNS) specification, issue 5.2, which was + subsequently incorporated into a joint Open Group/IEEE/ISO standard + [3]. + + Effort has been made to ensure that this document and [3] contain the + same information with regard to the API definitions. However, the + reader should note that this document is for informational purposes + only, and that the official standard specification of the sockets API + is [3]. + + It is expected that any future standardization work on this API would + be done by the Open Group Base Working Group [6]. + + It should also be noted that this document describes only those + portions of the API needed for IPv4 and IPv6 communications. Other + potential uses of the API, for example the use of getaddrinfo() and + getnameinfo() with the AF_UNIX address family, are beyond the scope + of this document. + + + + + + + + + + +Gilligan, et al. Informational [Page 3] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +2. Design Considerations + + There are a number of important considerations in designing changes + to this well-worn API: + + - The API changes should provide both source and binary + compatibility for programs written to the original API. That is, + existing program binaries should continue to operate when run on a + system supporting the new API. In addition, existing applications + that are re-compiled and run on a system supporting the new API + should continue to operate. Simply put, the API changes for IPv6 + should not break existing programs. An additional mechanism for + implementations to verify this is to verify the new symbols are + protected by Feature Test Macros as described in [3]. (Such + Feature Test Macros are not defined by this RFC.) + + - The changes to the API should be as small as possible in order to + simplify the task of converting existing IPv4 applications to + IPv6. + + - Where possible, applications should be able to use this API to + interoperate with both IPv6 and IPv4 hosts. Applications should + not need to know which type of host they are communicating with. + + - IPv6 addresses carried in data structures should be 64-bit + aligned. This is necessary in order to obtain optimum performance + on 64-bit machine architectures. + + Because of the importance of providing IPv4 compatibility in the API, + these extensions are explicitly designed to operate on machines that + provide complete support for both IPv4 and IPv6. A subset of this + API could probably be designed for operation on systems that support + only IPv6. However, this is not addressed in this memo. + +2.1 What Needs to be Changed + + The socket interface API consists of a few distinct components: + + - Core socket functions. + + - Address data structures. + + - Name-to-address translation functions. + + - Address conversion functions. + + + + + + +Gilligan, et al. Informational [Page 4] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + The core socket functions -- those functions that deal with such + things as setting up and tearing down TCP connections, and sending + and receiving UDP packets -- were designed to be transport + independent. Where protocol addresses are passed as function + arguments, they are carried via opaque pointers. A protocol-specific + address data structure is defined for each protocol that the socket + functions support. Applications must cast pointers to these + protocol-specific address structures into pointers to the generic + "sockaddr" address structure when using the socket functions. These + functions need not change for IPv6, but a new IPv6-specific address + data structure is needed. + + The "sockaddr_in" structure is the protocol-specific data structure + for IPv4. This data structure actually includes 8-octets of unused + space, and it is tempting to try to use this space to adapt the + sockaddr_in structure to IPv6. Unfortunately, the sockaddr_in + structure is not large enough to hold the 16-octet IPv6 address as + well as the other information (address family and port number) that + is needed. So a new address data structure must be defined for IPv6. + + IPv6 addresses are scoped [2] so they could be link-local, site, + organization, global, or other scopes at this time undefined. To + support applications that want to be able to identify a set of + interfaces for a specific scope, the IPv6 sockaddr_in structure must + support a field that can be used by an implementation to identify a + set of interfaces identifying the scope for an IPv6 address. + + The IPv4 name-to-address translation functions in the socket + interface are gethostbyname() and gethostbyaddr(). These are left as + is, and new functions are defined which support both IPv4 and IPv6. + + The IPv4 address conversion functions -- inet_ntoa() and inet_addr() + -- convert IPv4 addresses between binary and printable form. These + functions are quite specific to 32-bit IPv4 addresses. We have + designed two analogous functions that convert both IPv4 and IPv6 + addresses, and carry an address type parameter so that they can be + extended to other protocol families as well. + + Finally, a few miscellaneous features are needed to support IPv6. A + new interface is needed to support the IPv6 hop limit header field. + New socket options are needed to control the sending and receiving of + IPv6 multicast packets. + + The socket interface will be enhanced in the future to provide access + to other IPv6 features. Some of these extensions are described in + [4]. + + + + + +Gilligan, et al. Informational [Page 5] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +2.2 Data Types + + The data types of the structure elements given in this memo are + intended to track the relevant standards. uintN_t means an unsigned + integer of exactly N bits (e.g., uint16_t). The sa_family_t and + in_port_t types are defined in [3]. + +2.3 Headers + + When function prototypes and structures are shown we show the headers + that must be #included to cause that item to be defined. + +2.4 Structures + + When structures are described the members shown are the ones that + must appear in an implementation. Additional, nonstandard members + may also be defined by an implementation. As an additional + precaution nonstandard members could be verified by Feature Test + Macros as described in [3]. (Such Feature Test Macros are not + defined by this RFC.) + + The ordering shown for the members of a structure is the recommended + ordering, given alignment considerations of multibyte members, but an + implementation may order the members differently. + +3. Socket Interface + + This section specifies the socket interface changes for IPv6. + +3.1 IPv6 Address Family and Protocol Family + + A new address family name, AF_INET6, is defined in <sys/socket.h>. + The AF_INET6 definition distinguishes between the original + sockaddr_in address data structure, and the new sockaddr_in6 data + structure. + + A new protocol family name, PF_INET6, is defined in <sys/socket.h>. + Like most of the other protocol family names, this will usually be + defined to have the same value as the corresponding address family + name: + + #define PF_INET6 AF_INET6 + + The AF_INET6 is used in the first argument to the socket() function + to indicate that an IPv6 socket is being created. + + + + + + +Gilligan, et al. Informational [Page 6] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +3.2 IPv6 Address Structure + + A new in6_addr structure holds a single IPv6 address and is defined + as a result of including <netinet/in.h>: + + struct in6_addr { + uint8_t s6_addr[16]; /* IPv6 address */ + }; + + This data structure contains an array of sixteen 8-bit elements, + which make up one 128-bit IPv6 address. The IPv6 address is stored + in network byte order. + + The structure in6_addr above is usually implemented with an embedded + union with extra fields that force the desired alignment level in a + manner similar to BSD implementations of "struct in_addr". Those + additional implementation details are omitted here for simplicity. + + An example is as follows: + + struct in6_addr { + union { + uint8_t _S6_u8[16]; + uint32_t _S6_u32[4]; + uint64_t _S6_u64[2]; + } _S6_un; + }; + #define s6_addr _S6_un._S6_u8 + +3.3 Socket Address Structure for 4.3BSD-Based Systems + + In the socket interface, a different protocol-specific data structure + is defined to carry the addresses for each protocol suite. Each + protocol-specific data structure is designed so it can be cast into a + protocol-independent data structure -- the "sockaddr" structure. + Each has a "family" field that overlays the "sa_family" of the + sockaddr data structure. This field identifies the type of the data + structure. + + The sockaddr_in structure is the protocol-specific address data + structure for IPv4. It is used to pass addresses between + applications and the system in the socket functions. The following + sockaddr_in6 structure holds IPv6 addresses and is defined as a + result of including the <netinet/in.h> header: + + + + + + + +Gilligan, et al. Informational [Page 7] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +struct sockaddr_in6 { + sa_family_t sin6_family; /* AF_INET6 */ + in_port_t sin6_port; /* transport layer port # */ + uint32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + uint32_t sin6_scope_id; /* set of interfaces for a scope */ +}; + + This structure is designed to be compatible with the sockaddr data + structure used in the 4.3BSD release. + + The sin6_family field identifies this as a sockaddr_in6 structure. + This field overlays the sa_family field when the buffer is cast to a + sockaddr data structure. The value of this field must be AF_INET6. + + The sin6_port field contains the 16-bit UDP or TCP port number. This + field is used in the same way as the sin_port field of the + sockaddr_in structure. The port number is stored in network byte + order. + + The sin6_flowinfo field is a 32-bit field intended to contain flow- + related information. The exact way this field is mapped to or from a + packet is not currently specified. Until such time as its use is + specified, applications should set this field to zero when + constructing a sockaddr_in6, and ignore this field in a sockaddr_in6 + structure constructed by the system. + + The sin6_addr field is a single in6_addr structure (defined in the + previous section). This field holds one 128-bit IPv6 address. The + address is stored in network byte order. + + The ordering of elements in this structure is specifically designed + so that when sin6_addr field is aligned on a 64-bit boundary, the + start of the structure will also be aligned on a 64-bit boundary. + This is done for optimum performance on 64-bit architectures. + + The sin6_scope_id field is a 32-bit integer that identifies a set of + interfaces as appropriate for the scope [2] of the address carried in + the sin6_addr field. The mapping of sin6_scope_id to an interface or + set of interfaces is left to implementation and future specifications + on the subject of scoped addresses. + + Notice that the sockaddr_in6 structure will normally be larger than + the generic sockaddr structure. On many existing implementations the + sizeof(struct sockaddr_in) equals sizeof(struct sockaddr), with both + being 16 bytes. Any existing code that makes this assumption needs + to be examined carefully when converting to IPv6. + + + + +Gilligan, et al. Informational [Page 8] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +3.4 Socket Address Structure for 4.4BSD-Based Systems + + The 4.4BSD release includes a small, but incompatible change to the + socket interface. The "sa_family" field of the sockaddr data + structure was changed from a 16-bit value to an 8-bit value, and the + space saved used to hold a length field, named "sa_len". The + sockaddr_in6 data structure given in the previous section cannot be + correctly cast into the newer sockaddr data structure. For this + reason, the following alternative IPv6 address data structure is + provided to be used on systems based on 4.4BSD. It is defined as a + result of including the <netinet/in.h> header. + +struct sockaddr_in6 { + uint8_t sin6_len; /* length of this struct */ + sa_family_t sin6_family; /* AF_INET6 */ + in_port_t sin6_port; /* transport layer port # */ + uint32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + uint32_t sin6_scope_id; /* set of interfaces for a scope */ +}; + + The only differences between this data structure and the 4.3BSD + variant are the inclusion of the length field, and the change of the + family field to a 8-bit data type. The definitions of all the other + fields are identical to the structure defined in the previous + section. + + Systems that provide this version of the sockaddr_in6 data structure + must also declare SIN6_LEN as a result of including the + <netinet/in.h> header. This macro allows applications to determine + whether they are being built on a system that supports the 4.3BSD or + 4.4BSD variants of the data structure. + +3.5 The Socket Functions + + Applications call the socket() function to create a socket descriptor + that represents a communication endpoint. The arguments to the + socket() function tell the system which protocol to use, and what + format address structure will be used in subsequent functions. For + example, to create an IPv4/TCP socket, applications make the call: + + s = socket(AF_INET, SOCK_STREAM, 0); + + To create an IPv4/UDP socket, applications make the call: + + s = socket(AF_INET, SOCK_DGRAM, 0); + + + + + +Gilligan, et al. Informational [Page 9] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + Applications may create IPv6/TCP and IPv6/UDP sockets (which may also + handle IPv4 communication as described in section 3.7) by simply + using the constant AF_INET6 instead of AF_INET in the first argument. + For example, to create an IPv6/TCP socket, applications make the + call: + + s = socket(AF_INET6, SOCK_STREAM, 0); + + To create an IPv6/UDP socket, applications make the call: + + s = socket(AF_INET6, SOCK_DGRAM, 0); + + Once the application has created a AF_INET6 socket, it must use the + sockaddr_in6 address structure when passing addresses in to the + system. The functions that the application uses to pass addresses + into the system are: + + bind() + connect() + sendmsg() + sendto() + + The system will use the sockaddr_in6 address structure to return + addresses to applications that are using AF_INET6 sockets. The + functions that return an address from the system to an application + are: + + accept() + recvfrom() + recvmsg() + getpeername() + getsockname() + + No changes to the syntax of the socket functions are needed to + support IPv6, since all of the "address carrying" functions use an + opaque address pointer, and carry an address length as a function + argument. + +3.6 Compatibility with IPv4 Applications + + In order to support the large base of applications using the original + API, system implementations must provide complete source and binary + compatibility with the original API. This means that systems must + continue to support AF_INET sockets and the sockaddr_in address + structure. Applications must be able to create IPv4/TCP and IPv4/UDP + sockets using the AF_INET constant in the socket() function, as + + + + + +Gilligan, et al. Informational [Page 10] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + described in the previous section. Applications should be able to + hold a combination of IPv4/TCP, IPv4/UDP, IPv6/TCP and IPv6/UDP + sockets simultaneously within the same process. + + Applications using the original API should continue to operate as + they did on systems supporting only IPv4. That is, they should + continue to interoperate with IPv4 nodes. + +3.7 Compatibility with IPv4 Nodes + + The API also provides a different type of compatibility: the ability + for IPv6 applications to interoperate with IPv4 applications. This + feature uses the IPv4-mapped IPv6 address format defined in the IPv6 + addressing architecture specification [2]. This address format + allows the IPv4 address of an IPv4 node to be represented as an IPv6 + address. The IPv4 address is encoded into the low-order 32 bits of + the IPv6 address, and the high-order 96 bits hold the fixed prefix + 0:0:0:0:0:FFFF. IPv4-mapped addresses are written as follows: + + ::FFFF:<IPv4-address> + + These addresses can be generated automatically by the getaddrinfo() + function, as described in Section 6.1. + + Applications may use AF_INET6 sockets to open TCP connections to IPv4 + nodes, or send UDP packets to IPv4 nodes, by simply encoding the + destination's IPv4 address as an IPv4-mapped IPv6 address, and + passing that address, within a sockaddr_in6 structure, in the + connect() or sendto() call. When applications use AF_INET6 sockets + to accept TCP connections from IPv4 nodes, or receive UDP packets + from IPv4 nodes, the system returns the peer's address to the + application in the accept(), recvfrom(), or getpeername() call using + a sockaddr_in6 structure encoded this way. + + Few applications will likely need to know which type of node they are + interoperating with. However, for those applications that do need to + know, the IN6_IS_ADDR_V4MAPPED() macro, defined in Section 6.4, is + provided. + +3.8 IPv6 Wildcard Address + + While the bind() function allows applications to select the source IP + address of UDP packets and TCP connections, applications often want + the system to select the source address for them. With IPv4, one + specifies the address as the symbolic constant INADDR_ANY (called the + "wildcard" address) in the bind() call, or simply omits the bind() + entirely. + + + + +Gilligan, et al. Informational [Page 11] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + Since the IPv6 address type is a structure (struct in6_addr), a + symbolic constant can be used to initialize an IPv6 address variable, + but cannot be used in an assignment. Therefore systems provide the + IPv6 wildcard address in two forms. + + The first version is a global variable named "in6addr_any" that is an + in6_addr structure. The extern declaration for this variable is + defined in <netinet/in.h>: + + extern const struct in6_addr in6addr_any; + + Applications use in6addr_any similarly to the way they use INADDR_ANY + in IPv4. For example, to bind a socket to port number 23, but let + the system select the source address, an application could use the + following code: + + struct sockaddr_in6 sin6; + . . . + sin6.sin6_family = AF_INET6; + sin6.sin6_flowinfo = 0; + sin6.sin6_port = htons(23); + sin6.sin6_addr = in6addr_any; /* structure assignment */ + . . . + if (bind(s, (struct sockaddr *) &sin6, sizeof(sin6)) == -1) + . . . + + The other version is a symbolic constant named IN6ADDR_ANY_INIT and + is defined in <netinet/in.h>. This constant can be used to + initialize an in6_addr structure: + + struct in6_addr anyaddr = IN6ADDR_ANY_INIT; + + Note that this constant can be used ONLY at declaration time. It can + not be used to assign a previously declared in6_addr structure. For + example, the following code will not work: + + /* This is the WRONG way to assign an unspecified address */ + struct sockaddr_in6 sin6; + . . . + sin6.sin6_addr = IN6ADDR_ANY_INIT; /* will NOT compile */ + + Be aware that the IPv4 INADDR_xxx constants are all defined in host + byte order but the IPv6 IN6ADDR_xxx constants and the IPv6 + in6addr_xxx externals are defined in network byte order. + + + + + + + +Gilligan, et al. Informational [Page 12] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +3.9 IPv6 Loopback Address + + Applications may need to send UDP packets to, or originate TCP + connections to, services residing on the local node. In IPv4, they + can do this by using the constant IPv4 address INADDR_LOOPBACK in + their connect(), sendto(), or sendmsg() call. + + IPv6 also provides a loopback address to contact local TCP and UDP + services. Like the unspecified address, the IPv6 loopback address is + provided in two forms -- a global variable and a symbolic constant. + + The global variable is an in6_addr structure named + "in6addr_loopback." The extern declaration for this variable is + defined in <netinet/in.h>: + + extern const struct in6_addr in6addr_loopback; + + Applications use in6addr_loopback as they would use INADDR_LOOPBACK + in IPv4 applications (but beware of the byte ordering difference + mentioned at the end of the previous section). For example, to open + a TCP connection to the local telnet server, an application could use + the following code: + + struct sockaddr_in6 sin6; + . . . + sin6.sin6_family = AF_INET6; + sin6.sin6_flowinfo = 0; + sin6.sin6_port = htons(23); + sin6.sin6_addr = in6addr_loopback; /* structure assignment */ + . . . + if (connect(s, (struct sockaddr *) &sin6, sizeof(sin6)) == -1) + . . . + + The symbolic constant is named IN6ADDR_LOOPBACK_INIT and is defined + in <netinet/in.h>. It can be used at declaration time ONLY; for + example: + + struct in6_addr loopbackaddr = IN6ADDR_LOOPBACK_INIT; + + Like IN6ADDR_ANY_INIT, this constant cannot be used in an assignment + to a previously declared IPv6 address variable. + + + + + + + + + + +Gilligan, et al. Informational [Page 13] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +3.10 Portability Additions + + One simple addition to the sockets API that can help application + writers is the "struct sockaddr_storage". This data structure can + simplify writing code that is portable across multiple address + families and platforms. This data structure is designed with the + following goals. + + - Large enough to accommodate all supported protocol-specific address + structures. + + - Aligned at an appropriate boundary so that pointers to it can be + cast as pointers to protocol specific address structures and used + to access the fields of those structures without alignment + problems. + + The sockaddr_storage structure contains field ss_family which is of + type sa_family_t. When a sockaddr_storage structure is cast to a + sockaddr structure, the ss_family field of the sockaddr_storage + structure maps onto the sa_family field of the sockaddr structure. + When a sockaddr_storage structure is cast as a protocol specific + address structure, the ss_family field maps onto a field of that + structure that is of type sa_family_t and that identifies the + protocol's address family. + + + + + + + + + + + + + + + + + + + + + + + + + + + +Gilligan, et al. Informational [Page 14] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + An example implementation design of such a data structure would be as + follows. + +/* + * Desired design of maximum size and alignment + */ +#define _SS_MAXSIZE 128 /* Implementation specific max size */ +#define _SS_ALIGNSIZE (sizeof (int64_t)) + /* Implementation specific desired alignment */ +/* + * Definitions used for sockaddr_storage structure paddings design. + */ +#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (sa_family_t)) +#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (sa_family_t) + + _SS_PAD1SIZE + _SS_ALIGNSIZE)) +struct sockaddr_storage { + sa_family_t ss_family; /* address family */ + /* Following fields are implementation specific */ + char __ss_pad1[_SS_PAD1SIZE]; + /* 6 byte pad, this is to make implementation + /* specific pad up to alignment field that */ + /* follows explicit in the data structure */ + int64_t __ss_align; /* field to force desired structure */ + /* storage alignment */ + char __ss_pad2[_SS_PAD2SIZE]; + /* 112 byte pad to achieve desired size, */ + /* _SS_MAXSIZE value minus size of ss_family */ + /* __ss_pad1, __ss_align fields is 112 */ +}; + + The above example implementation illustrates a data structure which + will align on a 64-bit boundary. An implementation-specific field + "__ss_align" along with "__ss_pad1" is used to force a 64-bit + alignment which covers proper alignment good enough for the needs of + sockaddr_in6 (IPv6), sockaddr_in (IPv4) address data structures. The + size of padding field __ss_pad1 depends on the chosen alignment + boundary. The size of padding field __ss_pad2 depends on the value + of overall size chosen for the total size of the structure. This + size and alignment are represented in the above example by + implementation specific (not required) constants _SS_MAXSIZE (chosen + value 128) and _SS_ALIGNSIZE (with chosen value 8). Constants + _SS_PAD1SIZE (derived value 6) and _SS_PAD2SIZE (derived value 112) + are also for illustration and not required. The derived values + assume sa_family_t is 2 bytes. The implementation specific + definitions and structure field names above start with an underscore + to denote implementation private namespace. Portable code is not + expected to access or reference those fields or constants. + + + + +Gilligan, et al. Informational [Page 15] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + On implementations where the sockaddr data structure includes a + "sa_len" field this data structure would look like this: + +/* + * Definitions used for sockaddr_storage structure paddings design. + */ +#define _SS_PAD1SIZE (_SS_ALIGNSIZE - + (sizeof (uint8_t) + sizeof (sa_family_t)) +#define _SS_PAD2SIZE (_SS_MAXSIZE - + (sizeof (uint8_t) + sizeof (sa_family_t) + + _SS_PAD1SIZE + _SS_ALIGNSIZE)) +struct sockaddr_storage { + uint8_t ss_len; /* address length */ + sa_family_t ss_family; /* address family */ + /* Following fields are implementation specific */ + char __ss_pad1[_SS_PAD1SIZE]; + /* 6 byte pad, this is to make implementation + /* specific pad up to alignment field that */ + /* follows explicit in the data structure */ + int64_t __ss_align; /* field to force desired structure */ + /* storage alignment */ + char __ss_pad2[_SS_PAD2SIZE]; + /* 112 byte pad to achieve desired size, */ + /* _SS_MAXSIZE value minus size of ss_len, */ + /* __ss_family, __ss_pad1, __ss_align fields is 112 */ +}; + +4. Interface Identification + + This API uses an interface index (a small positive integer) to + identify the local interface on which a multicast group is joined + (Section 5.2). Additionally, the advanced API [4] uses these same + interface indexes to identify the interface on which a datagram is + received, or to specify the interface on which a datagram is to be + sent. + + Interfaces are normally known by names such as "le0", "sl1", "ppp2", + and the like. On Berkeley-derived implementations, when an interface + is made known to the system, the kernel assigns a unique positive + integer value (called the interface index) to that interface. These + are small positive integers that start at 1. (Note that 0 is never + used for an interface index.) There may be gaps so that there is no + current interface for a particular positive interface index. + + This API defines two functions that map between an interface name and + index, a third function that returns all the interface names and + indexes, and a fourth function to return the dynamic memory allocated + by the previous function. How these functions are implemented is + + + +Gilligan, et al. Informational [Page 16] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + left up to the implementation. 4.4BSD implementations can implement + these functions using the existing sysctl() function with the + NET_RT_IFLIST command. Other implementations may wish to use ioctl() + for this purpose. + +4.1 Name-to-Index + + The first function maps an interface name into its corresponding + index. + + #include <net/if.h> + + unsigned int if_nametoindex(const char *ifname); + + If ifname is the name of an interface, the if_nametoindex() function + shall return the interface index corresponding to name ifname; + otherwise, it shall return zero. No errors are defined. + +4.2 Index-to-Name + + The second function maps an interface index into its corresponding + name. + + #include <net/if.h> + + char *if_indextoname(unsigned int ifindex, char *ifname); + + When this function is called, the ifname argument shall point to a + buffer of at least IF_NAMESIZE bytes. The function shall place in + this buffer the name of the interface with index ifindex. + (IF_NAMESIZE is also defined in <net/if.h> and its value includes a + terminating null byte at the end of the interface name.) If ifindex + is an interface index, then the function shall return the value + supplied in ifname, which points to a buffer now containing the + interface name. Otherwise, the function shall return a NULL pointer + and set errno to indicate the error. If there is no interface + corresponding to the specified index, errno is set to ENXIO. If + there was a system error (such as running out of memory), errno would + be set to the proper value (e.g., ENOMEM). + + + + + + + + + + + + +Gilligan, et al. Informational [Page 17] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +4.3 Return All Interface Names and Indexes + + The if_nameindex structure holds the information about a single + interface and is defined as a result of including the <net/if.h> + header. + + struct if_nameindex { + unsigned int if_index; /* 1, 2, ... */ + char *if_name; /* null terminated name: "le0", ... */ + }; + + The final function returns an array of if_nameindex structures, one + structure per interface. + + #include <net/if.h> + + struct if_nameindex *if_nameindex(void); + + The end of the array of structures is indicated by a structure with + an if_index of 0 and an if_name of NULL. The function returns a NULL + pointer upon an error, and would set errno to the appropriate value. + + The memory used for this array of structures along with the interface + names pointed to by the if_name members is obtained dynamically. + This memory is freed by the next function. + +4.4 Free Memory + + The following function frees the dynamic memory that was allocated by + if_nameindex(). + + #include <net/if.h> + + void if_freenameindex(struct if_nameindex *ptr); + + The ptr argument shall be a pointer that was returned by + if_nameindex(). After if_freenameindex() has been called, the + application shall not use the array of which ptr is the address. + +5. Socket Options + + A number of new socket options are defined for IPv6. All of these + new options are at the IPPROTO_IPV6 level. That is, the "level" + parameter in the getsockopt() and setsockopt() calls is IPPROTO_IPV6 + when using these options. The constant name prefix IPV6_ is used in + all of the new socket options. This serves to clearly identify these + options as applying to IPv6. + + + + +Gilligan, et al. Informational [Page 18] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + The declaration for IPPROTO_IPV6, the new IPv6 socket options, and + related constants defined in this section are obtained by including + the header <netinet/in.h>. + +5.1 Unicast Hop Limit + + A new setsockopt() option controls the hop limit used in outgoing + unicast IPv6 packets. The name of this option is IPV6_UNICAST_HOPS, + and it is used at the IPPROTO_IPV6 layer. The following example + illustrates how it is used: + + int hoplimit = 10; + + if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + (char *) &hoplimit, sizeof(hoplimit)) == -1) + perror("setsockopt IPV6_UNICAST_HOPS"); + + When the IPV6_UNICAST_HOPS option is set with setsockopt(), the + option value given is used as the hop limit for all subsequent + unicast packets sent via that socket. If the option is not set, the + system selects a default value. The integer hop limit value (called + x) is interpreted as follows: + + x < -1: return an error of EINVAL + x == -1: use kernel default + 0 <= x <= 255: use x + x >= 256: return an error of EINVAL + + The IPV6_UNICAST_HOPS option may be used with getsockopt() to + determine the hop limit value that the system will use for subsequent + unicast packets sent via that socket. For example: + + int hoplimit; + socklen_t len = sizeof(hoplimit); + + if (getsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + (char *) &hoplimit, &len) == -1) + perror("getsockopt IPV6_UNICAST_HOPS"); + else + printf("Using %d for hop limit.\n", hoplimit); + +5.2 Sending and Receiving Multicast Packets + + IPv6 applications may send multicast packets by simply specifying an + IPv6 multicast address as the destination address, for example in the + destination address argument of the sendto() function. + + + + + +Gilligan, et al. Informational [Page 19] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + Three socket options at the IPPROTO_IPV6 layer control some of the + parameters for sending multicast packets. Setting these options is + not required: applications may send multicast packets without using + these options. The setsockopt() options for controlling the sending + of multicast packets are summarized below. These three options can + also be used with getsockopt(). + + IPV6_MULTICAST_IF + + Set the interface to use for outgoing multicast packets. The + argument is the index of the interface to use. If the + interface index is specified as zero, the system selects the + interface (for example, by looking up the address in a routing + table and using the resulting interface). + + Argument type: unsigned int + + IPV6_MULTICAST_HOPS + + Set the hop limit to use for outgoing multicast packets. (Note + a separate option - IPV6_UNICAST_HOPS - is provided to set the + hop limit to use for outgoing unicast packets.) + + The interpretation of the argument is the same as for the + IPV6_UNICAST_HOPS option: + + x < -1: return an error of EINVAL + x == -1: use kernel default + 0 <= x <= 255: use x + x >= 256: return an error of EINVAL + + If IPV6_MULTICAST_HOPS is not set, the default is 1 + (same as IPv4 today) + + Argument type: int + + IPV6_MULTICAST_LOOP + + If a multicast datagram is sent to a group to which the sending + host itself belongs (on the outgoing interface), a copy of the + datagram is looped back by the IP layer for local delivery if + this option is set to 1. If this option is set to 0 a copy is + not looped back. Other option values return an error of + EINVAL. + + + + + + + +Gilligan, et al. Informational [Page 20] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + If IPV6_MULTICAST_LOOP is not set, the default is 1 (loopback; + same as IPv4 today). + + Argument type: unsigned int + + The reception of multicast packets is controlled by the two + setsockopt() options summarized below. An error of EOPNOTSUPP is + returned if these two options are used with getsockopt(). + + IPV6_JOIN_GROUP + + Join a multicast group on a specified local interface. + If the interface index is specified as 0, + the kernel chooses the local interface. + For example, some kernels look up the multicast group + in the normal IPv6 routing table and use the resulting + interface. + + Argument type: struct ipv6_mreq + + IPV6_LEAVE_GROUP + + Leave a multicast group on a specified interface. + If the interface index is specified as 0, the system + may choose a multicast group membership to drop by + matching the multicast address only. + + Argument type: struct ipv6_mreq + + The argument type of both of these options is the ipv6_mreq + structure, defined as a result of including the <netinet/in.h> + header; + + struct ipv6_mreq { + struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast addr */ + unsigned int ipv6mr_interface; /* interface index */ + }; + + Note that to receive multicast datagrams a process must join the + multicast group to which datagrams will be sent. UDP applications + must also bind the UDP port to which datagrams will be sent. Some + processes also bind the multicast group address to the socket, in + addition to the port, to prevent other datagrams destined to that + same port from being delivered to the socket. + + + + + + + +Gilligan, et al. Informational [Page 21] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +5.3 IPV6_V6ONLY option for AF_INET6 Sockets + + This socket option restricts AF_INET6 sockets to IPv6 communications + only. As stated in section <3.7 Compatibility with IPv4 Nodes>, + AF_INET6 sockets may be used for both IPv4 and IPv6 communications. + Some applications may want to restrict their use of an AF_INET6 + socket to IPv6 communications only. For these applications the + IPV6_V6ONLY socket option is defined. When this option is turned on, + the socket can be used to send and receive IPv6 packets only. This + is an IPPROTO_IPV6 level option. This option takes an int value. + This is a boolean option. By default this option is turned off. + + Here is an example of setting this option: + + int on = 1; + + if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + (char *)&on, sizeof(on)) == -1) + perror("setsockopt IPV6_V6ONLY"); + else + printf("IPV6_V6ONLY set\n"); + + Note - This option has no effect on the use of IPv4 Mapped addresses + which enter a node as a valid IPv6 addresses for IPv6 communications + as defined by Stateless IP/ICMP Translation Algorithm (SIIT) [5]. + + An example use of this option is to allow two versions of the same + server process to run on the same port, one providing service over + IPv6, the other providing the same service over IPv4. + +6. Library Functions + + New library functions are needed to perform a variety of operations + with IPv6 addresses. Functions are needed to lookup IPv6 addresses + in the Domain Name System (DNS). Both forward lookup (nodename-to- + address translation) and reverse lookup (address-to-nodename + translation) need to be supported. Functions are also needed to + convert IPv6 addresses between their binary and textual form. + + We note that the two existing functions, gethostbyname() and + gethostbyaddr(), are left as-is. New functions are defined to handle + both IPv4 and IPv6 addresses. + + The commonly used function gethostbyname() is inadequate for many + applications, first because it provides no way for the caller to + specify anything about the types of addresses desired (IPv4 only, + IPv6 only, IPv4-mapped IPv6 are OK, etc.), and second because many + implementations of this function are not thread safe. RFC 2133 + + + +Gilligan, et al. Informational [Page 22] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + defined a function named gethostbyname2() but this function was also + inadequate, first because its use required setting a global option + (RES_USE_INET6) when IPv6 addresses were required, and second because + a flag argument is needed to provide the caller with additional + control over the types of addresses required. The gethostbyname2() + function was deprecated in RFC 2553 and is no longer part of the + basic API. + +6.1 Protocol-Independent Nodename and Service Name Translation + + Nodename-to-address translation is done in a protocol-independent + fashion using the getaddrinfo() function. + +#include <sys/socket.h> +#include <netdb.h> + + +int getaddrinfo(const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res); + +void freeaddrinfo(struct addrinfo *ai); + +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME, + AI_NUMERICHOST, .. */ + int ai_family; /* AF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + socklen_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for nodename */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; + + The getaddrinfo() function translates the name of a service location + (for example, a host name) and/or a service name and returns a set of + socket addresses and associated information to be used in creating a + socket with which to address the specified service. + + The nodename and servname arguments are either null pointers or + pointers to null-terminated strings. One or both of these two + arguments must be a non-null pointer. + + The format of a valid name depends on the address family or families. + If a specific family is not given and the name could be interpreted + as valid within multiple supported families, the implementation will + attempt to resolve the name in all supported families and, in absence + of errors, one or more results shall be returned. + + + +Gilligan, et al. Informational [Page 23] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + If the nodename argument is not null, it can be a descriptive name or + can be an address string. If the specified address family is + AF_INET, AF_INET6, or AF_UNSPEC, valid descriptive names include host + names. If the specified address family is AF_INET or AF_UNSPEC, + address strings using Internet standard dot notation as specified in + inet_addr() are valid. If the specified address family is AF_INET6 + or AF_UNSPEC, standard IPv6 text forms described in inet_pton() are + valid. + + If nodename is not null, the requested service location is named by + nodename; otherwise, the requested service location is local to the + caller. + + If servname is null, the call shall return network-level addresses + for the specified nodename. If servname is not null, it is a null- + terminated character string identifying the requested service. This + can be either a descriptive name or a numeric representation suitable + for use with the address family or families. If the specified + address family is AF_INET, AF_INET6 or AF_UNSPEC, the service can be + specified as a string specifying a decimal port number. + + If the argument hints is not null, it refers to a structure + containing input values that may direct the operation by providing + options and by limiting the returned information to a specific socket + type, address family and/or protocol. In this hints structure every + member other than ai_flags, ai_family, ai_socktype and ai_protocol + shall be set to zero or a null pointer. A value of AF_UNSPEC for + ai_family means that the caller shall accept any address family. A + value of zero for ai_socktype means that the caller shall accept any + socket type. A value of zero for ai_protocol means that the caller + shall accept any protocol. If hints is a null pointer, the behavior + shall be as if it referred to a structure containing the value zero + for the ai_flags, ai_socktype and ai_protocol fields, and AF_UNSPEC + for the ai_family field. + + Note: + + 1. If the caller handles only TCP and not UDP, for example, then the + ai_protocol member of the hints structure should be set to + IPPROTO_TCP when getaddrinfo() is called. + + 2. If the caller handles only IPv4 and not IPv6, then the ai_family + member of the hints structure should be set to AF_INET when + getaddrinfo() is called. + + + + + + + +Gilligan, et al. Informational [Page 24] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + The ai_flags field to which hints parameter points shall be set to + zero or be the bitwise-inclusive OR of one or more of the values + AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST, AI_NUMERICSERV, + AI_V4MAPPED, AI_ALL, and AI_ADDRCONFIG. + + If the AI_PASSIVE flag is specified, the returned address information + shall be suitable for use in binding a socket for accepting incoming + connections for the specified service (i.e., a call to bind()). In + this case, if the nodename argument is null, then the IP address + portion of the socket address structure shall be set to INADDR_ANY + for an IPv4 address or IN6ADDR_ANY_INIT for an IPv6 address. If the + AI_PASSIVE flag is not specified, the returned address information + shall be suitable for a call to connect() (for a connection-mode + protocol) or for a call to connect(), sendto() or sendmsg() (for a + connectionless protocol). In this case, if the nodename argument is + null, then the IP address portion of the socket address structure + shall be set to the loopback address. This flag is ignored if the + nodename argument is not null. + + If the AI_CANONNAME flag is specified and the nodename argument is + not null, the function shall attempt to determine the canonical name + corresponding to nodename (for example, if nodename is an alias or + shorthand notation for a complete name). + + If the AI_NUMERICHOST flag is specified, then a non-null nodename + string supplied shall be a numeric host address string. Otherwise, + an [EAI_NONAME] error is returned. This flag shall prevent any type + of name resolution service (for example, the DNS) from being invoked. + + If the AI_NUMERICSERV flag is specified, then a non-null servname + string supplied shall be a numeric port string. Otherwise, an + [EAI_NONAME] error shall be returned. This flag shall prevent any + type of name resolution service (for example, NIS+) from being + invoked. + + If the AI_V4MAPPED flag is specified along with an ai_family of + AF_INET6, then getaddrinfo() shall return IPv4-mapped IPv6 addresses + on finding no matching IPv6 addresses (ai_addrlen shall be 16). + + For example, when using the DNS, if no AAAA records are found then + a query is made for A records and any found are returned as IPv4- + mapped IPv6 addresses. + + The AI_V4MAPPED flag shall be ignored unless ai_family equals + AF_INET6. + + If the AI_ALL flag is used with the AI_V4MAPPED flag, then + getaddrinfo() shall return all matching IPv6 and IPv4 addresses. + + + +Gilligan, et al. Informational [Page 25] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + 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 + + + +Gilligan, et al. Informational [Page 26] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + 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. + + + + + + + + + +Gilligan, et al. Informational [Page 27] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + 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. + + + + +Gilligan, et al. Informational [Page 28] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + #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. + + + + + +Gilligan, et al. Informational [Page 29] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + 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. + + + + + + + + + + + + +Gilligan, et al. Informational [Page 30] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + 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 + + + +Gilligan, et al. Informational [Page 31] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + 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. + + + + + + + + +Gilligan, et al. Informational [Page 32] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +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 + + + +Gilligan, et al. Informational [Page 33] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +<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); + + + + + +Gilligan, et al. Informational [Page 34] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +<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 RFC 2553 + + 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. + + + + +Gilligan, et al. Informational [Page 35] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + + 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. + + + + + + + +Gilligan, et al. Informational [Page 36] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +11. References + + [1] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) + Specification", RFC 2460, December 1998. + + [2] Hinden, R. and S. Deering, "IP Version 6 Addressing + Architecture", RFC 2373, 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)", + RFC 2765, February 2000. + + [6] The Open Group Base Working Group + http://www.opengroup.org/platform/base.html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Gilligan, et al. Informational [Page 37] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +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 + + + + + + + + + + + + + + + +Gilligan, et al. Informational [Page 38] + +RFC 3493 Basic Socket Interface Extensions for IPv6 February 2003 + + +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 RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + + + + + + + + + + + +Gilligan, et al. Informational [Page 39] + |