summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/doc/rfc/rfc2133.txt
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/doc/rfc/rfc2133.txt')
-rw-r--r--contrib/bind9/doc/rfc/rfc2133.txt1795
1 files changed, 0 insertions, 1795 deletions
diff --git a/contrib/bind9/doc/rfc/rfc2133.txt b/contrib/bind9/doc/rfc/rfc2133.txt
deleted file mode 100644
index ea66cf0..0000000
--- a/contrib/bind9/doc/rfc/rfc2133.txt
+++ /dev/null
@@ -1,1795 +0,0 @@
-
-
-
-
-
-
-Network Working Group R. Gilligan
-Request for Comments: 2133 Freegate
-Category: Informational S. Thomson
- Bellcore
- J. Bound
- Digital
- W. Stevens
- Consultant
- April 1997
-
- Basic Socket Interface Extensions for IPv6
-
-Status of this Memo
-
- This memo provides information for the Internet community. This memo
- does not specify an Internet standard of any kind. Distribution of
- this memo is unlimited.
-
-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 [5].
-
-Table of Contents
-
- 1. Introduction ................................................ 2
- 2. Design Considerations ....................................... 3
- 2.1. What Needs to be Changed .................................. 3
- 2.2. Data Types ................................................ 5
- 2.3. Headers ................................................... 5
- 2.4. Structures ................................................ 5
- 3. Socket Interface ............................................ 5
- 3.1. IPv6 Address Family and Protocol Family ................... 5
- 3.2. IPv6 Address Structure .................................... 6
-
-
-
-Gilligan, et. al. Informational [Page 1]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 3.3. Socket Address Structure for 4.3BSD-Based Systems ......... 6
- 3.4. Socket Address Structure for 4.4BSD-Based Systems ......... 7
- 3.5. The Socket Functions ...................................... 8
- 3.6. Compatibility with IPv4 Applications ...................... 9
- 3.7. Compatibility with IPv4 Nodes ............................. 9
- 3.8. IPv6 Wildcard Address ..................................... 10
- 3.9. IPv6 Loopback Address ..................................... 11
- 4. Interface Identification .................................... 12
- 4.1. Name-to-Index ............................................. 13
- 4.2. Index-to-Name ............................................. 13
- 4.3. Return All Interface Names and Indexes .................... 14
- 4.4. Free Memory ............................................... 14
- 5. Socket Options .............................................. 14
- 5.1. Changing Socket Type ...................................... 15
- 5.2. Unicast Hop Limit ......................................... 16
- 5.3. Sending and Receiving Multicast Packets ................... 17
- 6. Library Functions ........................................... 19
- 6.1. Hostname-to-Address Translation ........................... 19
- 6.2. Address To Hostname Translation ........................... 22
- 6.3. Protocol-Independent Hostname and Service Name Translation 22
- 6.4. Socket Address Structure to Hostname and Service Name ..... 25
- 6.5. Address Conversion Functions .............................. 27
- 6.6. Address Testing Macros .................................... 28
- 7. Summary of New Definitions .................................. 29
- 8. Security Considerations ..................................... 31
- 9. Acknowledgments ............................................. 31
- 10. References ................................................. 31
- 11. Authors' Addresses ......................................... 32
-
-1. Introduction
-
- While IPv4 addresses are 32 bits long, IPv6 interfaces are identified
- by 128-bit addresses. The socket interface make 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., flow label and priority), 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.
-
-
-
-
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 2]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
-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.
-
- - 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.
-
- 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
-
-
-
-Gilligan, et. al. Informational [Page 3]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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.
-
- The name-to-address translation functions in the socket interface are
- gethostbyname() and gethostbyaddr(). These must be modified to
- support IPv6 and the semantics defined must provide 100% backward
- compatibility for all existing IPv4 applications, along with IPv6
- support for new applications. Additionally, the POSIX 1003.g work in
- progress [4] specifies a new hostname-to-address translation function
- which is protocol independent. This function can also be used with
- IPv6.
-
- 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 flow label, priority,
- 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 [5].
-
-
-
-
-
-
-
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 4]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
-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, POSIX 1003.1g data types are used: u_intN_t means an
- unsigned integer of exactly N bits (e.g., u_int16_t) and u_intNm_t
- means an unsigned integer of at least N bits (e.g., u_int32m_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.
-
- 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 PF_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 5]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
-3.2. IPv6 Address Structure
-
- A new data structure to hold a single IPv6 address is defined as
- follows:
-
- #include <netinet/in.h>
-
- struct in6_addr {
- u_int8_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.
-
-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
- structure is defined to carry IPv6 addresses:
-
- #include <netinet/in.h>
-
- struct sockaddr_in6 {
- u_int16m_t sin6_family; /* AF_INET6 */
- u_int16m_t sin6_port; /* transport layer port # */
- u_int32m_t sin6_flowinfo; /* IPv6 flow information */
- struct in6_addr sin6_addr; /* IPv6 address */
- };
-
- 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.
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 6]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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 that contains two pieces of
- information: the 24-bit IPv6 flow label and the 4-bit priority field.
- The contents and interpretation of this member is unspecified at this
- time.
-
- 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 the sin6_addr field will be aligned on a 64-bit boundary.
- This is done for optimum performance on 64-bit architectures.
-
- 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:
-
- #include <netinet/in.h>
-
- #define SIN6_LEN
-
- struct sockaddr_in6 {
- u_char sin6_len; /* length of this struct */
- u_char sin6_family; /* AF_INET6 */
- u_int16m_t sin6_port; /* transport layer port # */
- u_int32m_t sin6_flowinfo; /* IPv6 flow information */
- struct in6_addr sin6_addr; /* IPv6 address */
- };
-
-
-
-
-
-Gilligan, et. al. Informational [Page 7]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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);
-
- 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()
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 8]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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
- 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 are often generated automatically by the
- gethostbyname() function when the specified host has only IPv4
- addresses (as described in Section 6.1).
-
-
-
-Gilligan, et. al. Informational [Page 9]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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.6, 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 10]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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 11]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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.
-
-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 [5] 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.
-
-
-
-
-Gilligan, et. al. Informational [Page 12]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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_LIST 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 the specified interface does not exist, the return value is 0.
-
-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 IFNAMSIZ bytes
- into which the interface name corresponding to the specified index is
- returned. (IFNAMSIZ 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.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 13]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
-4.3. Return All Interface Names and Indexes
-
- The final function returns an array of if_nameindex structures, one
- structure per interface.
-
- #include <net/if.h>
-
- struct if_nameindex {
- unsigned int if_index; /* 1, 2, ... */
- char *if_name; /* null terminated name: "le0", ... */
- };
-
- 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.
-
- 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 argument to this function must be a pointer that was returned by
- 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>.
-
-
-
-
-
-Gilligan, et. al. Informational [Page 14]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
-5.1. Changing Socket Type
-
- Unix allows open sockets to be passed between processes via the
- exec() call and other means. It is a relatively common application
- practice to pass open sockets across exec() calls. Thus it is
- possible for an application using the original API to pass an open
- PF_INET socket to an application that is expecting to receive a
- PF_INET6 socket. Similarly, it is possible for an application using
- the extended API to pass an open PF_INET6 socket to an application
- using the original API, which would be equipped only to deal with
- PF_INET sockets. Either of these cases could cause problems, because
- the application that is passed the open socket might not know how to
- decode the address structures returned in subsequent socket
- functions.
-
- To remedy this problem, a new setsockopt() option is defined that
- allows an application to "convert" a PF_INET6 socket into a PF_INET
- socket and vice versa.
-
- An IPv6 application that is passed an open socket from an unknown
- process may use the IPV6_ADDRFORM setsockopt() option to "convert"
- the socket to PF_INET6. Once that has been done, the system will
- return sockaddr_in6 address structures in subsequent socket
- functions.
-
- An IPv6 application that is about to pass an open PF_INET6 socket to
- a program that is not be IPv6 capable can "downgrade" the socket to
- PF_INET before calling exec(). After that, the system will return
- sockaddr_in address structures to the application that was exec()'ed.
- Be aware that you cannot downgrade an IPv6 socket to an IPv4 socket
- unless all nonwildcard addresses already associated with the IPv6
- socket are IPv4-mapped IPv6 addresses.
-
- The IPV6_ADDRFORM option is valid at both the IPPROTO_IP and
- IPPROTO_IPV6 levels. The only valid option values are PF_INET6 and
- PF_INET. For example, to convert a PF_INET6 socket to PF_INET, a
- program would call:
-
- int addrform = PF_INET;
-
- if (setsockopt(s, IPPROTO_IPV6, IPV6_ADDRFORM,
- (char *) &addrform, sizeof(addrform)) == -1)
- perror("setsockopt IPV6_ADDRFORM");
-
-
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 15]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- An application may use IPV6_ADDRFORM with getsockopt() to learn
- whether an open socket is a PF_INET of PF_INET6 socket. For example:
-
- int addrform;
- size_t len = sizeof(addrform);
-
- if (getsockopt(s, IPPROTO_IPV6, IPV6_ADDRFORM,
- (char *) &addrform, &len) == -1)
- perror("getsockopt IPV6_ADDRFORM");
- else if (addrform == PF_INET)
- printf("This is an IPv4 socket.\n");
- else if (addrform == PF_INET6)
- printf("This is an IPv6 socket.\n");
- else
- printf("This system is broken.\n");
-
-5.2. 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
-
-
-
-
-
-
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 16]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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.3. 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:
-
- 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:
-
- x < -1: return an error of EINVAL
- x == -1: use kernel default
- 0 <= x <= 255: use x
- x >= 256: return an error of EINVAL
-
- Argument type: int
-
-
-
-
-
-Gilligan, et. al. Informational [Page 17]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- IPV6_MULTICAST_LOOP
-
- Controls whether outgoing multicast packets sent should be
- delivered back to the local application. A toggle. If the
- option is set to 1, multicast packets are looped back. If it
- is set to 0, they are not.
-
- Argument type: unsigned int
-
- The reception of multicast packets is controlled by the two
- setsockopt() options summarized below:
-
- IPV6_ADD_MEMBERSHIP
-
- 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_DROP_MEMBERSHIP
-
- 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:
-
- #include <netinet/in.h>
-
- 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.
-
-
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 18]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
-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 (hostname-to-
- address translation) and reverse lookup (address-to-hostname
- translation) need to be supported. Functions are also needed to
- convert IPv6 addresses between their binary and textual form.
-
-6.1. Hostname-to-Address Translation
-
- The commonly used function gethostbyname() remains unchanged as does
- the hostent structure to which it returns a pointer. Existing
- applications that call this function continue to receive only IPv4
- addresses that are the result of a query in the DNS for A records.
- (We assume the DNS is being used; some environments may be using a
- hosts file or some other name resolution system, either of which may
- impede renumbering. We also assume that the RES_USE_INET6 resolver
- option is not set, which we describe in more detail shortly.)
-
- Two new changes are made to support IPv6 addresses. First, the
- following function is new:
-
- #include <sys/socket.h>
- #include <netdb.h>
-
- struct hostent *gethostbyname2(const char *name, int af);
-
- The af argument specifies the address family. The default operation
- of this function is simple:
-
- - If the af argument is AF_INET, then a query is made for A
- records. If successful, IPv4 addresses are returned and the
- h_length member of the hostent structure will be 4, else the
- function returns a NULL pointer.
-
- - If the af argument is AF_INET6, then a query is made for AAAA
- records. If successful, IPv6 addresses are returned and the
- h_length member of the hostent structure will be 16, else the
- function returns a NULL pointer.
-
-
-
-
-
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 19]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- The second change, that provides additional functionality, is a new
- resolver option RES_USE_INET6, which is defined as a result of
- including the <resolv.h> header. (This option is provided starting
- with the BIND 4.9.4 release.) There are three ways to set this
- option.
-
- - The first way is
-
- res_init();
- _res.options |= RES_USE_INET6;
-
- and then call either gethostbyname() or gethostbyname2(). This
- option then affects only the process that is calling the
- resolver.
-
- - The second way to set this option is to set the environment
- variable RES_OPTIONS, as in RES_OPTIONS=inet6. (This example is
- for the Bourne and Korn shells.) This method affects any
- processes that see this environment variable.
-
- - The third way is to set this option in the resolver configuration
- file (normally /etc/resolv.conf) and the option then affects all
- applications on the host. This final method should not be done
- until all applications on the host are capable of dealing with
- IPv6 addresses.
-
- There is no priority among these three methods. When the
- RES_USE_INET6 option is set, two changes occur:
-
- - gethostbyname(host) first calls gethostbyname2(host, AF_INET6)
- looking for AAAA records, and if this fails it then calls
- gethostbyname2(host, AF_INET) looking for A records.
-
- - gethostbyname2(host, AF_INET) always returns IPv4-mapped IPv6
- addresses with the h_length member of the hostent structure set
- to 16.
-
- An application must not enable the RES_USE_INET6 option until it is
- prepared to deal with 16-byte addresses in the returned hostent
- structure.
-
-
-
-
-
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 20]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- The following table summarizes the operation of the existing
- gethostbyname() function, the new function gethostbyname2(), along
- with the new resolver option RES_USE_INET6.
-
-+------------------+---------------------------------------------------+
-| | RES_USE_INET6 option |
-| +-------------------------+-------------------------+
-| | off | on |
-+------------------+-------------------------+-------------------------+
-| |Search for A records. |Search for AAAA records. |
-| gethostbyname | If found, return IPv4 | If found, return IPv6 |
-| (host) | addresses (h_length=4). | addresses (h_length=16).|
-| | Else error. | Else search for A |
-| | | records. If found, |
-| |Provides backward | return IPv4-mapped IPv6 |
-| | compatibility with all | addresses (h_length=16).|
-| | existing IPv4 appls. | Else error. |
-+------------------+-------------------------+-------------------------+
-| |Search for A records. |Search for A records. |
-| gethostbyname2 | If found, return IPv4 | If found, return |
-| (host, AF_INET) | addresses (h_length=4). | IPv4-mapped IPv6 |
-| | Else error. | addresses (h_length=16).|
-| | | Else error. |
-+------------------+-------------------------+-------------------------+
-| |Search for AAAA records. |Search for AAAA records. |
-| gethostbyname2 | If found, return IPv6 | If found, return IPv6 |
-| (host, AF_INET6) | addresses (h_length=16).| addresses (h_length=16).|
-| | Else error. | Else error. |
-+------------------+-------------------------+-------------------------+
-
- It is expected that when a typical naive application that calls
- gethostbyname() today is modified to use IPv6, it simply changes the
- program to use IPv6 sockets and then enables the RES_USE_INET6
- resolver option before calling gethostbyname(). This application
- will then work with either IPv4 or IPv6 peers.
-
- Note that gethostbyname() and gethostbyname2() are not thread-safe,
- since both return a pointer to a static hostent structure. But
- several vendors have defined a thread-safe gethostbyname_r() function
- that requires four additional arguments. We expect these vendors to
- also define a gethostbyname2_r() function.
-
-
-
-
-
-
-
-
-
-
-Gilligan, et. al. Informational [Page 21]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
-6.2. Address To Hostname Translation
-
- The existing gethostbyaddr() function already requires an address
- family argument and can therefore work with IPv6 addresses:
-
- #include <sys/socket.h>
- #include <netdb.h>
-
- struct hostent *gethostbyaddr(const char *src, int len, int af);
-
- One possible source of confusion is the handling of IPv4-mapped IPv6
- addresses and IPv4-compatible IPv6 addresses. This is addressed in
- [6] and involves the following logic:
-
- 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, then query for a PTR record in the in-
- addr.arpa domain.
-
- 3. If af is AF_INET6, then query for a PTR record in the ip6.int
- domain.
-
- 4. If the function is returning success, and if af equals AF_INET,
- and if the RES_USE_INET6 option was set, then the single address
- that is returned in the hostent structure (a copy of the first
- argument to the function) is returned as an IPv4-mapped IPv6
- address and the h_length member is set to 16.
-
- All four steps listed are performed, in order. The same caveats
- regarding a thread-safe version of gethostbyname() that were made at
- the end of the previous section apply here as well.
-
-6.3. Protocol-Independent Hostname and Service Name Translation
-
- Hostname-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) work in progress specification [4].
-
- The official specification for this function will be the final POSIX
- standard. We are providing this independent description of the
- function because POSIX standards are not freely available (as are
- IETF documents). Should there be any discrepancies between this
- description and the POSIX description, the POSIX description takes
- precedence.
-
-
-
-Gilligan, et. al. Informational [Page 22]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- #include <sys/socket.h>
- #include <netdb.h>
-
- int getaddrinfo(const char *hostname, const char *servname,
- const struct addrinfo *hints,
- struct addrinfo **res);
-
- The addrinfo structure is defined as:
-
- #include <sys/socket.h>
- #include <netdb.h>
-
- struct addrinfo {
- int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
- 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 hostname */
- 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 hostname 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 hostname
- EAI_NONAME hostname 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 hostname 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 hostname and
- servname are specified. In the normal server scenario, only the
- servname is specified. A non-NULL hostname string can be either a
- host 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.
-
-
-
-
-Gilligan, et. al. Informational [Page 23]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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
- 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 hostname
- 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 hostname 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
- hostname.
-
-
-
-
-Gilligan, et. al. Informational [Page 24]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- All of the information returned by getaddrinfo() is dynamically
- allocated: the addrinfo structures, and the socket address structures
- and canonical host 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
- eturn 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.4. Socket Address Structure to Hostname and Service Name
-
- The POSIX 1003.1g specification includes no function to perform the
- reverse conversion from getaddrinfo(): to look up a hostname 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, size_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 25]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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 hostname 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 hostname 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 hostname 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
- gethostbyaddr()). 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 26]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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 (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.5. 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 27]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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 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.6. 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 28]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- 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.
-
-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> IFNAMSIZ
- <net/if.h> struct if_nameindex{};
-
- <netdb.h> AI_CANONNAME
- <netdb.h> AI_PASSIVE
- <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
- <netinet/in.h> INET_ADDRSTRLEN
- <netinet/in.h> IPPROTO_IPV6
- <netinet/in.h> IPV6_ADDRFORM
- <netinet/in.h> IPV6_ADD_MEMBERSHIP
- <netinet/in.h> IPV6_DROP_MEMBERSHIP
- <netinet/in.h> IPV6_MULTICAST_HOPS
- <netinet/in.h> IPV6_MULTICAST_IF
- <netinet/in.h> IPV6_MULTICAST_LOOP
- <netinet/in.h> IPV6_UNICAST_HOPS
-
-
-
-Gilligan, et. al. Informational [Page 29]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- <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{};
-
- <resolv.h> RES_USE_INET6
-
- <sys/socket.h> AF_INET6
- <sys/socket.h> PF_INET6
-
-
- 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 *, size_t,
- char *, size_t, char *, size_t, int);
-<netdb.h> void freeaddrinfo(struct addrinfo *);
-<netdb.h> char *gai_strerror(int);
-<netdb.h> struct hostent *gethostbyname(const char *);
-<netdb.h> struct hostent *gethostbyaddr(const char *, int, int);
-<netdb.h> struct hostent *gethostbyname2(const char *, 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 *);
-
-
-
-Gilligan, et. al. Informational [Page 30]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
-8. Security Considerations
-
- IPv6 provides a number of new security mechanisms, many of which need
- to be accessible to applications. A companion memo detailing the
- extensions to the socket interfaces to support IPv6 security is being
- written [3].
-
-9. Acknowledgments
-
- Thanks to the many people who made suggestions and provided feedback
- to to the numerous revisions of 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, Tim Hartrick, Tom Herbert, Bob Hinden, Wan-
- Yen Hsu, Christian Huitema, Koji Imada, Markus Jork, Ron Lee, Alan
- Lloyd, Charles Lynn, Jack McCann, Dan McDonald, Dave Mitton, Thomas
- Narten, Erik Nordmark, 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 Kazuhiko Yamamoto,
-
- The getaddrinfo() and getnameinfo() functions are taken from an
- earlier Work in Progress 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 made many contributions to this document. Ramesh Govindan
- made a number of contributions and co-authored an earlier version of
- this memo.
-
-10. References
-
- [1] Deering, S., and R. Hinden, "Internet Protocol, Version 6 (IPv6)
- Specification", RFC 1883, December 1995.
-
- [2] Hinden, R., and S. Deering, "IP Version 6 Addressing Architecture",
- RFC 1884, December 1995.
-
- [3] McDonald, D., "A Simple IP Security API Extension to BSD Sockets",
- Work in Progress.
-
-
-
-
-
-Gilligan, et. al. Informational [Page 31]
-
-RFC 2133 IPv6 Socket Interface Extensions April 1997
-
-
- [4] IEEE, "Protocol Independent Interfaces", IEEE Std 1003.1g, DRAFT
- 6.3, November 1995.
-
- [5] Stevens, W., and M. Thomas, "Advanced Sockets API for IPv6",
- Work in Progress.
-
- [6] Vixie, P., "Reverse Name Lookups of Encapsulated IPv4 Addresses in
- IPv6", Work in Progress.
-
-11. Authors' Addresses
-
- Robert E. Gilligan
- Freegate Corporation
- 710 Lakeway Dr. STE 230
- Sunnyvale, CA 94086
-
- Phone: +1 408 524 4804
- EMail: gilligan@freegate.net
-
-
- 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
- Digital Equipment Corporation
- 110 Spitbrook Road ZK3-3/U14
- Nashua, NH 03062-2698
-
- Phone: +1 603 881 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 32]
-
OpenPOWER on IntegriCloud