diff options
Diffstat (limited to 'doc/rfc/rfc2553.txt')
-rw-r--r-- | doc/rfc/rfc2553.txt | 2299 |
1 files changed, 2299 insertions, 0 deletions
diff --git a/doc/rfc/rfc2553.txt b/doc/rfc/rfc2553.txt new file mode 100644 index 0000000..6989bf3 --- /dev/null +++ b/doc/rfc/rfc2553.txt @@ -0,0 +1,2299 @@ + + + + + + +Network Working Group R. Gilligan +Request for Comments: 2553 FreeGate +Obsoletes: 2133 S. Thomson +Category: Informational Bellcore + J. Bound + Compaq + W. Stevens + Consultant + March 1999 + + + 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 (1999). 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 [4]. + + + + + + + + + + +Gilligan, et. al. Informational [Page 1] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + +Table of Contents + + 1. Introduction.................................................3 + 2. Design Considerations........................................3 + 2.1 What Needs to be Changed....................................4 + 2.2 Data Types..................................................5 + 2.3 Headers.....................................................5 + 2.4 Structures..................................................5 + 3. Socket Interface.............................................6 + 3.1 IPv6 Address Family and Protocol Family.....................6 + 3.2 IPv6 Address Structure......................................6 + 3.3 Socket Address Structure for 4.3BSD-Based Systems...........7 + 3.4 Socket Address Structure for 4.4BSD-Based Systems...........8 + 3.5 The Socket Functions........................................9 + 3.6 Compatibility with IPv4 Applications.......................10 + 3.7 Compatibility with IPv4 Nodes..............................10 + 3.8 IPv6 Wildcard Address......................................11 + 3.9 IPv6 Loopback Address......................................12 + 3.10 Portability Additions.....................................13 + 4. Interface Identification....................................16 + 4.1 Name-to-Index..............................................16 + 4.2 Index-to-Name..............................................17 + 4.3 Return All Interface Names and Indexes.....................17 + 4.4 Free Memory................................................18 + 5. Socket Options..............................................18 + 5.1 Unicast Hop Limit..........................................18 + 5.2 Sending and Receiving Multicast Packets....................19 + 6. Library Functions...........................................21 + 6.1 Nodename-to-Address Translation............................21 + 6.2 Address-To-Nodename Translation............................24 + 6.3 Freeing memory for getipnodebyname and getipnodebyaddr.....26 + 6.4 Protocol-Independent Nodename and Service Name Translation.26 + 6.5 Socket Address Structure to Nodename and Service Name......29 + 6.6 Address Conversion Functions...............................31 + 6.7 Address Testing Macros.....................................32 + 7. Summary of New Definitions..................................33 + 8. Security Considerations.....................................35 + 9. Year 2000 Considerations....................................35 + Changes From RFC 2133..........................................35 + Acknowledgments................................................38 + References.....................................................39 + Authors' Addresses.............................................40 + Full Copyright Statement.......................................41 + + + + + + + + +Gilligan, et. al. Informational [Page 2] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + +1. Introduction + + While IPv4 addresses are 32 bits long, IPv6 interfaces are identified + by 128-bit addresses. 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 (e.g., traffic class and flowlabel), 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. + +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 + additonal mechanism for implementations to verify this is to + verify the new symbols are protected by Feature Test Macros as + described in IEEE Std 1003.1. (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. + + + + +Gilligan, et. al. Informational [Page 3] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + +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. + + 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 name-to-address translation functions in the socket interface are + gethostbyname() and gethostbyaddr(). These are left as is and new + functions are defined to support IPv4 and IPv6. Additionally, the + POSIX 1003.g draft [3] specifies a new nodename-to-address + translation function which is protocol independent. This function + can also be used with IPv4 and IPv6. + + + + + + +Gilligan, et. al. Informational [Page 4] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + The 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. + New interfaces are needed to support the IPv6 traffic class, flow + label, and hop limit header fields. 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. These extensions are described in [4]. + +2.2 Data Types + + The data types of the structure elements given in this memo are + intended to be examples, not absolute requirements. Whenever + possible, data types from Draft 6.6 (March 1997) of POSIX 1003.1g are + used: uintN_t means an unsigned integer of exactly N bits (e.g., + uint16_t). We also assume the argument data types from 1003.1g when + possible (e.g., the final argument to setsockopt() is a size_t + value). Whenever buffer sizes are specified, the POSIX 1003.1 size_t + data type is used (e.g., the two length arguments to getnameinfo()). + +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 IEEE Std 1003.1. (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. + + + + + + + + +Gilligan, et. al. Informational [Page 5] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + +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 PF_INET6 is used in the first argument to the socket() function + to indicate that an IPv6 socket is being created. + +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: + + + + + + + + + + + +Gilligan, et. al. Informational [Page 6] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + 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: + +struct sockaddr_in6 { + sa_family_t sin6_family; /* AF_INET6 */ + in_port_t sin6_port; /* transport layer port # */ + uint32_t sin6_flowinfo; /* IPv6 traffic class & flow info */ + 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. + + + + + + + +Gilligan, et. al. Informational [Page 7] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + The sin6_flowinfo field is a 32-bit field that contains two pieces of + information: the traffic class and the flow label. The contents and + interpretation of this member is specified in [1]. The sin6_flowinfo + field SHOULD be set to zero by an implementation prior to using the + sockaddr_in6 structure by an application on receive operations. + + 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 of the address carried in the + sin6_addr field. For a link scope sin6_addr sin6_scope_id would be + an interface index. For a site scope sin6_addr, sin6_scope_id would + be a site identifier. The mapping of sin6_scope_id to an interface + or set of interfaces is left to implementation and future + specifications on the subject of site identifiers. + + 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. + +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. + + + + + + + + + + + +Gilligan, et. al. Informational [Page 8] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + +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(PF_INET, SOCK_STREAM, 0); + + To create an IPv4/UDP socket, applications make the call: + + s = socket(PF_INET, SOCK_DGRAM, 0); + + Applications may create IPv6/TCP and IPv6/UDP sockets by simply using + the constant PF_INET6 instead of PF_INET in the first argument. For + example, to create an IPv6/TCP socket, applications make the call: + + s = socket(PF_INET6, SOCK_STREAM, 0); + + To create an IPv6/UDP socket, applications make the call: + + s = socket(PF_INET6, SOCK_DGRAM, 0); + + + + + + + +Gilligan, et. al. Informational [Page 9] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + Once the application has created a PF_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 PF_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 PF_INET sockets and the sockaddr_in address + structure. Applications must be able to create IPv4/TCP and IPv4/UDP + sockets using the PF_INET constant in the socket() function, as + 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 + + + +Gilligan, et. al. Informational [Page 10] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + 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 + getipnodebyname() function when the specified host has only IPv4 + addresses (as described in Section 6.1). + + Applications may use PF_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 PF_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.7, 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. + + 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; + + + + + + +Gilligan, et. al. Informational [Page 11] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + 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. + +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. + + + + + + + +Gilligan, et. al. Informational [Page 12] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + 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. + +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 portable across multiple address families and + platforms. This data structure is designed with the following goals. + + - It has a large enough implementation specific maximum size to + store the desired set of protocol specific socket address data + structures. Specifically, it is at least large enough to + accommodate sockaddr_in and sockaddr_in6 and possibly other + protocol specific socket addresses too. + - It is aligned at an appropriate boundary so protocol specific + socket address data structure pointers can be cast to it and + access their fields without alignment problems. (e.g. pointers + to sockaddr_in6 and/or sockaddr_in can be cast to it and access + fields without alignment problems). + + + +Gilligan, et. al. Informational [Page 13] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + - It has the initial field(s) isomorphic to the fields of the + "struct sockaddr" data structure on that implementation which + can be used as a discriminants for deriving the protocol in use. + These initial field(s) would on most implementations either be a + single field of type "sa_family_t" (isomorphic to sa_family + field, 16 bits) or two fields of type uint8_t and sa_family_t + respectively, (isomorphic to sa_len and sa_family_t, 8 bits + each). + + 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 */ +}; + + On implementations where 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 (sa_family_t)+ + + + +Gilligan, et. al. Informational [Page 14] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + _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 */ +}; + + The above example implementation illustrates a data structure which + will align on a 64 bit boundary. An implementation specific field + "__ss_align" along "__ss_pad1" is used to force a 64-bit alignment + which covers proper alignment good enough for needs of sockaddr_in6 + (IPv6), sockaddr_in (IPv4) address data structures. The size of + padding fields __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_ALIGNMENT (with chosen value 8). Constants _SS_PAD1SIZE (derived + value 6) and _SS_PAD2SIZE (derived value 112) are also for + illustration and not required. 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. + + The sockaddr_storage structure solves the problem of declaring + storage for automatic variables which is large enough and aligned + enough for storing socket address data structure of any family. For + example, code with a file descriptor and without the context of the + address family can pass a pointer to a variable of this type where a + pointer to a socket address structure is expected in calls such as + getpeername() and determine the address family by accessing the + received content after the call. + + The sockaddr_storage structure may also be useful and applied to + certain other interfaces where a generic socket address large enough + and aligned for use with multiple address families may be needed. A + discussion of those interfaces is outside the scope of this document. + + + + +Gilligan, et. al. Informational [Page 15] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + Also, much existing code assumes that any socket address structure + can fit in a generic sockaddr structure. While this has been true + for IPv4 socket address structures, it has always been false for Unix + domain socket address structures (but in practice this has not been a + problem) and it is also false for IPv6 socket address structures + (which can be a problem). + + So now an application can do the following: + + struct sockaddr_storage __ss; + struct sockaddr_in6 *sin6; + sin6 = (struct sockaddr_in6 *) &__ss; + +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.3). 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 + 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); + + + + +Gilligan, et. al. Informational [Page 16] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + If the specified interface name does not exist, the return value is + 0, and errno is set to ENXIO. If there was a system error (such as + running out of memory), the return value is 0 and errno is set to the + proper value (e.g., ENOMEM). + +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); + + The ifname argument must point to a buffer of at least IF_NAMESIZE + bytes into which the interface name corresponding to the specified + index is returned. (IF_NAMESIZE is also defined in <net/if.h> and + its value includes a terminating null byte at the end of the + interface name.) This pointer is also the return value of the + function. If there is no interface corresponding to the specified + index, NULL is returned, and errno is set to ENXIO, if there was a + system error (such as running out of memory), if_indextoname returns + NULL and errno would be set to the proper value (e.g., ENOMEM). + +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. + + 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. + + + + +Gilligan, et. al. Informational [Page 17] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + +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 argument to this function must be a pointer that was returned by + if_nameindex(). + + Currently net/if.h doesn't have prototype definitions for functions + and it is recommended that these definitions be defined in net/if.h + as well and the struct if_nameindex{}. + +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. + + 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: + + + + +Gilligan, et. al. Informational [Page 18] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + 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; + size_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 UDP multicast packets by simply specifying + an IPv6 multicast address in the address argument of the sendto() + function. + + 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. + + 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: + + + + + +Gilligan, et. al. Informational [Page 19] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + 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. + + 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 using the resulting + interface. + + Argument type: struct ipv6_mreq + + IPV6_LEAVE_GROUP + + Leave a multicast group on a specified interface. + + 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; + + + + + +Gilligan, et. al. Informational [Page 20] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + 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 and 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. + +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. + +6.1 Nodename-to-Address Translation + + 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 + 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 following function is new and must be thread safe: + + #include <sys/socket.h> + #include <netdb.h> + + struct hostent *getipnodebyname(const char *name, int af, int flags + int *error_num); + + The name argument can be either a node name or a numeric address + string (i.e., a dotted-decimal IPv4 address or an IPv6 hex address). + The af argument specifies the address family, either AF_INET or + + + +Gilligan, et. al. Informational [Page 21] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + AF_INET6. The error_num value is returned to the caller, via a + pointer, with the appropriate error code in error_num, to support + thread safe error code returns. error_num will be set to one of the + following values: + + HOST_NOT_FOUND + + No such host is known. + + NO_ADDRESS + + The server recognised the request and the name but no address is + available. Another type of request to the name server for the + domain might return an answer. + + NO_RECOVERY + + An unexpected server failure occurred which cannot be recovered. + + TRY_AGAIN + + A temporary and possibly transient error occurred, such as a + failure of a server to respond. + + The flags argument specifies the types of addresses that are searched + for, and the types of addresses that are returned. We note that a + special flags value of AI_DEFAULT (defined below) should handle most + applications. + + That is, porting simple applications to use IPv6 replaces the call + + hptr = gethostbyname(name); + + with + + hptr = getipnodebyname(name, AF_INET6, AI_DEFAULT, &error_num); + + and changes any subsequent error diagnosis code to use error_num + instead of externally declared variables, such as h_errno. + + Applications desiring finer control over the types of addresses + searched for and returned, can specify other combinations of the + flags argument. + + + + + + + + +Gilligan, et. al. Informational [Page 22] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + A flags of 0 implies a strict interpretation of the af argument: + + - If flags is 0 and af is AF_INET, then the caller wants only + IPv4 addresses. A query is made for A records. If successful, + the IPv4 addresses are returned and the h_length member of the + hostent structure will be 4, else the function returns a NULL + pointer. + + - If flags is 0 and if af is AF_INET6, then the caller wants only + IPv6 addresses. A query is made for AAAA records. If + successful, the IPv6 addresses are returned and the h_length + member of the hostent structure will be 16, else the function + returns a NULL pointer. + + Other constants can be logically-ORed into the flags argument, to + modify the behavior of the function. + + - If the AI_V4MAPPED flag is specified along with an af of + AF_INET6, then the caller will accept IPv4-mapped IPv6 + addresses. That is, if no AAAA records are found then a query + is made for A records and any found are returned as IPv4-mapped + IPv6 addresses (h_length will be 16). The AI_V4MAPPED flag is + ignored unless af equals AF_INET6. + + - The AI_ALL flag is used in conjunction with the AI_V4MAPPED + flag, and is only used with the IPv6 address family. When AI_ALL + is logically or'd with AI_V4MAPPED flag then the caller wants + all addresses: IPv6 and IPv4-mapped IPv6. A query is first made + for AAAA records and if successful, the IPv6 addresses are + returned. Another query is then made for A records and any found + are returned as IPv4-mapped IPv6 addresses. h_length will be 16. + Only if both queries fail does the function return a NULL pointer. + This flag is ignored unless af equals AF_INET6. + + - The AI_ADDRCONFIG flag specifies that a query for AAAA records + should occur only if the node has at least one IPv6 source + address configured and a query for A records should occur only + if the node has at least one IPv4 source address configured. + + For example, if the node has no IPv6 source addresses + configured, and af equals AF_INET6, and the node name being + looked up has both AAAA and A records, then: + + (a) if only AI_ADDRCONFIG is specified, the function + returns a NULL pointer; + (b) if AI_ADDRCONFIG | AI_V4MAPPED is specified, the A + records are returned as IPv4-mapped IPv6 addresses; + + + + +Gilligan, et. al. Informational [Page 23] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + The special flags value of AI_DEFAULT is defined as + + #define AI_DEFAULT (AI_V4MAPPED | AI_ADDRCONFIG) + + We noted that the getipnodebyname() function must allow the name + argument to be either a node name or a literal address string (i.e., + a dotted-decimal IPv4 address or an IPv6 hex address). This saves + applications from having to call inet_pton() to handle literal + address strings. + + There are four scenarios based on the type of literal address string + and the value of the af argument. + + The two simple cases are: + + When name is a dotted-decimal IPv4 address and af equals AF_INET, or + when name is an IPv6 hex address and af equals AF_INET6. The members + of the returned hostent structure are: h_name points to a copy of the + name argument, h_aliases is a NULL pointer, h_addrtype is a copy of + the af argument, h_length is either 4 (for AF_INET) or 16 (for + AF_INET6), h_addr_list[0] is a pointer to the 4-byte or 16-byte + binary address, and h_addr_list[1] is a NULL pointer. + + When name is a dotted-decimal IPv4 address and af equals AF_INET6, + and flags equals AI_V4MAPPED, an IPv4-mapped IPv6 address is + returned: h_name points to an IPv6 hex address containing the IPv4- + mapped IPv6 address, h_aliases is a NULL pointer, h_addrtype is + AF_INET6, h_length is 16, h_addr_list[0] is a pointer to the 16-byte + binary address, and h_addr_list[1] is a NULL pointer. If AI_V4MAPPED + is set (with or without AI_ALL) return IPv4-mapped otherwise return + NULL. + + It is an error when name is an IPv6 hex address and af equals + AF_INET. The function's return value is a NULL pointer and error_num + equals HOST_NOT_FOUND. + +6.2 Address-To-Nodename Translation + + The following function has the same arguments as the existing + gethostbyaddr() function, but adds an error number. + + #include <sys/socket.h> #include <netdb.h> + + struct hostent *getipnodebyaddr(const void *src, size_t len, + int af, int *error_num); + + + + + + +Gilligan, et. al. Informational [Page 24] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + As with getipnodebyname(), getipnodebyaddr() must be thread safe. + The error_num value is returned to the caller with the appropriate + error code, to support thread safe error code returns. The following + error conditions may be returned for error_num: + + HOST_NOT_FOUND + + No such host is known. + + NO_ADDRESS + + The server recognized the request and the name but no address + is available. Another type of request to the name server for + the domain might return an answer. + + NO_RECOVERY + + An unexpected server failure occurred which cannot be + recovered. + + TRY_AGAIN + + A temporary and possibly transient error occurred, such as a + failure of a server to respond. + + One possible source of confusion is the handling of IPv4-mapped IPv6 + addresses and IPv4-compatible IPv6 addresses, but the following logic + should apply. + + 1. If af is AF_INET6, and if len equals 16, and if the IPv6 + address is an IPv4-mapped IPv6 address or an IPv4-compatible + IPv6 address, then skip over the first 12 bytes of the IPv6 + address, set af to AF_INET, and set len to 4. + + 2. If af is AF_INET, lookup the name for the given IPv4 address + (e.g., query for a PTR record in the in-addr.arpa domain). + + 3. If af is AF_INET6, lookup the name for the given IPv6 address + (e.g., query for a PTR record in the ip6.int domain). + + 4. If the function is returning success, then the single address + that is returned in the hostent structure is a copy of the + first argument to the function with the same address family + that was passed as an argument to this function. + + + + + + + +Gilligan, et. al. Informational [Page 25] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + All four steps listed are performed, in order. Also note that the + IPv6 hex addresses "::" and "::1" MUST NOT be treated as IPv4- + compatible addresses, and if the address is "::", HOST_NOT_FOUND MUST + be returned and a query of the address not performed. + + Also for the macro in section 6.7 IN6_IS_ADDR_V4COMPAT MUST return + false for "::" and "::1". + +6.3 Freeing memory for getipnodebyname and getipnodebyaddr + + The hostent structure does not change from its existing definition. + This structure, and the information pointed to by this structure, are + dynamically allocated by getipnodebyname and getipnodebyaddr. The + following function frees this memory: + + #include <netdb.h> + + void freehostent(struct hostent *ptr); + +6.4 Protocol-Independent Nodename and Service Name Translation + + Nodename-to-address translation is done in a protocol-independent + fashion using the getaddrinfo() function that is taken from the + Institute of Electrical and Electronic Engineers (IEEE) POSIX 1003.1g + (Protocol Independent Interfaces) draft specification [3]. + + The official specification for this function will be the final POSIX + standard, with the following additional requirements: + + - getaddrinfo() (along with the getnameinfo() function described + in the next section) must be thread safe. + + - The AI_NUMERICHOST is new with this document. + + - All fields in socket address structures returned by + getaddrinfo() that are not filled in through an explicit + argument (e.g., sin6_flowinfo and sin_zero) must be set to 0. + (This makes it easier to compare socket address structures.) + + - getaddrinfo() must fill in the length field of a socket address + structure (e.g., sin6_len) on systems that support this field. + + We are providing this independent description of the function because + POSIX standards are not freely available (as are IETF documents). + + #include <sys/socket.h> + #include <netdb.h> + + + + +Gilligan, et. al. Informational [Page 26] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + int getaddrinfo(const char *nodename, const char *servname, + const struct addrinfo *hints, + struct addrinfo **res); + + The addrinfo structure is defined as a result of including the + <netdb.h> header. + + struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_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 return value from the function is 0 upon success or a nonzero + error code. The following names are the nonzero error codes from + getaddrinfo(), and are defined in <netdb.h>: + + EAI_ADDRFAMILY address family for nodename not supported + EAI_AGAIN temporary failure in name resolution + EAI_BADFLAGS invalid value for ai_flags + EAI_FAIL non-recoverable failure in name resolution + EAI_FAMILY ai_family not supported + EAI_MEMORY memory allocation failure + EAI_NODATA no address associated with nodename + EAI_NONAME nodename nor servname provided, or not known + EAI_SERVICE servname not supported for ai_socktype + EAI_SOCKTYPE ai_socktype not supported + EAI_SYSTEM system error returned in errno + + The nodename and servname arguments are pointers to null-terminated + strings or NULL. One or both of these two arguments must be a non- + NULL pointer. In the normal client scenario, both the nodename and + servname are specified. In the normal server scenario, only the + servname is specified. A non-NULL nodename string can be either a + node name or a numeric host address string (i.e., a dotted-decimal + IPv4 address or an IPv6 hex address). A non-NULL servname string can + be either a service name or a decimal port number. + + The caller can optionally pass an addrinfo structure, pointed to by + the third argument, to provide hints concerning the type of socket + that the caller supports. In this hints structure all members other + than ai_flags, ai_family, ai_socktype, and ai_protocol must be zero + or a NULL pointer. A value of PF_UNSPEC for ai_family means the + + + +Gilligan, et. al. Informational [Page 27] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + caller will accept any protocol family. A value of 0 for ai_socktype + means the caller will accept any socket type. A value of 0 for + ai_protocol means the caller will accept any protocol. For example, + if the caller handles only TCP and not UDP, then the ai_socktype + member of the hints structure should be set to SOCK_STREAM when + getaddrinfo() is called. If the caller handles only IPv4 and not + IPv6, then the ai_family member of the hints structure should be set + to PF_INET when getaddrinfo() is called. If the third argument to + getaddrinfo() is a NULL pointer, this is the same as if the caller + had filled in an addrinfo structure initialized to zero with + ai_family set to PF_UNSPEC. + + Upon successful return a pointer to a linked list of one or more + addrinfo structures is returned through the final argument. The + caller can process each addrinfo structure in this list by following + the ai_next pointer, until a NULL pointer is encountered. In each + returned addrinfo structure the three members ai_family, ai_socktype, + and ai_protocol are the corresponding arguments for a call to the + socket() function. In each addrinfo structure the ai_addr member + points to a filled-in socket address structure whose length is + specified by the ai_addrlen member. + + If the AI_PASSIVE bit is set in the ai_flags member of the hints + structure, then the caller plans to use the returned socket address + structure in a call to bind(). In this case, if the nodename + argument is a NULL pointer, then the IP address portion of the socket + address structure will be set to INADDR_ANY for an IPv4 address or + IN6ADDR_ANY_INIT for an IPv6 address. + + If the AI_PASSIVE bit is not set in the ai_flags member of the hints + structure, then the returned socket address structure will be ready + for a call to connect() (for a connection-oriented protocol) or + either connect(), sendto(), or sendmsg() (for a connectionless + protocol). In this case, if the nodename argument is a NULL pointer, + then the IP address portion of the socket address structure will be + set to the loopback address. + + If the AI_CANONNAME bit is set in the ai_flags member of the hints + structure, then upon successful return the ai_canonname member of the + first addrinfo structure in the linked list will point to a null- + terminated string containing the canonical name of the specified + nodename. + + If the AI_NUMERICHOST bit is set in the ai_flags member of the hints + structure, then a non-NULL nodename string must be a numeric host + address string. Otherwise an error of EAI_NONAME is returned. This + flag prevents any type of name resolution service (e.g., the DNS) + from being called. + + + +Gilligan, et. al. Informational [Page 28] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + All of the information returned by getaddrinfo() is dynamically + allocated: the addrinfo structures, and the socket address structures + and canonical node name strings pointed to by the addrinfo + structures. To return this information to the system the function + freeaddrinfo() is called: + + #include <sys/socket.h> #include <netdb.h> + + void freeaddrinfo(struct addrinfo *ai); + + The addrinfo structure pointed to by the ai argument is freed, along + with any dynamic storage pointed to by the structure. This operation + is repeated until a NULL ai_next pointer is encountered. + + To aid applications in printing error messages based on the EAI_xxx + codes returned by getaddrinfo(), the following function is defined. + + #include <sys/socket.h> #include <netdb.h> + + char *gai_strerror(int ecode); + + The argument is one of the EAI_xxx values defined earlier and 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.5 Socket Address Structure to Nodename and Service Name + + The POSIX 1003.1g specification includes no function to perform the + reverse conversion from getaddrinfo(): to look up a nodename and + service name, given the binary address and port. Therefore, we + define the following function: + + #include <sys/socket.h> + #include <netdb.h> + + int getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, size_t hostlen, + char *serv, size_t servlen, + int flags); + + This function looks up an IP address and port number provided by the + caller in the DNS and system-specific database, and returns text + strings for both in buffers provided by the caller. The function + indicates successful completion by a zero return value; a non-zero + return value indicates failure. + + + + + +Gilligan, et. al. Informational [Page 29] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + The first argument, sa, points to either a sockaddr_in structure (for + IPv4) or a sockaddr_in6 structure (for IPv6) that holds the IP + address and port number. The salen argument gives the length of the + sockaddr_in or sockaddr_in6 structure. + + The function returns the nodename associated with the IP address in + the buffer pointed to by the host argument. The caller provides the + size of this buffer via the hostlen argument. The service name + associated with the port number is returned in the buffer pointed to + by serv, and the servlen argument gives the length of this buffer. + The caller specifies not to return either string by providing a zero + value for the hostlen or servlen arguments. Otherwise, the caller + must provide buffers large enough to hold the nodename and the + service name, including the terminating null characters. + + Unfortunately most systems do not provide constants that specify the + maximum size of either a fully-qualified domain name or a service + name. Therefore to aid the application in allocating buffers for + these two returned strings the following constants are defined in + <netdb.h>: + + #define NI_MAXHOST 1025 + #define NI_MAXSERV 32 + + The first value is actually defined as the constant MAXDNAME in recent + versions of BIND's <arpa/nameser.h> header (older versions of BIND + define this constant to be 256) and the second is a guess based on the + services listed in the current Assigned Numbers RFC. + + The final argument is a flag that changes the default actions of this + function. By default the fully-qualified domain name (FQDN) for the + host is looked up in the DNS and returned. If the flag bit NI_NOFQDN + is set, only the nodename portion of the FQDN is returned for local + hosts. + + If the flag bit NI_NUMERICHOST is set, or if the host's name cannot be + located in the DNS, the numeric form of the host's address is returned + instead of its name (e.g., by calling inet_ntop() instead of + getipnodebyaddr()). If the flag bit NI_NAMEREQD is set, an error is + returned if the host's name cannot be located in the DNS. + + If the flag bit NI_NUMERICSERV is set, the numeric form of the service + address is returned (e.g., its port number) instead of its name. The + two NI_NUMERICxxx flags are required to support the "-n" flag that + many commands provide. + + + + + + +Gilligan, et. al. Informational [Page 30] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + A fifth flag bit, NI_DGRAM, specifies that the service is a datagram + service, and causes getservbyport() to be called with a second + argument of "udp" instead of its default of "tcp". This is required + for the few ports (e.g. 512-514) that have different services for UDP + and TCP. + + These NI_xxx flags are defined in <netdb.h> along with the AI_xxx + flags already defined for getaddrinfo(). + +6.6 Address Conversion Functions + + The two 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 <sys/socket.h> + #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, size_t size); + + The inet_pton() function converts an address in its standard text + presentation form into its numeric binary form. The af argument + specifies the family of the address. Currently the AF_INET and + AF_INET6 address families are 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. The address is + returned in network byte order. Inet_pton() returns 1 if the + conversion succeeds, 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. The calling + application must ensure that the buffer referred to by dst is large + enough to hold the numeric address (e.g., 4 bytes for AF_INET or 16 + bytes for AF_INET6). + + If the af argument is AF_INET, the function accepts a string 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. + Note that many implementations of the existing inet_addr() and + inet_aton() functions accept nonstandard input: octal numbers, + hexadecimal numbers, and fewer than four numbers. inet_pton() does + not accept these formats. + + + +Gilligan, et. al. Informational [Page 31] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + If the af argument is AF_INET6, then the function accepts a string in + one of the standard IPv6 text forms defined in Section 2.2 of the + addressing architecture specification [2]. + + The inet_ntop() function converts a numeric address into a text + string suitable for presentation. The af argument specifies 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 will store the + resulting text string. The size argument specifies the size of this + buffer. The application must specify a non-NULL dst argument. For + IPv6 addresses, the buffer must be at least 46-octets. For IPv4 + addresses, the buffer must be at least 16-octets. 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 returns 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.7 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 *); + + + + + +Gilligan, et. al. Informational [Page 32] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + 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 local-use IPv6 unicast addresses. 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_DEFAULT + <netdb.h> AI_ALL + <netdb.h> AI_CANONNAME + <netdb.h> AI_NUMERICHOST + <netdb.h> AI_PASSIVE + <netdb.h> AI_V4MAPPED + <netdb.h> EAI_ADDRFAMILY + <netdb.h> EAI_AGAIN + <netdb.h> EAI_BADFLAGS + <netdb.h> EAI_FAIL + <netdb.h> EAI_FAMILY + <netdb.h> EAI_MEMORY + <netdb.h> EAI_NODATA + <netdb.h> EAI_NONAME + <netdb.h> EAI_SERVICE + <netdb.h> EAI_SOCKTYPE + <netdb.h> EAI_SYSTEM + <netdb.h> NI_DGRAM + <netdb.h> NI_MAXHOST + <netdb.h> NI_MAXSERV + <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 + + + +Gilligan, et. al. Informational [Page 33] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + <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> 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 *, size_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 *, size_t, char *, size_t, int); +<netdb.h> void freeaddrinfo(struct addrinfo *); +<netdb.h> char *gai_strerror(int); +<netdb.h> struct hostent *getipnodebyname(const char *, int, int, + int *); +<netdb.h> struct hostent *getipnodebyaddr(const void *, size_t, + int, int *); +<netdb.h> void freehostent(struct hostent *); + +<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 *); + + + +Gilligan, et. al. Informational [Page 34] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + +<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. Year 2000 Considerations + + There are no issues for this memo concerning the Year 2000 issue + regarding the use of dates. + +Changes From RFC 2133 + + Changes made in the March 1998 Edition (-01 draft): + + Changed all "hostname" to "nodename" for consistency with other + IPv6 documents. + + Section 3.3: changed comment for sin6_flowinfo to be "traffic + class & flow info" and updated corresponding text description to + current definition of these two fields. + + Section 3.10 ("Portability Additions") is new. + + Section 6: a new paragraph was added reiterating that the existing + gethostbyname() and gethostbyaddr() are not changed. + + Section 6.1: change gethostbyname3() to getnodebyname(). Add + AI_DEFAULT to handle majority of applications. Renamed + AI_V6ADDRCONFIG to AI_ADDRCONFIG and define it for A records and + IPv4 addresses too. Defined exactly what getnodebyname() must + return if the name argument is a numeric address string. + + Section 6.2: change gethostbyaddr() to getnodebyaddr(). Reword + items 2 and 3 in the description of how to handle IPv4-mapped and + IPv4- compatible addresses to "lookup a name" for a given address, + instead of specifying what type of DNS query to issue. + + + + +Gilligan, et. al. Informational [Page 35] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + Section 6.3: added two more requirements to getaddrinfo(). + + Section 7: added the following constants to the list for + <netdb.h>: AI_ADDRCONFIG, AI_ALL, and AI_V4MAPPED. Add union + sockaddr_union and SA_LEN to the lists for <sys/socket.h>. + + Updated references. + + Changes made in the November 1997 Edition (-00 draft): + + The data types have been changed to conform with Draft 6.6 of the + Posix 1003.1g standard. + + Section 3.2: data type of s6_addr changed to "uint8_t". + + Section 3.3: data type of sin6_family changed to "sa_family_t". + data type of sin6_port changed to "in_port_t", data type of + sin6_flowinfo changed to "uint32_t". + + Section 3.4: same as Section 3.3, plus data type of sin6_len + changed to "uint8_t". + + Section 6.2: first argument of gethostbyaddr() changed from "const + char *" to "const void *" and second argument changed from "int" + to "size_t". + + Section 6.4: second argument of getnameinfo() changed from + "size_t" to "socklen_t". + + The wording was changed when new structures were defined, to be + more explicit as to which header must be included to define the + structure: + + Section 3.2 (in6_addr{}), Section 3.3 (sockaddr_in6{}), Section + 3.4 (sockaddr_in6{}), Section 4.3 (if_nameindex{}), Section 5.3 + (ipv6_mreq{}), and Section 6.3 (addrinfo{}). + + Section 4: NET_RT_LIST changed to NET_RT_IFLIST. + + Section 5.1: The IPV6_ADDRFORM socket option was removed. + + Section 5.3: Added a note that an option value other than 0 or 1 + for IPV6_MULTICAST_LOOP returns an error. Added a note that + IPV6_MULTICAST_IF, IPV6_MULTICAST_HOPS, and IPV6_MULTICAST_LOOP + can also be used with getsockopt(), but IPV6_ADD_MEMBERSHIP and + IPV6_DROP_MEMBERSHIP cannot be used with getsockopt(). + + + + + +Gilligan, et. al. Informational [Page 36] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + Section 6.1: Removed the description of gethostbyname2() and its + associated RES_USE_INET6 option, replacing it with + gethostbyname3(). + + Section 6.2: Added requirement that gethostbyaddr() be thread + safe. Reworded step 4 to avoid using the RES_USE_INET6 option. + + Section 6.3: Added the requirement that getaddrinfo() and + getnameinfo() be thread safe. Added the AI_NUMERICHOST flag. + + Section 6.6: Added clarification about IN6_IS_ADDR_LINKLOCAL and + IN6_IS_ADDR_SITELOCAL macros. + + Changes made to the draft -01 specification Sept 98 + + Changed priority to traffic class in the spec. + + Added the need for scope identification in section 2.1. + + Added sin6_scope_id to struct sockaddr_in6 in sections 3.3 and + 3.4. + + Changed 3.10 to use generic storage structure to support holding + IPv6 addresses and removed the SA_LEN macro. + + Distinguished between invalid input parameters and system failures + for Interface Identification in Section 4.1 and 4.2. + + Added defaults for multicast operations in section 5.2 and changed + the names from ADD to JOIN and DROP to LEAVE to be consistent with + IPv6 multicast terminology. + + Changed getnodebyname to getipnodebyname, getnodebyaddr to + getipnodebyaddr, and added MT safe error code to function + parameters in section 6. + + Moved freehostent to its own sub-section after getipnodebyaddr now + 6.3 (so this bumps all remaining sections in section 6. + + Clarified the use of AI_ALL and AI_V4MAPPED that these are + dependent on the AF parameter and must be used as a conjunction in + section 6.1. + + Removed the restriction that literal addresses cannot be used with + a flags argument in section 6.1. + + Added Year 2000 Section to the draft + + + + +Gilligan, et. al. Informational [Page 37] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + Deleted Reference to the following because the attached is deleted + from the ID directory and has expired. But the logic from the + aforementioned draft still applies, so that was kept in Section + 6.2 bullets after 3rd paragraph. + + [7] P. Vixie, "Reverse Name Lookups of Encapsulated IPv4 + Addresses in IPv6", Internet-Draft, <draft-vixie-ipng- + ipv4ptr-00.txt>, May 1996. + + Deleted the following reference as it is no longer referenced. + And the draft has expired. + + [3] D. McDonald, "A Simple IP Security API Extension to BSD + Sockets", Internet-Draft, <draft-mcdonald-simple-ipsec-api- + 01.txt>, March 1997. + + Deleted the following reference as it is no longer referenced. + + [4] C. Metz, "Network Security API for Sockets", + Internet-Draft, <draft-metz-net-security-api-01.txt>, January + 1998. + + Update current references to current status. + + Added alignment notes for in6_addr and sin6_addr. + + Clarified further that AI_V4MAPPED must be used with a dotted IPv4 + literal address for getipnodebyname(), when address family is + AF_INET6. + + Added text to clarify "::" and "::1" when used by + getipnodebyaddr(). + +Acknowledgments + + 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, 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, Thomas Narten, Josh Osborne, Craig Partridge, Jean-Luc + Richier, Erik Scoredos, Keith Sklower, Matt Thomas, Harvey Thompson, + Dean D. Throop, Karen Tracey, Glenn Trewitt, Paul Vixie, David + Waitzman, Carl Williams, and Kazu Yamamoto, + + + + + + +Gilligan, et. al. Informational [Page 38] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + + The getaddrinfo() and getnameinfo() functions are taken from an + earlier Internet Draft by Keith Sklower. As noted in that draft, + 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. + +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, "Protocol Independent Interfaces", IEEE Std 1003.1g, DRAFT + 6.6, March 1997. + + [4] Stevens, W. and M. Thomas, "Advanced Sockets API for IPv6", RFC + 2292, February 1998. + + + + + + + + + + + + + + + + + + + + + + +Gilligan, et. al. Informational [Page 39] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + +Authors' Addresses + + Robert E. Gilligan + FreeGate Corporation + 1208 E. Arques Ave. + Sunnyvale, CA 94086 + + Phone: +1 408 617 1004 + EMail: gilligan@freegate.com + + + Susan Thomson + Bell Communications Research + MRE 2P-343, 445 South Street + Morristown, NJ 07960 + + Phone: +1 201 829 4514 + EMail: set@thumper.bellcore.com + + + Jim Bound + Compaq Computer Corporation + 110 Spitbrook Road ZK3-3/U14 + Nashua, NH 03062-2698 + + Phone: +1 603 884 0400 + EMail: bound@zk3.dec.com + + + W. Richard Stevens + 1202 E. Paseo del Zorro + Tucson, AZ 85718-2826 + + Phone: +1 520 297 9416 + EMail: rstevens@kohala.com + + + + + + + + + + + + + + + + +Gilligan, et. al. Informational [Page 40] + +RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999 + + +Full Copyright Statement + + Copyright (C) The Internet Society (1999). 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. + + + + + + + + + + + + + + + + + + + + + + + + +Gilligan, et. al. Informational [Page 41] + |