diff --git a/doc/draft/draft-ietf-ipngwg-rfc2292bis-02.txt b/doc/draft/draft-ietf-ipngwg-rfc2292bis-02.txt new file mode 100644 index 0000000000..b588cf15b0 --- /dev/null +++ b/doc/draft/draft-ietf-ipngwg-rfc2292bis-02.txt @@ -0,0 +1,4141 @@ +INTERNET-DRAFT W. Richard Stevens (Consultant) +Expires: May 7, 2001 Matt Thomas (Consultant) +Obsoletes RFC 2292 Erik Nordmark (Sun) + November 7, 2000 + + + Advanced Sockets API for IPv6 + + + + +Abstract + + A separate specification [RFC-2553] contain changes to the sockets + API to support IP version 6. Those changes are for TCP and UDP-based + applications and will support most end-user applications in use + today: Telnet and FTP clients and servers, HTTP clients and servers, + and the like. + + But another class of applications exists that will also be run under + IPv6. We call these "advanced" applications and today this includes + programs such as Ping, Traceroute, routing daemons, multicast routing + daemons, router discovery daemons, and the like. The API feature + typically used by these programs that make them "advanced" is a raw + socket to access ICMPv4, IGMPv4, or IPv4, along with some knowledge + of the packet header formats used by these protocols. To provide + portability for applications that use raw sockets under IPv6, some + standardization is needed for the advanced API features. + + There are other features of IPv6 that some applications will need to + access: interface identification (specifying the outgoing interface + and determining the incoming interface) and IPv6 extension headers + that are not addressed in [RFC-2553]: The Routing header (source + routing), Hop-by-Hop options, and Destination options. This document + provides API access to these features too. + +Status of this Memo + + This document is an Internet-Draft and is in full conformance with + all provisions of Section 10 of RFC2026. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that + other groups may also distribute working documents as Internet- + Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 1] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + The list of current Internet-Drafts can be accessed at + http://www.ietf.org/ietf/1id-abstracts.txt + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + This Internet Draft expires May 7, 2001. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 2] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + +Table of Contents + + 1. Introduction ..................................................... 6 + + 2. Common Structures and Definitions ................................ 7 + 2.1. The ip6_hdr Structure .......................................... 8 + 2.1.1. IPv6 Next Header Values ...................................... 8 + 2.1.2. IPv6 Extension Headers ....................................... 9 + 2.1.3. IPv6 Options ................................................. 10 + 2.2. The icmp6_hdr Structure ........................................ 13 + 2.2.1. ICMPv6 Type and Code Values .................................. 13 + 2.2.2. ICMPv6 Neighbor Discovery Definitions ........................ 14 + 2.2.3. Multicast Listener Discovery Definitions ..................... 17 + 2.2.4. ICMPv6 Router Renumbering Definitions ........................ 18 + 2.3. Address Testing Macros ......................................... 19 + 2.4. Protocols File ................................................. 20 + + 3. IPv6 Raw Sockets ................................................. 20 + 3.1. Checksums ...................................................... 22 + 3.2. ICMPv6 Type Filtering .......................................... 22 + 3.3. ICMPv6 Verification of Received Packets ........................ 25 + + 4. Access to IPv6 and Extension Headers ............................. 25 + 4.1. TCP Implications ............................................... 27 + 4.2. UDP and Raw Socket Implications ................................ 28 + + 5. Extensions to Socket Ancillary Data .............................. 28 + + 6. Packet Information ............................................... 29 + 6.1. Specifying/Receiving the Interface ............................. 30 + 6.2. Specifying/Receiving Source/Destination Address ................ 30 + 6.3. Specifying/Receiving the Hop Limit ............................. 31 + 6.4. Specifying the Next Hop Address ................................ 32 + 6.5. Additional Errors with sendmsg() and setsockopt() .............. 32 + + 7. Routing Header Option ............................................ 33 + 7.1. inet6_rth_space ................................................ 34 + 7.2. inet6_rth_init ................................................. 35 + 7.3. inet6_rth_add .................................................. 35 + 7.4. inet6_rth_reverse .............................................. 35 + 7.5. inet6_rth_segments ............................................. 36 + 7.6. inet6_rth_getaddr .............................................. 36 + + 8. Hop-By-Hop Options ............................................... 36 + 8.1. Receiving Hop-by-Hop Options ................................... 38 + 8.2. Sending Hop-by-Hop Options ..................................... 38 + + 9. Destination Options .............................................. 38 + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 3] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + 9.1. Receiving Destination Options .................................. 39 + 9.2. Sending Destination Options .................................... 39 + + 10. Hop-by-Hop and Destination Options Processing ................... 40 + 10.1. inet6_opt_init ................................................ 40 + 10.2. inet6_opt_append .............................................. 41 + 10.3. inet6_opt_finish .............................................. 41 + 10.4. inet6_opt_set_val ............................................. 42 + 10.5. inet6_opt_next ................................................ 42 + 10.6. inet6_opt_find ................................................ 42 + 10.7. inet6_opt_get_val ............................................. 43 + + 11. Additional Advanced API Functions ............................... 43 + 11.1. Sending with the Minimum MTU .................................. 43 + 11.2. Path MTU Discovery and UDP .................................... 44 + 11.3. Neighbor Reachability and UDP ................................. 44 + + 12. Ordering of Ancillary Data and IPv6 Extension Headers ........... 45 + + 13. IPv6-Specific Options with IPv4-Mapped IPv6 Addresses ........... 46 + + 14. Extended interfaces for rresvport, rcmd and rexec ............... 46 + 14.1. rresvport_af .................................................. 46 + 14.2. rcmd_af ....................................................... 47 + 14.3. rexec_af ...................................................... 47 + + 15. Summary of New Definitions ...................................... 47 + + 16. Security Considerations ......................................... 52 + + 17. Change History .................................................. 52 + + 18. TODO and Open Issues ............................................ 54 + + 19. References ...................................................... 56 + + 20. Acknowledgments ................................................. 56 + + 21. Authors' Addresses .............................................. 57 + + 22. Appendix A: Ancillary Data Overview ............................. 57 + 22.1. The msghdr Structure .......................................... 58 + 22.2. The cmsghdr Structure ......................................... 59 + 22.3. Ancillary Data Object Macros .................................. 60 + 22.3.1. CMSG_FIRSTHDR ............................................... 61 + 22.3.2. CMSG_NXTHDR ................................................. 62 + 22.3.3. CMSG_DATA ................................................... 63 + 22.3.4. CMSG_SPACE .................................................. 63 + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 4] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + 22.3.5. CMSG_LEN .................................................... 64 + + 23. Appendix B: Examples using the inet6_rth_XXX() functions ........ 64 + 23.1. Sending a Routing Header ...................................... 64 + 23.2. Receiving Routing Headers ..................................... 69 + + 24. Appendix C: Examples using the inet6_opt_XXX() functions ........ 71 + 24.1. Building options .............................................. 71 + 24.2. Parsing received options ...................................... 73 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 5] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + +1. Introduction + + A separate specification [RFC-2553] contain changes to the sockets + API to support IP version 6. Those changes are for TCP and UDP-based + applications. This document defines some the "advanced" features of + the sockets API that are required for applications to take advantage + of additional features of IPv6. + + Today, the portability of applications using IPv4 raw sockets is + quite high, but this is mainly because most IPv4 implementations + started from a common base (the Berkeley source code) or at least + started with the Berkeley header files. This allows programs such as + Ping and Traceroute, for example, to compile with minimal effort on + many hosts that support the sockets API. With IPv6, however, there + is no common source code base that implementors are starting from, + and the possibility for divergence at this level between different + implementations is high. To avoid a complete lack of portability + amongst applications that use raw IPv6 sockets, some standardization + is necessary. + + There are also features from the basic IPv6 specification that are + not addressed in [RFC-2553]: sending and receiving Routing headers, + Hop-by-Hop options, and Destination options, specifying the outgoing + interface, and being told of the receiving interface. + + This document can be divided into the following main sections. + + 1. Definitions of the basic constants and structures required for + applications to use raw IPv6 sockets. This includes structure + definitions for the IPv6 and ICMPv6 headers and all associated + constants (e.g., values for the Next Header field). + + 2. Some basic semantic definitions for IPv6 raw sockets. For + example, a raw ICMPv4 socket requires the application to + calculate and store the ICMPv4 header checksum. But with IPv6 + this would require the application to choose the source IPv6 + address because the source address is part of the pseudo header + that ICMPv6 now uses for its checksum computation. It should be + defined that with a raw ICMPv6 socket the kernel always + calculates and stores the ICMPv6 header checksum. + + 3. Packet information: how applications can obtain the received + interface, destination address, and received hop limit, along + with specifying these values on a per-packet basis. There are a + class of applications that need this capability and the technique + should be portable. + + 4. Access to the optional Routing header, Hop-by-Hop, and + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 6] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + Destination extension headers. + + 5. Additional features required for improved IPv6 application + portability. + + The packet information along with access to the extension headers + (Routing header, Hop-by-Hop options, and Destination options) are + specified using the "ancillary data" fields that were added to the + 4.3BSD Reno sockets API in 1990. The reason is that these ancillary + data fields are part of the Posix.1g standard and should therefore be + adopted by most vendors. + + This document does not address application access to either the + authentication header or the encapsulating security payload header. + + All examples in this document omit error checking in favor of brevity + and clarity. + + We note that many of the functions and socket options defined in this + document may have error returns that are not defined in this + document. Many of these possible error returns will be recognized + only as implementations proceed. + + Datatypes in this document follow the Posix.1g format: intN_t means + a signed integer of exactly N bits (e.g., int16_t) and uintN_t means + an unsigned integer of exactly N bits (e.g., uint32_t). + + Note that we use the (unofficial) terminology ICMPv4, IGMPv4, and + ARPv4 to avoid any confusion with the newer ICMPv6 protocol. + + +2. Common Structures and Definitions + + Many advanced applications examine fields in the IPv6 header and set + and examine fields in the various ICMPv6 headers. Common structure + definitions for these protocol headers are required, along with + common constant definitions for the structure members. + + This API assumes that the fields in the protocol headers are left in + the network byte order, which is big-endian for the Internet + protocols. If not, then either these constants or the fields being + tested must be converted at run-time, using something like htons() or + htonl(). + + Two new header files are defined: and + . + + When an include file is specified, that include file is allowed to + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 7] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + include other files that do the actual declaration or definition. + + +2.1. The ip6_hdr Structure + + The following structure is defined as a result of including + . Note that this is a new header. + + struct ip6_hdr { + union { + struct ip6_hdrctl { + uint32_t ip6_un1_flow; /* 4 bits version, 8 bits TC, 20 bits flow-ID */ + uint16_t ip6_un1_plen; /* payload length */ + uint8_t ip6_un1_nxt; /* next header */ + uint8_t ip6_un1_hlim; /* hop limit */ + } ip6_un1; + uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits tclass */ + } ip6_ctlun; + struct in6_addr ip6_src; /* source address */ + struct in6_addr ip6_dst; /* destination address */ + }; + + #define ip6_vfc ip6_ctlun.ip6_un2_vfc + #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow + #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen + #define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt + #define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim + #define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim + + + +2.1.1. IPv6 Next Header Values + + IPv6 defines many new values for the Next Header field. The + following constants are defined as a result of including + . + + #define IPPROTO_HOPOPTS 0 /* IPv6 Hop-by-Hop options */ + #define IPPROTO_IPV6 41 /* IPv6 header */ + #define IPPROTO_ROUTING 43 /* IPv6 Routing header */ + #define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ + #define IPPROTO_ESP 50 /* encapsulating security payload */ + #define IPPROTO_AH 51 /* authentication header */ + #define IPPROTO_ICMPV6 58 /* ICMPv6 */ + #define IPPROTO_NONE 59 /* IPv6 no next header */ + #define IPPROTO_DSTOPTS 60 /* IPv6 Destination options */ + + Berkeley-derived IPv4 implementations also define IPPROTO_IP to be 0. + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 8] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + This should not be a problem since IPPROTO_IP is used only with IPv4 + sockets and IPPROTO_HOPOPTS only with IPv6 sockets. + + +2.1.2. IPv6 Extension Headers + + Six extension headers are defined for IPv6. We define structures for + all except the Authentication header and Encapsulating Security + Payload header, both of which are beyond the scope of this document. + The following structures are defined as a result of including + . + + /* + * Generic extension header structure used by many extension headers. + * Note that not all headers have this format. E.g. the fragmentation + * header is different. + */ + struct ip6_ext { + uint8_t ip6e_nxt; /* next header */ + uint8_t ip6e_len; /* length in units of 8 octets */ + }; + + /* Hop-by-Hop options header */ + struct ip6_hbh { + uint8_t ip6h_nxt; /* next header */ + uint8_t ip6h_len; /* length in units of 8 octets */ + /* followed by options */ + }; + + /* Destination options header */ + struct ip6_dest { + uint8_t ip6d_nxt; /* next header */ + uint8_t ip6d_len; /* length in units of 8 octets */ + /* followed by options */ + }; + + /* Routing header */ + struct ip6_rthdr { + uint8_t ip6r_nxt; /* next header */ + uint8_t ip6r_len; /* length in units of 8 octets */ + uint8_t ip6r_type; /* routing type */ + uint8_t ip6r_segleft; /* segments left */ + /* followed by routing type specific data */ + }; + + /* Type 0 Routing header */ + struct ip6_rthdr0 { + uint8_t ip6r0_nxt; /* next header */ + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 9] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + uint8_t ip6r0_len; /* length in units of 8 octets */ + uint8_t ip6r0_type; /* always zero */ + uint8_t ip6r0_segleft; /* segments left */ + uint32_t ip6r0_reserved; /* reserved field */ + /* followed by up to 127 struct in6_addr */ + }; + + /* Fragment header */ + struct ip6_frag { + uint8_t ip6f_nxt; /* next header */ + uint8_t ip6f_reserved; /* reserved field */ + uint16_t ip6f_offlg; /* offset, reserved, and flag */ + uint32_t ip6f_ident; /* identification */ + }; + + #if BYTE_ORDER == BIG_ENDIAN + #define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */ + #define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */ + #define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */ + #else /* BYTE_ORDER == LITTLE_ENDIAN */ + #define IP6F_OFF_MASK 0xf8ff /* mask out offset from _offlg */ + #define IP6F_RESERVED_MASK 0x0600 /* reserved bits in ip6f_offlg */ + #define IP6F_MORE_FRAG 0x0100 /* more-fragments flag */ + #endif + + + +2.1.3. IPv6 Options + + Eleven options are defined for IPv6 at the time of writing this + document. We define structures for all except the unspecified EID + option. The following structures are defined as a result of + including . + + /* IPv6 options */ + struct ip6_opt { + uint8_t ip6o_type; + uint8_t ip6o_len; + }; + + /* + * The high-order 3 bits of the option type define the behavior + * when processing an unknown option and whether or not the option + * content changes in flight. + */ + #define IP6OPT_TYPE(o) ((o) & 0xc0) + #define IP6OPT_TYPE_SKIP 0x00 + #define IP6OPT_TYPE_DISCARD 0x40 + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 10] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + #define IP6OPT_TYPE_FORCEICMP 0x80 + #define IP6OPT_TYPE_ICMP 0xc0 + #define IP6OPT_MUTABLE 0x20 + + #define IP6OPT_PAD1 0x00 /* 00 0 00000 */ + #define IP6OPT_PADN 0x01 /* 00 0 00001 */ + #define IP6OPT_JUMBO 0xc2 /* 11 0 00010 = 194 */ + #define IP6OPT_NSAP_ADDR 0xc3 /* 11 0 00011 */ + #define IP6OPT_TUNNEL_LIMIT 0x04 /* 00 0 00100 */ + #define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ + #define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ + #define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ + #define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ + #define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ + #define IP6OPT_EID 0x8a /* 10 0 01010 */ + + /* Jumbo Payload Option */ + struct ip6_opt_jumbo { + uint8_t ip6oj_type; + uint8_t ip6oj_len; + uint8_t ip6oj_jumbo_len[4]; + }; + #define IP6OPT_JUMBO_LEN 6 + + /* NSAP Address Option */ + struct ip6_opt_nsap { + uint8_t ip6on_type; + uint8_t ip6on_len; + uint8_t ip6on_src_nsap_len; + uint8_t ip6on_dst_nsap_len; + /* followed by source NSAP */ + /* followed by destination NSAP */ + }; + + /* Tunnel Limit Option */ + struct ip6_opt_tunnel { + uint8_t ip6ot_type; + uint8_t ip6ot_len; + uint8_t ip6ot_encap_limit; + }; + + /* Router Alert Option */ + struct ip6_opt_router { + uint8_t ip6or_type; + uint8_t ip6or_len; + uint8_t ip6or_value[2]; + }; + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 11] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + /* Router alert values (in network byte order) */ + #ifdef _BIG_ENDIAN + #define IP6_ALERT_MLD 0x0000 + #define IP6_ALERT_RSVP 0x0001 + #define IP6_ALERT_AN 0x0002 + #else + #define IP6_ALERT_MLD 0x0000 + #define IP6_ALERT_RSVP 0x0100 + #define IP6_ALERT_AN 0x0200 + #endif + + /* Binding Update Option */ + struct ip6_opt_binding_update { + uint8_t ip6ou_type; + uint8_t ip6ou_len; + uint8_t ip6ou_flags; + uint8_t ip6ou_prefixlen; + uint8_t ip6ou_seqno[2]; + uint8_t ip6ou_lifetime[4]; + uint8_t ip6ou_coa[16]; /* Optional based on flags */ + /* followed by sub-options */ + }; + + /* Binding Update Flags */ + #define IP6_BUF_ACK 0x80 /* Request a binding ack */ + #define IP6_BUF_HOME 0x40 /* Home Registration */ + #define IP6_BUF_COA 0x20 /* Care-of-address present in option */ + #define IP6_BUF_ROUTER 0x10 /* Sending mobile node is a router */ + + /* Binding Ack Option */ + struct ip6_opt_binding_ack { + uint8_t ip6oa_type; + uint8_t ip6oa_len; + uint8_t ip6oa_status; + uint8_t ip6oa_seqno[2]; + uint8_t ip6oa_lifetime[4]; + uint8_t ip6oa_refresh[4]; + /* followed by sub-options */ + }; + + /* Binding Request Option */ + struct ip6_opt_binding_request { + uint8_t ip6or_type; + uint8_t ip6or_len; + /* followed by sub-options */ + }; + + /* Home Address Option */ + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 12] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + struct ip6_opt_home_address { + uint8_t ip6oh_type; + uint8_t ip6oh_len; + uint8_t ip6oh_addr[16]; /* Home Address */ + /* followed by sub-options */ + }; + + + +2.2. The icmp6_hdr Structure + + The ICMPv6 header is needed by numerous IPv6 applications including + Ping, Traceroute, router discovery daemons, and neighbor discovery + daemons. The following structure is defined as a result of including + . Note that this is a new header. + + struct icmp6_hdr { + uint8_t icmp6_type; /* type field */ + uint8_t icmp6_code; /* code field */ + uint16_t icmp6_cksum; /* checksum field */ + union { + uint32_t icmp6_un_data32[1]; /* type-specific field */ + uint16_t icmp6_un_data16[2]; /* type-specific field */ + uint8_t icmp6_un_data8[4]; /* type-specific field */ + } icmp6_dataun; + }; + + #define icmp6_data32 icmp6_dataun.icmp6_un_data32 + #define icmp6_data16 icmp6_dataun.icmp6_un_data16 + #define icmp6_data8 icmp6_dataun.icmp6_un_data8 + #define icmp6_pptr icmp6_data32[0] /* parameter prob */ + #define icmp6_mtu icmp6_data32[0] /* packet too big */ + #define icmp6_id icmp6_data16[0] /* echo request/reply */ + #define icmp6_seq icmp6_data16[1] /* echo request/reply */ + #define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */ + + + +2.2.1. ICMPv6 Type and Code Values + + In addition to a common structure for the ICMPv6 header, common + definitions are required for the ICMPv6 type and code fields. The + following constants are also defined as a result of including + . + + #define ICMP6_DST_UNREACH 1 + #define ICMP6_PACKET_TOO_BIG 2 + #define ICMP6_TIME_EXCEEDED 3 + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 13] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + #define ICMP6_PARAM_PROB 4 + + #define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */ + + #define ICMP6_ECHO_REQUEST 128 + #define ICMP6_ECHO_REPLY 129 + + #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ + #define ICMP6_DST_UNREACH_ADMIN 1 /* communication with */ + /* destination */ + /* admin. prohibited */ + #define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ + #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ + #define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */ + + #define ICMP6_TIME_EXCEED_TRANSIT 0 /* Hop Limit == 0 in transit */ + #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */ + + #define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ + #define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized Next Header */ + #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */ + + The five ICMP message types defined by IPv6 neighbor discovery (133- + 137) are defined in the next section. + + +2.2.2. ICMPv6 Neighbor Discovery Definitions + + The following structures and definitions are defined as a result of + including . + + #define ND_ROUTER_SOLICIT 133 + #define ND_ROUTER_ADVERT 134 + #define ND_NEIGHBOR_SOLICIT 135 + #define ND_NEIGHBOR_ADVERT 136 + #define ND_REDIRECT 137 + + struct nd_router_solicit { /* router solicitation */ + struct icmp6_hdr nd_rs_hdr; + /* could be followed by options */ + }; + + #define nd_rs_type nd_rs_hdr.icmp6_type + #define nd_rs_code nd_rs_hdr.icmp6_code + #define nd_rs_cksum nd_rs_hdr.icmp6_cksum + #define nd_rs_reserved nd_rs_hdr.icmp6_data32[0] + + struct nd_router_advert { /* router advertisement */ + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 14] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + struct icmp6_hdr nd_ra_hdr; + uint32_t nd_ra_reachable; /* reachable time */ + uint32_t nd_ra_retransmit; /* retransmit timer */ + /* could be followed by options */ + }; + + #define nd_ra_type nd_ra_hdr.icmp6_type + #define nd_ra_code nd_ra_hdr.icmp6_code + #define nd_ra_cksum nd_ra_hdr.icmp6_cksum + #define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0] + #define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1] + #define ND_RA_FLAG_MANAGED 0x80 + #define ND_RA_FLAG_OTHER 0x40 + #define ND_RA_FLAG_HOME_AGENT 0x20 + #define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1] + + struct nd_neighbor_solicit { /* neighbor solicitation */ + struct icmp6_hdr nd_ns_hdr; + struct in6_addr nd_ns_target; /* target address */ + /* could be followed by options */ + }; + + #define nd_ns_type nd_ns_hdr.icmp6_type + #define nd_ns_code nd_ns_hdr.icmp6_code + #define nd_ns_cksum nd_ns_hdr.icmp6_cksum + #define nd_ns_reserved nd_ns_hdr.icmp6_data32[0] + + struct nd_neighbor_advert { /* neighbor advertisement */ + struct icmp6_hdr nd_na_hdr; + struct in6_addr nd_na_target; /* target address */ + /* could be followed by options */ + }; + + #define nd_na_type nd_na_hdr.icmp6_type + #define nd_na_code nd_na_hdr.icmp6_code + #define nd_na_cksum nd_na_hdr.icmp6_cksum + #define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0] + #if BYTE_ORDER == BIG_ENDIAN + #define ND_NA_FLAG_ROUTER 0x80000000 + #define ND_NA_FLAG_SOLICITED 0x40000000 + #define ND_NA_FLAG_OVERRIDE 0x20000000 + #else /* BYTE_ORDER == LITTLE_ENDIAN */ + #define ND_NA_FLAG_ROUTER 0x00000080 + #define ND_NA_FLAG_SOLICITED 0x00000040 + #define ND_NA_FLAG_OVERRIDE 0x00000020 + #endif + + struct nd_redirect { /* redirect */ + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 15] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + struct icmp6_hdr nd_rd_hdr; + struct in6_addr nd_rd_target; /* target address */ + struct in6_addr nd_rd_dst; /* destination address */ + /* could be followed by options */ + }; + + #define nd_rd_type nd_rd_hdr.icmp6_type + #define nd_rd_code nd_rd_hdr.icmp6_code + #define nd_rd_cksum nd_rd_hdr.icmp6_cksum + #define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] + + struct nd_opt_hdr { /* Neighbor discovery option header */ + uint8_t nd_opt_type; + uint8_t nd_opt_len; /* in units of 8 octets */ + /* followed by option specific data */ + }; + + #define ND_OPT_SOURCE_LINKADDR 1 + #define ND_OPT_TARGET_LINKADDR 2 + #define ND_OPT_PREFIX_INFORMATION 3 + #define ND_OPT_REDIRECTED_HEADER 4 + #define ND_OPT_MTU 5 + #define ND_OPT_ADVINTERVAL 7 + #define ND_OPT_HOMEAGENT_INFO 8 + + struct nd_opt_prefix_info { /* prefix information */ + uint8_t nd_opt_pi_type; + uint8_t nd_opt_pi_len; + uint8_t nd_opt_pi_prefix_len; + uint8_t nd_opt_pi_flags_reserved; + uint32_t nd_opt_pi_valid_time; + uint32_t nd_opt_pi_preferred_time; + uint32_t nd_opt_pi_reserved2; + /* XXX uint8_t nd_opt_pi_reserved2[3]; */ + /* XXX uint8_t nd_opt_pi_sitelen; */ + struct in6_addr nd_opt_pi_prefix; + }; + + #define ND_OPT_PI_FLAG_ONLINK 0x80 + #define ND_OPT_PI_FLAG_AUTO 0x40 + #define ND_OPT_PI_FLAG_ROUTER 0x20 /* Added my Mobile IPv6 */ + #define ND_OPT_PI_FLAG_SITEPREF 0x10 /* XXX sitelen is valid */ + + struct nd_opt_rd_hdr { /* redirected header */ + uint8_t nd_opt_rh_type; + uint8_t nd_opt_rh_len; + uint16_t nd_opt_rh_reserved1; + uint32_t nd_opt_rh_reserved2; + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 16] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + /* followed by IP header and data */ + }; + + struct nd_opt_mtu { /* MTU option */ + uint8_t nd_opt_mtu_type; + uint8_t nd_opt_mtu_len; + uint16_t nd_opt_mtu_reserved; + uint32_t nd_opt_mtu_mtu; + }; + + struct nd_opt_advinterval { /* Advertisement Interval */ + uint8_t nd_opt_adv_type; + uint8_t nd_opt_adv_len; + uint16_t nd_opt_adv_reserved; + uint32_t nd_opt_adv_interval; /* In milliseconds */ + }; + + struct nd_opt_homeagent_info { /* Home Agent info */ + uint8_t nd_opt_hai_type; + uint8_t nd_opt_hai_len; + uint16_t nd_opt_hai_reserved; + int16_t nd_opt_hai_preference; + uint16_t nd_opt_hai_lifetime; + }; + + We note that the nd_na_flags_reserved flags have the same byte + ordering problems as we discussed with ip6f_offlg. + + +2.2.3. Multicast Listener Discovery Definitions + + The following structures and definitions are defined as a result of + including . + + #define MLD_LISTENER_QUERY 130 + #define MLD_LISTENER_REPORT 131 + #define MLD_LISTENER_REDUCTION 132 + + struct mld_hdr { + struct icmp6_hdr mld_hdr; + struct in6_addr mld_addr; /* multicast address */ + }; + #define mld_type mld_hdr.icmp6_type + #define mld_code mld_hdr.icmp6_code + #define mld_cksum mld_hdr.icmp6_cksum + #define mld_maxdelay mld_hdr.icmp6_data16[0] + #define mld_reserved mld_hdr.icmp6_data16[1] + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 17] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + +2.2.4. ICMPv6 Router Renumbering Definitions + + The following structures and definitions are defined as a result of + including . + + #define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */ + + struct icmp6_router_renum { /* router renumbering header */ + struct icmp6_hdr rr_hdr; + u_int8_t rr_segnum; + u_int8_t rr_flags; + u_int16_t rr_maxdelay; + u_int32_t rr_reserved; + }; + #define rr_type rr_hdr.icmp6_type + #define rr_code rr_hdr.icmp6_code + #define rr_cksum rr_hdr.icmp6_cksum + #define rr_seqnum rr_hdr.icmp6_data32[0] + + /* Router renumbering flags */ + #define ICMP6_RR_FLAGS_TEST 0x80 + #define ICMP6_RR_FLAGS_REQRESULT 0x40 + #define ICMP6_RR_FLAGS_FORCEAPPLY 0x20 + #define ICMP6_RR_FLAGS_SPECSITE 0x10 + #define ICMP6_RR_FLAGS_PREVDONE 0x08 + + + struct rr_pco_match { /* match prefix part */ + u_int8_t rpm_code; + u_int8_t rpm_len; + u_int8_t rpm_ordinal; + u_int8_t rpm_matchlen; + u_int8_t rpm_minlen; + u_int8_t rpm_maxlen; + u_int16_t rpm_reserved; + struct in6_addr rpm_prefix; + }; + + /* PCO code values */ + #define RPM_PCO_ADD 1 + #define RPM_PCO_CHANGE 2 + #define RPM_PCO_SETGLOBAL 3 + + struct rr_pco_use { /* use prefix part */ + u_int8_t rpu_uselen; + u_int8_t rpu_keeplen; + u_int8_t rpu_ramask; + u_int8_t rpu_raflags; + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 18] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + u_int32_t rpu_vltime; + u_int32_t rpu_pltime; + u_int32_t rpu_flags; + struct in6_addr rpu_prefix; + }; + #define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20 + #define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10 + + #if BYTE_ORDER == BIG_ENDIAN + #define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000 + #define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000 + #elif BYTE_ORDER == LITTLE_ENDIAN + #define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80 + #define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40 + #endif + + struct rr_result { /* router renumbering result message */ + u_int16_t rrr_flags; + u_int8_t rrr_ordinal; + u_int8_t rrr_matchedlen; + u_int32_t rrr_ifid; + struct in6_addr rrr_prefix; + }; + + #if BYTE_ORDER == BIG_ENDIAN + #define ICMP6_RR_RESULT_FLAGS_OOB 0x0002 + #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001 + #elif BYTE_ORDER == LITTLE_ENDIAN + #define ICMP6_RR_RESULT_FLAGS_OOB 0x0200 + #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100 + #endif + + + +2.3. Address Testing Macros + + The basic API ([RFC-2553]) defines some macros for testing an IPv6 + address for certain properties. This API extends those definitions + with additional address testing macros, defined as a result of + including . + + int IN6_ARE_ADDR_EQUAL(const struct in6_addr *, + const struct in6_addr *); + + This macro returns non-zero if the addresses are equal; otherwise it + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 19] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + returns zero. + + +2.4. Protocols File + + Many hosts provide the file /etc/protocols that contains the names of + the various IP protocols and their protocol number (e.g., the value + of the protocol field in the IPv4 header for that protocol, such as 1 + for ICMP). Some programs then call the function getprotobyname() to + obtain the protocol value that is then specified as the third + argument to the socket() function. For example, the Ping program + contains code of the form + + struct protoent *proto; + + proto = getprotobyname("icmp"); + + s = socket(PF_INET, SOCK_RAW, proto->p_proto); + + Common names are required for the new IPv6 protocols in this file, to + provide portability of applications that call the getprotoXXX() + functions. + + We define the following protocol names with the values shown. These + are taken from ftp://ftp.isi.edu/in-notes/iana/assignments/protocol- + numbers. + + hopopt 0 # hop-by-hop options for ipv6 + ipv6 41 # ipv6 + ipv6-route 43 # routing header for ipv6 + ipv6-frag 44 # fragment header for ipv6 + esp 50 # encapsulating security payload for ipv6 + ah 51 # authentication header for ipv6 + ipv6-icmp 58 # icmp for ipv6 + ipv6-nonxt 59 # no next header for ipv6 + ipv6-opts 60 # destination options for ipv6 + + + +3. IPv6 Raw Sockets + + Raw sockets bypass the transport layer (TCP or UDP). With IPv4, raw + sockets are used to access ICMPv4, IGMPv4, and to read and write IPv4 + datagrams containing a protocol field that the kernel does not + process. An example of the latter is a routing daemon for OSPF, + since it uses IPv4 protocol field 89. With IPv6 raw sockets will be + used for ICMPv6 and to read and write IPv6 datagrams containing a + Next Header field that the kernel does not process. Examples of the + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 20] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + latter are a routing daemon for OSPF for IPv6 and RSVP (protocol + field 46). + + All data sent via raw sockets MUST be in network byte order and all + data received via raw sockets will be in network byte order. This + differs from the IPv4 raw sockets, which did not specify a byte + ordering and used the host's byte order for certain IP header fields. + + Another difference from IPv4 raw sockets is that complete packets + (that is, IPv6 packets with extension headers) cannot be sent or + received using the IPv6 raw sockets API. Instead, ancillary data + objects are used to transfer the extension headers and hoplimit + information, as described in Section 6. Should an application need + access to the complete IPv6 packet, some other technique, such as the + datalink interfaces BPF or DLPI, must be used. + + All fields in the IPv6 header that an application might want to + change (i.e., everything other than the version number) can be + modified using ancillary data and/or socket options by the + application for output. All fields in a received IPv6 header (other + than the version number and Next Header fields) and all extension + headers are also made available to the application as ancillary data + on input. Hence there is no need for a socket option similar to the + IPv4 IP_HDRINCL socket option and on receipt the application will + only receive the payload i.e. the data after the IPv6 header and all + the extension headers. + + When writing to a raw socket the kernel will automatically fragment + the packet if its size exceeds the path MTU, inserting the required + fragmentation headers. On input the kernel reassembles received + fragments, so the reader of a raw socket never sees any fragment + headers. + + When we say "an ICMPv6 raw socket" we mean a socket created by + calling the socket function with the three arguments PF_INET6, + SOCK_RAW, and IPPROTO_ICMPV6. + + Most IPv4 implementations give special treatment to a raw socket + created with a third argument to socket() of IPPROTO_RAW, whose value + is normally 255, to have it mean that the application will send down + complete packets including the IPv4 header. (Note: This feature was + added to IPv4 in 1988 by Van Jacobson to support traceroute, allowing + a complete IP header to be passed by the application, before the + IP_HDRINCL socket option was added.) We note that IPPROTO_RAW has no + special meaning to an IPv6 raw socket (and the IANA currently + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 21] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + reserves the value of 255 when used as a next-header field). + + +3.1. Checksums + + The kernel will calculate and insert the ICMPv6 checksum for ICMPv6 + raw sockets, since this checksum is mandatory. + + For other raw IPv6 sockets (that is, for raw IPv6 sockets created + with a third argument other than IPPROTO_ICMPV6), the application + must set the new IPV6_CHECKSUM socket option to have the kernel (1) + compute and store a checksum for output, and (2) verify the received + checksum on input, discarding the packet if the checksum is in error. + This option prevents applications from having to perform source + address selection on the packets they send. The checksum will + incorporate the IPv6 pseudo-header, defined in Section 8.1 of [RFC- + 2460]. This new socket option also specifies an integer offset into + the user data of where the checksum is located. + + int offset = 2; + setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); + + By default, this socket option is disabled. Setting the offset to -1 + also disables the option. By disabled we mean (1) the kernel will + not calculate and store a checksum for outgoing packets, and (2) the + kernel will not verify a checksum for received packets. + + An attempt to set IPV6_CHECKSUM for an ICMPv6 socket will fail. + + (Note: Since the checksum is always calculated by the kernel for an + ICMPv6 socket, applications are not able to generate ICMPv6 packets + with incorrect checksums (presumably for testing purposes) using this + API.) + + +3.2. ICMPv6 Type Filtering + + ICMPv4 raw sockets receive most ICMPv4 messages received by the + kernel. (We say "most" and not "all" because Berkeley-derived + kernels never pass echo requests, timestamp requests, or address mask + requests to a raw socket. Instead these three messages are processed + entirely by the kernel.) But ICMPv6 is a superset of ICMPv4, also + including the functionality of IGMPv4 and ARPv4. This means that an + ICMPv6 raw socket can potentially receive many more messages than + would be received with an ICMPv4 raw socket: ICMP messages similar + to ICMPv4, along with neighbor solicitations, neighbor + advertisements, and the three multicast listener discovery messages. + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 22] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + Most applications using an ICMPv6 raw socket care about only a small + subset of the ICMPv6 message types. To transfer extraneous ICMPv6 + messages from the kernel to user can incur a significant overhead. + Therefore this API includes a method of filtering ICMPv6 messages by + the ICMPv6 type field. + + Each ICMPv6 raw socket has an associated filter whose datatype is + defined as + + struct icmp6_filter; + + This structure, along with the macros and constants defined later in + this section, are defined as a result of including the + . + + The current filter is fetched and stored using getsockopt() and + setsockopt() with a level of IPPROTO_ICMPV6 and an option name of + ICMP6_FILTER. + + Six macros operate on an icmp6_filter structure: + + void ICMP6_FILTER_SETPASSALL (struct icmp6_filter *); + void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *); + + void ICMP6_FILTER_SETPASS ( int, struct icmp6_filter *); + void ICMP6_FILTER_SETBLOCK( int, struct icmp6_filter *); + + int ICMP6_FILTER_WILLPASS (int, + const struct icmp6_filter *); + int ICMP6_FILTER_WILLBLOCK(int, + const struct icmp6_filter *); + + The first argument to the last four macros (an integer) is an ICMPv6 + message type, between 0 and 255. The pointer argument to all six + macros is a pointer to a filter that is modified by the first four + macros examined by the last two macros. + + The first two macros, SETPASSALL and SETBLOCKALL, let us specify that + all ICMPv6 messages are passed to the application or that all ICMPv6 + messages are blocked from being passed to the application. + + The next two macros, SETPASS and SETBLOCK, let us specify that + messages of a given ICMPv6 type should be passed to the application + or not passed to the application (blocked). + + The final two macros, WILLPASS and WILLBLOCK, return true or false + depending whether the specified message type is passed to the + application or blocked from being passed to the application by the + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 23] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + filter pointed to by the second argument. + + When an ICMPv6 raw socket is created, it will by default pass all + ICMPv6 message types to the application. + + As an example, a program that wants to receive only router + advertisements could execute the following: + + struct icmp6_filter myfilt; + + fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + + ICMP6_FILTER_SETBLOCKALL(&myfilt); + ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &myfilt); + setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &myfilt, sizeof(myfilt)); + + The filter structure is declared and then initialized to block all + messages types. The filter structure is then changed to allow router + advertisement messages to be passed to the application and the filter + is installed using setsockopt(). + + The icmp6_filter structure is similar to the fd_set datatype used + with the select() function in the sockets API. The icmp6_filter + structure is an opaque datatype and the application should not care + how it is implemented. All the application does with this datatype + is allocate a variable of this type, pass a pointer to a variable of + this type to getsockopt() and setsockopt(), and operate on a variable + of this type using the six macros that we just defined. + + Nevertheless, it is worth showing a simple implementation of this + datatype and the six macros. + + struct icmp6_filter { + uint32_t icmp6_filt[8]; /* 8*32 = 256 bits */ + }; + + #define ICMP6_FILTER_WILLPASS(type, filterp) \ + ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0) + #define ICMP6_FILTER_WILLBLOCK(type, filterp) \ + ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0) + #define ICMP6_FILTER_SETPASS(type, filterp) \ + ((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))) + #define ICMP6_FILTER_SETBLOCK(type, filterp) \ + ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))) + #define ICMP6_FILTER_SETPASSALL(filterp) \ + memset((filterp), 0xFF, sizeof(struct icmp6_filter)) + #define ICMP6_FILTER_SETBLOCKALL(filterp) \ + memset((filterp), 0, sizeof(struct icmp6_filter)) + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 24] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + (Note: These sample definitions have two limitations that an + implementation may want to change. The first four macros evaluate + their first argument two times. The second two macros require the + inclusion of the header for the memset() function.) + + +3.3. ICMPv6 Verification of Received Packets + + The protocol stack will verify the ICMPv6 checksum and discard any + packets with invalid checksums. + + An implementation might perform additional validity checks on the + ICMP message content and discard malformed packets. However, a + portable application must not assume that such validity checks have + been performed. + + The protocol stack should not automatically discard packets if the + ICMP type is unknown to the stack. For extensibility reasons received + ICMP packets with any type (informational or error) must be passed to + the applications (subject to ICMP6_FILTER filtering on the type value + and the checksum verification). + + +4. Access to IPv6 and Extension Headers + + Applications need to be able to control IPv6 header and extension + header content when sending as well as being able to receive the + content of these headers. This is done by defining socket option + types which can be used both with setsockopt and with ancillary data. + Ancillary data is discussed in Appendix A. The following optional + information can be exchanged between the application and the kernel: + + 1. The send/receive interface and source/destination address, + 2. The hop limit, + 3. Next hop address, + 4. Routing header. + 5. Hop-by-Hop options, and + 6. Destination options (both before and after a Routing header). + + First, to receive any of this optional information (other than the + next hop address, which can only be set), the application must call + setsockopt() to turn on the corresponding flag: + + + + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 25] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + + int on = 1; + + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)); + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on)); + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on)); + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &on, sizeof(on)); + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &on, sizeof(on)); + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, + &on, sizeof(on)); + + When any of these options are enabled, the corresponding data is + returned as control information by recvmsg(), as one or more + ancillary data objects. + + Two different mechanisms exist for sending this optional information: + + 1. Using setsockopt to specify the option content for a socket. + These are known an "sticky" options since they affect all + transmitted packets on the socket until either the a new + setsockopt is done or the options are overridden using ancillary + data. + + 2. Using ancillary data to specify the option content for a single + datagram. This only applies to datagram and raw sockets; not to + TCP sockets. + + + The three socket option parameters and the three cmsghdr fields that + describe the options/ancillary data objects are summarized as: + + opt level/ optname/ optval/ + cmsg_level cmsg_type cmsg_data[] + ------------ ------------ ------------------------ + IPPROTO_IPV6 IPV6_PKTINFO in6_pktinfo structure + IPPROTO_IPV6 IPV6_HOPLIMIT int + IPPROTO_IPV6 IPV6_NEXTHOP socket address structure + IPPROTO_IPV6 IPV6_RTHDR ip6_rthdr structure + IPPROTO_IPV6 IPV6_HOPOPTS ip6_hbh structure + IPPROTO_IPV6 IPV6_DSTOPTS ip6_dest structure + IPPROTO_IPV6 IPV6_RTHDRDSTOPTS ip6_dest structure + + + All these options are described in detail in Section 6, 7, 8 and 9. + All the constants beginning with IPV6_ are defined as a result of + including the . + + Issuing getsockopt() for the above options will return the sticky + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 26] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + option value i.e. the value set with setsockopt(). If no sticky + option value has been set getsockopt() will return the default value. + + Note: We intentionally use the same constant for the cmsg_level + member as is used as the second argument to getsockopt() and + setsockopt() (what is called the "level"), and the same constant for + the cmsg_type member as is used as the third argument to getsockopt() + and setsockopt() (what is called the "option name"). + + The application does not explicitly need to access the data + structures for the Routing header option, Hop-by-Hop option, and + Destination options, since the API to these features is through a set + of inet6_rth_XXX() and inet6_opt_XXX() functions that we define in + Section 8 and Section 10. Those functions simplify the interface to + these features instead of requiring the application to know the + intimate details of the extension header formats. + + +4.1. TCP Implications + + It is not possible to use ancillary data to transmit the above + options for TCP since there is not a one-to-one mapping between send + operations and the TCP segments being transmitted. Instead an + application can use setsockopt to specify them as sticky options. + When the application uses setsockopt to specify the above options it + is expected that TCP will start using the new information when + sending segments. However, TCP may or may not use the new + information when retransmitting segments that were originally sent + when the old sticky options were in effect. + + Applications using TCP can use ancillary data (after enabling the + desired IPV6_RECVxxx options) to receive the IPv6 and extension + header information. However, since there is not a one-to-one mapping + between received TCP segments and recv operations seen by the + application, when different TCP segments have different IPv6 and + extension headers the application might not be able to observe all + received headers. For efficiency reasons it is recommended that a + TCP implementation not send ancillary data items with every received + segment but instead try to detect the points in the data stream when + the requested IPv6 and extension header content changes and only send + a single ancillary data item at the time of the change. Also, TCP + should send ancillary data items at the start of the connection and + when the application enables a new IPV6_RECVxxx option. + + For example, assume an application has enabled IPV6_RECVHOPLIMIT + before a connection is established. Then the first recvmsg() would + have an IPV6_HOPLIMIT item indicating the hop limit in the first data + segment. Should the hoplimit in the received data segment change a + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 27] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + subsequent recvmsg() will also have an IPV6_HOPLIMIT item. However, + the application must be prepared to handle ancillary data items even + though the hop limit did not change. Note that should the hop limit + in received ACK-only segments be different than the hop limit in data + segments the application might only be able to observe the hop limit + in the received data segments. + + The above example was for hop limit but the application should be + prepared to handle the corresponding behavior for the other option + information. + + The above recvmsg() behavior allows the application to detect changes + in the received IPv6 and extension headers without resorting to + periodic getsockopt() calls. + + +4.2. UDP and Raw Socket Implications + + The receive behavior for UDP and raw sockets is quite + straightforward. After the application has enabled an IPV6_RECVxxx + socket option it will receive ancillary data items for every + recvmsg() call containing the requested information. However, if the + information is not present in the packet the ancillary data item will + not be included. For example, if the application enables + IPV6_RECVRTHDR and a received datagram does not contain a Routing + header there will not be an IPV6_RTHDR ancillary data item. Note + that due to buffering in the socket implementation there might be + some packets queued when an IPV6_RECVxxx option is enabled and they + might not have the ancillary data information. + + For sending the application has the choice between using sticky + options and ancillary data. The application can also use both having + the sticky options specify the "default" and using ancillary data to + override the default options. Note that if any ancillary data is + specified in a call to sendmsg(), all of the sticky options are + overridden for that datagram. For example, if the application has + set IPV6_RTHDR using a sticky option and later passes IPV6_HOPLIMIT + as ancillary data this will override the IPV6_RTHDR sticky option and + no Routing header will be sent with that datagram. + + +5. Extensions to Socket Ancillary Data + + This specification uses ancillary data as defined in Posix.1g which + the following compatible extensions: + + - CMSG_NXTHDR has been extended to handle a NULL 2nd argument to + mean "get the first header". See Section 22.3.2. + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 28] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + - A new CMSG_SPACE macro is defined. It is used to determine how + much space need to be allocated for an ancillary data item. See + Section 22.3.4. + + - A new CMSG_LEN macro is defined. It returns the value to store + in the cmsg_len member of the cmsghdr structure, taking into + account any padding needed to satisfy alignment requirements. + See Section 22.3.5. + + +6. Packet Information + + There are four pieces of information that an application can specify + for an outgoing packet using ancillary data: + + 1. the source IPv6 address, + 2. the outgoing interface index, + 3. the outgoing hop limit, and + 4. the next hop address. + + Three similar pieces of information can be returned for a received + packet as ancillary data: + + 1. the destination IPv6 address, + 2. the arriving interface index, and + 3. the arriving hop limit. + + + The first two pieces of information are contained in an in6_pktinfo + structure that is set with setsockopt() or sent as ancillary data + with sendmsg() and received as ancillary data with recvmsg(). This + structure is defined as a result of including the . + + struct in6_pktinfo { + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + unsigned int ipi6_ifindex; /* send/recv interface index */ + }; + + In the socket option and cmsghdr level will be IPPROTO_IPV6, the type + will be IPV6_PKTINFO, and the first byte of the option value and + cmsg_data[] will be the first byte of the in6_pktinfo structure. An + application can clear any sticky IPV6_PKTINFO option by either doing + a setsockopt for option with optlen being zero, or by doing a + "regular" setsockopt with ipi6_addr being in6addr_any and + ipi6_ifindex being zero. + + This information is returned as ancillary data by recvmsg() only if + the application has enabled the IPV6_RECVPKTINFO socket option: + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 29] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + + int on = 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)); + + + (Note: The hop limit is not contained in the in6_pktinfo structure + for the following reason. Some UDP servers want to respond to client + requests by sending their reply out the same interface on which the + request was received and with the source IPv6 address of the reply + equal to the destination IPv6 address of the request. To do this the + application can enable just the IPV6_RECVPKTINFO socket option and + then use the received control information from recvmsg() as the + outgoing control information for sendmsg(). The application need not + examine or modify the in6_pktinfo structure at all. But if the hop + limit were contained in this structure, the application would have to + parse the received control information and change the hop limit + member, since the received hop limit is not the desired value for an + outgoing packet.) + + +6.1. Specifying/Receiving the Interface + + Interfaces on an IPv6 node are identified by a small positive + integer, as described in Section 4 of [RFC-2553]. That document also + describes a function to map an interface name to its interface index, + a function to map an interface index to its interface name, and a + function to return all the interface names and indexes. Notice from + this document that no interface is ever assigned an index of 0. + + When specifying the outgoing interface, if the ipi6_ifindex value is + 0, the kernel will choose the outgoing interface. If the application + specifies an outgoing interface for a multicast packet, the interface + specified by the ancillary data overrides any interface specified by + the IPV6_MULTICAST_IF socket option (described in [RFC-2553]), for + that call to sendmsg() only. + + When the IPV6_RECVPKTINFO socket option is enabled, the received + interface index is always returned as the ipi6_ifindex member of the + in6_pktinfo structure. + + +6.2. Specifying/Receiving Source/Destination Address + + The source IPv6 address can be specified by calling bind() before + each output operation, but supplying the source address together with + the data requires less overhead (i.e., fewer system calls) and + requires less state to be stored and protected in a multithreaded + application. + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 30] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + When specifying the source IPv6 address as ancillary data, if the + ipi6_addr member of the in6_pktinfo structure is the unspecified + address (IN6ADDR_ANY_INIT or in6addr_any), then (a) if an address is + currently bound to the socket, it is used as the source address, or + (b) if no address is currently bound to the socket, the kernel will + choose the source address. If the ipi6_addr member is not the + unspecified address, but the socket has already bound a source + address, then the ipi6_addr value overrides the already-bound source + address for this output operation only. + + The kernel must verify that the requested source address is indeed a + unicast address assigned to the node. + + When the in6_pktinfo structure is returned as ancillary data by + recvmsg(), the ipi6_addr member contains the destination IPv6 address + from the received packet. + + +6.3. Specifying/Receiving the Hop Limit + + The outgoing hop limit is normally specified with either the + IPV6_UNICAST_HOPS socket option or the IPV6_MULTICAST_HOPS socket + option, both of which are described in [RFC-2553]. Specifying the + hop limit as ancillary data lets the application override either the + kernel's default or a previously specified value, for either a + unicast destination or a multicast destination, for a single output + operation. Returning the received hop limit is useful for programs + such as Traceroute and for IPv6 applications that need to verify that + the received hop limit is 255 (e.g., that the packet has not been + forwarded). + + The received hop limit is returned as ancillary data by recvmsg() + only if the application has enabled the IPV6_RECVHOPLIMIT socket + option: + + int on = 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on)); + + In the cmsghdr structure containing this ancillary data, the + cmsg_level member will be IPPROTO_IPV6, the cmsg_type member will be + IPV6_HOPLIMIT, and the first byte of cmsg_data[] will be the first + byte of the integer hop limit. + + Nothing special need be done to specify the outgoing hop limit: just + specify the control information as ancillary data for sendmsg() or + using setsockopt(). As specified in [RFC-2553], the interpretation + of the integer hop limit value is + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 31] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + + x < -1: return an error of EINVAL + x == -1: use kernel default + 0 <= x <= 255: use x + x >= 256: return an error of EINVAL + + + In order to clear a sticky IPV6_HOPLIMIT option the application can + specify -1 as the value. Alternatively, the application can specify + an IPV6_HOPLIMIT socket option with a zero length. + + +6.4. Specifying the Next Hop Address + + The IPV6_NEXTHOP ancillary data object specifies the next hop for the + datagram as a socket address structure. In the cmsghdr structure + containing this ancillary data, the cmsg_level member will be + IPPROTO_IPV6, the cmsg_type member will be IPV6_NEXTHOP, and the + first byte of cmsg_data[] will be the first byte of the socket + address structure. + + This is a privileged option. (Note: It is implementation defined and + beyond the scope of this document to define what "privileged" means. + Unix systems use this term to mean the process must have an effective + user ID of 0.) + + If the socket address structure contains an IPv6 address (e.g., the + sin6_family member is AF_INET6), then the node identified by that + address must be a neighbor of the sending host. If that address + equals the destination IPv6 address of the datagram, then this is + equivalent to the existing SO_DONTROUTE socket option. + + In order to clear a sticky IPV6_NEXTHOP option the application must + issue a setsockopt for IPv6_NEXTHOP with a zero length. + + + +6.5. Additional Errors with sendmsg() and setsockopt() + + With the IPV6_PKTINFO socket option there are no additional errors + possible with the call to recvmsg(). But when specifying the + outgoing interface or the source address, additional errors are + possible from sendmsg() or setsockopt(). Note that some + implementations might only be able to return this type of errors for + setsockopt(). The following are examples, but some of these may not + be provided by some implementations, and some implementations may + define additional errors: + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 32] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + ENXIO The interface specified by ipi6_ifindex does not exist. + + ENETDOWN The interface specified by ipi6_ifindex is not enabled + for IPv6 use. + + EADDRNOTAVAIL ipi6_ifindex specifies an interface but the address + ipi6_addr is not available for use on that interface. + + EHOSTUNREACH No route to the destination exists over the interface + specified by ifi6_ifindex. + + +7. Routing Header Option + + Source routing in IPv6 is accomplished by specifying a Routing header + as an extension header. There can be different types of Routing + headers, but IPv6 currently defines only the Type 0 Routing header + [RFC-2460]. This type supports up to 127 intermediate nodes (limited + by the length field in the extension header). With this maximum + number of intermediate nodes, a source, and a destination, there are + 128 hops. + + Source routing with IPv4 sockets API (the IP_OPTIONS socket option) + requires the application to build the source route in the format that + appears as the IPv4 header option, requiring intimate knowledge of + the IPv4 options format. This IPv6 API, however, defines six + functions that the application calls to build and examine a Routing + header, and the ability to use sticky options or ancillary data to + communicate this information between the application and the kernel + using the IPV6_RTHDR option. + + Three functions build a Routing header: + + inet6_rth_space() - return #bytes required for Routing header + inet6_rth_init() - initialize buffer data for Routing header + inet6_rth_add() - add one IPv6 address to the Routing header + + Three functions deal with a returned Routing header: + + inet6_rth_reverse() - reverse a Routing header + inet6_rth_segments() - return #segments in a Routing header + inet6_rth_getaddr() - fetch one address from a Routing header + + The function prototypes for these functions are defined as a result + of including the . + + To receive a Routing header the application must enable the + IPV6_RECVRTHDR socket option: + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 33] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + + int on = 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on)); + + To send a Routing header the application specifies it either as + ancillary data in a call to sendmsg() or using setsockopt(). + + The application can remove any sticky Routing header by calling + setsockopt() for IPV6_RTHDR with a zero option length. + + When using ancillary data a Routing header is passed between the + application and the kernel as follows: The cmsg_level member has a + value of IPPROTO_IPV6 and the cmsg_type member has a value of + IPV6_RTHDR. The contents of the cmsg_data[] member is implementation + dependent and should not be accessed directly by the application, but + should be accessed using the six functions that we are about to + describe. + + The following constant is defined as a result of including the + : + + #define IPV6_RTHDR_TYPE_0 0 /* IPv6 Routing header type 0 */ + + When a Routing header is specified, the destination address specified + for connect(), sendto(), or sendmsg() is the final destination + address of the datagram. The Routing header then contains the + addresses of all the intermediate nodes. + + +7.1. inet6_rth_space + + + size_t inet6_rth_space(int type, int segments); + + This function returns the number of bytes required to hold a Routing + header of the specified type containing the specified number of + segments (addresses). For an IPv6 Type 0 Routing header, the number + of segments must be between 0 and 127, inclusive. The return value + is just the space for the Routing header. When the application uses + ancillary data it must pass the returned length to CMSG_LEN() to + determine how much memory is needed for the ancillary data object + (including the cmsghdr structure). + + If the return value is 0, then either the type of the Routing header + is not supported by this implementation or the number of segments is + invalid for this type of Routing header. + + (Note: This function returns the size but does not allocate the space + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 34] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + required for the ancillary data. This allows an application to + allocate a larger buffer, if other ancillary data objects are + desired, since all the ancillary data objects must be specified to + sendmsg() as a single msg_control buffer.) + + +7.2. inet6_rth_init + + + void *inet6_rth_init(void *bp, int bp_len, int type, int segments); + + This function initializes the buffer pointed to by bp to contain a + Routing header of the specified type and sets ip6r_len based on the + segments parameter. bp_len is only used to verify that the buffer is + large enough. The ip6r_segleft field is set to zero; inet6_rth_add() + will increment it. + + When the application uses ancillary data the application must + initialize any cmsghdr fields. + + The caller must allocate the buffer and its size can be determined by + calling inet6_rth_space(). + + Upon success the return value is the pointer to the buffer (bp), and + this is then used as the first argument to the inet6_rth_add() + function. Upon an error the return value is NULL. + + +7.3. inet6_rth_add + + + int inet6_rth_add(void *bp, const struct in6_addr *addr); + + This function adds the IPv6 address pointed to by addr to the end of + the Routing header being constructed. + + If successful, the segleft member of the Routing Header is updated to + account for the new address in the Routing header and the return + value of the function is 0. Upon an error the return value of the + function is -1. + + +7.4. inet6_rth_reverse + + + int inet6_rth_reverse(const void *in, void *out); + + This function takes a Routing header extension header (pointed to by + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 35] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + the first argument) and writes a new Routing header that sends + datagrams along the reverse of that route. The function reverses the + order of the addresses and sets the segleft member in the new Routing + header to the number of segments. Both arguments are allowed to + point to the same buffer (that is, the reversal can occur in place). + + The return value of the function is 0 on success, or -1 upon an + error. + + +7.5. inet6_rth_segments + + + int inet6_rth_segments(const void *bp); + + This function returns the number of segments (addresses) contained in + the Routing header described by bp. On success the return value is + zero or greater. The return value of the function is -1 upon an + error. + + +7.6. inet6_rth_getaddr + + + struct in6_addr *inet6_rth_getaddr(const void *bp, int index); + + This function returns a pointer to the IPv6 address specified by + index (which must have a value between 0 and one less than the value + returned by inet6_rth_segments()) in the Routing header described by + bp. An application should first call inet6_rth_segments() to obtain + the number of segments in the Routing header. + + Upon an error the return value of the function is NULL. + + +8. Hop-By-Hop Options + + A variable number of Hop-by-Hop options can appear in a single Hop- + by-Hop options header. Each option in the header is TLV-encoded with + a type, length, and value. + + Today only four Hop-by-Hop options are defined for IPv6 [RFC-2460]: + Jumbo Payload, Pad1, PadN, and router-alert. The two pad options are + for alignment purposes and are automatically inserted by the + inet6_opt_XXX() routines and ignored by the inet6_opt_XXX() routines + on the receive side. + + This section of the API is therefore defined for future Hop-by-Hop + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 36] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + options (as well as destination options) that an application may need + to specify and receive. This IPv6 API defines seven functions that + the application calls to build and examine a Hop-by_Hop options + header, and the ability to use sticky options or ancillary data to + communicate this information between the application and the kernel. + This uses the IPV6_HOPOPTS for hob-by-hop options. + + Four functions build a options header: + + inet6_opt_init() - initialize buffer data for options header + inet6_opt_append() - add one TLV option to the options header + inet6_opt_finish() - finish adding TLV options to the options header + inet6_opt_set_val() - add one component of the option content to the option + + Three functions deal with a returned options header: + + inet6_opt_next() - extract the next option from the options header + inet6_opt_find() - extract an option of a specified type from the header + inet6_opt_get_val() - retrieve one component of the option content + + + Individual Hop-by-Hop options (and Destination options, which are + described in Section 9 and are very similar to the Hop-by-Hop + options) may have specific alignment requirements. For example, the + 4-byte Jumbo Payload length should appear on a 4-byte boundary, and + IPv6 addresses are normally aligned on an 8-byte boundary. These + requirements and the terminology used with these options are + discussed in Section 4.2 and Appendix B of [RFC-2460]. The alignment + of first byte of each option is specified by two values, called x and + y, written as "xn + y". This states that the option must appear at + an integer multiple of x bytes from the beginning of the options + header (x can have the values 1, 2, 4, or 8), plus y bytes (y can + have a value between 0 and 7, inclusive). The Pad1 and PadN options + are inserted as needed to maintain the required alignment. The + functions below need to know the alignment of the end of the option + (which is always in the form "xn," where x can have the values 1, 2, + 4, or 8) and the total size of the data portion of the option. These + are passed as the "align" and "len" arguments to inet6_opt_append(). + + Multiple Hop-by-Hop options must be specified by the application by + placing them in a single extension header. + + Finally, we note that use of some Hop-by-Hop options or some + Destination options, might require special privilege. That is, + normal applications (without special privilege) might be forbidden + from setting certain options in outgoing packets, and might never see + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 37] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + certain options in received packets. + + +8.1. Receiving Hop-by-Hop Options + + To receive Hop-by-Hop options the application must enable the + IPV6_RECVHOPOPTS socket option: + + int on = 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &on, sizeof(on)); + + When using ancillary data a Hop-by-hop options is passed between the + application and the kernel as follows: The cmsg_level member will be + IPPROTO_IPV6 and the cmsg_type member will be IPV6_HOPOPTS. These + options are then processed by calling the inet6_opt_next(), + inet6_opt_find(), and inet6_opt_get_val() functions, described in + Section 10.6. + + +8.2. Sending Hop-by-Hop Options + + To send a Hop-by-Hop options header, the application specifies the + header either as ancillary data in a call to sendmsg() or using + setsockopt(). + + The application can remove any sticky Hop-by-Hop extension header by + calling setsockopt() for IPV6_HOPOPTS with a zero option length. + + All the Hop-by-Hop options must specified by a single ancillary data + object. The cmsg_level member is set to IPPROTO_IPV6 and the + cmsg_type member is set to IPV6_HOPOPTS. The option is normally + constructed using the inet6_opt_init(), inet6_opt_append(), + inet6_opt_finish(), and inet6_set_val() functions, described in + Section 10. + + Additional errors may be possible from sendmsg() and setsockopt() if + the specified option is in error. + + +9. Destination Options + + A variable number of Destination options can appear in one or more + Destination option headers. As defined in [RFC-2460], a Destination + options header appearing before a Routing header is processed by the + first destination plus any subsequent destinations specified in the + Routing header, while a Destination options header appearing after a + Routing header is processed only by the final destination. As with + the Hop-by-Hop options, each option in a Destination options header + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 38] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + is TLV-encoded with a type, length, and value. + + Today no Destination options are defined for IPv6 [RFC-2460], + although proposals exist to use Destination options with Mobile IPv6. + + +9.1. Receiving Destination Options + + To receive Destination options appearing after a Routing header (or + in a packet without a Routing header) the application must enable the + IPV6_RECVDSTOPTS socket option: + + int on = 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &on, sizeof(on)); + + To receive Destination options appearing before a Routing header the + application must enable the IPV6_RECVRTHDRDSTOPTS socket option: + + int on = 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, + &on, sizeof(on)); + + All the Destination options appearing before a Routing header are + returned as one ancillary data object described by a cmsghdr + structure (with cmsg_type set to IPV6_RTHDRDSTOPTS) and all the + Destination options appearing after a Routing header (or in a packet + without a Routing header) are returned as another ancillary data + object described by a cmsghdr structure (with cmsg_type set to + IPV6_DSTOPTS). For all these ancillary data objects, the cmsg_level + member will be IPPROTO_IPV6. + + These options are then processed by calling the inet6_opt_next(), + inet6_opt_find(), and inet6_opt_get_value() functions. + + +9.2. Sending Destination Options + + To send a Destination options header, the application specifies it + either as ancillary data in a call to sendmsg() or using + setsockopt(). + + The application can remove any sticky Destination extension header by + calling setsockopt() for IPV6_RTHDRDSTOPTS/IPV6_DSTOPTS with a zero + option length. + + As described in Section 6 one set of Destination options can appear + before a Routing header, and one set can appear after a Routing + header (or in a packet with no Routing header). Each set can consist + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 39] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + of one or more options but each set is a single extension header. + + When using ancillary data a Destination options header is passed + between the application and the kernel as follows: The set preceding + a Routing header are specified with the cmsg_level member is set to + IPPROTO_IPV6 and the cmsg_type member is set to IPV6_RTHDRDSTOPTS. + Any setsockopt or ancillary data for IPV6_RTHDRDSTOPTS is silently + ignored when sending packets unless a Routing header is also + specified. + + The set of Destination options after a Routing header, which are also + used when no Routing header is present, are specified with the + cmsg_level member is set to IPPROTO_IPV6 and the cmsg_type member is + set to IPV6_DSTOPTS. + + The Destination options are normally constructed using the + inet6_opt_init(), inet6_opt_append(), inet6_opt_finish(), and + inet6_set_val() functions, described in Section 10. + + Additional errors may be possible from sendmsg() and setsockopt() if + the specified option is in error. + + +10. Hop-by-Hop and Destination Options Processing + + Building and parsing the Hop-by-Hop and Destination options is + complicated for the reasons given earlier. We therefore define a set + of functions to help the application. These functions assume the + formatting rules specified in Appendix B in [RFC-2460] i.e. that the + largest field is placed last in the option. + + The function prototypes for these functions are defined as a result + of including the . + + The first 3 functions (init, append, and finish) are used both to + calculate the needed buffer size for the options, and to actually + encode the options once the application has allocated a buffer for + the header. In order to only calculate the size the application must + pass a NULL extbuf and a zero extlen to those functions. + + +10.1. inet6_opt_init + + + int inet6_opt_init(void *extbuf, size_t extlen); + + This function returns the number of bytes needed for the empty + extension header i.e. without any options. If extbuf is not NULL it + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 40] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + also initializes the extension header to have the correct length + field. In that case if the extlen value is not a positive (i.e., + non-zero) multiple of 8 the function fails and returns -1. + + +10.2. inet6_opt_append + + + int inet6_opt_append(void *extbuf, size_t extlen, int prevlen, + uint8_t type, size_t len, uint_t align, + void **databufp); + + Prevlen should be the length returned by inet6_opt_init() or a + previous inet6_opt_append(). This function returns the updated total + length taking into account adding an option with length 'len' and + alignment 'align'. If extbuf is not NULL then, in addition to + returning the length, the function inserts any needed pad option, + initializes the option (setting the type and length fields) and + returns a pointer to the location for the option content in databufp. + If the option does not fit in the extension header buffer the + function returns -1. + + Type is the 8-bit option type. Len is the length of the option data + (i.e. excluding the option type and option length fields). + + Once inet6_opt_append() has been called the application can use the + databuf directly, or use inet6_opt_set_val() to specify the content + of the option. + + The option type must have a value from 2 to 255, inclusive. (0 and 1 + are reserved for the Pad1 and PadN options, respectively.) + + The option data length must have a value between 0 and 255, + inclusive, and is the length of the option data that follows. + + The align parameter must have a value of 1, 2, 4, or 8. The align + value can not exceed the value of len. + + +10.3. inet6_opt_finish + + + int inet6_opt_finish(void *extbuf, size_t extlen, int prevlen); + + Prevlen should be the length returned by inet6_opt_init() or + inet6_opt_append(). This function returns the updated total length + taking into account the final padding of the extension header to make + it a multiple of 8 bytes. If extbuf is not NULL the function also + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 41] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + initializes the option by inserting a Pad1 or PadN option of the + proper length. + + If the necessary pad does not fit in the extension header buffer the + function returns -1. + + +10.4. inet6_opt_set_val + + + int inet6_opt_set_val(void *databuf, size_t offset, void *val, + int vallen); + + Databuf should be a pointer returned by inet6_opt_append(). This + function inserts data items of various sizes (1, 2, 4, or 8 bytes) in + the data portion of the option. Val should point to the data to be + inserted. Offset specifies where in the data portion of the option + the value should be inserted; the first byte after the option type + and length is accessed by specifying an offset of zero. + + The function returns the offset for the next field (i.e., offset + + vallen) which can be used when composing option content with multiple + fields. + + +10.5. inet6_opt_next + + + int inet6_opt_next(void *extbuf, size_t extlen, int prevlen, + uint8_t *typep, size_t *lenp, + void **databufp); + + This function parses received option extension headers returning the + next option. Extbuf and extlen specifies the extension header. + Prevlen should either be zero (for the first option) or the length + returned by a previous call to inet6_opt_next() or inet6_opt_find(). + It specifies the position where to continue scanning the extension + buffer. The next option is returned by updating typep, lenp, and + databufp. This function returns the updated "previous" length + computed by advancing past the option that was returned. This + returned "previous" length can then be passed to subsequent calls to + inet6_opt_next(). This function does not return any PAD1 or PADN + options. When there are no more options or if the option extension + header is malformed the return value is -1. + + +10.6. inet6_opt_find + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 42] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + + int inet6_opt_find(void *extbuf, size_t extlen, int prevlen, + uint8_t type, size_t *lenp, + void **databufp); + + This function is similar to the previously described inet6_opt_next() + function, except this function lets the caller specify the option + type to be searched for, instead of always returning the next option + in the extension header. + + If an option of the specified type is located, the function returns + the updated "previous" total length computed by advancing past the + option that was returned and past any options that didn't match the + type. This returned "previous" length can then be passed to + subsequent calls to inet6_opt_find() for finding the next occurrence + of the same option type. + + If an option of the specified type is not located, the return value + is -1. If the option extension header is malformed, the return value + is -1. + + +10.7. inet6_opt_get_val + + + int inet6_opt_get_val(void *databuf, size_t offset, void *val, + int vallen); + + Databuf should be a pointer returned by inet6_opt_next() or + inet6_opt_find(). This function extracts data items of various sizes + (1, 2, 4, or 8 bytes) in the data portion of the option. Val should + point to the destination for the extracted data. Offset specifies + from where in the data portion of the option the value should be + extracted; the first byte after the option type and length is + accessed by specifying an offset of zero. + + The function returns the offset for the next field (i.e., offset + + vallen) which can be used when extracting option content with + multiple fields. + + +11. Additional Advanced API Functions + + + +11.1. Sending with the Minimum MTU + + Some applications might not want to incur the overhead of path MTU + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 43] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + discovery, especially if the applications only send a single datagram + to a destination. A potential example is a DNS server. + + This specification defines a mechanism to avoid path MTU discovery by + sending at the minimum IPv6 MTU [RFC-2460]. If the packet is larger + than the minimum MTU and this feature has been enabled the IP layer + will fragment to the minimum MTU. This can be enabled using the + IPV6_USE_MIN_MTU socket option. + + int on = 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, &on, sizeof(on)); + + By default, this socket option is disabled. Setting the value to 0 + also disables the option. This option can also be sent as ancillary + data. + + + +11.2. Path MTU Discovery and UDP + + UDP and raw socket applications need to be able to determine the + "maximum send transport-message size" (Section 5.1 of [RFC-1981]) to + a given destination so that those applications can participate in + path MTU discovery. This lets those applications send smaller + datagrams to the destination, avoiding fragmentation. + + This is accomplished using a new ancillary data item (IPV6_PATHMTU) + which is delivered to recvmsg() without any actual data. The + application enable the receipt of IPV6_PATHMTU ancillary data items + by enabing IPV6_RECVPATHMTU. + + int on = 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPATHMTU, &on, sizeof(on)); + + By default, this socket option is disabled. Setting the value to 0 + also disables the option. + + When the application is sending packets too big for the path MTU + recvmsg will return zero (indicating no data) but there will be a + cmsghdr with cmsg_type set to IPV6_PATHMTU, and cmsg_len will + indicate that cmsg_data is 4 bytes long. CMSG_DATA will point to an + integer carrying the path MTU to use. + + +11.3. Neighbor Reachability and UDP + + UDP and raw socket application might know that communication is + making forward progress i.e. that the path from the node to the next + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 44] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + hop is working. In such a case the applications, similarly to TCP as + specified in [RFC-2461], has the option indicate to the internet + layer that the neighbor is reachable. See section 7.3.1 of [RFC- + 2461]. This could save unneeded neighbor solicitation and neighbor + advertisement messages. + + This is done by including an ancilary data item with cmsg_type being + IPV6_REACHCONF and with no attached CMSG_DATA. + + If implementations honor the IPV6_REACHCONF from any application + there is a possibility that, when there is an unreachability + situation, one application can cause a denial of service attack on + anogther application running on the same node by periodically issuing + sendmsg() with an IPV6_REACHCONF ancillary data item to prevent the + Neighbor Unreachability Detection algoritm to send probe messages and + declare the neighbor unreachable. It is unclear whether + implementations need to mitigate this very minor threat by e.g. + restricting IPV6_REACHCONF to priviledged applications. + + +12. Ordering of Ancillary Data and IPv6 Extension Headers + + Three IPv6 extension headers can be specified by the application and + returned to the application using ancillary data with sendmsg() and + recvmsg(): the Routing header, Hop-by-Hop options, and Destination + options. When multiple ancillary data objects are transferred via + recvmsg() and these objects represent any of these three extension + headers, their placement in the control buffer is directly tied to + their location in the corresponding IPv6 datagram. This API imposes + some ordering constraints for using these ancillary data objects with + sendmsg(). + + All Hop-by-Hop options must be specified in a single ancillary data + object. Should multiple hop-by-hop ancillary data objects be + specified the implementation might choose an arbitrary one or drop + the packet. + + All Destination options that precede a Routing header must be + specified in a single ancillary data object. If there is no Routing + header ancillary data object the IPV6_RTHDRDSTOPTS object will be + silently ignored. + + All Destination options that follow a Routing header (or are used + without a Routing header) must be specified in a single ancillary + data object. + + If Destination options are specified in the control buffer after a + Routing header, or if Destination options are specified without a + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 45] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + Routing header, the kernel will place those Destination options after + an authentication header and/or an encapsulating security payload + header, if present. + + +13. IPv6-Specific Options with IPv4-Mapped IPv6 Addresses + + The various socket options and ancillary data specifications defined + in this document apply only to true IPv6 sockets. It is possible to + create an IPv6 socket that actually sends and receives IPv4 packets, + using IPv4-mapped IPv6 addresses, but the mapping of the options + defined in this document to an IPv4 datagram is beyond the scope of + this document. + + In general, attempting to specify an IPv6-only option, such as the + Hop-by-Hop options, Destination options, or Routing header on an IPv6 + socket that is using IPv4-mapped IPv6 addresses, will probably result + in an error. Some implementations, however, may provide access to + the packet information (source/destination address, send/receive + interface, and hop limit) on an IPv6 socket that is using IPv4-mapped + IPv6 addresses. + + +14. Extended interfaces for rresvport, rcmd and rexec + + TBD + + +14.1. rresvport_af + + The rresvport() function is used by the rcmd() function, and this + function is in turn called by many of the "r" commands such as + rlogin. While new applications are not being written to use the + rcmd() function, legacy applications such as rlogin will continue to + use it and these will be ported to IPv6. + + rresvport() creates an IPv4/TCP socket and binds a "reserved port" to + the socket. Instead of defining an IPv6 version of this function we + define a new function that takes an address family as its argument. + + #include + + int rresvport_af(int *port, int family); + + This function behaves the same as the existing rresvport() function, + but instead of creating an AF_INET TCP socket, it can also create an + AF_INET6 TCP socket. The family argument is either AF_INET or + AF_INET6, and a new error return is EAFNOSUPPORT if the address + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 46] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + family is not supported. + + (Note: There is little consensus on which header defines the + rresvport() and rcmd() function prototypes. 4.4BSD defines it in + , others in , and others don't define the function + prototypes at all.) + + +14.2. rcmd_af + + The existing rcmd() function can not transparently use AF_INET6 + sockets since the an application would not be prepared to handle + AF_INET6 addresses returned by e.g. getpeername on the file + descriptor created by rcmd. Thus a new function is needed. + + int rcmd_af(char **ahost, unsigned short rport, const char *locuser, + const char *remuser, const char *cmd, int *fd2p, int af) + + This function behaves the same as the existing rcmd() function, but + instead of creating an AF_INET TCP socket, it can also create an + AF_INET6 TCP socket. The family argument is either AF_INET or + AF_INET6, and a new error return is EAFNOSUPPORT if the address + family is not supported. + + +14.3. rexec_af + + The existing rexec() function can not transparently use AF_INET6 + sockets since the an application would not be prepared to handle + AF_INET6 addresses returned by e.g. getpeername on the file + descriptor created by rexec. Thus a new function is needed. + + int rexec_af(char **ahost, unsigned short rport, const char *name, + const char *pass, const char *cmd, int *fd2p, int af) + + This function behaves the same as the existing rexec() function, but + instead of creating an AF_INET TCP socket, it can also create an + AF_INET6 TCP socket. The family argument is either AF_INET or + AF_INET6, and a new error return is EAFNOSUPPORT if the address + family is not supported. + + +15. Summary of New Definitions + + The following list summarizes the constants and structure, + definitions discussed in this memo, sorted by header. + + ICMP6_DST_UNREACH + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 47] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + ICMP6_DST_UNREACH_ADDR + ICMP6_DST_UNREACH_ADMIN + ICMP6_DST_UNREACH_BEYONDSCOPE + ICMP6_DST_UNREACH_NOPORT + ICMP6_DST_UNREACH_NOROUTE + ICMP6_ECHO_REPLY + ICMP6_ECHO_REQUEST + ICMP6_INFOMSG_MASK + ICMP6_PACKET_TOO_BIG + ICMP6_PARAMPROB_HEADER + ICMP6_PARAMPROB_NEXTHEADER + ICMP6_PARAMPROB_OPTION + ICMP6_PARAM_PROB + ICMP6_ROUTER_RENUMBERING + ICMP6_RR_FLAGS_FORCEAPPLY + ICMP6_RR_FLAGS_PREVDONE + ICMP6_RR_FLAGS_REQRESULT + ICMP6_RR_FLAGS_SPECSITE + ICMP6_RR_FLAGS_TEST + ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME + ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME + ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME + ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME + ICMP6_RR_PCOUSE_RAFLAGS_AUTO + ICMP6_RR_PCOUSE_RAFLAGS_ONLINK + ICMP6_RR_RESULT_FLAGS_FORBIDDEN + ICMP6_RR_RESULT_FLAGS_FORBIDDEN + ICMP6_RR_RESULT_FLAGS_OOB + ICMP6_RR_RESULT_FLAGS_OOB + ICMP6_TIME_EXCEEDED + ICMP6_TIME_EXCEED_REASSEMBLY + ICMP6_TIME_EXCEED_TRANSIT + MLD_LISTENER_QUERY + MLD_LISTENER_REDUCTION + MLD_LISTENER_REPORT + ND_NA_FLAG_OVERRIDE + ND_NA_FLAG_ROUTER + ND_NA_FLAG_SOLICITED + ND_NEIGHBOR_ADVERT + ND_NEIGHBOR_SOLICIT + ND_OPT_MTU + ND_OPT_PI_FLAG_AUTO + ND_OPT_PI_FLAG_ONLINK + ND_OPT_PI_FLAG_ROUTER + ND_OPT_PI_FLAG_SITEPREF + ND_OPT_PREFIX_INFORMATION + ND_OPT_REDIRECTED_HEADER + ND_OPT_SOURCE_LINKADDR + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 48] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + ND_OPT_TARGET_LINKADDR + ND_RA_FLAG_HOME_AGENT + ND_RA_FLAG_MANAGED + ND_RA_FLAG_OTHER + ND_REDIRECT + ND_ROUTER_ADVERT + ND_ROUTER_SOLICIT + + struct icmp6_filter{}; + struct icmp6_hdr{}; + struct icmp6_router_renum{}; + struct mld_hdr{}; + struct nd_neighbor_advert{}; + struct nd_neighbor_solicit{}; + struct nd_opt_hdr{}; + struct nd_opt_mtu{}; + struct nd_opt_prefix_info{}; + struct nd_opt_rd_hdr{}; + struct nd_redirect{}; + struct nd_router_advert{}; + struct nd_router_solicit{}; + struct rr_pco_match{}; + struct rr_pco_use{}; + struct rr_result{}; + + IPPROTO_AH + IPPROTO_DSTOPTS + IPPROTO_ESP + IPPROTO_FRAGMENT + IPPROTO_HOPOPTS + IPPROTO_ICMPV6 + IPPROTO_IPV6 + IPPROTO_NONE + IPPROTO_ROUTING + IPV6_CHECKSUM + IPV6_DSTOPTS + IPV6_HOPLIMIT + IPV6_HOPOPTS + IPV6_NEXTHOP + IPV6_PATHMTU + IPV6_PKTINFO + IPV6_RECVDSTOPTS + IPV6_RECVHOPLIMIT + IPV6_RECVHOPOPTS + IPV6_RECVPKTINFO + IPV6_RECVRTHDR + IPV6_RECVRTHDRDSTOPTS + IPV6_RTHDR + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 49] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + IPV6_RTHDRDSTOPTS + IPV6_RTHDR_TYPE_0 + IPV6_RECVPATHMTU + IPV6_REACHCONF + IPV6_USE_MIN_MTU + struct in6_pktinfo{}; + + IP6F_MORE_FRAG + IP6F_OFF_MASK + IP6F_RESERVED_MASK + IP6OPT_BINDING_ACK + IP6OPT_BINDING_REQ + IP6OPT_BINDING_UPDATE + IP6OPT_EID + IP6OPT_HOME_ADDRESS + IP6OPT_JUMBO + IP6OPT_JUMBO_LEN + IP6OPT_MUTABLE + IP6OPT_NSAP_ADDR + IP6OPT_PAD1 + IP6OPT_PADN + IP6OPT_ROUTER_ALERT + IP6OPT_TUNNEL_LIMIT + IP6OPT_TYPE_DISCARD + IP6OPT_TYPE_FORCEICMP + IP6OPT_TYPE_ICMP + IP6OPT_TYPE_SKIP + IP6_ALERT_AN + IP6_ALERT_AN + IP6_ALERT_MLD + IP6_ALERT_MLD + IP6_ALERT_RSVP + IP6_ALERT_RSVP + IP6_BUF_ACK + IP6_BUF_COA + IP6_BUF_HOME + IP6_BUF_ROUTER + struct ip6_dest{}; + struct ip6_ext{}; + struct ip6_frag{}; + struct ip6_hbh{}; + struct ip6_hdr{}; + struct ip6_opt{}; + struct ip6_opt_binding_ack{}; + struct ip6_opt_binding_request{}; + struct ip6_opt_binding_update{}; + struct ip6_opt_home_address{}; + struct ip6_opt_jumbo{}; + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 50] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + struct ip6_opt_nsap{}; + struct ip6_opt_router{}; + struct ip6_opt_tunnel{}; + struct ip6_rthdr{}; + struct ip6_rthdr0{}; + + + The following list summarizes the function and macro prototypes + discussed in this memo, sorted by header. + + void ICMP6_FILTER_SETBLOCK(int, struct icmp6_filter *); + void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *); + void ICMP6_FILTER_SETPASS(int, struct icmp6_filter *); + void ICMP6_FILTER_SETPASSALL(struct icmp6_filter *); + int ICMP6_FILTER_WILLBLOCK(int, + const struct icmp6_filter *); + int ICMP6_FILTER_WILLPASS(int, + const struct icmp6_filter *); + + int IN6_ARE_ADDR_EQUAL(const struct in6_addr *, + const struct in6_addr *); + + int inet6_opt_append(void *, size_t, int, + uint8_t, size_t, uint_t, void **); + int inet6_opt_get_val(void *, size_t, void *, int); + int inet6_opt_find(void *, size_t, int, uint8_t , + size_t *, void **); + int inet6_opt_finish(void *, size_t, int); + int inet6_opt_init(void *, size_t); + int inet6_opt_next(void *, size_t, int, uint8_t *, + size_t *, void **); + int inet6_opt_set_val(void *, size_t, void *, int); + + int inet6_rth_add(void *, + const struct in6_addr *); + struct in6_addr inet6_rth_getaddr(const void *, + int); + void *inet6_rth_init(void *, int, int, int); + int inet6_rth_reverse(const void *, void *); + int inet6_rth_segments(const void *); + size_t inet6_rth_space(int, int); + + int IP6OPT_TYPE(uint8_t); + + unsigned int CMSG_LEN(unsigned int); + unsigned int CMSG_SPACE(unsigned int); + + int rresvport_af(int *, int); + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 51] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + int rcmd_af(char **, unsigned short, const char *, + const char *, const char *, int *, int); + int rexec_af(char **, unsigned short , const char *, + const char *, const char *, int *, int); + + + +16. Security Considerations + + The setting of certain Hop-by-Hop options and Destination options may + be restricted to privileged processes. Similarly some Hop-by-Hop + options and Destination options may not be returned to nonprivileged + applications. + + The ability to specify an arbitrary source address using IPV6_PKTINFO + must be prevented; at least for non-privileged processes. + + +17. Change History + + Changes from RFC 2292: + + - Removed the IPV6_PKTOPTIONS socket option by allowing sticky + options to be set with individual setsockopt calls. This + simplifies the protocol stack implementation by not having to + handle options within options and also clarifies the failure + semantics when some option is incorrectly formatted. + + - Added the IPV6_RTHDRDSTOPTS for a Destination header before the + Routing header. This is necessary to allow setting these + Destination headers without IPV6_PKTOPTIONS. + + - Removed the ability to be able to specify Hop-by-Hop and + Destination options using multiple ancillary data items. The + application, using the inet6_option_*() routines, is responsible + for formatting the whole extension header. This removes the need + for the protocol stack to somehow guess the alignment + restrictions on options when concatenating them together. + + - Added separate IPV6_RECVxxx options to enable the receipt of the + corresponding ancillary data items. This makes the API cleaner + since it allows the application to retrieve with getsockopt the + sticky options it has set with setsockopt. + + - Clarified how sticky options are turned off. + + - Clarified how and when TCP returns ancillary data. + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 52] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + - Removed the support for the loose/strict Routing header since + that has been removed from the IPv6 specification. + + - Modified the inet6_rthdr_XXX() functions to not assume a cmsghdr + structure in order to work with both sticky options and ancillary + data. Renamed the functions to inet6_rth_XXX() to allow + implementations to provide both the old and new functions. + + - Modified the inet6_option_XXX() functions to not assume a cmsghdr + structure in order to work with both sticky options and ancillary + data. Renamed the functions to inet6_opt_XXX() to allow + implementations to provide both the old and new functions. + + - The new inet6_opt_XXX() functions were made different that the + old as to not require structure declarations but instead use + functions to add the individual fields to the option. + + - Changed inet6_rthdr_getaddr() to operate on index O through N-1 + (used to be 1 through N). + + - Changed the comments in the struct ip6_hdr from "priority" to + "traffic class". + + - Clarified the alignment issues involving ancillary data to allow + for separate alignment of cmsghdr structures and the data. Made + CMSG_SPACE() return an upper bound on the needed space. + + - Added rcmd_af() and rexec_af(). + + Changes since -00: + + - Changed ICMP unreachable code 2 name to be "beyond scope of + source address". + + - Added motivation for rcmd_af() and rexec_af(). + + - Added option definitions (IP6OPT_PAD1 etc) to ip6.h. + + - Added MLD and router renumbering definitions to icmp6.h + + - Removed ip6r0_addr field - replaced by a comment. + + - Made the content of IPV6_RTHDR, IPV6_HOPOPTS etc be specified as + the extension header format (struct ip6_rthdr etc) instead of the + previous "implementation dependent". + + - Removed attempt at RFC 2292 compatibility. + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 53] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + - Excluded pad options from inet6_opt_next(). + + - Added IPV6_USE_MIN_MTU socket option for applications to avoid + fragmentation by sending at the minimum IPv6 MTU. + + - Added MTU notification so that UDP and raw socket applications + can participate in path MTU discovery. + + - Added Reachability confirmation for UDP and raw socket + applications. + + - Clarified that if the application asks for e.g., IPV6_RTHDR and a + received datagram does not contain a Routing header an + implementation will exclude the IPV6_RTHDR ancillary data item. + + - Removed the constraints for jumbo option. + + - Moved the new CMSG macros and changes from the appendix. + + - Add text about inet6_opt_ depending on 2260 appendix B formatting + rules i.e. largest field last in the option. + + - Specified that getsockopt() of a sticky option returns what was + set with setsockopt(). + + - Updated the summary of new definitions to make it current. + + Changes since -01: + + - Added a note about the minor threat for DoS attacks using + IPV6_REACHCONF + + - Clarified checksum and other receive side verification for RAW + ICMP sockets. + + - Editorial clarifications. + + + +18. TODO and Open Issues + + Items left to do: + + - Add macros for ip6_hdr to access the traffic class and flow label + fields. + + - Should we remove the 1, 2, 4, 8 byte restriction for + inet6_opt_set_val and inet6_opt_get_val? Option values can be + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 54] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + any size even though there alignment must be a power of two. + Issue of how natural alignment is defined for sizes that are not + a power of two. + + - Perhaps we should add a note to point out that robust receivers + should verify alignment before calling inet6_opt_get_val(). Or + require that inet6_opt_get_val() should check the alignment and + fail by returning -1? + + - Should we change IPV6_USE_MIN_MTU to IPV6_USEMTU taking a + uint32_t Should we add IPV6_DONTFRAG option for traceroute?? + + - Add credits for UDP MTU stuff + + - Move information about mapping from inet6_opt to setsockopt and + cmsg. + + - Clarify IPV6_RTHDRDSTOPTS's interaction with IPV6_RTHDR. + + - Make the new inet6_opt_set_val() and inet6_opt_get_val() check + the length of the data item. + + - Add sending and receiving sections for routing header text just + like destination options? + + - Include sample implementation of inet6_opt_XXX. + + - Fix Authors address wrt Rich. + + Open issues: + + - Add ICMP name lookups definitions? + + - Add site-prefixes definitions? + + - Add flow label allocation API as requested in draft-berson-rsvp- + ipv6-fl-00.txt? Draft has expired! + + - Anything special for mobility options? Restrict setting at API? + Filter out on receipt? If received what does the home address + option contain? + + - Specify "change" for TCP especially when there are multiple HBH + option headers etc. + + - Specify binding to scope-id => implies filtering of addresses + with that scope if the address you are bound to is link-local + etc. What about conflicts with bound scope-id and sendto/connect + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 55] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + scope-id? + + - Specify order for ifindex selection. Put in separate section. + Different cases for sending to link-local (scope_id including + nexthop scope_id) and global. Is multicast different? + + - bind() and sin6_scope_id. Should have been in Basic API. Error + checks when bind/sendto sin6_scope_id does not match? + + - Specify notion of default multicast interface? In Basic API? + + - What about site names and site ids? Need for interfaces to map? + Requires that site-prefixes pass name - does name need to use DNS + format to handle character sets? + + - If the home address option passed out in IPV6_RECVDSTOPTS? If so + what address value does it contain? + + +19. References + + + [RFC-2460] Deering, S., Hinden, R., "Internet Protocol, Version 6 + (IPv6), Specification", RFC 2460, Dec. 1998. + + [RFC-2553] Gilligan, R. E., Thomson, S., Bound, J., Stevens, W., + "Basic Socket Interface Extensions for IPv6", RFC 2553, + March 1999. + + [RFC-1981] McCann, J., Deering, S., Mogul, J, "Path MTU Discovery + for IP version 6", RFC 1981, Aug. 1996. + + [RFC-2461] Narten, T., Nordmark, E., Simpson, W., "Neighbor + Discovery for IP Version 6 (IPv6)", RFC 2461, Dec. 1998. + + +20. Acknowledgments + + Matt Thomas and Jim Bound have been working on the technical details + in this draft for over a year. Keith Sklower is the original + implementor of ancillary data in the BSD networking code. Craig Metz + provided lots of feedback, suggestions, and comments based on his + implementing many of these features as the document was being + written. + + The following provided comments on earlier drafts: Pascal Anelli, + Hamid Asayesh, Ran Atkinson, Karl Auerbach, Hamid Asayesh, Jim Bound, + Don Coolidge, Matt Crawford, Sam T. Denton, Richard Draves, Francis + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 56] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + Dupont, Bob Gilligan, Jun-ichiro Hagino, Gerri Harter, Tim Hartrick, + Bob Halley, Masaki Hirabaru, Yoshinobu Inoue, Mukesh Kacker, A. N. + Kuznetsov, Sam Manthorpe, Pedro Marques, Jack McCann, der Mouse, John + Moy, Thomas Narten, Steve Parker, Charles Perkins, Ken Powell, Tom + Pusateri, Pedro Roque, Sameer Shah, Peter Sjodin, Stephen P. + Spackman, Jinmei Tatuya, Karen Tracey, Sowmini Varadhan, Quaizar + Vohra, Carl Williams, Steve Wise, Eric Wong, Farrell Woods, Kazu + Yamamoto, and Vlad Yasevich. + + +21. Authors' Addresses + + W. Richard Stevens + 1202 E. Paseo del Zorro + Tucson, AZ 85718 + Email: rstevens@kohala.com + + + Matt Thomas + 3am Software Foundry + 8053 Park Villa Circle + Cupertino, CA 95014 + Email: matt@3am-software.com + + + Erik Nordmark + Sun Microsystems, Inc. + 901 San Antonio Road + Palo Alto, CA 94303, USA + Email: erik.nordmark@eng.sun.com + + + +22. Appendix A: Ancillary Data Overview + + 4.2BSD allowed file descriptors to be transferred between separate + processes across a UNIX domain socket using the sendmsg() and + recvmsg() functions. Two members of the msghdr structure, + msg_accrights and msg_accrightslen, were used to send and receive the + descriptors. When the OSI protocols were added to 4.3BSD Reno in + 1990 the names of these two fields in the msghdr structure were + changed to msg_control and msg_controllen, because they were used by + the OSI protocols for "control information", although the comments in + the source code call this "ancillary data". + + Other than the OSI protocols, the use of ancillary data has been + rare. In 4.4BSD, for example, the only use of ancillary data with + IPv4 is to return the destination address of a received UDP datagram + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 57] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + if the IP_RECVDSTADDR socket option is set. With Unix domain sockets + ancillary data is still used to send and receive descriptors. + + Nevertheless the ancillary data fields of the msghdr structure + provide a clean way to pass information in addition to the data that + is being read or written. The inclusion of the msg_control and + msg_controllen members of the msghdr structure along with the cmsghdr + structure that is pointed to by the msg_control member is required by + the Posix.1g sockets API standard. + + + +22.1. The msghdr Structure + + The msghdr structure is used by the recvmsg() and sendmsg() + functions. Its Posix.1g definition is: + + struct msghdr { + void *msg_name; /* ptr to socket address structure */ + socklen_t msg_namelen; /* size of socket address structure */ + struct iovec *msg_iov; /* scatter/gather array */ + size_t msg_iovlen; /* # elements in msg_iov */ + void *msg_control; /* ancillary data */ + socklen_t msg_controllen; /* ancillary data buffer length */ + int msg_flags; /* flags on received message */ + }; + + The structure is declared as a result of including . + + (Note: Before Posix.1g the two "void *" pointers were typically "char + *", and the two socklen_t members and the size_t member were + typically integers. Earlier drafts of Posix.1g had the two socklen_t + members as size_t, but Draft 6.6 of Posix.1g, apparently the final + draft, changed these to socklen_t to simplify binary portability for + 64-bit implementations and to align Posix.1g with X/Open's Networking + Services, Issue 5. The change in msg_control to a "void *" pointer + affects any code that increments this pointer.) + + (Note: Before Posix.1g the cmsg_len member was an integer, and not a + socklen_t. See the Note in the previous section for why socklen_t is + used here.) + + Most Berkeley-derived implementations limit the amount of ancillary + data in a call to sendmsg() to no more than 108 bytes (an mbuf). + This API requires a minimum of 10240 bytes of ancillary data, but it + is recommended that the amount be limited only by the buffer space + reserved by the socket (which can be modified by the SO_SNDBUF socket + option). (Note: This magic number 10240 was picked as a value that + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 58] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + should always be large enough. 108 bytes is clearly too small as the + maximum size of a Routing header is 2048 bytes.) + + +22.2. The cmsghdr Structure + + The cmsghdr structure describes ancillary data objects transferred by + recvmsg() and sendmsg(). Its Posix.1g definition is: + + struct cmsghdr { + socklen_t cmsg_len; /* #bytes, including this header */ + int cmsg_level; /* originating protocol */ + int cmsg_type; /* protocol-specific type */ + /* followed by unsigned char cmsg_data[]; */ + }; + + This structure is declared as a result of including . + + As shown in this definition, normally there is no member with the + name cmsg_data[]. Instead, the data portion is accessed using the + CMSG_xxx() macros, as described in Section 22.3. Nevertheless, it is + common to refer to the cmsg_data[] member. + + When ancillary data is sent or received, any number of ancillary data + objects can be specified by the msg_control and msg_controllen + members of the msghdr structure, because each object is preceded by a + cmsghdr structure defining the object's length (the cmsg_len member). + Historically Berkeley-derived implementations have passed only one + object at a time, but this API allows multiple objects to be passed + in a single call to sendmsg() or recvmsg(). The following example + shows two ancillary data objects in a control buffer. + + + + + + + + + + + + + + + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 59] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + + |<--------------------------- msg_controllen -------------------------->| + | OR | + |<--------------------------- msg_controllen ----------------------->| + | | + |<----- ancillary data object ----->|<----- ancillary data object ----->| + |<------ min CMSG_SPACE() --------->|<------ min CMSG_SPACE() --------->| + | | | + |<---------- cmsg_len ---------->| |<--------- cmsg_len ----------->| | + |<--------- CMSG_LEN() --------->| |<-------- CMSG_LEN() ---------->| | + | | | | | + +-----+-----+-----+--+-----------+--+-----+-----+-----+--+-----------+--+ + |cmsg_|cmsg_|cmsg_|XX| |XX|cmsg_|cmsg_|cmsg_|XX| |XX| + |len |level|type |XX|cmsg_data[]|XX|len |level|type |XX|cmsg_data[]|XX| + +-----+-----+-----+--+-----------+--+-----+-----+-----+--+-----------+--+ + ^ + | + msg_control + points here + + + The fields shown as "XX" are possible padding, between the cmsghdr + structure and the data, and between the data and the next cmsghdr + structure, if required by the implementation. While sending an + application may or may not include padding at the end of last + ancillary data in msg_controllen and implementations must accept both + as valid. On receiving a portable application must provide space for + padding at the end of the last ancillary data as implementations may + copy out the padding at the end of the control message buffer and + include it in the received msg_controllen. When recvmsg() is called + if msg_controllen is too small for all the ancillary data items + including any trailing padding after the last item an implementation + may set MSG_CTRUNC. + + +22.3. Ancillary Data Object Macros + + To aid in the manipulation of ancillary data objects, three macros + from 4.4BSD are defined by Posix.1g: CMSG_DATA(), CMSG_NXTHDR(), and + CMSG_FIRSTHDR(). Before describing these macros, we show the + following example of how they might be used with a call to recvmsg(). + + + + + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 60] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + + struct msghdr msg; + struct cmsghdr *cmsgptr; + + /* fill in msg */ + + /* call recvmsg() */ + + for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; + cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { + if (cmsgptr->cmsg_len == 0) { + /* Error handling */ + break; + } + if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) { + u_char *ptr; + + ptr = CMSG_DATA(cmsgptr); + /* process data pointed to by ptr */ + } + } + + We now describe the three Posix.1g macros, followed by two more that + are new with this API: CMSG_SPACE() and CMSG_LEN(). All these + macros are defined as a result of including . + + +22.3.1. CMSG_FIRSTHDR + + + struct cmsghdr *CMSG_FIRSTHDR(const struct msghdr *mhdr); + + CMSG_FIRSTHDR() returns a pointer to the first cmsghdr structure in + the msghdr structure pointed to by mhdr. The macro returns NULL if + there is no ancillary data pointed to by the msghdr structure (that + is, if either msg_control is NULL or if msg_controllen is less than + the size of a cmsghdr structure). + + One possible implementation could be + + #define CMSG_FIRSTHDR(mhdr) \ + ( (mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \ + (struct cmsghdr *)(mhdr)->msg_control : \ + (struct cmsghdr *)NULL ) + + (Note: Most existing implementations do not test the value of + msg_controllen, and just return the value of msg_control. The value + of msg_controllen must be tested, because if the application asks + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 61] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + recvmsg() to return ancillary data, by setting msg_control to point + to the application's buffer and setting msg_controllen to the length + of this buffer, the kernel indicates that no ancillary data is + available by setting msg_controllen to 0 on return. It is also + easier to put this test into this macro, than making the application + perform the test.) + + +22.3.2. CMSG_NXTHDR + + + struct cmsghdr *CMSG_NXTHDR(const struct msghdr *mhdr, + const struct cmsghdr *cmsg); + + CMSG_NXTHDR() returns a pointer to the cmsghdr structure describing + the next ancillary data object. mhdr is a pointer to a msghdr + structure and cmsg is a pointer to a cmsghdr structure. If there is + not another ancillary data object, the return value is NULL. + + The following behavior of this macro is new to this API: if the + value of the cmsg pointer is NULL, a pointer to the cmsghdr structure + describing the first ancillary data object is returned. That is, + CMSG_NXTHDR(mhdr, NULL) is equivalent to CMSG_FIRSTHDR(mhdr). If + there are no ancillary data objects, the return value is NULL. This + provides an alternative way of coding the processing loop shown + earlier: + + struct msghdr msg; + struct cmsghdr *cmsgptr = NULL; + + /* fill in msg */ + + /* call recvmsg() */ + + while ((cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) != NULL) { + if (cmsgptr->cmsg_len == 0) { + /* Error handling */ + break; + } + if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) { + u_char *ptr; + + ptr = CMSG_DATA(cmsgptr); + /* process data pointed to by ptr */ + } + } + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 62] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + One possible implementation could be: + + #define CMSG_NXTHDR(mhdr, cmsg) \ + (((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \ + (((u_char *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) \ + + ALIGN_D(sizeof(struct cmsghdr)) > \ + (u_char *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \ + (struct cmsghdr *)NULL : \ + (struct cmsghdr *)((u_char *)(cmsg) + ALIGN_H((cmsg)->cmsg_len)))) + + The macros ALIGN_H() and ALIGN_D(), which are implementation + dependent, round their arguments up to the next even multiple of + whatever alignment is required for the start of the cmsghdr structure + and the data, respectively. (This is probably a multiple of 4 or 8 + bytes.) They are often the same macro in implementations platforms + where alignment requirement for header and data is chosen to be + identical. + + +22.3.3. CMSG_DATA + + + unsigned char *CMSG_DATA(const struct cmsghdr *cmsg); + + CMSG_DATA() returns a pointer to the data (what is called the + cmsg_data[] member, even though such a member is not defined in the + structure) following a cmsghdr structure. + + One possible implementation could be: + + #define CMSG_DATA(cmsg) ( (u_char *)(cmsg) + \ + ALIGN_D(sizeof(struct cmsghdr)) ) + + + +22.3.4. CMSG_SPACE + + + unsigned int CMSG_SPACE(unsigned int length); + + This macro is new with this API. Given the length of an ancillary + data object, CMSG_SPACE() returns an upper bound on the space + required by the object and its cmsghdr structure, including any + padding needed to satisfy alignment requirements. This macro can be + used, for example, when allocating space dynamically for the + ancillary data. This macro should not be used to initialize the + cmsg_len member of a cmsghdr structure; instead use the CMSG_LEN() + macro. + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 63] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + One possible implementation could be: + + #define CMSG_SPACE(length) ( ALIGN_D(sizeof(struct cmsghdr)) + \ + ALIGN_H(length) ) + + + +22.3.5. CMSG_LEN + + + unsigned int CMSG_LEN(unsigned int length); + + This macro is new with this API. Given the length of an ancillary + data object, CMSG_LEN() returns the value to store in the cmsg_len + member of the cmsghdr structure, taking into account any padding + needed to satisfy alignment requirements. + + One possible implementation could be: + + #define CMSG_LEN(length) ( ALIGN_D(sizeof(struct cmsghdr)) + length ) + + Note the difference between CMSG_SPACE() and CMSG_LEN(), shown also + in the figure in Section 4.2: the former accounts for any required + padding at the end of the ancillary data object and the latter is the + actual length to store in the cmsg_len member of the ancillary data + object. + + +23. Appendix B: Examples using the inet6_rth_XXX() functions + + Here we show an example for both sending Routing headers and + processing and reversing a received Routing header. + + +23.1. Sending a Routing Header + + As an example of these Routing header functions defined in this + document, we go through the function calls for the example on p. 17 + of [RFC-2460]. The source is S, the destination is D, and the three + intermediate nodes are I1, I2, and I3. + + + + + + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 64] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + + S -----> I1 -----> I2 -----> I3 -----> D + + src: * S S S S S + dst: D I1 I2 I3 D D + A[1]: I1 I2 I1 I1 I1 I1 + A[2]: I2 I3 I3 I2 I2 I2 + A[3]: I3 D D D I3 I3 + #seg: 3 3 2 1 0 3 + + src and dst are the source and destination IPv6 addresses in the IPv6 + header. A[1], A[2], and A[3] are the three addresses in the Routing + header. #seg is the Segments Left field in the Routing header. + + The six values in the column beneath node S are the values in the + Routing header specified by the sending application using sendmsg() + of setsockopt(). The function calls by the sender would look like: + + void *extptr; + int extlen; + struct msghdr msg; + struct cmsghdr *cmsgptr; + int cmsglen; + struct sockaddr_in6 I1, I2, I3, D; + + extlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, 3); + cmsglen = CMSG_SPACE(extlen); + cmsgptr = malloc(cmsglen); + cmsgptr->cmsg_len = CMSG_LEN(extlen); + cmsgptr->cmsg_level = IPPROTO_IPV6; + cmsgptr->cmsg_type = IPV6_RTHDR; + + extptr = CMSG_DATA(cmsgptr); + extptr = inet6_rth_init(extptr, extlen, IPV6_RTHDR_TYPE_0, 3); + + inet6_rth_add(extptr, &I1.sin6_addr); + inet6_rth_add(extptr, &I2.sin6_addr); + inet6_rth_add(extptr, &I3.sin6_addr); + + msg.msg_control = cmsgptr; + msg.msg_controllen = cmsglen; + + /* finish filling in msg{}, msg_name = D */ + /* call sendmsg() */ + + We also assume that the source address for the socket is not + specified (i.e., the asterisk in the figure). + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 65] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + The four columns of six values that are then shown between the five + nodes are the values of the fields in the packet while the packet is + in transit between the two nodes. Notice that before the packet is + sent by the source node S, the source address is chosen (replacing + the asterisk), I1 becomes the destination address of the datagram, + the two addresses A[2] and A[3] are "shifted up", and D is moved to + A[3]. + + The columns of values that are shown beneath the destination node are + the values returned by recvmsg(), assuming the application has + enabled both the IPV6_RECVPKTINFO and IPV6_RECVRTHDR socket options. + The source address is S (contained in the sockaddr_in6 structure + pointed to by the msg_name member), the destination address is D + (returned as an ancillary data object in an in6_pktinfo structure), + and the ancillary data object specifying the Routing header will + contain three addresses (I1, I2, and I3). The number of segments in + the Routing header is known from the Hdr Ext Len field in the Routing + header (a value of 6, indicating 3 addresses). + + The return value from inet6_rth_segments() will be 3 and + inet6_rth_getaddr(0) will return I1, inet6_rth_getaddr(1) will return + I2, and inet6_rth_getaddr(2) will return I3, + + If the receiving application then calls inet6_rth_reverse(), the + order of the three addresses will become I3, I2, and I1. + + We can also show what an implementation might store in the ancillary + data object as the Routing header is being built by the sending + process. If we assume a 32-bit architecture where sizeof(struct + cmsghdr) equals 12, with a desired alignment of 4-byte boundaries, + then the call to inet6_rth_space(3) returns 68: 12 bytes for the + cmsghdr structure and 56 bytes for the Routing header (8 + 3*16). + + The call to inet6_rth_init() initializes the ancillary data object to + contain a Type 0 Routing header: + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_len = 20 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_level = IPPROTO_IPV6 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_type = IPV6_RTHDR | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next Header | Hdr Ext Len=6 | Routing Type=0| Seg Left=0 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 66] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + The first call to inet6_rth_add() adds I1 to the list. + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_len = 36 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_level = IPPROTO_IPV6 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_type = IPV6_RTHDR | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next Header | Hdr Ext Len=6 | Routing Type=0| Seg Left=1 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Address[1] = I1 + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + cmsg_len is incremented by 16, and the Segments Left field is + incremented by 1. + + The next call to inet6_rth_add() adds I2 to the list. + + + + + + + + + + + + + + + + + + + + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 67] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_len = 52 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_level = IPPROTO_IPV6 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_type = IPV6_RTHDR | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next Header | Hdr Ext Len=6 | Routing Type=0| Seg Left=2 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Address[1] = I1 + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Address[2] = I2 + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + cmsg_len is incremented by 16, and the Segments Left field is + incremented by 1. + + The last call to inet6_rth_add() adds I3 to the list. + + + + + + + + + + + + + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 68] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_len = 68 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_level = IPPROTO_IPV6 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | cmsg_type = IPV6_RTHDR | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next Header | Hdr Ext Len=6 | Routing Type=0| Seg Left=3 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Address[1] = I1 + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Address[2] = I2 + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Address[3] = I3 + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + cmsg_len is incremented by 16, and the Segments Left field is + incremented by 1. + + +23.2. Receiving Routing Headers + + This example assumes that the application has enabled IPV6_RECVRTHDR + socket option. The application prints and reverses a source route + and uses that to echo the received data. + + struct sockaddr_in6 addr; + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 69] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + struct msghdr msg; + struct iovec iov; + struct cmsghdr *cmsgptr; + size_t cmsgspace; + void *extptr; + int extlen; + + int segments; + int i; + char databuf[8192]; + + segments = 100; /* Enough */ + extlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, segments); + cmsgspace = CMSG_SPACE(extlen); + cmsgptr = malloc(cmsgspace); + if (cmsgptr == NULL) { + perror("malloc"); + exit(1); + } + extptr = CMSG_DATA(cmsgptr); + + msg.msg_control = (char *)cmsgptr; + msg.msg_controllen = cmsgspace; + msg.msg_name = (struct sockaddr *)&addr; + msg.msg_namelen = sizeof (addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + iov.iov_base = databuf; + iov.iov_len = sizeof (databuf); + msg.msg_flags = 0; + if (recvmsg(s, &msg, 0) == -1) { + perror("recvmsg"); + return; + } + if (msg.msg_controllen != 0 && + cmsgptr->cmsg_level == IPPROTO_IPV6 && + cmsgptr->cmsg_type == IPV6_RTHDR) { + struct in6_addr *in6; + char asciiname[INET6_ADDRSTRLEN]; + struct ip6_rthdr *rthdr; + + rthdr = (struct ip6_rthdr *)extptr; + segments = inet6_rth_segments(extptr); + printf("route (%d segments, %d left): ", + segments, rthdr->ip6r_segleft); + for (i = 0; i < segments; i++) { + in6 = inet6_rth_getaddr(extptr, i); + if (in6 == NULL) + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 70] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + printf(" "); + else + printf("%s ", inet_ntop(AF_INET6, + (void *)in6->s6_addr, + asciiname, INET6_ADDRSTRLEN)); + } + if (inet6_rth_reverse(extptr, extptr) == -1) { + printf("reverse failed"); + return; + } + } + iov.iov_base = databuf; + iov.iov_len = strlen(databuf); + if (sendmsg(s, &msg, 0) == -1) + perror("sendmsg"); + if (cmsgptr != NULL) + free(cmsgptr); + + Note: The above example is a simple illustration. It skips some + error checks involving the MSG_TRUNC and MSG_CTRUNC flags. + + +24. Appendix C: Examples using the inet6_opt_XXX() functions + + This shows how Hop-by-Hop and Destination options can be both built + as well as parsed using the inet6_opt_XXX() functions. This examples + assume that there are defined values for OPT_X and OPT_Y. + + +24.1. Building options + + We now provide an example that builds two Hop-by-Hop options using + the example in Appendix B of [RFC-2460]. + + void *extbuf; + size_t extlen; + int currentlen; + void *databuf; + size_t offset; + uint8_t value1; + uint16_t value2; + uint32_t value4; + uint64_t value8; + + /* Estimate the length */ + currentlen = inet6_opt_init(NULL, 0); + if (currentlen == -1) + return (-1); + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 71] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + currentlen = inet6_opt_append(NULL, 0, currentlen, OPT_X, 12, 8, NULL); + if (currentlen == -1) + return (-1); + currentlen = inet6_opt_append(NULL, 0, currentlen, OPT_Y, 7, 4, NULL); + if (currentlen == -1) + return (-1); + currentlen = inet6_opt_finish(NULL, 0, currentlen); + if (currentlen == -1) + return (-1); + extlen = currentlen; + + extbuf = malloc(extlen); + if (extbuf == NULL) { + perror("malloc"); + return (-1); + } + currentlen = inet6_opt_init(extbuf, extlen); + if (currentlen == -1) + return (-1); + + currentlen = inet6_opt_append(extbuf, extlen, currentlen, + OPT_X, 12, 8, &databuf); + if (currentlen == -1) + return (-1); + /* Insert value 0x12345678 for 4-octet field */ + offset = 0; + value4 = 0x12345678; + offset = inet6_opt_set_val(databuf, offset, &value4, sizeof (value4)); + /* Insert value 0x0102030405060708 for 8-octet field */ + value8 = 0x0102030405060708; + offset = inet6_opt_set_val(databuf, offset, &value8, sizeof (value8)); + + currentlen = inet6_opt_append(extbuf, extlen, currentlen, + OPT_Y, 7, 4, &databuf); + if (currentlen == -1) + return (-1); + /* Insert value 0x01 for 1-octet field */ + offset = 0; + value1 = 0x01; + offset = inet6_opt_set_val(databuf, offset, &value1, sizeof (value1)); + /* Insert value 0x1331 for 2-octet field */ + value2 = 0x1331; + offset = inet6_opt_set_val(databuf, offset, &value2, sizeof (value2)); + /* Insert value 0x01020304 for 4-octet field */ + value4 = 0x01020304; + offset = inet6_opt_set_val(databuf, offset, &value4, sizeof (value4)); + + currentlen = inet6_opt_finish(extbuf, extlen, currentlen); + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 72] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + if (currentlen == -1) + return (-1); + /* extbuf and extlen are now completely formatted */ + + + +24.2. Parsing received options + + This example parses and prints the content of the two options in the + previous example. + + int + print_opt(void *extbuf, size_t extlen) + { + struct ip6_dest *ext; + int currentlen; + uint8_t type; + size_t len; + void *databuf; + size_t offset; + uint8_t value1; + uint16_t value2; + uint32_t value4; + uint64_t value8; + + ext = (struct ip6_dest *)extbuf; + printf("nxt %u, len %u (bytes %d)\n", ext->ip6d_nxt, + ext->ip6d_len, (ext->ip6d_len + 1) * 8); + + currentlen = 0; + while (1) { + currentlen = inet6_opt_next(extbuf, extlen, currentlen, + &type, &len, &databuf); + if (currentlen == -1) + break; + printf("Received opt %u len %u\n", + type, len); + switch (type) { + case OPT_X: + offset = 0; + offset = inet6_opt_get_val(databuf, offset, + &value4, sizeof (value4)); + printf("X 4-byte field %x\n", value4); + offset = inet6_opt_get_val(databuf, offset, + &value8, sizeof (value8)); + printf("X 8-byte field %llx\n", value8); + break; + case OPT_Y: + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 73] + +INTERNET-DRAFT Advanced Sockets API for IPv6 Nov. 7, 2000 + + + offset = 0; + offset = inet6_opt_get_val(databuf, offset, + &value1, sizeof (value1)); + printf("Y 1-byte field %x\n", value1); + offset = inet6_opt_get_val(databuf, offset, + &value2, sizeof (value2)); + printf("Y 2-byte field %x\n", value2); + offset = inet6_opt_get_val(databuf, offset, + &value4, sizeof (value4)); + printf("Y 4-byte field %x\n", value4); + break; + default: + printf("Unknown option %u\n", type); + break; + } + } + return (0); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +draft-ietf-ipngwg-2292bis-02.txt [Page 74] + diff --git a/doc/draft/draft-ietf-ipngwg-rfc2553bis-03.txt b/doc/draft/draft-ietf-ipngwg-rfc2553bis-03.txt new file mode 100644 index 0000000000..aa99ffd6c8 --- /dev/null +++ b/doc/draft/draft-ietf-ipngwg-rfc2553bis-03.txt @@ -0,0 +1,2044 @@ +IPNG Working Group R.E. Gilligan +INTERNET-DRAFT: draft-ietf-ipngwg-rfc2553bis-03.txt Cache Flow +Obsoletes RFC 2553 S. Thomson + Cisco + J. Bound + Nokia Networks + W. R. Stevens + February 2001 + + + + + + + Basic Socket Interface Extensions for IPv6 + + + + +Status of this Memo + + This document is an Internet-Draft and is in full conformance with + all provisions of Section 10 of RFC2026. + + This document is a submission by the Internet Protocol IPv6 Working + Group of the Internet Engineering Task Force (IETF). Comments should + be submitted to the ipng@sunroof.eng.sun.com mailing list. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that + other groups may also distribute working documents as Internet- + Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet- Drafts as reference + material or to cite them other than as "work in progress." + + The list of current Internet-Drafts can be accessed at + http://www.ietf.org/ietf/1id-abstracts.txt + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + +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. + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 1] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +Additional extensions for advanced IPv6 features (raw sockets and access +to the IPv6 extension headers) are defined in another document [4]. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 2] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +Table of Contents: + + +1. Introduction.................................................4 +2. Design Considerations........................................4 +2.1 What Needs to be Changed....................................4 +2.2 Data Types..................................................6 +2.3 Headers.....................................................6 +2.4 Structures..................................................6 +3. Socket Interface.............................................6 +3.1 IPv6 Address Family and Protocol Family.....................6 +3.2 IPv6 Address Structure......................................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......................................10 +3.9 IPv6 Loopback Address......................................11 +3.10 Portability Additions.....................................12 +4. Interface Identification....................................14 +4.1 Name-to-Index..............................................14 +4.2 Index-to-Name..............................................15 +4.3 Return All Interface Names and Indexes.....................15 +4.4 Free Memory................................................15 +5. Socket Options..............................................16 +5.1 Unicast Hop Limit..........................................16 +5.2 Sending and Receiving Multicast Packets....................17 +5.3 IPV6_V6ONLY option for AF_INET6 Sockets....................18 +6. Library Functions...........................................19 +6.1 Protocol-Independent Nodename and Service Name Translation.19 +6.2 Socket Address Structure to Nodename and Service Name......23 +6.3 Address Conversion Functions...............................25 +6.4 Address Testing Macros.....................................26 +7. Summary of New Definitions..................................27 +8. Security Considerations.....................................28 +9. Year 2000 Considerations....................................28 +Changes made to rfc2553bis-02 to rfc2553bis-03.................29 +Changes made to rfc2553bis-01 to rfc2553bis-02.................29 +Changes made to rfc2553bis-00 to rfc2553bis-01.................29 +Changes made rfc2553 to rfc2553bis-00:.........................29 +Acknowledgments................................................30 +References.....................................................30 +Authors' Addresses.............................................31 + + + + + + + + + + + + + + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 3] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +1. Introduction + +While IPv4 addresses are 32 bits long, IPv6 interfaces are identified by +128-bit addresses. The socket interface makes the size of an IP address +quite visible to an application; virtually all TCP/IP applications for +BSD-based systems have knowledge of the size of an IP address. Those +parts of the API that expose the addresses must be changed to +accommodate the larger IPv6 address size. IPv6 also introduces new +features (e.g., traffic class and flowlabel), some of which must be made +visible to applications via the API. This memo defines a set of +extensions to the socket interface to support the larger address size +and new features of IPv6. + + + +2. Design Considerations + +There are a number of important considerations in designing changes to +this well-worn API: + + - The API changes should provide both source and binary + compatibility for programs written to the original API. That + is, existing program binaries should continue to operate when + run on a system supporting the new API. In addition, existing + applications that are re-compiled and run on a system supporting + the new API should continue to operate. Simply put, the API + changes for IPv6 should not break existing programs. An additional + mechanism for implementations to verify this is to verify the new + symbols are protected by Feature Test Macros as described in IEEE Std + 1003.1-200x. (Such Feature Test Macros are not defined by this RFC.) + + - The changes to the API should be as small as possible in order + to simplify the task of converting existing IPv4 applications to + IPv6. + + - Where possible, applications should be able to use this + API to interoperate with both IPv6 and IPv4 hosts. Applications + should not need to know which type of host they are + communicating with. + + - IPv6 addresses carried in data structures should be 64-bit + aligned. This is necessary in order to obtain optimum + performance on 64-bit machine architectures. + +Because of the importance of providing IPv4 compatibility in the API, +these extensions are explicitly designed to operate on machines that +provide complete support for both IPv4 and IPv6. A subset of this API +could probably be designed for operation on systems that support only +IPv6. However, this is not addressed in this memo. + + + +2.1 What Needs to be Changed + +The socket interface API consists of a few distinct components: + + - Core socket functions. + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 4] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + + - Address data structures. + + - Name-to-address translation functions. + + - Address conversion functions. + +The core socket functions -- those functions that deal with such things +as setting up and tearing down TCP connections, and sending and +receiving UDP packets -- were designed to be transport independent. +Where protocol addresses are passed as function arguments, they are +carried via opaque pointers. A protocol-specific address data structure +is defined for each protocol that the socket functions support. +Applications must cast pointers to these protocol-specific address +structures into pointers to the generic "sockaddr" address structure +when using the socket functions. These functions need not change for +IPv6, but a new IPv6-specific address data structure is needed. + +The "sockaddr_in" structure is the protocol-specific data structure for +IPv4. This data structure actually includes 8-octets of unused space, +and it is tempting to try to use this space to adapt the sockaddr_in +structure to IPv6. Unfortunately, the sockaddr_in structure is not +large enough to hold the 16-octet IPv6 address as well as the other +information (address family and port number) that is needed. So a new +address data structure must be defined for IPv6. + +IPv6 addresses are scoped [2] so they could be link-local, site, +organization, global, or other scopes at this time undefined. To +support applications that want to be able to identify a set of +interfaces for a specific scope, the IPv6 sockaddr_in structure must +support a field that can be used by an implementation to identify a set +of interfaces identifying the scope for an IPv6 address. + +The name-to-address translation functions in the socket interface are +gethostbyname() and gethostbyaddr(). These are left as is and new +functions are defined to support IPv4 and IPv6. The new API is based on +the IEEE Std 1003.1-200x draft [3] and specifies a new nodename-to- +address translation function which is protocol independent. This +function can also be used with IPv4 and 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 traffic class, flow label, and +hop limit header fields. New socket options are needed to control the +sending and receiving of IPv6 multicast packets. + +The socket interface will be enhanced in the future to provide access to +other IPv6 features. These extensions are described in [4]. + + + + + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 5] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +2.2 Data Types + +The data types of the structure elements given in this memo are intended +to track the relevant standards. uintN_t means an unsigned integer of +exactly N bits (e.g., uint16_t). + + + +2.3 Headers + +When function prototypes and structures are shown we show the headers +that must be #included to cause that item to be defined. + + + +2.4 Structures + +When structures are described the members shown are the ones that must +appear in an implementation. Additional, nonstandard members may also +be defined by an implementation. As an additional precaution +nonstandard members could be verified by Feature Test Macros as +described in IEEE Std 1003.1-200x. (Such Feature Test Macros are not +defined by this RFC.) + +The ordering shown for the members of a structure is the recommended +ordering, given alignment considerations of multibyte members, but an +implementation may order the members differently. + + + +3. Socket Interface + +This section specifies the socket interface changes for IPv6. + + + +3.1 IPv6 Address Family and Protocol Family + +A new address family name, AF_INET6, is defined in . 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 . +Like most of the other protocol family names, this will usually be +defined to have the same value as the corresponding address family name: + + #define PF_INET6 AF_INET6 + +The PF_INET6 is used in the first argument to the socket() function to +indicate that an IPv6 socket is being created. + + + +3.2 IPv6 Address Structure + +A new in6_addr structure holds a single IPv6 address and is defined as a +result of including : + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 6] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + + struct in6_addr { + uint8_t s6_addr[16]; /* IPv6 address */ + }; + +This data structure contains an array of sixteen 8-bit elements, which +make up one 128-bit IPv6 address. The IPv6 address is stored in network +byte order. + +The structure in6_addr above is usually implemented with an embedded +union with extra fields that force the desired alignment level in a +manner similar to BSD implementations of "struct in_addr". Those +additional implementation details are omitted here for simplicity. + +An example is as follows: + +struct in6_addr { + union { + uint8_t _S6_u8[16]; + uint32_t _S6_u32[4]; + uint64_t _S6_u64[2]; + } _S6_un; +}; +#define s6_addr _S6_un._S6_u8 + + + +3.3 Socket Address Structure for 4.3BSD-Based Systems + +In the socket interface, a different protocol-specific data structure is +defined to carry the addresses for each protocol suite. Each protocol- +specific data structure is designed so it can be cast into a protocol- +independent data structure -- the "sockaddr" structure. Each has a +"family" field that overlays the "sa_family" of the sockaddr data +structure. This field identifies the type of the data structure. + +The sockaddr_in structure is the protocol-specific address data +structure for IPv4. It is used to pass addresses between applications +and the system in the socket functions. The following sockaddr_in6 +structure holds IPv6 addresses and is defined as a result of including +the header: + + struct sockaddr_in6 { + sa_family_t sin6_family; /* AF_INET6 */ + in_port_t sin6_port; /* transport layer port # */ + uint32_t sin6_flowinfo; /* IPv6 traffic class & flow info */ + struct in6_addr sin6_addr; /* IPv6 address */ + uint32_t sin6_scope_id; /* set of interfaces for a scope */ + }; + +This structure is designed to be compatible with the sockaddr data +structure used in the 4.3BSD release. + +The sin6_family field identifies this as a sockaddr_in6 structure. This +field overlays the sa_family field when the buffer is cast to a sockaddr +data structure. The value of this field must be AF_INET6. + +The sin6_port field contains the 16-bit UDP or TCP port number. This +field is used in the same way as the sin_port field of the sockaddr_in + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 7] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +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 traffic class and the flow label. The contents and +interpretation of this member is specified in [1]. The sin6_flowinfo +field SHOULD be set to zero by an implementation prior to using the +sockaddr_in6 structure by an application on receive operations. + +The sin6_addr field is a single in6_addr structure (defined in the +previous section). This field holds one 128-bit IPv6 address. The +address is stored in network byte order. + +The ordering of elements in this structure is specifically designed so +that when sin6_addr field is aligned on a 64-bit boundary, the start of +the structure will also be aligned on a 64-bit boundary. This is done +for optimum performance on 64-bit architectures. + +The sin6_scope_id field is a 32-bit integer that identifies a set of +interfaces as appropriate for the scope of the address carried in the +sin6_addr field [2,5,6,7]. For a link scope sin6_addr, sin6_scope_id +would be an interface index. For a site scope sin6_addr, sin6_scope_id +would be a site identifier. The mapping of sin6_scope_id to an +interface or set of interfaces is left to implementation and future +specifications on the subject of site identifiers. + +Notice that the sockaddr_in6 structure will normally be larger than the +generic sockaddr structure. On many existing implementations the +sizeof(struct sockaddr_in) equals sizeof(struct sockaddr), with both +being 16 bytes. Any existing code that makes this assumption needs to +be examined carefully when converting to IPv6. + + + +3.4 Socket Address Structure for 4.4BSD-Based Systems + +The 4.4BSD release includes a small, but incompatible change to the +socket interface. The "sa_family" field of the sockaddr data structure +was changed from a 16-bit value to an 8-bit value, and the space saved +used to hold a length field, named "sa_len". The sockaddr_in6 data +structure given in the previous section cannot be correctly cast into +the newer sockaddr data structure. For this reason, the following +alternative IPv6 address data structure is provided to be used on +systems based on 4.4BSD. It is defined as a result of including the + header. + + struct sockaddr_in6 { + uint8_t sin6_len; /* length of this struct */ + sa_family_t sin6_family; /* AF_INET6 */ + in_port_t sin6_port; /* transport layer port # */ + uint32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + uint32_t sin6_scope_id; /* set of interfaces for a scope */ + }; + +The only differences between this data structure and the 4.3BSD variant +are the inclusion of the length field, and the change of the family +field to a 8-bit data type. The definitions of all the other fields are +identical to the structure defined in the previous section. + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 8] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +Systems that provide this version of the sockaddr_in6 data structure +must also declare SIN6_LEN as a result of including the +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() + +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. + + + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 9] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +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: + +These addresses can be generated automatically by the getaddrinfo() +function, when the specified host has only IPv4 addresses (as described +in Section 6.1 and 6.2). + +Applications may use PF_INET6 sockets to open TCP connections to IPv4 +nodes, or send UDP packets to IPv4 nodes, by simply encoding the +destination's IPv4 address as an IPv4-mapped IPv6 address, and passing +that address, within a sockaddr_in6 structure, in the connect() or +sendto() call. When applications use PF_INET6 sockets to accept TCP +connections from IPv4 nodes, or receive UDP packets from IPv4 nodes, the +system returns the peer's address to the application in the accept(), +recvfrom(), or getpeername() call using a sockaddr_in6 structure encoded +this way. + +Few applications will likely need to know which type of node they are +interoperating with. However, for those applications that do need to +know, the IN6_IS_ADDR_V4MAPPED() macro, defined in Section 6.7, is +provided. + + + +3.8 IPv6 Wildcard Address + +While the bind() function allows applications to select the source IP +address of UDP packets and TCP connections, applications often want the +system to select the source address for them. With IPv4, one specifies +the address as the symbolic constant INADDR_ANY (called the "wildcard" + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 10] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +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 : + + extern const struct in6_addr in6addr_any; + +Applications use in6addr_any similarly to the way they use INADDR_ANY in +IPv4. For example, to bind a socket to port number 23, but let the +system select the source address, an application could use the following +code: + + struct sockaddr_in6 sin6; + . . . + sin6.sin6_family = AF_INET6; + sin6.sin6_flowinfo = 0; + sin6.sin6_port = htons(23); + sin6.sin6_addr = in6addr_any; /* structure assignment */ + . . . + if (bind(s, (struct sockaddr *) &sin6, sizeof(sin6)) == -1) + . . . + +The other version is a symbolic constant named IN6ADDR_ANY_INIT and is +defined in . 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 + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 11] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +provided in two forms -- a global variable and a symbolic constant. + +The global variable is an in6_addr structure named "in6addr_loopback." +The extern declaration for this variable is defined in : + + 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 +. It can be used at declaration time ONLY; for example: + + struct in6_addr loopbackaddr = IN6ADDR_LOOPBACK_INIT; + +Like IN6ADDR_ANY_INIT, this constant cannot be used in an assignment to +a previously declared IPv6 address variable. + + + +3.10 Portability Additions + +One simple addition to the sockets API that can help application writers +is the "struct sockaddr_storage". This data structure can simplify +writing portable code across multiple address families and platforms. +This data structure is designed with the following goals. + + - Large enough to accommodate all supported protocol-specific address + structures. + - Aligned at an appropriate boundary so that pointers to it can be cast + as pointers to protocol specific address structures and used to + access the fields of those structures without alignment problems. + + +The sockaddr_storage structure contains field ss_family which is of type +sa_family_t. When a sockaddr_storage structure is cast to a sockaddr +structure, the ss_family field of the sockaddr_storage structure maps +onto the sa_family field of the sockaddr structure. When a +sockaddr_storage structure is cast as a protocol specific address +structure, the ss_family field maps onto a field of that structure that +is of type sa_family_t and that identifies the protocol's address +family. + +An example implementation design of such a data structure would be as +follows. + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 12] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +/* + * Desired design of maximum size and alignment + */ +#define _SS_MAXSIZE 128 /* Implementation specific max size */ +#define _SS_ALIGNSIZE (sizeof (int64_t)) + /* Implementation specific desired alignment */ +/* + * Definitions used for sockaddr_storage structure paddings design. + */ +#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (sa_family_t)) +#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (sa_family_t)+ + _SS_PAD1SIZE + _SS_ALIGNSIZE)) +struct sockaddr_storage { + sa_family_t ss_family; /* address family */ + /* Following fields are implementation specific */ + char __ss_pad1[_SS_PAD1SIZE]; + /* 6 byte pad, this is to make implementation + /* specific pad up to alignment field that */ + /* follows explicit in the data structure */ + int64_t __ss_align; /* field to force desired structure */ + /* storage alignment */ + char __ss_pad2[_SS_PAD2SIZE]; + /* 112 byte pad to achieve desired size, */ + /* _SS_MAXSIZE value minus size of ss_family */ + /* __ss_pad1, __ss_align fields is 112 */ +}; + +The above example implementation illustrates a data structure which +will align on a 64-bit boundary. An implementation-specific field +"_ss_align" along "_ss_pad1" is used to force a 64-bit alignment which +covers proper alignment good enough for needs of sockaddr_in6 (IPv6), +sockaddr_in (IPv4) address data structures. The size of padding fields +_ss_pad1 depends on the chosen alignment boundary. The size of padding +field _ss_pad2 depends on the value of overall size chosen for the total +size of the structure. This size and alignment are represented in the +above example by implementation specific (not required) constants +_SS_MAXSIZE (chosen value 128) and _SS_ALIGNMENT (with chosen value 8). +Constants _SS_PAD1SIZE (derived value 6) and _SS_PAD2SIZE (derived value +112) are also for illustration and not required. The implementation specific +definitions and structure field names above start with an underscore to +denote implementation private namespace. Portable code is not expected to +access or reference those fields or constants. + +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)+ + _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]; + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 13] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + + /* 6 byte pad, this is to make implementation + /* specific pad up to alignment field that */ + /* follows explicit in the data structure */ + int64_t __ss_align; /* field to force desired structure */ + /* storage alignment */ + char __ss_pad2[_SS_PAD2SIZE]; + /* 112 byte pad to achieve desired size, */ + /* _SS_MAXSIZE value minus size of ss_len, */ + /* __ss_family, __ss_pad1, __ss_align fields is 112 */ +}; + + + +4. Interface Identification + +This API uses an interface index (a small positive integer) to identify +the local interface on which a multicast group is joined (Section 5.3). +Additionally, the advanced API [4] uses these same interface indexes to +identify the interface on which a datagram is received, or to specify +the interface on which a datagram is to be sent. + +Interfaces are normally known by names such as "le0", "sl1", "ppp2", and +the like. On Berkeley-derived implementations, when an interface is +made known to the system, the kernel assigns a unique positive integer +value (called the interface index) to that interface. These are small +positive integers that start at 1. (Note that 0 is never used for an +interface index.) There may be gaps so that there is no current +interface for a particular positive interface index. + +This API defines two functions that map between an interface name and +index, a third function that returns all the interface names and +indexes, and a fourth function to return the dynamic memory allocated by +the previous function. How these functions are implemented is left up +to the implementation. 4.4BSD implementations can implement these +functions using the existing sysctl() function with the NET_RT_IFLIST +command. Other implementations may wish to use ioctl() for this +purpose. + + + +4.1 Name-to-Index + +The first function maps an interface name into its corresponding index. + + #include + + unsigned int if_nametoindex(const char *ifname); + +If the specified interface name does not exist, the return value is 0, +and errno is set to ENXIO. If there was a system error (such as +running out of memory), the return value is 0 and errno is set to the +proper value (e.g., ENOMEM). + + + + + + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 14] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +4.2 Index-to-Name + +The second function maps an interface index into its corresponding name. + + #include + + char *if_indextoname(unsigned int ifindex, char *ifname); + +The ifname argument must point to a buffer of at least IF_NAMESIZE bytes +into which the interface name corresponding to the specified index is +returned. (IF_NAMESIZE is also defined in and its value +includes a terminating null byte at the end of the interface name.) This +pointer is also the return value of the function. If there is no +interface corresponding to the specified index, NULL is returned, and +errno is set to ENXIO, if there was a system error (such as running out +of memory), if_indextoname returns NULL and errno would be set to the +proper value (e.g., ENOMEM). + + + +4.3 Return All Interface Names and Indexes + +The if_nameindex structure holds the information about a single +interface and is defined as a result of including the header. + + struct if_nameindex { + unsigned int if_index; /* 1, 2, ... */ + char *if_name; /* null terminated name: "le0", ... */ + }; + +The final function returns an array of if_nameindex structures, one +structure per interface. + + struct if_nameindex *if_nameindex(void); + +The end of the array of structures is indicated by a structure with an +if_index of 0 and an if_name of NULL. The function returns a NULL +pointer upon an error, and would set errno to the appropriate value. + +The memory used for this array of structures along with the interface +names pointed to by the if_name members is obtained dynamically. This +memory is freed by the next function. + + + +4.4 Free Memory + +The following function frees the dynamic memory that was allocated by +if_nameindex(). + + #include + + void if_freenameindex(struct if_nameindex *ptr); + +The argument to this function must be a pointer that was returned by +if_nameindex(). + +Currently net/if.h doesn't have prototype definitions for functions and + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 15] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +it is recommended that these definitions be defined in net/if.h as well +as the struct if_nameindex{}. + + + +5. Socket Options + +A number of new socket options are defined for IPv6. All of these new +options are at the IPPROTO_IPV6 level. That is, the "level" parameter +in the getsockopt() and setsockopt() calls is IPPROTO_IPV6 when using +these options. The constant name prefix IPV6_ is used in all of the new +socket options. This serves to clearly identify these options as +applying to IPv6. + +The declaration for IPPROTO_IPV6, the new IPv6 socket options, and +related constants defined in this section are obtained by including the +header . + + + +5.1 Unicast Hop Limit + +A new setsockopt() option controls the hop limit used in outgoing +unicast IPv6 packets. The name of this option is IPV6_UNICAST_HOPS, and +it is used at the IPPROTO_IPV6 layer. The following example illustrates +how it is used: + + int hoplimit = 10; + + if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + (char *) &hoplimit, sizeof(hoplimit)) == -1) + perror("setsockopt IPV6_UNICAST_HOPS"); + +When the IPV6_UNICAST_HOPS option is set with setsockopt(), the option +value given is used as the hop limit for all subsequent unicast packets +sent via that socket. If the option is not set, the system selects a +default value. The integer hop limit value (called x) is interpreted as +follows: + + x < -1: return an error of EINVAL + x == -1: use kernel default + 0 <= x <= 255: use x + x >= 256: return an error of EINVAL + +The IPV6_UNICAST_HOPS option may be used with getsockopt() to determine +the hop limit value that the system will use for subsequent unicast +packets sent via that socket. For example: + + int hoplimit; + socklen_t len = sizeof(hoplimit); + + if (getsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + (char *) &hoplimit, &len) == -1) + perror("getsockopt IPV6_UNICAST_HOPS"); + else + printf("Using %d for hop limit.\n", hoplimit); + + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 16] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +5.2 Sending and Receiving Multicast Packets + +IPv6 applications may send UDP multicast packets by simply specifying an +IPv6 multicast address in the address argument of the sendto() function. + +Three socket options at the IPPROTO_IPV6 layer control some of the +parameters for sending multicast packets. Setting these options is not +required: applications may send multicast packets without using these +options. The setsockopt() options for controlling the sending of +multicast packets are summarized below. These three options can also be +used with getsockopt(). + + IPV6_MULTICAST_IF + + Set the interface to use for outgoing multicast packets. + The argument is the index of the interface to use. + + Argument type: unsigned int + + IPV6_MULTICAST_HOPS + + Set the hop limit to use for outgoing multicast packets. + (Note a separate option - IPV6_UNICAST_HOPS - is + provided to set the hop limit to use for outgoing + unicast packets.) + + The interpretation of the argument is the same + as for the IPV6_UNICAST_HOPS option: + + x < -1: return an error of EINVAL + x == -1: use kernel default + 0 <= x <= 255: use x + x >= 256: return an error of EINVAL + + If IPV6_MULTICAST_HOPS is not set, the default is 1 + (same as IPv4 today) + + Argument type: int + + IPV6_MULTICAST_LOOP + + If a multicast datagram is sent to a group to which the sending host + itself belongs (on the outgoing interface), a copy of the datagram is + looped back by the IP layer for local delivery if this option is set to + 1. If this option is set to 0 a copy is not looped back. Other option + values return an error of EINVAL. + + If IPV6_MULTICAST_LOOP is not set, the default is 1 (loopback; same as + IPv4 today). + + Argument type: unsigned int + +The reception of multicast packets is controlled by the two setsockopt() +options summarized below. An error of EOPNOTSUPP is returned if these +two options are used with getsockopt(). + + IPV6_JOIN_GROUP + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 17] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + + Join a multicast group on a specified local interface. + If the interface index is specified as 0, + the kernel chooses the local interface. + For example, some kernels look up the multicast group + in the normal IPv6 routing table and use the resulting interface. + + Argument type: struct ipv6_mreq + + IPV6_LEAVE_GROUP + + Leave a multicast group on a specified interface. + + Argument type: struct ipv6_mreq + +The argument type of both of these options is the ipv6_mreq structure, +defined as a result of including the header; + + struct ipv6_mreq { + struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast addr */ + unsigned int ipv6mr_interface; /* interface index */ + }; + +Note that to receive multicast datagrams a process must join the +multicast group 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. + + + +5.3 IPV6_V6ONLY option for AF_INET6 Sockets + +This socket option restricts AF_INET6 sockets to IPv6 communications +only. As stated in section <3.7 Compatibility with IPv4 Nodes>, +AF_INET6 sockets may be used for both IPv4 and IPv6 communications. Some +applications may want to restrict their use of an AF_INET6 socket to +IPv6 communications only. For these applications the IPV6_V6ONLY socket +option is defined. When this option is turned on, the socket can be +used to send and receive IPv6 packets only. This is an IPPROTO_IPV6 +level option. This option takes an int value. This is a boolean +option. By default this option is turned off. + + Here is an example of setting this option: + + int on = 1; + + if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + (char *)&on, sizeof(on)) == -1) + perror("setsockopt IPV6_V6ONLY"); + else + printf("IPV6_V6ONLY set0); + +Note - This option has no effect on the use of IPv4 Mapped addresses +which enter a node as a valid IPv6 addresses for IPv6 communications as +defined by Stateless IP/ICMP Translation Algorithm (SIIT) [8]. + + + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 18] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +6. Library Functions + +New library functions are needed to perform a variety of operations with +IPv6 addresses. Functions are needed to lookup IPv6 addresses in the +Domain Name System (DNS). Both forward lookup (nodename-to-address +translation) and reverse lookup (address-to-nodename translation) need +to be supported. Functions are also needed to convert IPv6 addresses +between their binary and textual form. + +We note that the two existing functions, gethostbyname() and +gethostbyaddr(), are left as-is. New functions are defined to handle +both IPv4 and IPv6 addresses. + +The commonly used function gethostbyname() is inadequate for many +applications, first because it provides no way for the caller to specify +anything about the types of addresses desired (IPv4 only, IPv6 only, +IPv4-mapped IPv6 are OK, etc.), and second because many implementations +of this function are not thread safe. RFC 2133 defined a function named +gethostbyname2() but this function was also inadequate, first because +its use required setting a global option (RES_USE_INET6) when IPv6 +addresses were required, and second because a flag argument is needed to +provide the caller with additional control over the types of addresses +required. + + + +6.1 Protocol-Independent Nodename and Service Name Translation + +Nodename-to-address translation is done in a protocol-independent +fashion using the getaddrinfo() function that is taken from the +Institute of Electrical and Electronic Engineers IEEE 1003.1-200x +(POSIX) draft specification [3]. + +The official specification for this function will be the final IEEE +standard. In addition this specification is not specifying all +parameter possibilities for this function, but only the parameters that +can be provided to support IPv4 and IPv6 communications to support this +specification. This is beyond the scope of this document and additional +work on this function will be done by the Austin (IEEE/ISO/TOG) Group. + #include + #include + + + int getaddrinfo(const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res); + + void freeaddrinfo(struct addrinfo *ai); + + struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST, .. */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + socklen_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for nodename */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ + }; + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 19] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + + The getaddrinfo ( ) function translates the name of a service + location (for example, a host name) and/or a service name and returns + a set of socket addresses and associated information to be used in + creating a socket with which to address the specified service. + + The nodename and servname arguments are either null pointers or + pointers to null-terminated strings. One or both of these two + arguments must be a non-null pointer. + + The format of a valid name depends on the protocol family or + families. If a specific family is not given and the name could be + interpreted as valid within multiple supported families, the + implementation will attempt to resolve the name in all supported + families and, all successful results will be returned. + + If the nodename argument is not null, it can be a descriptive name or + can be an address string. If the specified address family is AF_INET, + or AF_UNSPEC, the permissable nodename argument is specified as + defined in inet_pton(). If the specified address family is AF_INET6 + or AF_UNSPEC, the permissable nodename argument is specified as + defined in [5]. + + If nodename is not null, the requested service location is named by + nodename; otherwise, the requested service location is local to the + caller. + + If servname is null, the call returns network-level addresses for the + specified nodename. If servname is not null, it is a null-terminated + character string identifying the requested service. This can be + either a descriptive name or a numeric representation suitable for + use with the address family or families. If the specified address + family is AF_INET, AF_INET6 or AF_UNSPEC, the service can be + specified as a string specifying a decimal port number. + + If the argument hints is not null, it refers to a structure + containing input values that may direct the operation by providing + options and by limiting the returned information to a specific socket + type, address family and/or protocol. In this hints structure every + member other than ai_flags, ai_family, ai_socktype and ai_protocol + must be zero or a null pointer. A value of AF_UNSPEC for ai_family + means that the caller will accept any protocol family. A value of + zero for ai_socktype means that the caller will accept any socket + type. A value of zero for ai_protocol means that the caller will + accept any protocol. If hints is a null pointer, the behavior must be + as if it referred to a structure containing the value zero for the + ai_flags, ai_socktype and ai_protocol fields, and AF_UNSPEC for the + ai_family field. + + Note: + + 1. If the caller handles only TCP and not UDP, for example, then the + ai_protocol member of the hints structure should be set to + IPPROTO_TCP when getaddrinfo ( ) is called. + + 2. If the caller handles only IPv4 and not IPv6, then the ai_family + member of the hints structure should be set to PF_INET when + getaddrinfo ( ) is called. + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 20] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + + The ai_flags field to which hints parameter points must have the + value zero or be the bitwise OR of one or more of the values + AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST, AI_NUMERICSERV, + AI_V4MAPPED, AI_ALL, and AI_ADDRCONFIG. + + The AI_PASSIVE flag in the ai_flags member of the hints structure + specifies how to fill in the IP address portion of the socket address + structure. If the AI_PASSIVE flag is specified, then the returned + address information must be suitable for use in binding a socket for + accepting incoming connections for the specified service (i.e. a call + to bind()). In this case, if the nodename argument is null, then the + IP address portion of the socket address structure 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, the returned address + information must be suitable for a call to connect( ) (for a + connection-mode protocol) or for a call to connect(), sendto() or + sendmsg( ) (for a connectionless protocol). In this case, if the + nodename argument is null, then the IP address portion of the socket + address structure will be set to the loopback address. This flag is + ignored if the nodename argument is not null. + + If the flag AI_CANONNAME is specified and the nodename argument is + not null, the function attempts to determine the canonical name + corresponding to nodename (for example, if nodename is an alias or + shorthand notation for a complete name). + + If the flag AI_NUMERICHOST is specified then a non-null nodename + string must be a numeric host address string. Otherwise an error of + [EAI_NONAME] is returned. This flag prevents any type of name + resolution service (for example, the DNS) from being invoked. + + If the flag AI_NUMERICSERV is specified then a non-null servname + string must be a numeric port string. Otherwise an error [EAI_NONAME] + is returned. This flag prevents any type of name resolution service + (for example, NIS+) from being invoked. + + If the AI_V4MAPPED flag is specified along with an ai_family of + AF_INET6, then the caller will accept IPv4-mapped IPv6 addresses. + That is, if no AAAA or A6, records are found then a query is made for + A records and any found are returned as IPv4-mapped IPv6 addresses + (ai_addrlen will be 16). The AI_V4MAPPED flag is ignored unless + ai_family equals AF_INET6. + + The AI_ALL flag is used in conjunction with the AI_V4MAPPED flag, and + is only used with an ai_family of AF_INET6. When AI_ALL is logically + or'd with AI_V4MAPPED flag then the caller will accept all addresses: + IPv6 and IPv4-mapped IPv6. A query is first made for AAAA/A6 records + and if successful, the IPv6 addresses are returned. Another query is + then made for A records and any found are returned as IPv4-mapped + IPv6 addresses (ai_addrlen will be 16). This flag is ignored unless + ai_family equals AF_INET6. + + Note: + + When ai_family is not specified (AF_UNSPEC), AI_V4MAPPED and + AI_ALL flags will only be used if AF_INET6 is supported. + + If the AI_ADDRCONFIG flag is specified then a query for AAAA or A6 + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 21] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + + records should occur only if the node has at least one IPv6 source + address configured and a query for A records should occur only if the + node has at least one IPv4 source address configured. The loopback + address is not considered for this case as valid as a configured + sources address. + + The ai_socktype field to which argument hints points specifies the + socket type for the service. If a specific socket type is not given + (for example, a value of zero) and the service name could be + interpreted as valid with multiple supported socket types, the + implementation will attempt to resolve the service name for all + supported socket types and, all successful results will be returned. + A non-zero socket type value will limit the returned information to + values with the specified socket type. + + The freeaddrinfo ( ) function frees one or more addrinfo structures + returned by getaddrinfo ( ), along with any additional storage + associated with those structures. If the ai_next field of the + structure is not null, the entire list of structures is freed. The + freeaddrinfo () function must support the freeing of arbitrary + sublists of an addrinfo list originally returned by getaddrinfo (). + + Functions getaddrinfo ( ) and freeaddrinfo ( ) must be thread-safe. + + A zero return value for getaddrinfo ( ) indicates successful + completion; a non-zero return value indicates failure. + + Upon successful return of getaddrinfo ( ), the location to which res + points refers to a linked list of addrinfo structures, each of which + specifies a socket address and information for use in creating a + socket with which to use that socket address. The list must include + at least one addrinfo structure. The ai_next field of each structure + contains a pointer to the next structure on the list, or a null + pointer if it is the last structure on the list. Each structure on + the list includes values for use with a call to the socket( ) + function, and a socket address for use with the connect() function + or, if the AI_PASSIVE flag was specified, for use with the bind( ) + function. The fields ai_family, ai_socktype, and ai_protocol are + usable as the arguments to the socket() function to create a socket + suitable for use with the returned address. The fields ai_addr and + ai_addrlen are usable as the arguments to the connect() or bind( ) + functions with such a socket, according to the AI_PASSIVE flag. + + If nodename is not null, and if requested by the AI_CANONNAME flag, + the ai_canonname field of the first returned addrinfo structure + points to a null-terminated string containing the canonical name + corresponding to the input nodename; if the canonical name is not + available, then ai_canonname refers to the argument nodename or a + string with the same contents. The contents of the ai_flags field of + the returned structures is undefined. + + All fields in socket address structures returned by getaddrinfo ( ) + that are not filled in through an explicit argument (for example, + sin6_flowinfo) must be set to zero. + + Note: This makes it easier to compare socket address structures. + + Error Return Values: + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 22] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + + [EAI_AGAIN] The name could not be resolved at this time. Future + attempts may succeed. + + [EAI_BADFLAGS] The flags parameter had an invalid value. + + [EAI_FAIL] A non-recoverable error occurred when attempting to + resolve the name. + + [EAI_FAMILY] The address family was not recognized. + + [EAI_MEMORY] There was a memory allocation failure when trying to + allocate storage for the return value. + + [EAI_NONAME] The name does not resolve for the supplied parameters. + Neither nodename nor servname were passed. At least one + of these must be passed. + + [EAI_SERVICE] The service passed was not recognized for the specified + socket type. + + [EAI_SOCKTYPE] The intended socket type was not recognized. + + [EAI_SYSTEM] A system error occurred; the error code can be found in + errno. + + #include + + #include + + char *gai_strerror(int ecode); + +The argument is one of the EAI_xxx values defined earlier and the return +value points to a string describing the error. If the argument is not +one of the EAI_xxx values, the function still returns a pointer to a +string whose contents indicate an unknown error. + + + +6.2 Socket Address Structure to Nodename and Service Name + +The official specification for this function will be the final Austin +Group standard update to getaddrinfo(), and will incorporate this +function. In addition this specification is not specifying all +parameter possibilities for this function, but only the parameters that +can be provided to support IPv4 and IPv6 communications to support this +specification. This is beyond the scope of this document and additional +work on this function will be done by the Austin group. + + #include + #include + + int getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, socklen_t hostlen, + char *serv, socklen_t servlen, + int flags); + +The getnameinfo( ) translates a socket address to a node name and +service location, all of which are defined as with getaddrinfo (). + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 23] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +The argument sa points to a socket address structure to be translated. + +If the argument node is non-NULL and the argument nodelen is nonzero, +then the argument node points to a buffer able to contain up to nodelen +characters that will receive the node name as a null-terminated string. +If the argument node is NULL or the argument nodelen is zero, the node +name will not be returned. If the nodeÆs name cannot be located, the +numeric form of the nodes address is returned instead of its name. If +the sa argument is an IPv6 address the returned nodename may be in the +format as defined in [5]. + +If the argument service is non-NULL and the argument servicelen is +nonzero, then the argument service points to a buffer able to contain up +to servicelen characters that will receive the service name as a null- +terminated string. If the argument service is NULL or the argument +servicelen is zero, the service name will not be returned. If the +service name cannot be located, the numeric form of the service address +(for example, its port number) is returned instead of its name. + +The arguments node and service cannot both be NULL. + +The flags argument is a flag that changes the default actions of the +function. By default the fully-qualified domain name (FQDN) for the host +is returned, but + + - If the flag bit NI_NOFQDN is set, only the nodename portion of the + FQDN is returned for local hosts. + + - If the flag bit NI_NUMERICHOST is set, the numeric form of the + host's address is returned instead of its name, under all + circumstances. + + - If the flag bit NI_NAMEREQD is set, an error is returned if the + hostÆs name cannot be located. + + - If the flag bit NI_NUMERICSERV is set, the numeric form of the + service address is returned (for example, its port number) instead of + its name, under all circumstances. + + - If the flag bit NI_NUMERICSCOPE is set, the numeric form of the + scope identifier is returned (for example, interface index) + instead of its name. This flag is ignored if the sa argument is + not an IPv6 address. + + - If the flag bit NI_DGRAM is set, this indicates that the service is + a datagram service (SOCK_DGRAM). The default behavior is to assume that + the service is a stream service (SOCK_STREAM). + +Note: + + 1. The three NI_NUMERICxxx flags are required to support the "-n" + flags that many commands support. + 2. The NI_DGRAM flag is required for the new AF_INET/AF_INET6 port + numbers (for example, 512-514) that represent different services + for UDP and TCP. + +Function getnameinfo() must be thread safe. + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 24] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +A zero return value for getnameinfo( ) indicates successful completion; +a non-zero return value indicates failure. + +On successful completion, function getnameinfo( ) returns the node and +service names, if requested, in the buffers provided. The returned names +are always null-terminated strings. + +Error Return Values: + + [EAI_AGAIN] The name could not be resolved at this time. + Future attempts may succeed. + + [EAI_BADFLAGS] The flags had an invalid value. + + [EAI_FAIL] A non-recoverable error occurred. + + [EAI_FAMILY] The address family was not recognized or the address + length was invalid for the specified family. + + [EAI_MEMORY] There was a memory allocation failure. + + [EAI_NONAME] The name does not resolve for the supplied parameters. + NI_NAMEREQD is set and the hostÆs name cannot be located, or + both nodename and servname were null. + + [EAI_SYSTEM] A system error occurred. The error code can be found in + errno. + + + + +6.3 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 + #include + + int inet_pton(int af, const char *src, void *dst); + + const char *inet_ntop(int af, const void *src, + char *dst, socklen_t size); + +The inet_pton() function 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). + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 25] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +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. + +If the af argument is AF_INET6, then the function accepts a string in +one of the standard IPv6 text forms defined in Section 2.2 of the +addressing architecture specification [2]. + +The inet_ntop() function converts a numeric address into a text string +suitable for presentation. The af argument specifies the family of the +address. This can be AF_INET or AF_INET6. The src argument points to a +buffer holding an IPv4 address if the af argument is AF_INET, or an IPv6 +address if the af argument is AF_INET6, the address must be in network +byte order. The dst argument points to a buffer where the function will +store the resulting text string. The size argument specifies the size +of this buffer. The application must specify a non-NULL dst argument. +For IPv6 addresses, the buffer must be at least 46-octets. For IPv4 +addresses, the buffer must be at least 16-octets. In order to allow +applications to easily declare buffers of the proper size to store IPv4 +and IPv6 addresses in string form, the following two constants are +defined in : + + #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.4 Address Testing Macros + +The following macros can be used to test for special IPv6 addresses. + + #include + + 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 *); + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 26] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +The first seven macros return true if the address is of the specified +type, or false otherwise. The last five test the scope of a multicast +address and return true if the address is a multicast address of the +specified scope or false if the address is either not a multicast +address or not of the specified scope. Note that IN6_IS_ADDR_LINKLOCAL +and IN6_IS_ADDR_SITELOCAL return true only for the two local-use IPv6 +unicast addresses. These two macros do not return true for IPv6 +multicast addresses of either link-local scope or site-local scope. + + + +7. Summary of New Definitions + +The following list summarizes the constants, structure, and extern +definitions discussed in this memo, sorted by header. + + IF_NAMESIZE + struct if_nameindex{}; + + AI_ADDRCONFIG + AI_DEFAULT + AI_ALL + AI_CANONNAME + AI_NUMERICHOST + AI_PASSIVE + AI_V4MAPPED + EAI_AGAIN + EAI_BADFLAGS + EAI_FAIL + EAI_FAMILY + EAI_MEMORY + EAI_NONAME + EAI_SERVICE + EAI_SOCKTYPE + EAI_SYSTEM + NI_DGRAM + NI_MAXHOST + NI_MAXSERV + NI_NAMEREQD + NI_NOFQDN + NI_NUMERICHOST + NI_NUMERICSERV + struct addrinfo{}; + + IN6ADDR_ANY_INIT + IN6ADDR_LOOPBACK_INIT + INET6_ADDRSTRLEN + INET_ADDRSTRLEN + IPPROTO_IPV6 + IPV6_JOIN_GROUP + IPV6_LEAVE_GROUP + IPV6_MULTICAST_HOPS + IPV6_MULTICAST_IF + IPV6_MULTICAST_LOOP + IPV6_UNICAST_HOPS + SIN6_LEN + extern const struct in6_addr in6addr_any; + extern const struct in6_addr in6addr_loopback; + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 27] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + + struct in6_addr{}; + struct ipv6_mreq{}; + struct sockaddr_in6{}; + + AF_INET6 + PF_INET6 + struct sockaddr_storage; + +The following list summarizes the function and macro prototypes +discussed in this memo, sorted by header. + + int inet_pton(int, const char *, void *); + const char *inet_ntop(int, const void *, + char *, socklen_t); + + char *if_indextoname(unsigned int, char *); + unsigned int if_nametoindex(const char *); + void if_freenameindex(struct if_nameindex *); + struct if_nameindex *if_nameindex(void); + + int getaddrinfo(const char *, const char *, + const struct addrinfo *, + struct addrinfo **); + int getnameinfo(const struct sockaddr *, socklen_t, + char *, socklen_t, char *, socklen_t, int); + void freeaddrinfo(struct addrinfo *); + char *gai_strerror(int); + + int IN6_IS_ADDR_LINKLOCAL(const struct in6_addr *); + int IN6_IS_ADDR_LOOPBACK(const struct in6_addr *); + int IN6_IS_ADDR_MC_GLOBAL(const struct in6_addr *); + int IN6_IS_ADDR_MC_LINKLOCAL(const struct in6_addr *); + int IN6_IS_ADDR_MC_NODELOCAL(const struct in6_addr *); + int IN6_IS_ADDR_MC_ORGLOCAL(const struct in6_addr *); + int IN6_IS_ADDR_MC_SITELOCAL(const struct in6_addr *); + int IN6_IS_ADDR_MULTICAST(const struct in6_addr *); + int IN6_IS_ADDR_SITELOCAL(const struct in6_addr *); + int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *); + int IN6_IS_ADDR_V4COMPAT(const struct in6_addr *); + int IN6_IS_ADDR_V4MAPPED(const struct in6_addr *); + + + + +8. Security Considerations + +IPv6 provides a number of new security mechanisms, many of which need to +be accessible to applications. Companion memos detailing the extensions +to the socket interfaces to support IPv6 security are being written. + + + +9. Year 2000 Considerations + +There are no issues for this draft concerning the Year 2000 issue +regarding the use of dates. + + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 28] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +Changes made to rfc2553bis-02 to rfc2553bis-03 + + + 1. Edits only. + + + + +Changes made to rfc2553bis-01 to rfc2553bis-02 + + + 1. Updated all references to comply with latest IEEEE work on + socket APIs and changed all remaining size_t to socklen_t. + + 2. Edits caught. + + + + +Changes made to rfc2553bis-00 to rfc2553bis-01 + + + 1. Removed all references to getipnodebyname() and + getipnodebyaddr(). + + 2. Added IPV6_V6ONLY Socket IP level option to permit nodes + to not process IPv4 packets as IPv4 Mapped addresses + in implementations. + + 3. Added note to getaddrinfo() and getnameinfo() + that final specification of parameter associations for + these functions will be done by Austin. + + 4. Added SIIT to references and added new contributors. + + + + +Changes made rfc2553 to rfc2553bis-00: + + 1. Updated Portability Section 3.10 to conform to XNS 5.2. + + 2. Updated getaddrinfo(), getnameinfo(), to conform to XNS 5.2. + + 3. Added references to Scope Architecture, Scope Routing, and + Extension Format for Scoped Addresses work in progress. + + 4. Added NI_NUMERICSCOPE flag to getnameinfo(). + + 5. Added qualification to getipnodebyname/addr() functions that + they will not work as is with scope identifiers with IPv6, and + getaddrinfo/getnameinfo should be used. + + 6. Added DNS A6 record notation to AAAA and added ip6.arpa as new + PTR record domain. + + + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 29] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + +Acknowledgments + +This specification's evolution and completeness were significantly +influenced by the efforts of Richard Stevens, who has passed on. Rich's +wisdom and talent made the specification what it is today. The co- +authors will long think of Richard with great respect. + +Thanks to the many people who made suggestions and provided feedback to +this document, including: Werner Almesberger, Ran Atkinson, Fred Baker, +Dave Borman, Andrew Cherenson, Alex Conta, Alan Cox, Steve Deering, +Richard Draves, Francis Dupont, Robert Elz, Brian Haberman, Jun-ichiro +itojun Hagino, Marc Hasson, Tom Herbert, Bob Hinden, Wan-Yen Hsu, +Christian Huitema, Koji Imada, Markus Jork, Ron Lee, Alan Lloyd, Charles +Lynn, Dan McDonald, Dave Mitton, Thomas Narten, Josh Osborne, Craig +Partridge, Jean-Luc Richier, Bill Sommerfield, Erik Scoredos, Keith +Sklower, JINMEI Tatuya, Dave Thaler, Matt Thomas, Harvey Thompson, Dean +D. Throop, Karen Tracey, Glenn Trewitt, Paul Vixie, David Waitzman, Carl +Williams, Kazu Yamamoto, Vlad Yasevich, Stig Venaas, and Brian Zill + +The getaddrinfo() and getnameinfo() functions are taken from an earlier +Internet Draft by Keith Sklower. As noted in that draft, William Durst, +Steven Wise, Michael Karels, and Eric Allman provided many useful +discussions on the subject of protocol-independent name-to-address +translation, and reviewed early versions of Keith Sklower's original +proposal. Eric Allman implemented the first prototype of getaddrinfo(). +The observation that specifying the pair of name and service would +suffice for connecting to a service independent of protocol details was +made by Marshall Rose in a proposal to X/Open for a "Uniform Network +Interface". + +Craig Metz, Jack McCann, Erik Nordmark, Tim Hartrick, and Mukesh Kacker +made many contributions to this document. Ramesh Govindan made a number +of contributions and co-authored an earlier version of this memo. + + + +References + + [1] S. Deering, R. Hinden, "Internet Protocol, Version 6 (IPv6) + Specification", RFC 2460 Draft Standard. + + [2] R. Hinden, S. Deering, "IP Version 6 Addressing Architecture", + RFC 2373, July 1998 Draft Standard. + + [3] IEEE Std. 1003.1-200x (Portable Operating System Interface (POSIX)) + DRAFT 6, July 2000. + + [4] W. Stevens, M. Thomas, "Advanced Sockets API for IPv6", + RFC 2292, February 1998. + + [5] T. Jinmei, A. Onoe, "An Extension of Format for IPv6 Scoped + Addresses", Work-in-Progress. + + [6] S. Deering, B. Haberman, B. Zill "IP Version 6 Scoped Address + Architecture", Work-in-Progress. + + [7] B. Haberman " Routing of Scoped Addresses in the Internet Protocol + Version 6 (IPv6)", Work-in-Progress. + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 30] + + +INTERNET-DRAFT draft-ietf-ipngwg-rfc2553bis-03.txt February 2001 + + + [8] E. Nordmark "Stateless IP/ICMP Translation Algorithm (SIIT)" + RFC 2765, February 2000. + + + +Authors' Addresses + + +Bob Gilligan +Cacheflow, Inc. +650 Almanor Ave.. +Sunnyvale, CA 94086 +Telephone: 408-220-2084 (voice) + 408-220-2250 (fax) +Email: gilligan@cacheflow.com + +Susan Thomson +Cisco Systems +499 Thornall Street, 8th floor +Edison, NJ 08837 +Telephone: 732-635-3086 +Email: sethomso@cisco.com + +Jim Bound +Nokia Networks +5 Wayside Road +Burlington, MA 01803 +Phone: +1 781 492 6013 +Email: Jim.Bound@nokia.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +draft-ietf-ipngwg-2553bis-03.txt Expires July 2001 [Page 31] +