As per Relevance of the word structure, we have this rfc below:











Network Working Group R.
Request for Comments: 2553
Obsoletes: 2133 S.
Category: Informational
J.

W.

March 1999


Basic Socket Interface Extensions for IPv

Status of this

This memo provides information for the Internet community. It
not specify an Internet standard of any kind. Distribution of
memo is unlimited

Copyright

Copyright (C) The Internet Society (1999). All Rights Reserved



The de facto standard application program interface (API) for TCP/
applications is the "sockets" interface. Although this API
developed for Unix in the early 1980s it has also been implemented
a wide variety of non-Unix systems. TCP/IP applications
using the sockets API have in the past enjoyed a high degree
portability and we would like the same portability with IPv
applications. But changes are required to the sockets API to
IPv6 and this memo describes these changes. These include a
socket address structure to carry IPv6 addresses, new
conversion functions, and some new socket options. These
are designed to provide access to the basic IPv6 features required
TCP and UDP applications, including multicasting, while introducing
minimum of change into the system and providing
compatibility for existing IPv4 applications. Additional
for advanced IPv6 features (raw sockets and access to the IPv
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

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.

While IPv4 addresses are 32 bits long, IPv6 interfaces are
by 128-bit addresses. The socket interface makes the size of an
address quite visible to an application; virtually all TCP/
applications for BSD-based systems have knowledge of the size of
IP address. Those parts of the API that expose the addresses must
changed to accommodate the larger IPv6 address size. IPv6
introduces new features (e.g., traffic class and flowlabel), some
which must be made visible to applications via the API. This
defines a set of extensions to the socket interface to support
larger address size and new features of IPv6.

2. Design

There are a number of important considerations in designing
to this well-worn API

- The API changes should provide both source and
compatibility for programs written to the original API.
is, existing program binaries should continue to operate
run on a system supporting the new API. In addition,
applications that are re-compiled and run on a system
the new API should continue to operate. Simply put, the
changes for IPv6 should not break existing programs.
additonal mechanism for implementations to verify this is
verify the new symbols are protected by Feature Test Macros
described in IEEE Std 1003.1. (Such Feature Test Macros are
defined by this RFC.)

- The changes to the API should be as small as possible in
to simplify the task of converting existing IPv4 applications
IPv6.

- Where possible, applications should be able to use this API
interoperate with both IPv6 and IPv4 hosts. Applications
not need to know which type of host they are communicating with

- IPv6 addresses carried in data structures should be 64-
aligned. This is necessary in order to obtain
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
provide complete support for both IPv4 and IPv6. A subset of
API could probably be designed for operation on systems that
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

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
things as setting up and tearing down TCP connections, and
and receiving UDP packets -- were designed to be
independent. Where protocol addresses are passed as
arguments, they are carried via opaque pointers. A protocol-
address data structure is defined for each protocol that the
functions support. Applications must cast pointers to
protocol-specific address structures into pointers to the
"sockaddr" address structure when using the socket functions.
functions need not change for IPv6, but a new IPv6-specific
data structure is needed

The "sockaddr_in" structure is the protocol-specific data
for IPv4. This data structure actually includes 8-octets of
space, and it is tempting to try to use this space to adapt
sockaddr_in structure to IPv6. Unfortunately, the sockaddr_
structure is not large enough to hold the 16-octet IPv6 address
well as the other information (address family and port number)
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.
support applications that want to be able to identify a set
interfaces for a specific scope, the IPv6 sockaddr_in structure
support a field that can be used by an implementation to identify
set of interfaces identifying the scope for an IPv6 address

The name-to-address translation functions in the socket interface
gethostbyname() and gethostbyaddr(). These are left as is and
functions are defined to support IPv4 and IPv6. Additionally,
POSIX 1003.g draft [3] specifies a new nodename-to-
translation function which is protocol independent. This
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.
functions are quite specific to 32-bit IPv4 addresses. We
designed two analogous functions that convert both IPv4 and IPv
addresses, and carry an address type parameter so that they can
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,
label, and hop limit header fields. New socket options are needed
control the sending and receiving of IPv6 multicast packets

The socket interface will be enhanced in the future to provide
to other IPv6 features. These extensions are described in [4].

2.2 Data

The data types of the structure elements given in this memo
intended to be examples, not absolute requirements.
possible, data types from Draft 6.6 (March 1997) of POSIX 1003.1g
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
possible (e.g., the final argument to setsockopt() is a size_
value). Whenever buffer sizes are specified, the POSIX 1003.1 size_
data type is used (e.g., the two length arguments to getnameinfo()).

2.3

When function prototypes and structures are shown we show the
that must be #included to cause that item to be defined

2.4

When structures are described the members shown are the ones
must appear in an implementation. Additional, nonstandard
may also be defined by an implementation. As an
precaution nonstandard members could be verified by Feature
Macros as described in IEEE Std 1003.1. (Such Feature Test
are not defined by this RFC.)

The ordering shown for the members of a structure is the
ordering, given alignment considerations of multibyte members, but
implementation may order the members differently








Gilligan, et. al. Informational [Page 5]

RFC 2553 Basic Socket Interface Extensions for IPv6 March 1999


3. Socket

This section specifies the socket interface changes for IPv6.

3.1 IPv6 Address Family and Protocol

A new address family name, AF_INET6, is defined in .
The AF_INET6 definition distinguishes between the
sockaddr_in address data structure, and the new sockaddr_in6
structure

A new protocol family name, PF_INET6, is defined in .
Like most of the other protocol family names, this will usually
defined to have the same value as the corresponding address
name

#define PF_INET6 AF_INET

The PF_INET6 is used in the first argument to the socket()
to indicate that an IPv6 socket is being created

3.2 IPv6 Address

A new in6_addr structure holds a single IPv6 address and is
as a result of including :

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
in network byte order

The structure in6_addr above is usually implemented with an
union with extra fields that force the desired alignment level in
manner similar to BSD implementations of "struct in_addr".
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_u

3.3 Socket Address Structure for 4.3BSD-Based

In the socket interface, a different protocol-specific data
is defined to carry the addresses for each protocol suite.
protocol- specific data structure is designed so it can be cast into
protocol- independent data structure -- the "sockaddr" structure
Each has a "family" field that overlays the "sa_family" of
sockaddr data structure. This field identifies the type of the
structure

The sockaddr_in structure is the protocol-specific address
structure for IPv4. It is used to pass addresses between
and the system in the socket functions. The following sockaddr_in
structure holds IPv6 addresses and is defined as a result of
the 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
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
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.
field is used in the same way as the sin_port field of
sockaddr_in structure. The port number is stored in network
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
information: the traffic class and the flow label. The contents
interpretation of this member is specified in [1]. The sin6_
field SHOULD be set to zero by an implementation prior to using
sockaddr_in6 structure by an application on receive operations

The sin6_addr field is a single in6_addr structure (defined in
previous section). This field holds one 128-bit IPv6 address.
address is stored in network byte order

The ordering of elements in this structure is specifically
so that when sin6_addr field is aligned on a 64-bit boundary,
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
interfaces as appropriate for the scope of the address carried in
sin6_addr field. For a link scope sin6_addr sin6_scope_id would
an interface index. For a site scope sin6_addr, sin6_scope_id
be a site identifier. The mapping of sin6_scope_id to an
or set of interfaces is left to implementation and
specifications on the subject of site identifiers

Notice that the sockaddr_in6 structure will normally be larger
the generic sockaddr structure. On many existing implementations
sizeof(struct sockaddr_in) equals sizeof(struct sockaddr), with
being 16 bytes. Any existing code that makes this assumption
to be examined carefully when converting to IPv6.

3.4 Socket Address Structure for 4.4BSD-Based

The 4.4BSD release includes a small, but incompatible change to
socket interface. The "sa_family" field of the sockaddr
structure was changed from a 16-bit value to an 8-bit value, and
space saved used to hold a length field, named "sa_len".
sockaddr_in6 data structure given in the previous section cannot
correctly cast into the newer sockaddr data structure. For
reason, the following alternative IPv6 address data structure
provided to be used on systems based on 4.4BSD. It is defined as
result of including the 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.3
variant are the inclusion of the length field, and the change of
family field to a 8-bit data type. The definitions of all the
fields are identical to the structure defined in the
section

Systems that provide this version of the sockaddr_in6 data
must also declare SIN6_LEN as a result of including
header. This macro allows applications to
whether they are being built on a system that supports the 4.3BSD
4.4BSD variants of the data structure

3.5 The Socket

Applications call the socket() function to create a socket
that represents a communication endpoint. The arguments to
socket() function tell the system which protocol to use, and
format address structure will be used in subsequent functions.
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
the constant PF_INET6 instead of PF_INET in the first argument.
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
sockaddr_in6 address structure when passing addresses in to
system. The functions that the application uses to pass
into the system are

bind()
connect()
sendmsg()
sendto()

The system will use the sockaddr_in6 address structure to
addresses to applications that are using PF_INET6 sockets.
functions that return an address from the system to an
are

accept()
recvfrom()
recvmsg()
getpeername()
getsockname()

No changes to the syntax of the socket functions are needed
support IPv6, since all of the "address carrying" functions use
opaque address pointer, and carry an address length as a
argument

3.6 Compatibility with IPv4

In order to support the large base of applications using the
API, system implementations must provide complete source and
compatibility with the original API. This means that systems
continue to support PF_INET sockets and the sockaddr_in
structure. Applications must be able to create IPv4/TCP and IPv4/
sockets using the PF_INET constant in the socket() function,
described in the previous section. Applications should be able
hold a combination of IPv4/TCP, IPv4/UDP, IPv6/TCP and IPv6/
sockets simultaneously within the same process

Applications using the original API should continue to operate
they did on systems supporting only IPv4. That is, they
continue to interoperate with IPv4 nodes

3.7 Compatibility with IPv4

The API also provides a different type of compatibility: the
for IPv6 applications to interoperate with IPv4 applications.
feature uses the IPv4-mapped IPv6 address format defined in the IPv
addressing architecture specification [2]. This address



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 IPv
address. The IPv4 address is encoded into the low-order 32 bits
the IPv6 address, and the high-order 96 bits hold the fixed
0:0:0:0:0:FFFF. IPv4- mapped addresses are written as follows

::FFFF:
These addresses can be generated automatically by
getipnodebyname() function when the specified host has only IPv
addresses (as described in Section 6.1).

Applications may use PF_INET6 sockets to open TCP connections to IPv
nodes, or send UDP packets to IPv4 nodes, by simply encoding
destination's IPv4 address as an IPv4-mapped IPv6 address,
passing that address, within a sockaddr_in6 structure, in
connect() or sendto() call. When applications use PF_INET6
to accept TCP connections from IPv4 nodes, or receive UDP
from IPv4 nodes, the system returns the peer's address to
application in the accept(), recvfrom(), or getpeername() call
a sockaddr_in6 structure encoded this way

Few applications will likely need to know which type of node they
interoperating with. However, for those applications that do need
know, the IN6_IS_ADDR_V4MAPPED() macro, defined in Section 6.7,
provided

3.8 IPv6 Wildcard

While the bind() function allows applications to select the source
address of UDP packets and TCP connections, applications often
the system to select the source address for them. With IPv4,
specifies the address as the symbolic constant INADDR_ANY (called
"wildcard" address) in the bind() call, or simply omits the bind()
entirely

Since the IPv6 address type is a structure (struct in6_addr),
symbolic constant can be used to initialize an IPv6 address variable
but cannot be used in an assignment. Therefore systems provide
IPv6 wildcard address in two forms

The first version is a global variable named "in6addr_any" that is
in6_addr structure. The extern declaration for this variable
defined in :

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_
in IPv4. For example, to bind a socket to port number 23, but
the system select the source address, an application could use
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
is defined in . This constant can be used
initialize an in6_addr structure

struct in6_addr anyaddr = IN6ADDR_ANY_INIT

Note that this constant can be used ONLY at declaration time. It
not be used to assign a previously declared in6_addr structure.
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
byte order but the IPv6 IN6ADDR_xxx constants and the IPv
in6addr_xxx externals are defined in network byte order

3.9 IPv6 Loopback

Applications may need to send UDP packets to, or originate
connections to, services residing on the local node. In IPv4,
can do this by using the constant IPv4 address INADDR_LOOPBACK
their connect(), sendto(), or sendmsg() call

IPv6 also provides a loopback address to contact local TCP and
services. Like the unspecified address, the IPv6 loopback address
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
"in6addr_loopback." The extern declaration for this variable
defined in :

extern const struct in6_addr in6addr_loopback

Applications use in6addr_loopback as they would use INADDR_
in IPv4 applications (but beware of the byte ordering
mentioned at the end of the previous section). For example, to
a TCP connection to the local telnet server, an application could
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
in . It can be used at declaration time ONLY;
example

struct in6_addr loopbackaddr = IN6ADDR_LOOPBACK_INIT

Like IN6ADDR_ANY_INIT, this constant cannot be used in an
to a previously declared IPv6 address variable

3.10 Portability

One simple addition to the sockets API that can help
writers is the "struct sockaddr_storage". This data structure
simplify writing code portable across multiple address families
platforms. This data structure is designed with the following goals

- It has a large enough implementation specific maximum size
store the desired set of protocol specific socket address
structures. Specifically, it is at least large enough
accommodate sockaddr_in and sockaddr_in6 and possibly
protocol specific socket addresses too
- It is aligned at an appropriate boundary so protocol
socket address data structure pointers can be cast to it
access their fields without alignment problems. (e.g.
to sockaddr_in6 and/or sockaddr_in can be cast to it and
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
"struct sockaddr" data structure on that implementation
can be used as a discriminants for deriving the protocol in use
These initial field(s) would on most implementations either be
single field of type "sa_family_t" (isomorphic to sa_
field, 16 bits) or two fields of type uint8_t and sa_family_
respectively, (isomorphic to sa_len and sa_family_t, 8
each).

An example implementation design of such a data structure would be
follows

/*
* Desired design of maximum size and
*/
#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
/* 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
/* 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
will align on a 64 bit boundary. An implementation specific
"__ss_align" along "__ss_pad1" is used to force a 64-bit
which covers proper alignment good enough for needs of sockaddr_in
(IPv6), sockaddr_in (IPv4) address data structures. The size
padding fields __ss_pad1 depends on the chosen alignment boundary
The size of padding field __ss_pad2 depends on the value of
size chosen for the total size of the structure. This size
alignment are represented in the above example by
specific (not required) constants _SS_MAXSIZE (chosen value 128)
_SS_ALIGNMENT (with chosen value 8). Constants _SS_PAD1SIZE (
value 6) and _SS_PAD2SIZE (derived value 112) are also
illustration and not required. The implementation
definitions and structure field names above start with an
to denote implementation private namespace. Portable code is
expected to access or reference those fields or constants

The sockaddr_storage structure solves the problem of
storage for automatic variables which is large enough and
enough for storing socket address data structure of any family.
example, code with a file descriptor and without the context of
address family can pass a pointer to a variable of this type where
pointer to a socket address structure is expected in calls such
getpeername() and determine the address family by accessing
received content after the call

The sockaddr_storage structure may also be useful and applied
certain other interfaces where a generic socket address large
and aligned for use with multiple address families may be needed.
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
can fit in a generic sockaddr structure. While this has been
for IPv4 socket address structures, it has always been false for
domain socket address structures (but in practice this has not been
problem) and it is also false for IPv6 socket address
(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

This API uses an interface index (a small positive integer)
identify the local interface on which a multicast group is
(Section 5.3). Additionally, the advanced API [4] uses these
interface indexes to identify the interface on which a datagram
received, or to specify the interface on which a datagram is to
sent

Interfaces are normally known by names such as "le0", "sl1", "ppp2",
and the like. On Berkeley-derived implementations, when an
is made known to the system, the kernel assigns a unique
integer value (called the interface index) to that interface.
are small positive integers that start at 1. (Note that 0 is
used for an interface index.) There may be gaps so that there is
current interface for a particular positive interface index

This API defines two functions that map between an interface name
index, a third function that returns all the interface names
indexes, and a fourth function to return the dynamic memory
by the previous function. How these functions are implemented
left up to the implementation. 4.4BSD implementations can
these functions using the existing sysctl() function with
NET_RT_IFLIST command. Other implementations may wish to use ioctl()
for this purpose

4.1 Name-to-

The first function maps an interface name into its
index

#include
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
0, and errno is set to ENXIO. If there was a system error (such
running out of memory), the return value is 0 and errno is set to
proper value (e.g., ENOMEM).

4.2 Index-to-

The second function maps an interface index into its
name

#include
char *if_indextoname(unsigned int ifindex, char *ifname);

The ifname argument must point to a buffer of at least IF_
bytes into which the interface name corresponding to the
index is returned. (IF_NAMESIZE is also defined in
its value includes a terminating null byte at the end of
interface name.) This pointer is also the return value of
function. If there is no interface corresponding to the
index, NULL is returned, and errno is set to ENXIO, if there was
system error (such as running out of memory), if_indextoname
NULL and errno would be set to the proper value (e.g., ENOMEM).

4.3 Return All Interface Names and

The if_nameindex structure holds the information about a
interface and is defined as a result of including the 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,
structure per interface

struct if_nameindex *if_nameindex(void);

The end of the array of structures is indicated by a structure
an if_index of 0 and an if_name of NULL. The function returns a
pointer upon an error, and would set errno to the appropriate value

The memory used for this array of structures along with the
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

The following function frees the dynamic memory that was allocated
if_nameindex().

#include
void if_freenameindex(struct if_nameindex *ptr);

The argument to this function must be a pointer that was returned
if_nameindex().

Currently net/if.h doesn't have prototype definitions for
and it is recommended that these definitions be defined in net/if.
as well and the struct if_nameindex{}.

5. Socket

A number of new socket options are defined for IPv6. All of
new options are at the IPPROTO_IPV6 level. That is, the "level
parameter in the getsockopt() and setsockopt() calls is IPPROTO_IPV
when using these options. The constant name prefix IPV6_ is used
all of the new socket options. This serves to clearly identify
options as applying to IPv6.

The declaration for IPPROTO_IPV6, the new IPv6 socket options,
related constants defined in this section are obtained by
the header .

5.1 Unicast Hop

A new setsockopt() option controls the hop limit used in
unicast IPv6 packets. The name of this option is IPV6_UNICAST_HOPS
and it is used at the IPPROTO_IPV6 layer. The following
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(),
option value given is used as the hop limit for all
unicast packets sent via that socket. If the option is not set,
system selects a default value. The integer hop limit value (
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
x == -1: use kernel
0 <= x <= 255: use
x >= 256: return an error of

The IPV6_UNICAST_HOPS option may be used with getsockopt()
determine the hop limit value that the system will use for
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");

printf("Using %d for hop limit.\n", hoplimit);

5.2 Sending and Receiving Multicast

IPv6 applications may send UDP multicast packets by simply
an IPv6 multicast address in the address argument of the sendto()
function

Three socket options at the IPPROTO_IPV6 layer control some of
parameters for sending multicast packets. Setting these options
not required: applications may send multicast packets without
these options. The setsockopt() options for controlling the
of multicast packets are summarized below. These three options
also be used with getsockopt().

IPV6_MULTICAST_

Set the interface to use for outgoing multicast packets.
argument is the index of the interface to use

Argument type: unsigned

IPV6_MULTICAST_

Set the hop limit to use for outgoing multicast packets. (
a separate option - IPV6_UNICAST_HOPS - is provided to set
hop limit to use for outgoing unicast packets.)

The interpretation of the argument is the same as for
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
x == -1: use kernel
0 <= x <= 255: use
x >= 256: return an error of

If IPV6_MULTICAST_HOPS is not set, the default is 1
(same as IPv4 today

Argument type:

IPV6_MULTICAST_

If a multicast datagram is sent to a group to which the
host itself belongs (on the outgoing interface), a copy of
datagram is looped back by the IP layer for local delivery
this option is set to 1. If this option is set to 0 a
is not looped back. Other option values return an error
EINVAL

If IPV6_MULTICAST_LOOP is not set, the default is 1 (loopback
same as IPv4 today).

Argument type: unsigned

The reception of multicast packets is controlled by the
setsockopt() options summarized below. An error of EOPNOTSUPP
returned if these two options are used with getsockopt().

IPV6_JOIN_

Join a multicast group on a specified local interface. If
interface index is specified as 0, the kernel chooses the
interface. For example, some kernels look up the
group in the normal IPv6 routing table and using the
interface

Argument type: struct ipv6_

IPV6_LEAVE_

Leave a multicast group on a specified interface

Argument type: struct ipv6_

The argument type of both of these options is the ipv6_mreq structure
defined as a result of including the 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
multicast group and bind the UDP port to which datagrams will
sent. Some processes also bind the multicast group address to
socket, in addition to the port, to prevent other datagrams
to that same port from being delivered to the socket

6. Library

New library functions are needed to perform a variety of
with IPv6 addresses. Functions are needed to lookup IPv6
in the Domain Name System (DNS). Both forward lookup (nodename-to
address translation) and reverse lookup (address-to-
translation) need to be supported. Functions are also needed
convert IPv6 addresses between their binary and textual form

We note that the two existing functions, gethostbyname()
gethostbyaddr(), are left as-is. New functions are defined to
both IPv4 and IPv6 addresses

6.1 Nodename-to-Address

The commonly used function gethostbyname() is inadequate for
applications, first because it provides no way for the caller
specify anything about the types of addresses desired (IPv4 only
IPv6 only, IPv4-mapped IPv6 are OK, etc.), and second because
implementations of this function are not thread safe. RFC 2133
defined a function named gethostbyname2() but this function was
inadequate, first because its use required setting a global
(RES_USE_INET6) when IPv6 addresses were required, and second
a flag argument is needed to provide the caller with
control over the types of addresses required

The following function is new and must be thread safe

#include #include
struct hostent *getipnodebyname(const char *name, int af, int
int *error_num);

The name argument can be either a node name or a numeric
string (i.e., a dotted-decimal IPv4 address or an IPv6 hex address).
The af argument specifies the address family, either AF_INET



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
pointer, with the appropriate error code in error_num, to
thread safe error code returns. error_num will be set to one of
following values

HOST_NOT_

No such host is known

NO_

The server recognised the request and the name but no address
available. Another type of request to the name server for
domain might return an answer

NO_

An unexpected server failure occurred which cannot be recovered

TRY_

A temporary and possibly transient error occurred, such as
failure of a server to respond

The flags argument specifies the types of addresses that are
for, and the types of addresses that are returned. We note that
special flags value of AI_DEFAULT (defined below) should handle
applications

That is, porting simple applications to use IPv6 replaces the

hptr = gethostbyname(name);



hptr = getipnodebyname(name, AF_INET6, AI_DEFAULT, &error_num);

and changes any subsequent error diagnosis code to use error_
instead of externally declared variables, such as h_errno

Applications desiring finer control over the types of
searched for and returned, can specify other combinations of
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
IPv4 addresses. A query is made for A records. If successful
the IPv4 addresses are returned and the h_length member of
hostent structure will be 4, else the function returns a
pointer

- If flags is 0 and if af is AF_INET6, then the caller wants
IPv6 addresses. A query is made for AAAA records.
successful, the IPv6 addresses are returned and the h_
member of the hostent structure will be 16, else the
returns a NULL pointer

Other constants can be logically-ORed into the flags argument,
modify the behavior of the function

- If the AI_V4MAPPED flag is specified along with an af
AF_INET6, then the caller will accept IPv4-mapped IPv
addresses. That is, if no AAAA records are found then a
is made for A records and any found are returned as IPv4-
IPv6 addresses (h_length will be 16). The AI_V4MAPPED flag
ignored unless af equals AF_INET6.

- The AI_ALL flag is used in conjunction with the AI_V4
flag, and is only used with the IPv6 address family. When AI_
is logically or'd with AI_V4MAPPED flag then the caller
all addresses: IPv6 and IPv4-mapped IPv6. A query is first
for AAAA records and if successful, the IPv6 addresses
returned. Another query is then made for A records and any
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
should occur only if the node has at least one IPv6
address configured and a query for A records should occur
if the node has at least one IPv4 source address configured

For example, if the node has no IPv6 source
configured, and af equals AF_INET6, and the node name
looked up has both AAAA and A records, then

(a) if only AI_ADDRCONFIG is specified, the
returns a NULL pointer
(b) if AI_ADDRCONFIG | AI_V4MAPPED is specified, the
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

#define AI_DEFAULT (AI_V4MAPPED | AI_ADDRCONFIG

We noted that the getipnodebyname() function must allow the
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
applications from having to call inet_pton() to handle
address strings

There are four scenarios based on the type of literal address
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,
when name is an IPv6 hex address and af equals AF_INET6. The
of the returned hostent structure are: h_name points to a copy of
name argument, h_aliases is a NULL pointer, h_addrtype is a copy
the af argument, h_length is either 4 (for AF_INET) or 16 (
AF_INET6), h_addr_list[0] is a pointer to the 4-byte or 16-
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
returned: h_name points to an IPv6 hex address containing the IPv4-
mapped IPv6 address, h_aliases is a NULL pointer, h_addrtype
AF_INET6, h_length is 16, h_addr_list[0] is a pointer to the 16-
binary address, and h_addr_list[1] is a NULL pointer. If AI_V4
is set (with or without AI_ALL) return IPv4-mapped otherwise
NULL

It is an error when name is an IPv6 hex address and af
AF_INET. The function's return value is a NULL pointer and error_
equals HOST_NOT_FOUND

6.2 Address-To-Nodename

The following function has the same arguments as the
gethostbyaddr() function, but adds an error number

#include #include
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
error code, to support thread safe error code returns. The
error conditions may be returned for error_num

HOST_NOT_

No such host is known

NO_

The server recognized the request and the name but no
is available. Another type of request to the name server
the domain might return an answer

NO_

An unexpected server failure occurred which cannot
recovered

TRY_

A temporary and possibly transient error occurred, such as
failure of a server to respond

One possible source of confusion is the handling of IPv4-mapped IPv
addresses and IPv4-compatible IPv6 addresses, but the following
should apply

1. If af is AF_INET6, and if len equals 16, and if the IPv
address is an IPv4-mapped IPv6 address or an IPv4-
IPv6 address, then skip over the first 12 bytes of the IPv
address, set af to AF_INET, and set len to 4.

2. If af is AF_INET, lookup the name for the given IPv4
(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
(e.g., query for a PTR record in the ip6.int domain).

4. If the function is returning success, then the single
that is returned in the hostent structure is a copy of
first argument to the function with the same address
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
IPv6 hex addresses "::" and "::1" MUST NOT be treated as IPv4-
compatible addresses, and if the address is "::", HOST_NOT_FOUND
be returned and a query of the address not performed

Also for the macro in section 6.7 IN6_IS_ADDR_V4COMPAT MUST
false for "::" and "::1".

6.3 Freeing memory for getipnodebyname and

The hostent structure does not change from its existing definition
This structure, and the information pointed to by this structure,
dynamically allocated by getipnodebyname and getipnodebyaddr.
following function frees this memory

#include
void freehostent(struct hostent *ptr);

6.4 Protocol-Independent Nodename and Service Name

Nodename-to-address translation is done in a protocol-
fashion using the getaddrinfo() function that is taken from
Institute of Electrical and Electronic Engineers (IEEE) POSIX 1003.1
(Protocol Independent Interfaces) draft specification [3].

The official specification for this function will be the final
standard, with the following additional requirements

- getaddrinfo() (along with the getnameinfo() function
in the next section) must be thread safe

- The AI_NUMERICHOST is new with this document

- All fields in socket address structures returned
getaddrinfo() that are not filled in through an
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
structure (e.g., sin6_len) on systems that support this field

We are providing this independent description of the function
POSIX standards are not freely available (as are IETF documents).

#include #include



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
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
error code. The following names are the nonzero error codes
getaddrinfo(), and are defined in :

EAI_ADDRFAMILY address family for nodename not
EAI_AGAIN temporary failure in name
EAI_BADFLAGS invalid value for ai_
EAI_FAIL non-recoverable failure in name
EAI_FAMILY ai_family not
EAI_MEMORY memory allocation
EAI_NODATA no address associated with
EAI_NONAME nodename nor servname provided, or not
EAI_SERVICE servname not supported for ai_
EAI_SOCKTYPE ai_socktype not
EAI_SYSTEM system error returned in

The nodename and servname arguments are pointers to null-
strings or NULL. One or both of these two arguments must be a non
NULL pointer. In the normal client scenario, both the nodename
servname are specified. In the normal server scenario, only
servname is specified. A non-NULL nodename string can be either
node name or a numeric host address string (i.e., a dotted-
IPv4 address or an IPv6 hex address). A non-NULL servname string
be either a service name or a decimal port number

The caller can optionally pass an addrinfo structure, pointed to
the third argument, to provide hints concerning the type of
that the caller supports. In this hints structure all members
than ai_flags, ai_family, ai_socktype, and ai_protocol must be
or a NULL pointer. A value of PF_UNSPEC for ai_family means



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_
means the caller will accept any socket type. A value of 0
ai_protocol means the caller will accept any protocol. For example
if the caller handles only TCP and not UDP, then the ai_
member of the hints structure should be set to SOCK_STREAM
getaddrinfo() is called. If the caller handles only IPv4 and
IPv6, then the ai_family member of the hints structure should be
to PF_INET when getaddrinfo() is called. If the third argument
getaddrinfo() is a NULL pointer, this is the same as if the
had filled in an addrinfo structure initialized to zero
ai_family set to PF_UNSPEC

Upon successful return a pointer to a linked list of one or
addrinfo structures is returned through the final argument.
caller can process each addrinfo structure in this list by
the ai_next pointer, until a NULL pointer is encountered. In
returned addrinfo structure the three members ai_family, ai_socktype
and ai_protocol are the corresponding arguments for a call to
socket() function. In each addrinfo structure the ai_addr
points to a filled-in socket address structure whose length
specified by the ai_addrlen member

If the AI_PASSIVE bit is set in the ai_flags member of the
structure, then the caller plans to use the returned socket
structure in a call to bind(). In this case, if the
argument is a NULL pointer, then the IP address portion of the
address structure will be set to INADDR_ANY for an IPv4 address
IN6ADDR_ANY_INIT for an IPv6 address

If the AI_PASSIVE bit is not set in the ai_flags member of the
structure, then the returned socket address structure will be
for a call to connect() (for a connection-oriented protocol)
either connect(), sendto(), or sendmsg() (for a
protocol). In this case, if the nodename argument is a NULL pointer
then the IP address portion of the socket address structure will
set to the loopback address

If the AI_CANONNAME bit is set in the ai_flags member of the
structure, then upon successful return the ai_canonname member of
first addrinfo structure in the linked list will point to a null
terminated string containing the canonical name of the
nodename

If the AI_NUMERICHOST bit is set in the ai_flags member of the
structure, then a non-NULL nodename string must be a numeric
address string. Otherwise an error of EAI_NONAME is returned.
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
allocated: the addrinfo structures, and the socket address
and canonical node name strings pointed to by the
structures. To return this information to the system the
freeaddrinfo() is called

#include #include
void freeaddrinfo(struct addrinfo *ai);

The addrinfo structure pointed to by the ai argument is freed,
with any dynamic storage pointed to by the structure. This
is repeated until a NULL ai_next pointer is encountered

To aid applications in printing error messages based on the EAI_
codes returned by getaddrinfo(), the following function is defined

#include #include
char *gai_strerror(int ecode);

The argument is one of the EAI_xxx values defined earlier and
return value points to a string describing the error. If
argument is not one of the EAI_xxx values, the function still
a pointer to a string whose contents indicate an unknown error

6.5 Socket Address Structure to Nodename and Service

The POSIX 1003.1g specification includes no function to perform
reverse conversion from getaddrinfo(): to look up a nodename
service name, given the binary address and port. Therefore,
define the following function

#include #include
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
caller in the DNS and system-specific database, and returns
strings for both in buffers provided by the caller. The
indicates successful completion by a zero return value; a non-
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 (
IPv4) or a sockaddr_in6 structure (for IPv6) that holds the
address and port number. The salen argument gives the length of
sockaddr_in or sockaddr_in6 structure

The function returns the nodename associated with the IP address
the buffer pointed to by the host argument. The caller provides
size of this buffer via the hostlen argument. The service
associated with the port number is returned in the buffer pointed
by serv, and the servlen argument gives the length of this buffer
The caller specifies not to return either string by providing a
value for the hostlen or servlen arguments. Otherwise, the
must provide buffers large enough to hold the nodename and
service name, including the terminating null characters

Unfortunately most systems do not provide constants that specify
maximum size of either a fully-qualified domain name or a
name. Therefore to aid the application in allocating buffers
these two returned strings the following constants are defined
:

#define NI_MAXHOST 1025
#define NI_MAXSERV 32

The first value is actually defined as the constant MAXDNAME in
versions of BIND's header (older versions of
define this constant to be 256) and the second is a guess based on
services listed in the current Assigned Numbers RFC

The final argument is a flag that changes the default actions of
function. By default the fully-qualified domain name (FQDN) for
host is looked up in the DNS and returned. If the flag bit NI_
is set, only the nodename portion of the FQDN is returned for
hosts

If the flag bit NI_NUMERICHOST is set, or if the host's name cannot
located in the DNS, the numeric form of the host's address is
instead of its name (e.g., by calling inet_ntop() instead
getipnodebyaddr()). If the flag bit NI_NAMEREQD is set, an error
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
address is returned (e.g., its port number) instead of its name.
two NI_NUMERICxxx flags are required to support the "-n" flag
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
service, and causes getservbyport() to be called with a
argument of "udp" instead of its default of "tcp". This is
for the few ports (e.g. 512-514) that have different services for
and TCP

These NI_xxx flags are defined in along with the AI_
flags already defined for getaddrinfo().

6.6 Address Conversion

The two functions inet_addr() and inet_ntoa() convert an IPv4
between binary and text form. IPv6 applications need
functions. The following two functions convert both IPv6 and IPv
addresses

#include #include
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
presentation form into its numeric binary form. The af
specifies the family of the address. Currently the AF_INET
AF_INET6 address families are supported. The src argument points
the string being passed in. The dst argument points to a buffer
which the function stores the numeric address. The address
returned in network byte order. Inet_pton() returns 1 if
conversion succeeds, 0 if the input is not a valid IPv4 dotted
decimal string or a valid IPv6 address string, or -1 with errno
to EAFNOSUPPORT if the af argument is unknown. The
application must ensure that the buffer referred to by dst is
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
standard IPv4 dotted-decimal form

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()
inet_aton() functions accept nonstandard input: octal numbers
hexadecimal numbers, and fewer than four numbers. inet_pton()
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
one