draft-ietf-ipngwg-bsd-api-03.txt   draft-ietf-ipngwg-bsd-api-04.txt 
Internet Engineering Task Force R. E. Gilligan (Sun) Internet Engineering Task Force R. E. Gilligan (Sun)
INTERNET-DRAFT S. Thomson (Bellcore) INTERNET-DRAFT S. Thomson (Bellcore)
J. Bound (Digital) J. Bound (Digital)
November 21, 1995 January 9, 1996
IPv6 Program Interfaces for BSD Systems IPv6 Program Interfaces for BSD Systems
<draft-ietf-ipngwg-bsd-api-03.txt> <draft-ietf-ipngwg-bsd-api-04.txt>
Abstract Abstract
In order to implement the version 6 Internet Protocol (IPv6) [1] in an In order to implement the version 6 Internet Protocol (IPv6) [1] in an
operating system based on Berkeley Unix (4.x BSD), changes must be made operating system based on Berkeley Unix (4.x BSD), changes must be made
to the application program interface (API). TCP/IP applications written to the application program interface (API). TCP/IP applications written
for BSD-based operating systems have in the past enjoyed a high degree for BSD-based operating systems have in the past enjoyed a high degree
of portability because most of the systems derived from BSD provide the of portability because most of the systems derived from BSD provide the
same API, known informally as "the socket interface". We would like the same API, known informally as "the socket interface". We would like the
same portability with IPv6. This memo presents a set of extensions to same portability with IPv6. This memo presents a set of extensions to
the BSD socket API to support IPv6. The changes include a new data the BSD socket API to support IPv6. The changes include a new data
structure to carry IPv6 addresses, new name to address translation structure to carry IPv6 addresses, new name-to-address translation
library functions, new address conversion functions, and some new library functions, new address conversion functions, and some new
setsockopt() options. The extensions are designed to provide access to setsockopt() options. The extensions are designed to provide access to
IPv6 features, while introducing a minimum of change into the system and IPv6 features, while introducing a minimum of change into the system and
providing complete compatibility for existing IPv4 applications. providing complete compatibility for existing IPv4 applications.
Status of this Memo Status of this Memo
This document is an Internet Draft. Internet Drafts are working This document is an Internet Draft. Internet Drafts are working
documents of the Internet Engineering Task Force (IETF), its Areas, documents of the Internet Engineering Task Force (IETF), its Areas,
and its Working Groups. Note that other groups may also distribute and its Working Groups. Note that other groups may also distribute
working documents as Internet Drafts. working documents as Internet Drafts.
Internet Drafts are draft documents valid for a maximum of six months. Internet Drafts are draft documents valid for a maximum of six months.
This Internet Draft expires on May 21, 1996. Internet Drafts may be This Internet Draft expires on July 6, 1996. Internet Drafts may be
updated, replaced, or obsoleted by other documents at any time. It is updated, replaced, or obsoleted by other documents at any time. It is
not appropriate to use Internet Drafts as reference material or to cite not appropriate to use Internet Drafts as reference material or to cite
them other than as a "working draft" or "work in progress." them other than as a "working draft" or "work in progress."
To learn the current status of any Internet-Draft, please check the To learn the current status of any Internet-Draft, please check the
1id-abstracts.txt listing contained in the Internet-Drafts Shadow 1id-abstracts.txt listing contained in the Internet-Drafts Shadow
Directories on ds.internic.net, nic.nordu.net, ftp.isi.edu, or Directories on ds.internic.net, nic.nordu.net, ftp.isi.edu, or
munnari.oz.au. munnari.oz.au.
Distribution of this memo is unlimited. Distribution of this memo is unlimited.
skipping to change at page 11, line 15 skipping to change at page 11, line 15
sin6.sin6_flowinfo = IPV6_PRIORITY_UNATTENDED | sin6.sin6_flowinfo = IPV6_PRIORITY_UNATTENDED |
(IPV6_FLOWINFO_FLOWLABEL & send_flowlabel); (IPV6_FLOWINFO_FLOWLABEL & send_flowlabel);
The macro declarations for these constants are obtained by including The macro declarations for these constants are obtained by including
the header file <netinet/in.h>. the header file <netinet/in.h>.
3.9. Binding to System-Selected Address 3.9. Binding to System-Selected Address
While the bind() function allows applications to select the source IP While the bind() function allows applications to select the source IP
address of UDP packets and TCP connections, applications often wish to address of UDP packets and TCP connections, applications often wish to
let the system to select the source address for them. In IPv4, this let the system select the source address for them. In IPv4, this is
is done by specifying the IPv4 address represented by the symbolic done by specifying the IPv4 address represented by the symbolic
constant INADDR_ANY in the bind() call, or by simply by skipping the constant INADDR_ANY in the bind() call, or by simply by skipping the
bind() entirely. bind() entirely.
A symbolic constant can not be used for IPv6 because the address is Since the IPv6 address type is a structure (struct in6_addr), a
not a scalar type. Instead, the system provides a global variable symbolic constant can be used to initialize an IPv6 address variable,
holding the distinguished IPv6 address that can be used in the bind() but can not be used in an assignment. Therefore systems provide the
call to instruct the system to select the source IPv6 address. The IPv6 address value that can be used to instruct the system to select
global variable is an in6_addr type structure named "ipv6addr_any." the source IPv6 address in two forms.
The extern declaration for this is:
The first version is a global variable named "ipv6addr_any" which is
an in6_addr type structure. The extern declaration for this variable
is:
extern struct in6_addr ipv6addr_any; extern struct in6_addr ipv6addr_any;
Applications use ipv6addr_any similarly to the way they use INADDR_ANY Applications use ipv6addr_any similarly to the way they use INADDR_ANY
in IPv4. For example, to bind a socket to port number 23, but let the 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 system select the source address, an application could use the
following code: following code:
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
. . . . . .
sin6.sin6_family = AF_INET6; sin6.sin6_family = AF_INET6;
sin6.sin6_flowinfo = 0; sin6.sin6_flowinfo = 0;
sin6.sin6_port = htons(23); sin6.sin6_port = htons(23);
sin6.sin6_addr = ipv6addr_any; sin6.sin6_addr = ipv6addr_any;
. . . . . .
if (bind(s, (struct sockaddr *) &sin6, sizeof(sin6)) == -1) if (bind(s, (struct sockaddr *) &sin6, sizeof(sin6)) == -1)
. . . . . .
Note that the value of ipv6addr_any can not be the all-zeros IPv6 The other version is a symbolic constant named IPV6ADDR_ANY_INIT.
address, since that can be used as a valid IPv6 source address in some This constant can be used to initialize an in6_addr structure:
cases.
struct in6_addr anyaddr = IPV6ADDR_ANY_INIT;
Note that this constant can be used ONLY at declaration type. It can
not be used 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 = IPV6ADDR_ANY_INIT; /* Will NOT compile */
3.10. Communicating with Local Services 3.10. Communicating with Local Services
Applications may need to send UDP packets to, or originate TCP 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.
connections to, services residing on the local node. In IPv4, they can IPv6 also provides a loopback address which can be used to contact
do this by using the constant IPv4 address INADDR_LOOPBACK in their local TCP and UDP services. Like the unspecified address, the IPv6
connect(), sendto(), or sendmsg() call. loopback address is provided in two forms -- a global variable and a
symbolic constant.
For IPv6, the system provides a global variable holding a distinguished The global variable is an in6_addr type structure named
IPv6 address that can be used to contact local TCP and UDP services. "ipv6addr_loopback." The extern declaration for this variable is:
This variable is an in6_addr type structure named "ipv6addr_loopback."
The extern declaration for this variable is:
extern struct in6_addr ipv6addr_loopback; extern struct in6_addr ipv6addr_loopback;
Applications use ipv6addr_loopback as they would use INADDR_LOOPBACK Applications use ipv6addr_loopback as they would use INADDR_LOOPBACK
in IPv4 applications. For example, to open a TCP connection to the in IPv4 applications. For example, to open a TCP connection to the
local telnet server, an application could use the following code: local telnet server, an application could use the following code:
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
. . . . . .
sin6.sin6_family = AF_INET6; sin6.sin6_family = AF_INET6;
sin6.sin6_flowinfo = 0; sin6.sin6_flowinfo = 0;
sin6.sin6_port = htons(23); sin6.sin6_port = htons(23);
sin6.sin6_addr = ipv6addr_loopback; sin6.sin6_addr = ipv6addr_loopback;
. . . . . .
if (connect(s, (struct sockaddr *) &sin6, sizeof(sin6)) == -1) if (connect(s, (struct sockaddr *) &sin6, sizeof(sin6)) == -1)
. . . . . .
The symbolic constant is named IPV6ADDR_LOOPBACK_INIT. It can be used
at declaration time ONLY; for example:
struct in6_addr loopbackaddr = IPV6ADDR_LOOPBACK_INIT;
Like IPV6ADDR_ANY_INIT, this constant can not be used in an assignment
to a previously declared IPv6 address variable.
4. Socket Options 4. Socket Options
A number of new socket options are defined for IPv6. All of these new 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 options are at the IPPROTO_IPV6 level. That is, the "level" parameter
in the getsockopt() and setsockopt() call is IPPROTO_IPV6 when using in the getsockopt() and setsockopt() call is IPPROTO_IPV6 when using
these options. The constant name prefix IPV6_ is used in all of the new these options. The constant name prefix IPV6_ is used in all of the new
socket options. This serves to clearly identify these options as socket options. This serves to clearly identify these options as
applying to IPv6. applying to IPv6.
The macro declaration for IPPROTO_IPV6, the new IPv6 socket options, and The macro declaration for IPPROTO_IPV6, the new IPv6 socket options, and
skipping to change at page 14, line 31 skipping to change at page 15, line 4
being originated and UDP packets being sent. But to receive source being originated and UDP packets being sent. But to receive source
routes, the application must enable an option. routes, the application must enable an option.
To provide a source route, an application simply provides an array of To provide a source route, an application simply provides an array of
sockaddr_in6 data structures in the msg_name field of the msghdr sockaddr_in6 data structures in the msg_name field of the msghdr
structure of a sendmsg() function, or the address argument of the structure of a sendmsg() function, or the address argument of the
sendto() function (when sending a UDP packet), or the address argument sendto() function (when sending a UDP packet), or the address argument
of the connect() function (when actively opening a TCP connection). For of the connect() function (when actively opening a TCP connection). For
sendto() and connect(), the length argument of the function is the total sendto() and connect(), the length argument of the function is the total
length, in octets, of the array. For sendmsg(), the msg_namelen field length, in octets, of the array. For sendmsg(), the msg_namelen field
of the msghdr structure specifies the total length of the array. The of the msghdr structure specifies the total length of the array. The
elements of the array represent the full source route, including both elements of the array represent the full source route, including both
source and destination endpoint address. The elements of the array are source and destination endpoint address. The elements of the array are
ordered from destination to source. That is, the first element of the ordered from destination to source. That is, the first element of the
array represents the destination endpoint address, and the last element array represents the destination endpoint address, and the last element
of the array represents the source endpoint address. If the application of the array represents the source endpoint address. If the application
provides a source route, the source endpoint address can not be omitted. provides a source route, the source endpoint address can not be omitted.
The sin6_addr field of the source endpoint address may be set to zero, The sin6_addr field of the source endpoint address may be set to
however, in which case the system will select an appropriate source ipv6addr_any, however, in which case the system will select an
address. The sin6_port field of the destination endpoint address must appropriate source address. The sin6_port field of the destination
be assigned. The sin6_port field of the source endpoint address may be endpoint address must be assigned. The sin6_port field of the source
set to zero, in which case the system will select an appropriate source endpoint address may be set to zero, in which case the system will
port number. The sin6_port fields of the intermediate addresses must be select an appropriate source port number. The sin6_port fields of the
set to zero. intermediate addresses must be set to zero.
The application also has control over the loose/strict source routing The application also has control over the loose/strict source routing
flag that is defined in the IPv6 specification [1]. It does this by flag that is defined in the IPv6 specification [1]. It does this by
setting or clearing the loose/strict flag contained in the sin6_flowinfo setting or clearing the loose/strict flag contained in the sin6_flowinfo
field of the destination and intermediate addresses. On the receive field of the destination and intermediate addresses. On the receive
side, the implementation uses the loose/strict flag in the address array side, the implementation uses the loose/strict flag in the address array
returned to the application to indicate the loose/strict status of each returned to the application to indicate the loose/strict status of each
hop. hop.
The implementation provides a set of constant definitions to simplify The implementation provides a set of constant definitions to simplify
skipping to change at page 15, line 37 skipping to change at page 16, line 11
And they can also be used to set the source route flags: And they can also be used to set the source route flags:
struct sockaddr_in6 sin6[3]; struct sockaddr_in6 sin6[3];
. . . . . .
sin6[0].sin6_flowinfo = sin6[0].sin6_flowinfo =
(sin6[0].sin6_flowinfo & ~IPV6_FLOWINFO_SRFLAG) | (sin6[0].sin6_flowinfo & ~IPV6_FLOWINFO_SRFLAG) |
IPV6_SRFLAG_STRICT; IPV6_SRFLAG_STRICT;
The flow label and priority sub-fields of the sin6_flowinfo field of the The flow label and priority sub-fields of the sin6_flowinfo field of the
destination endpoint address may be set, but the these fields must be destination endpoint address may be set, but the these fields must be
set to zero in the intermediate and source endpoint address. set to zero in the intermediate and source endpoint addresses.
The arrangement of the address structures in the address buffer passed The arrangement of the address structures in the address buffer passed
to sendmsg(), connect() or sendto() is shown in the figure below: to sendmsg(), connect() or sendto() is shown in the figure below:
+--------------------+ +--------------------+
| | | |
| sockaddr_in6[0] | Destination Endpoint Address | sockaddr_in6[0] | Destination Endpoint Address
| | | |
+--------------------+ +--------------------+
| | | |
skipping to change at page 20, line 31 skipping to change at page 20, line 31
+--------------------+ - - - - - - - - - - - - - - - +--------------------+ - - - - - - - - - - - - - - -
Address buffer with receiving interface address Address buffer with receiving interface address
The last address in the array is an IPv6 address of the receiving The last address in the array is an IPv6 address of the receiving
interface. Since interfaces in IPv6 may have more than one address, and interface. Since interfaces in IPv6 may have more than one address, and
some addresses (e.g. link-local addresses) may be used on more than one some addresses (e.g. link-local addresses) may be used on more than one
interface, the system should select an address that uniquely identifies interface, the system should select an address that uniquely identifies
the interface. the interface.
As when receiving source routes, the system returns a single
sockaddr_in6 structure holding the source endpoint address if the buffer
supplied by the application is too small to hold the receiving interface
address.
4.4. Sending Interface Specification 4.4. Sending Interface Specification
Applications may also need to specify the outgoing interface that Applications may also need to specify the outgoing interface that
originated UDP or TCP packets should use. This is accomplished like originated UDP or TCP packets should use. This is accomplished like
source route selection. The application may provide an additional source route selection. The application may provide an additional
sockaddr_in6 structure in its sendto(), sendmsg() or connect() call sockaddr_in6 structure in its sendto(), sendmsg() or connect() call
specifying the address of the outgoing interface. Unlike source route specifying the address of the outgoing interface. Unlike source route
selection, the outgoing interface address can only be included if a new selection, the outgoing interface address can only be included if a new
option is enabled. The new option is needed so that the system can option is enabled. The new option is needed so that the system can
differentiate between the application's specification of an outgoing differentiate between the application's specification of an outgoing
skipping to change at page 23, line 40 skipping to change at page 23, line 40
The reception of multicast packets is controlled by the two setsockopt() The reception of multicast packets is controlled by the two setsockopt()
options summarized below: options summarized below:
IPV6_ADD_MEMBERSHIP IPV6_ADD_MEMBERSHIP
Join a multicast group. Requests that multicast packets Join a multicast group. Requests that multicast packets
sent to a particular multicast address be delivered to sent to a particular multicast address be delivered to
this socket. The argument is the IPv6 multicast address this socket. The argument is the IPv6 multicast address
of the group to join. of the group to join.
Argument type: struct in6_addr Argument type: struct ipv6_mreq
IPV6_DROP_MEMBERSHIP IPV6_DROP_MEMBERSHIP
Leave a multicast group. Requests that multicast Leave a multicast group. Requests that multicast
packets sent to a particular multicast address no longer packets sent to a particular multicast address no longer
be delivered to this socket. The argument is the IPv6 be delivered to this socket. The argument is the IPv6
multicast address of the group to join. multicast address of the group to join.
Argument type: struct in6_addr Argument type: struct ipv6_mreq
The argument type of both of these options is the ipv6_mreq structure,
which is defined as follows:
struct ipv6_mreq {
/* IPv6 multicast address of group */
struct in6_addr ipv6mr_multiaddr;
/* local IPv6 address of interface */
struct in6_addr ipv6mr_interface;
};
5. Library Functions 5. Library Functions
New library functions are needed to lookup IPv6 addresses in the name New library functions are needed to lookup IPv6 addresses in the name
service, and to manipulate IPv6 addresses. service, and to manipulate IPv6 addresses.
5.1. Name-to-Address Translation Functions 5.1. Name-to-Address Translation Functions
Two new functions analogous to gethostbyname() and gethostbyaddr() have Two new functions analogous to gethostbyname() and gethostbyaddr() have
been defined which support both IPv4 and IPv6 addresses. The names of been defined which support both IPv4 and IPv6 addresses. The names of
skipping to change at page 25, line 42 skipping to change at page 26, line 5
The af argument specifies the address family of the addr argument. This The af argument specifies the address family of the addr argument. This
function supports both the AF_INET and AF_INET6 address families. If function supports both the AF_INET and AF_INET6 address families. If
the af argument is AF_INET, then addr refers to an IPv4 address and the af argument is AF_INET, then addr refers to an IPv4 address and
addrlen must have the value 4. If af is AF_INET6, addr represents an addrlen must have the value 4. If af is AF_INET6, addr represents an
IPv6 address and addrlen must have the value 16. In the latter case, IPv6 address and addrlen must have the value 16. In the latter case,
the caller may present an IPv4-mapped IPv6 address in the addr argument. the caller may present an IPv4-mapped IPv6 address in the addr argument.
If this is done, an IPv4 address-to-name lookup is performed on the If this is done, an IPv4 address-to-name lookup is performed on the
embedded IPv4 address. embedded IPv4 address.
The hostent structure returned by both of these functions is allocated IPv6 addresses are returned by hostname2addr() and addr2hostname() via
by the library. Applications use the freehostent() function to return the hostent structure. This h_addr_list element of this structure
the hostent structure to the library after they are done using it: points to an array of ipv6_hostent_addr type structures. This
structure is declared as follows:
struct ipv6_hostent_addr {
/* amount of time in seconds that address is valid for */
u_int32_t iha_lifetime;
/* the IPv6 address being returned */
struct in6_addr iha_addr;
};
The hostent and address structures returned by both of these functions
is allocated by the library. Applications use the freehostent()
function to return this storage to the library after they are done using
it:
void freehostent( void freehostent(
struct hostent *hp); struct hostent *hp);
Applications may not access the hostent structure after they have Applications may not access the hostent structure after they have
returned it to the library. returned it to the library.
Another new name-to-address translation library function is now under Another new name-to-address translation library function is now under
development at Berkeley. This new function, named getconninfo(), will development at Berkeley. This new function, named getconninfo(), will
subsume the functionality of gethostbyname(), hostname2addr(), as well subsume the functionality of gethostbyname(), hostname2addr(), as well
as the getservbyname() and getservbyport() functions. The new function as the getservbyname() and getservbyport() functions. The new function
is specifically designed to be "transport independent", so it should be is specifically designed to be "transport independent", so it should be
directly usable by IPv6 applications. directly usable by IPv6 applications.
System implementations should provide the addr2hostname() and System implementations should provide the addr2hostname() and
hostname2addr() functions in order to simplify the porting of existing hostname2addr() functions in order to simplify the porting of existing
IPv4 applications to IPv6. System implementations may also provide the IPv4 applications to IPv6. System implementations may also provide the
getconninfo() function, once it is defined, so that newly written getconninfo() function, once it is defined, so that newly written
skipping to change at page 28, line 7 skipping to change at page 28, line 31
function does not modify the storage pointed to by cp if the conversion function does not modify the storage pointed to by cp if the conversion
fails. fails.
Applications obtain the prototype declarations for addr2ascii() and Applications obtain the prototype declarations for addr2ascii() and
ascii2addr() by including the header file <arpa/inet.h>. ascii2addr() by including the header file <arpa/inet.h>.
5.3. Embedded IPv4 Addresses 5.3. Embedded IPv4 Addresses
The IPv4-mapped IPv6 address format is used to represent IPv4 addresses The IPv4-mapped IPv6 address format is used to represent IPv4 addresses
as IPv6 addresses. Most applications should be able to to manipulate as IPv6 addresses. Most applications should be able to to manipulate
IPv6 addresses as opaque 16-bit quantities, without needing to know IPv6 addresses as opaque 16-octet quantities, without needing to know
whether they represent IPv4 addresses. However, a few applications may whether they represent IPv4 addresses. However, a few applications may
need to determine whether an IPv6 address is an IPv4-mapped address or need to determine whether an IPv6 address is an IPv4-mapped address or
not. The following function is provided for those applications: not. The following function is provided for those applications:
int inet6_isipv4addr (const struct in6_addr *addr); int inet6_isipv4addr (const struct in6_addr *addr);
The "addr" argument to this function points to a buffer holding an IPv6 The "addr" argument to this function points to a buffer holding an IPv6
address in network byte order. The function returns true (non-zero) if address in network byte order. The function returns true (non-zero) if
that address is an IPv4-mapped address, and returns 0 otherwise. that address is an IPv4-mapped address, and returns 0 otherwise.
skipping to change at page 28, line 37 skipping to change at page 29, line 13
6. Security Considerations 6. Security Considerations
IPv6 provides a number of new security mechanisms, many of which need to IPv6 provides a number of new security mechanisms, many of which need to
be accessible to applications. A companion document detailing the be accessible to applications. A companion document detailing the
extensions to the socket interfaces to support IPv6 security is being extensions to the socket interfaces to support IPv6 security is being
written [4]. At some point in the future, that document and this one written [4]. At some point in the future, that document and this one
may be merged into a single API specification. may be merged into a single API specification.
7. Change History 7. Change History
Changes from the November 1995 Edition
- Added the symbolic constants IPV6ADDR_ANY_INIT and
IPV6ADDR_LOOPBACK_INIT for applications to use for
initializations.
- Eliminated restrictions on the value of ipv6addr_any. Systems
may now choose any value, including all-zeros.
- Added a mechanism for returning time to live with the address in
the name-to-address translation functions.
- Added a mechanism for applications to specify the interface in
the setsockopt() options to join and leave a multicast group.
Changes from the July 1995 Edition Changes from the July 1995 Edition
- Changed u_long and u_short types in structures to u_int32_t and - Changed u_long and u_short types in structures to u_int32_t and
u_int16_t for consistency and clarity. u_int16_t for consistency and clarity.
- Added implementation-provided constants for IPv4 and IPv6 text - Added implementation-provided constants for IPv4 and IPv6 text
address buffer length. address buffer length.
- Defined a set of constants for subfields of sin6_flowid and for - Defined a set of constants for subfields of sin6_flowid and for
priority values. priority values.
skipping to change at page 29, line 40 skipping to change at page 30, line 30
- Deleted the implementation experience section. It was too - Deleted the implementation experience section. It was too
wordy. wordy.
- Added argument types to multicast socket options. - Added argument types to multicast socket options.
- Added constant for largest source route array buffer. - Added constant for largest source route array buffer.
- Added the freehostent() function. - Added the freehostent() function.
- Added receving interface determination and sending interface - Added receiving interface determination and sending interface
selection options. selection options.
- Added definitions of ipv6addr_any and ipv6addr_loopback. - Added definitions of ipv6addr_any and ipv6addr_loopback.
- Added text making the lookup of IPv4 addresses by - Added text making the lookup of IPv4 addresses by
hostname2addr() optional. hostname2addr() optional.
Changes from the June 1995 Edition Changes from the June 1995 Edition
- Added capability for application to select loose or strict - Added capability for application to select loose or strict
skipping to change at page 32, line 21 skipping to change at page 33, line 11
Both of these techniques have drawbacks. This is an area for further Both of these techniques have drawbacks. This is an area for further
study. System implementors may use one of these techniques or implement study. System implementors may use one of these techniques or implement
another solution. another solution.
Acknowledgments Acknowledgments
Thanks to the many people who made suggestions and provided feedback to Thanks to the many people who made suggestions and provided feedback to
to the numerous revisions of this document, including: Ran Atkinson, to the numerous revisions of this document, including: Ran Atkinson,
Fred Baker, Dave Borman, Andrew Cherenson, Alex Conta, Alan Cox, Steve Fred Baker, Dave Borman, Andrew Cherenson, Alex Conta, Alan Cox, Steve
Deering, Francis Dupont, Robert Elz, Marc Hasson, Tom Herbert, Christian Deering, Francis Dupont, Robert Elz, Marc Hasson, Tom Herbert, Christian
Huitema, Wan-Yen Hsu, Alan Lloyd, Charles Lynn, Dan McDonald, Erik Huitema, Wan-Yen Hsu, Alan Lloyd, Charles Lynn, Dan McDonald, Craig
Nordmark, Josh Osborne, Richard Stevens, Dean D. Throop, Glenn Trewitt, Metz, Erik Nordmark, Josh Osborne, Richard Stevens, Matt Thomas, Dean D.
and Carl Williams. Craig Partridge suggested the addr2ascii() and Throop, Glenn Trewitt, David Waitzman, and Carl Williams. Craig
ascii2addr() functions. Partridge suggested the addr2ascii() and ascii2addr() functions.
Ramesh Govindan made a number of contributions and co-authored an Ramesh Govindan made a number of contributions and co-authored an
earlier version of this paper. earlier version of this paper.
References References
[1] R. Hinden. "Internet Protocol, Version 6 (IPv6) Specification". [1] R. Hinden. "Internet Protocol, Version 6 (IPv6) Specification".
Internet Draft. June 1995. Internet Draft. June 1995.
[2] Keith Sklower. "Getconninfo(): An alternative to Gethostbyname()" [2] Keith Sklower. "Getconninfo(): An alternative to Gethostbyname()"
 End of changes. 23 change blocks. 
42 lines changed or deleted 111 lines changed or added

This html diff was produced by rfcdiff 1.33. The latest version is available from http://tools.ietf.org/tools/rfcdiff/