draft-ietf-ipngwg-rfc2292bis-01.txt   draft-ietf-ipngwg-rfc2292bis-02.txt 
INTERNET-DRAFT W. Richard Stevens (Consultant) INTERNET-DRAFT W. Richard Stevens (Consultant)
Expires: December 24, 1999 Matt Thomas (Consultant) Expires: May 7, 2001 Matt Thomas (Consultant)
Obsoletes RFC 2292 Erik Nordmark (Sun) Obsoletes RFC 2292 Erik Nordmark (Sun)
Oct 22, 1999 November 7, 2000
Advanced Sockets API for IPv6 Advanced Sockets API for IPv6
<draft-ietf-ipngwg-rfc2292bis-01.txt> <draft-ietf-ipngwg-rfc2292bis-02.txt>
Abstract Abstract
A separate specification [RFC-2553] contain changes to the sockets A separate specification [RFC-2553] contain changes to the sockets
API to support IP version 6. Those changes are for TCP and UDP-based API to support IP version 6. Those changes are for TCP and UDP-based
applications and will support most end-user applications in use applications and will support most end-user applications in use
today: Telnet and FTP clients and servers, HTTP clients and servers, today: Telnet and FTP clients and servers, HTTP clients and servers,
and the like. and the like.
But another class of applications exists that will also be run under But another class of applications exists that will also be run under
skipping to change at page 2, line 13 skipping to change at page 2, line 13
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt http://www.ietf.org/ietf/1id-abstracts.txt
The list of Internet-Draft Shadow Directories can be accessed at The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html. http://www.ietf.org/shadow.html.
This Internet Draft expires April 22, 2000. This Internet Draft expires May 7, 2001.
Table of Contents Table of Contents
1. Introduction .................................................... 6 1. Introduction ..................................................... 6
2. Common Structures and Definitions ............................... 7 2. Common Structures and Definitions ................................ 7
2.1. The ip6_hdr Structure ...................................... 8 2.1. The ip6_hdr Structure .......................................... 8
2.1.1. IPv6 Next Header Values ............................. 8 2.1.1. IPv6 Next Header Values ...................................... 8
2.1.2. IPv6 Extension Headers .............................. 9 2.1.2. IPv6 Extension Headers ....................................... 9
2.1.3. IPv6 Options ........................................ 10 2.1.3. IPv6 Options ................................................. 10
2.2. The icmp6_hdr Structure .................................... 12 2.2. The icmp6_hdr Structure ........................................ 13
2.2.1. ICMPv6 Type and Code Values ......................... 13 2.2.1. ICMPv6 Type and Code Values .................................. 13
2.2.2. ICMPv6 Neighbor Discovery Type and Code Values ...... 14 2.2.2. ICMPv6 Neighbor Discovery Definitions ........................ 14
2.2.3. Multicast Listener Discovery Type and Code Values ... 16 2.2.3. Multicast Listener Discovery Definitions ..................... 17
2.2.4. ICMPv6 Router Renumbering Type and Code Values ...... 17 2.2.4. ICMPv6 Router Renumbering Definitions ........................ 18
2.3. Address Testing Macros ..................................... 19 2.3. Address Testing Macros ......................................... 19
2.4. Protocols File ............................................. 19 2.4. Protocols File ................................................. 20
3. IPv6 Raw Sockets ................................................ 20 3. IPv6 Raw Sockets ................................................. 20
3.1. Checksums .................................................. 21 3.1. Checksums ...................................................... 22
3.2. ICMPv6 Type Filtering ...................................... 21 3.2. ICMPv6 Type Filtering .......................................... 22
3.3. ICMPv6 Verification of Received Packets ........................ 25
4. Access to IPv6 and Extension Headers ............................ 24 4. Access to IPv6 and Extension Headers ............................. 25
4.1. TCP Implications ........................................... 26 4.1. TCP Implications ............................................... 27
4.2. UDP and Raw Socket Implications ............................ 27 4.2. UDP and Raw Socket Implications ................................ 28
5. Extensions to Socket Ancillary Data ............................. 27 5. Extensions to Socket Ancillary Data .............................. 28
6. Packet Information .............................................. 28 6. Packet Information ............................................... 29
6.1. Specifying/Receiving the Interface ......................... 29 6.1. Specifying/Receiving the Interface ............................. 30
6.2. Specifying/Receiving Source/Destination Address ............ 29 6.2. Specifying/Receiving Source/Destination Address ................ 30
6.3. Specifying/Receiving the Hop Limit ......................... 30 6.3. Specifying/Receiving the Hop Limit ............................. 31
6.4. Specifying the Next Hop Address ............................ 31 6.4. Specifying the Next Hop Address ................................ 32
6.5. Additional Errors with sendmsg() and setsockopt() .......... 31 6.5. Additional Errors with sendmsg() and setsockopt() .............. 32
7. Routing Header Option ........................................... 32 7. Routing Header Option ............................................ 33
7.1. inet6_rth_space ............................................ 33 7.1. inet6_rth_space ................................................ 34
7.2. inet6_rth_init ............................................. 33 7.2. inet6_rth_init ................................................. 35
7.3. inet6_rth_add .............................................. 34 7.3. inet6_rth_add .................................................. 35
7.4. inet6_rth_reverse .......................................... 34 7.4. inet6_rth_reverse .............................................. 35
7.5. inet6_rth_segments ......................................... 35 7.5. inet6_rth_segments ............................................. 36
7.6. inet6_rth_getaddr .......................................... 35 7.6. inet6_rth_getaddr .............................................. 36
8. Hop-By-Hop Options .............................................. 35 8. Hop-By-Hop Options ............................................... 36
8.1. Receiving Hop-by-Hop Options ............................... 36 8.1. Receiving Hop-by-Hop Options ................................... 38
8.2. Sending Hop-by-Hop Options ................................. 37 8.2. Sending Hop-by-Hop Options ..................................... 38
9. Destination Options ............................................. 37 9. Destination Options .............................................. 38
9.1. Receiving Destination Options .............................. 37 9.1. Receiving Destination Options .................................. 39
9.2. Sending Destination Options ................................ 38 9.2. Sending Destination Options .................................... 39
10. Hop-by-Hop and Destination Options Processing ................... 39 10. Hop-by-Hop and Destination Options Processing ................... 40
10.1. inet6_opt_init ............................................ 39 10.1. inet6_opt_init ................................................ 40
10.2. inet6_opt_append .......................................... 39 10.2. inet6_opt_append .............................................. 41
10.3. inet6_opt_finish .......................................... 40 10.3. inet6_opt_finish .............................................. 41
10.4. inet6_opt_set_val ......................................... 41 10.4. inet6_opt_set_val ............................................. 42
10.5. inet6_opt_next ............................................ 41 10.5. inet6_opt_next ................................................ 42
10.6. inet6_opt_find ............................................ 41 10.6. inet6_opt_find ................................................ 42
10.7. inet6_opt_get_val ......................................... 42 10.7. inet6_opt_get_val ............................................. 43
11. Additional Advanced API Functions ............................... 42 11. Additional Advanced API Functions ............................... 43
11.1. Sending with the Minimum MTU .............................. 42 11.1. Sending with the Minimum MTU .................................. 43
11.2. Path MTU Discovery and UDP ................................ 43 11.2. Path MTU Discovery and UDP .................................... 44
11.3. Neighbor Reachability and UDP ............................. 43 11.3. Neighbor Reachability and UDP ................................. 44
12. Ordering of Ancillary Data and IPv6 Extension Headers ........... 44 12. Ordering of Ancillary Data and IPv6 Extension Headers ........... 45
13. IPv6-Specific Options with IPv4-Mapped IPv6 Addresses ........... 44 13. IPv6-Specific Options with IPv4-Mapped IPv6 Addresses ........... 46
14. Extended interfaces for rresvport, rcmd and rexec ............... 45 14. Extended interfaces for rresvport, rcmd and rexec ............... 46
14.1. rresvport_af .............................................. 45 14.1. rresvport_af .................................................. 46
14.2. rcmd_af ................................................... 45 14.2. rcmd_af ....................................................... 47
14.3. rexec_af .................................................. 46 14.3. rexec_af ...................................................... 47
15. Summary of New Definitions ...................................... 46 15. Summary of New Definitions ...................................... 47
16. Security Considerations ......................................... 49 16. Security Considerations ......................................... 52
17. Change History .................................................. 49 17. Change History .................................................. 52
18. TODO and Open Issues ............................................ 52 18. TODO and Open Issues ............................................ 54
19. References ...................................................... 52 19. References ...................................................... 56
20. Acknowledgments ................................................. 53 20. Acknowledgments ................................................. 56
21. Authors' Addresses .............................................. 53 21. Authors' Addresses .............................................. 57
22. Appendix A: Ancillary Data Overview ............................. 54 22. Appendix A: Ancillary Data Overview ............................. 57
22.1. The msghdr Structure ...................................... 54 22.1. The msghdr Structure .......................................... 58
22.2. The cmsghdr Structure ..................................... 55 22.2. The cmsghdr Structure ......................................... 59
22.3. Ancillary Data Object Macros .............................. 57 22.3. Ancillary Data Object Macros .................................. 60
22.3.1. CMSG_FIRSTHDR ...................................... 57 22.3.1. CMSG_FIRSTHDR ............................................... 61
22.3.2. CMSG_NXTHDR ........................................ 58 22.3.2. CMSG_NXTHDR ................................................. 62
22.3.3. CMSG_DATA .......................................... 59 22.3.3. CMSG_DATA ................................................... 63
22.3.4. CMSG_SPACE ......................................... 60 22.3.4. CMSG_SPACE .................................................. 63
22.3.5. CMSG_LEN ........................................... 60 22.3.5. CMSG_LEN .................................................... 64
23. Appendix B: Examples using the inet6_rth_XXX() functions ........ 61
23.1. Sending a Routing Header .................................. 61
23.2. Receiving Routing Headers ................................. 66
24. Appendix C: Examples using the inet6_opt_XXX() functions ........ 68 23. Appendix B: Examples using the inet6_rth_XXX() functions ........ 64
24.1. Building options .......................................... 68 23.1. Sending a Routing Header ...................................... 64
24.2. Parsing received options .................................. 70 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
1. Introduction 1. Introduction
A separate specification [RFC-2553] contain changes to the sockets A separate specification [RFC-2553] contain changes to the sockets
API to support IP version 6. Those changes are for TCP and UDP-based API to support IP version 6. Those changes are for TCP and UDP-based
applications. This document defines some the "advanced" features of applications. This document defines some the "advanced" features of
the sockets API that are required for applications to take advantage the sockets API that are required for applications to take advantage
of additional features of IPv6. of additional features of IPv6.
Today, the portability of applications using IPv4 raw sockets is Today, the portability of applications using IPv4 raw sockets is
skipping to change at page 7, line 27 skipping to change at page 7, line 27
authentication header or the encapsulating security payload header. authentication header or the encapsulating security payload header.
All examples in this document omit error checking in favor of brevity All examples in this document omit error checking in favor of brevity
and clarity. and clarity.
We note that many of the functions and socket options defined in this 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 may have error returns that are not defined in this
document. Many of these possible error returns will be recognized document. Many of these possible error returns will be recognized
only as implementations proceed. only as implementations proceed.
Datatypes in this document follow the Posix.1g format: intN_t means a Datatypes in this document follow the Posix.1g format: intN_t means
signed integer of exactly N bits (e.g., int16_t) and uintN_t means an a signed integer of exactly N bits (e.g., int16_t) and uintN_t means
unsigned integer of exactly N bits (e.g., uint32_t). an unsigned integer of exactly N bits (e.g., uint32_t).
Note that we use the (unofficial) terminology ICMPv4, IGMPv4, and Note that we use the (unofficial) terminology ICMPv4, IGMPv4, and
ARPv4 to avoid any confusion with the newer ICMPv6 protocol. ARPv4 to avoid any confusion with the newer ICMPv6 protocol.
2. Common Structures and Definitions 2. Common Structures and Definitions
Many advanced applications examine fields in the IPv6 header and set Many advanced applications examine fields in the IPv6 header and set
and examine fields in the various ICMPv6 headers. Common structure and examine fields in the various ICMPv6 headers. Common structure
definitions for these protocol headers are required, along with definitions for these protocol headers are required, along with
common constant definitions for the structure members. common constant definitions for the structure members.
skipping to change at page 8, line 14 skipping to change at page 8, line 14
include other files that do the actual declaration or definition. include other files that do the actual declaration or definition.
2.1. The ip6_hdr Structure 2.1. The ip6_hdr Structure
The following structure is defined as a result of including The following structure is defined as a result of including
<netinet/ip6.h>. Note that this is a new header. <netinet/ip6.h>. Note that this is a new header.
struct ip6_hdr { struct ip6_hdr {
union { union {
struct ip6_hdrctl { struct ip6_hdrctl {
uint32_t ip6_un1_flow; /* 4 bits version, 8 bits TC, 24 bits flow-ID */ uint32_t ip6_un1_flow; /* 4 bits version, 8 bits TC, 20 bits flow-ID */
uint16_t ip6_un1_plen; /* payload length */ uint16_t ip6_un1_plen; /* payload length */
uint8_t ip6_un1_nxt; /* next header */ uint8_t ip6_un1_nxt; /* next header */
uint8_t ip6_un1_hlim; /* hop limit */ uint8_t ip6_un1_hlim; /* hop limit */
} ip6_un1; } ip6_un1;
uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits tclass */ uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits tclass */
} ip6_ctlun; } ip6_ctlun;
struct in6_addr ip6_src; /* source address */ struct in6_addr ip6_src; /* source address */
struct in6_addr ip6_dst; /* destination address */ struct in6_addr ip6_dst; /* destination address */
}; };
skipping to change at page 9, line 16 skipping to change at page 9, line 16
sockets and IPPROTO_HOPOPTS only with IPv6 sockets. sockets and IPPROTO_HOPOPTS only with IPv6 sockets.
2.1.2. IPv6 Extension Headers 2.1.2. IPv6 Extension Headers
Six extension headers are defined for IPv6. We define structures for Six extension headers are defined for IPv6. We define structures for
all except the Authentication header and Encapsulating Security all except the Authentication header and Encapsulating Security
Payload header, both of which are beyond the scope of this document. Payload header, both of which are beyond the scope of this document.
The following structures are defined as a result of including The following structures are defined as a result of including
<netinet/ip6.h>. <netinet/ip6.h>.
/*
* 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 */ /* Hop-by-Hop options header */
struct ip6_hbh { struct ip6_hbh {
uint8_t ip6h_nxt; /* next header */ uint8_t ip6h_nxt; /* next header */
uint8_t ip6h_len; /* length in units of 8 octets */ uint8_t ip6h_len; /* length in units of 8 octets */
/* followed by options */ /* followed by options */
}; };
/* Destination options header */ /* Destination options header */
struct ip6_dest { struct ip6_dest {
uint8_t ip6d_nxt; /* next header */ uint8_t ip6d_nxt; /* next header */
skipping to change at page 13, line 45 skipping to change at page 14, line 10
#define ICMP6_DST_UNREACH 1 #define ICMP6_DST_UNREACH 1
#define ICMP6_PACKET_TOO_BIG 2 #define ICMP6_PACKET_TOO_BIG 2
#define ICMP6_TIME_EXCEEDED 3 #define ICMP6_TIME_EXCEEDED 3
#define ICMP6_PARAM_PROB 4 #define ICMP6_PARAM_PROB 4
#define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */ #define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */
#define ICMP6_ECHO_REQUEST 128 #define ICMP6_ECHO_REQUEST 128
#define ICMP6_ECHO_REPLY 129 #define ICMP6_ECHO_REPLY 129
#define ICMP6_MEMBERSHIP_QUERY 130
#define ICMP6_MEMBERSHIP_REPORT 131
#define ICMP6_MEMBERSHIP_REDUCTION 132
#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
#define ICMP6_DST_UNREACH_ADMIN 1 /* communication with */ #define ICMP6_DST_UNREACH_ADMIN 1 /* communication with */
/* destination */ /* destination */
/* admin. prohibited */ /* admin. prohibited */
#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ #define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */
#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */
#define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */ #define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */
#define ICMP6_TIME_EXCEED_TRANSIT 0 /* Hop Limit == 0 in transit */ #define ICMP6_TIME_EXCEED_TRANSIT 0 /* Hop Limit == 0 in transit */
#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */ #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */
#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ #define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */
#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized Next Header */ #define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized Next Header */
#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */ #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */
The five ICMP message types defined by IPv6 neighbor discovery The five ICMP message types defined by IPv6 neighbor discovery (133-
(133-137) are defined in the next section. 137) are defined in the next section.
2.2.2. ICMPv6 Neighbor Discovery Type and Code Values 2.2.2. ICMPv6 Neighbor Discovery Definitions
The following structures and definitions are defined as a result of The following structures and definitions are defined as a result of
including <netinet/icmp6.h>. including <netinet/icmp6.h>.
#define ND_ROUTER_SOLICIT 133 #define ND_ROUTER_SOLICIT 133
#define ND_ROUTER_ADVERT 134 #define ND_ROUTER_ADVERT 134
#define ND_NEIGHBOR_SOLICIT 135 #define ND_NEIGHBOR_SOLICIT 135
#define ND_NEIGHBOR_ADVERT 136 #define ND_NEIGHBOR_ADVERT 136
#define ND_REDIRECT 137 #define ND_REDIRECT 137
skipping to change at page 15, line 9 skipping to change at page 15, line 17
/* could be followed by options */ /* could be followed by options */
}; };
#define nd_ra_type nd_ra_hdr.icmp6_type #define nd_ra_type nd_ra_hdr.icmp6_type
#define nd_ra_code nd_ra_hdr.icmp6_code #define nd_ra_code nd_ra_hdr.icmp6_code
#define nd_ra_cksum nd_ra_hdr.icmp6_cksum #define nd_ra_cksum nd_ra_hdr.icmp6_cksum
#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0] #define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1] #define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
#define ND_RA_FLAG_MANAGED 0x80 #define ND_RA_FLAG_MANAGED 0x80
#define ND_RA_FLAG_OTHER 0x40 #define ND_RA_FLAG_OTHER 0x40
#define ND_RA_FLAG_HOME_AGENT 0x20
#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1] #define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
struct nd_neighbor_solicit { /* neighbor solicitation */ struct nd_neighbor_solicit { /* neighbor solicitation */
struct icmp6_hdr nd_ns_hdr; struct icmp6_hdr nd_ns_hdr;
struct in6_addr nd_ns_target; /* target address */ struct in6_addr nd_ns_target; /* target address */
/* could be followed by options */ /* could be followed by options */
}; };
#define nd_ns_type nd_ns_hdr.icmp6_type #define nd_ns_type nd_ns_hdr.icmp6_type
#define nd_ns_code nd_ns_hdr.icmp6_code #define nd_ns_code nd_ns_hdr.icmp6_code
skipping to change at page 16, line 17 skipping to change at page 16, line 26
uint8_t nd_opt_type; uint8_t nd_opt_type;
uint8_t nd_opt_len; /* in units of 8 octets */ uint8_t nd_opt_len; /* in units of 8 octets */
/* followed by option specific data */ /* followed by option specific data */
}; };
#define ND_OPT_SOURCE_LINKADDR 1 #define ND_OPT_SOURCE_LINKADDR 1
#define ND_OPT_TARGET_LINKADDR 2 #define ND_OPT_TARGET_LINKADDR 2
#define ND_OPT_PREFIX_INFORMATION 3 #define ND_OPT_PREFIX_INFORMATION 3
#define ND_OPT_REDIRECTED_HEADER 4 #define ND_OPT_REDIRECTED_HEADER 4
#define ND_OPT_MTU 5 #define ND_OPT_MTU 5
#define ND_OPT_ADVINTERVAL 7
#define ND_OPT_HOMEAGENT_INFO 8
struct nd_opt_prefix_info { /* prefix information */ struct nd_opt_prefix_info { /* prefix information */
uint8_t nd_opt_pi_type; uint8_t nd_opt_pi_type;
uint8_t nd_opt_pi_len; uint8_t nd_opt_pi_len;
uint8_t nd_opt_pi_prefix_len; uint8_t nd_opt_pi_prefix_len;
uint8_t nd_opt_pi_flags_reserved; uint8_t nd_opt_pi_flags_reserved;
uint32_t nd_opt_pi_valid_time; uint32_t nd_opt_pi_valid_time;
uint32_t nd_opt_pi_preferred_time; uint32_t nd_opt_pi_preferred_time;
uint32_t nd_opt_pi_reserved2; 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; struct in6_addr nd_opt_pi_prefix;
}; };
#define ND_OPT_PI_FLAG_ONLINK 0x80 #define ND_OPT_PI_FLAG_ONLINK 0x80
#define ND_OPT_PI_FLAG_AUTO 0x40 #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 */ struct nd_opt_rd_hdr { /* redirected header */
uint8_t nd_opt_rh_type; uint8_t nd_opt_rh_type;
uint8_t nd_opt_rh_len; uint8_t nd_opt_rh_len;
uint16_t nd_opt_rh_reserved1; uint16_t nd_opt_rh_reserved1;
uint32_t nd_opt_rh_reserved2; uint32_t nd_opt_rh_reserved2;
/* followed by IP header and data */ /* followed by IP header and data */
}; };
struct nd_opt_mtu { /* MTU option */ struct nd_opt_mtu { /* MTU option */
uint8_t nd_opt_mtu_type; uint8_t nd_opt_mtu_type;
uint8_t nd_opt_mtu_len; uint8_t nd_opt_mtu_len;
uint16_t nd_opt_mtu_reserved; uint16_t nd_opt_mtu_reserved;
uint32_t nd_opt_mtu_mtu; 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 We note that the nd_na_flags_reserved flags have the same byte
ordering problems as we discussed with ip6f_offlg. ordering problems as we discussed with ip6f_offlg.
2.2.3. Multicast Listener Discovery Type and Code Values 2.2.3. Multicast Listener Discovery Definitions
The following structures and definitions are defined as a result of The following structures and definitions are defined as a result of
including <netinet/icmp6.h>. including <netinet/icmp6.h>.
#define MLD_LISTENER_QUERY 130
#define MLD_LISTENER_REPORT 131
#define MLD_LISTENER_REDUCTION 132
struct mld_hdr { struct mld_hdr {
struct icmp6_hdr mld_hdr; struct icmp6_hdr mld_hdr;
struct in6_addr mld_addr; /* multicast address */ struct in6_addr mld_addr; /* multicast address */
}; };
#define mld_type mld_hdr.icmp6_type #define mld_type mld_hdr.icmp6_type
#define mld_code mld_hdr.icmp6_code #define mld_code mld_hdr.icmp6_code
#define mld_cksum mld_hdr.icmp6_cksum #define mld_cksum mld_hdr.icmp6_cksum
#define mld_maxdelay mld_hdr.icmp6_data16[0] #define mld_maxdelay mld_hdr.icmp6_data16[0]
#define mld_reserved mld_hdr.icmp6_data16[1] #define mld_reserved mld_hdr.icmp6_data16[1]
2.2.4. ICMPv6 Router Renumbering Type and Code Values 2.2.4. ICMPv6 Router Renumbering Definitions
The following structures and definitions are defined as a result of The following structures and definitions are defined as a result of
including <netinet/icmp6.h>. including <netinet/icmp6.h>.
#define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */
struct icmp6_router_renum { /* router renumbering header */ struct icmp6_router_renum { /* router renumbering header */
struct icmp6_hdr rr_hdr; struct icmp6_hdr rr_hdr;
u_int8_t rr_segnum; u_int8_t rr_segnum;
u_int8_t rr_flags; u_int8_t rr_flags;
u_int16_t rr_maxdelay; u_int16_t rr_maxdelay;
u_int32_t rr_reserved; u_int32_t rr_reserved;
}; };
#define rr_type rr_hdr.icmp6_type #define rr_type rr_hdr.icmp6_type
#define rr_code rr_hdr.icmp6_code #define rr_code rr_hdr.icmp6_code
#define rr_cksum rr_hdr.icmp6_cksum #define rr_cksum rr_hdr.icmp6_cksum
skipping to change at page 18, line 7 skipping to change at page 18, line 42
u_int8_t rpm_code; u_int8_t rpm_code;
u_int8_t rpm_len; u_int8_t rpm_len;
u_int8_t rpm_ordinal; u_int8_t rpm_ordinal;
u_int8_t rpm_matchlen; u_int8_t rpm_matchlen;
u_int8_t rpm_minlen; u_int8_t rpm_minlen;
u_int8_t rpm_maxlen; u_int8_t rpm_maxlen;
u_int16_t rpm_reserved; u_int16_t rpm_reserved;
struct in6_addr rpm_prefix; struct in6_addr rpm_prefix;
}; };
/* PCI code values */ /* PCO code values */
#define RPM_PCO_ADD 1 #define RPM_PCO_ADD 1
#define RPM_PCO_CHANGE 2 #define RPM_PCO_CHANGE 2
#define RPM_PCO_SETGLOBAL 3 #define RPM_PCO_SETGLOBAL 3
struct rr_pco_use { /* use prefix part */ struct rr_pco_use { /* use prefix part */
u_int8_t rpu_uselen; u_int8_t rpu_uselen;
u_int8_t rpu_keeplen; u_int8_t rpu_keeplen;
u_int8_t rpu_ramask; u_int8_t rpu_ramask;
u_int8_t rpu_raflags; u_int8_t rpu_raflags;
u_int32_t rpu_vltime; u_int32_t rpu_vltime;
skipping to change at page 21, line 8 skipping to change at page 21, line 47
When we say "an ICMPv6 raw socket" we mean a socket created by When we say "an ICMPv6 raw socket" we mean a socket created by
calling the socket function with the three arguments PF_INET6, calling the socket function with the three arguments PF_INET6,
SOCK_RAW, and IPPROTO_ICMPV6. SOCK_RAW, and IPPROTO_ICMPV6.
Most IPv4 implementations give special treatment to a raw socket Most IPv4 implementations give special treatment to a raw socket
created with a third argument to socket() of IPPROTO_RAW, whose value 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 is normally 255, to have it mean that the application will send down
complete packets including the IPv4 header. (Note: This feature was complete packets including the IPv4 header. (Note: This feature was
added to IPv4 in 1988 by Van Jacobson to support traceroute, allowing added to IPv4 in 1988 by Van Jacobson to support traceroute, allowing
a complete IP header to be passed by the application, before the a complete IP header to be passed by the application, before the
IP_HDRINCL socket option was added.) We note that this value has no IP_HDRINCL socket option was added.) We note that IPPROTO_RAW has no
special meaning to an IPv6 raw socket (and the IANA currently special meaning to an IPv6 raw socket (and the IANA currently
reserves the value of 255 when used as a next-header field). reserves the value of 255 when used as a next-header field).
3.1. Checksums 3.1. Checksums
The kernel will calculate and insert the ICMPv6 checksum for ICMPv6 The kernel will calculate and insert the ICMPv6 checksum for ICMPv6
raw sockets, since this checksum is mandatory. raw sockets, since this checksum is mandatory.
For other raw IPv6 sockets (that is, for raw IPv6 sockets created For other raw IPv6 sockets (that is, for raw IPv6 sockets created
with a third argument other than IPPROTO_ICMPV6), the application with a third argument other than IPPROTO_ICMPV6), the application
must set the new IPV6_CHECKSUM socket option to have the kernel (1) 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 compute and store a checksum for output, and (2) verify the received
checksum on input, discarding the packet if the checksum is in error. checksum on input, discarding the packet if the checksum is in error.
This option prevents applications from having to perform source This option prevents applications from having to perform source
address selection on the packets they send. The checksum will address selection on the packets they send. The checksum will
incorporate the IPv6 pseudo-header, defined in Section 8.1 of incorporate the IPv6 pseudo-header, defined in Section 8.1 of [RFC-
[RFC-2460]. This new socket option also specifies an integer offset 2460]. This new socket option also specifies an integer offset into
into the user data of where the checksum is located. the user data of where the checksum is located.
int offset = 2; int offset = 2;
setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset));
By default, this socket option is disabled. Setting the offset to -1 By default, this socket option is disabled. Setting the offset to -1
also disables the option. By disabled we mean (1) the kernel will also disables the option. By disabled we mean (1) the kernel will
not calculate and store a checksum for outgoing packets, and (2) the not calculate and store a checksum for outgoing packets, and (2) the
kernel will not verify a checksum for received packets. kernel will not verify a checksum for received packets.
An attempt to set IPV6_CHECKSUM for an ICMPv6 socket will fail. An attempt to set IPV6_CHECKSUM for an ICMPv6 socket will fail.
skipping to change at page 22, line 6 skipping to change at page 22, line 46
3.2. ICMPv6 Type Filtering 3.2. ICMPv6 Type Filtering
ICMPv4 raw sockets receive most ICMPv4 messages received by the ICMPv4 raw sockets receive most ICMPv4 messages received by the
kernel. (We say "most" and not "all" because Berkeley-derived kernel. (We say "most" and not "all" because Berkeley-derived
kernels never pass echo requests, timestamp requests, or address mask kernels never pass echo requests, timestamp requests, or address mask
requests to a raw socket. Instead these three messages are processed requests to a raw socket. Instead these three messages are processed
entirely by the kernel.) But ICMPv6 is a superset of ICMPv4, also entirely by the kernel.) But ICMPv6 is a superset of ICMPv4, also
including the functionality of IGMPv4 and ARPv4. This means that an including the functionality of IGMPv4 and ARPv4. This means that an
ICMPv6 raw socket can potentially receive many more messages than ICMPv6 raw socket can potentially receive many more messages than
would be received with an ICMPv4 raw socket: ICMP messages similar to would be received with an ICMPv4 raw socket: ICMP messages similar
ICMPv4, along with neighbor solicitations, neighbor advertisements, to ICMPv4, along with neighbor solicitations, neighbor
and the three multicast listener discovery messages. advertisements, and the three multicast listener discovery messages.
Most applications using an ICMPv6 raw socket care about only a small Most applications using an ICMPv6 raw socket care about only a small
subset of the ICMPv6 message types. To transfer extraneous ICMPv6 subset of the ICMPv6 message types. To transfer extraneous ICMPv6
messages from the kernel to user can incur a significant overhead. messages from the kernel to user can incur a significant overhead.
Therefore this API includes a method of filtering ICMPv6 messages by Therefore this API includes a method of filtering ICMPv6 messages by
the ICMPv6 type field. the ICMPv6 type field.
Each ICMPv6 raw socket has an associated filter whose datatype is Each ICMPv6 raw socket has an associated filter whose datatype is
defined as defined as
skipping to change at page 24, line 21 skipping to change at page 25, line 4
#define ICMP6_FILTER_WILLBLOCK(type, filterp) \ #define ICMP6_FILTER_WILLBLOCK(type, filterp) \
((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0) ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
#define ICMP6_FILTER_SETPASS(type, filterp) \ #define ICMP6_FILTER_SETPASS(type, filterp) \
((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))) ((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31))))
#define ICMP6_FILTER_SETBLOCK(type, filterp) \ #define ICMP6_FILTER_SETBLOCK(type, filterp) \
((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))) ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))
#define ICMP6_FILTER_SETPASSALL(filterp) \ #define ICMP6_FILTER_SETPASSALL(filterp) \
memset((filterp), 0xFF, sizeof(struct icmp6_filter)) memset((filterp), 0xFF, sizeof(struct icmp6_filter))
#define ICMP6_FILTER_SETBLOCKALL(filterp) \ #define ICMP6_FILTER_SETBLOCKALL(filterp) \
memset((filterp), 0, sizeof(struct icmp6_filter)) memset((filterp), 0, sizeof(struct icmp6_filter))
(Note: These sample definitions have two limitations that an (Note: These sample definitions have two limitations that an
implementation may want to change. The first four macros evaluate implementation may want to change. The first four macros evaluate
their first argument two times. The second two macros require the their first argument two times. The second two macros require the
inclusion of the <string.h> header for the memset() function.) inclusion of the <string.h> 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 4. Access to IPv6 and Extension Headers
Applications need to be able to control IPv6 header and extension Applications need to be able to control IPv6 header and extension
header content when sending as well as being able to receive the header content when sending as well as being able to receive the
content of these headers. This is done by defining socket option content of these headers. This is done by defining socket option
types which can be used both with setsockopt and with ancillary data. types which can be used both with setsockopt and with ancillary data.
Ancillary data is discussed in Appendix A. The following optional Ancillary data is discussed in Appendix A. The following optional
information can be exchanged between the application and the kernel: information can be exchanged between the application and the kernel:
1. The send/receive interface and source/destination address, 1. The send/receive interface and source/destination address,
skipping to change at page 26, line 4 skipping to change at page 27, line 4
IPPROTO_IPV6 IPV6_RTHDR ip6_rthdr structure IPPROTO_IPV6 IPV6_RTHDR ip6_rthdr structure
IPPROTO_IPV6 IPV6_HOPOPTS ip6_hbh structure IPPROTO_IPV6 IPV6_HOPOPTS ip6_hbh structure
IPPROTO_IPV6 IPV6_DSTOPTS ip6_dest structure IPPROTO_IPV6 IPV6_DSTOPTS ip6_dest structure
IPPROTO_IPV6 IPV6_RTHDRDSTOPTS 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 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 All the constants beginning with IPV6_ are defined as a result of
including the <netinet/in.h>. including the <netinet/in.h>.
Issuing getsockopt() for the above options will return the sticky Issuing getsockopt() for the above options will return the sticky
option value i.e. the value set with setsockopt(). 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 Note: We intentionally use the same constant for the cmsg_level
member as is used as the second argument to getsockopt() and member as is used as the second argument to getsockopt() and
setsockopt() (what is called the "level"), and the same constant for setsockopt() (what is called the "level"), and the same constant for
the cmsg_type member as is used as the third argument to getsockopt() the cmsg_type member as is used as the third argument to getsockopt()
and setsockopt() (what is called the "option name"). and setsockopt() (what is called the "option name").
The application does not explicitly need to access the data The application does not explicitly need to access the data
structures for the Routing header option, Hop-by-Hop option, and structures for the Routing header option, Hop-by-Hop option, and
Destination options, since the API to these features is through a set Destination options, since the API to these features is through a set
skipping to change at page 27, line 47 skipping to change at page 28, line 48
overridden for that datagram. For example, if the application has overridden for that datagram. For example, if the application has
set IPV6_RTHDR using a sticky option and later passes IPV6_HOPLIMIT set IPV6_RTHDR using a sticky option and later passes IPV6_HOPLIMIT
as ancillary data this will override the IPV6_RTHDR sticky option and as ancillary data this will override the IPV6_RTHDR sticky option and
no Routing header will be sent with that datagram. no Routing header will be sent with that datagram.
5. Extensions to Socket Ancillary Data 5. Extensions to Socket Ancillary Data
This specification uses ancillary data as defined in Posix.1g which This specification uses ancillary data as defined in Posix.1g which
the following compatible extensions: the following compatible extensions:
- CMSG_NEXTHDR has been extended to handle a NULL 2nd argument to - CMSG_NXTHDR has been extended to handle a NULL 2nd argument to
mean "get the first header". See Section 22.3.2. mean "get the first header". See Section 22.3.2.
- A new CMSG_SPACE macro is defined. It is used to determine how - 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 much space need to be allocated for an ancillary data item. See
Section 22.3.4. Section 22.3.4.
- A new CMSG_LEN macro is defined. It returns the value to store - A new CMSG_LEN macro is defined. It returns the value to store
in the cmsg_len member of the cmsghdr structure, taking into in the cmsg_len member of the cmsghdr structure, taking into
account any padding needed to satisfy alignment requirements. account any padding needed to satisfy alignment requirements.
See Section 22.3.5. See Section 22.3.5.
skipping to change at page 29, line 38 skipping to change at page 30, line 38
function to return all the interface names and indexes. Notice from function to return all the interface names and indexes. Notice from
this document that no interface is ever assigned an index of 0. this document that no interface is ever assigned an index of 0.
When specifying the outgoing interface, if the ipi6_ifindex value is When specifying the outgoing interface, if the ipi6_ifindex value is
0, the kernel will choose the outgoing interface. If the application 0, the kernel will choose the outgoing interface. If the application
specifies an outgoing interface for a multicast packet, the interface specifies an outgoing interface for a multicast packet, the interface
specified by the ancillary data overrides any interface specified by specified by the ancillary data overrides any interface specified by
the IPV6_MULTICAST_IF socket option (described in [RFC-2553]), for the IPV6_MULTICAST_IF socket option (described in [RFC-2553]), for
that call to sendmsg() only. that call to sendmsg() only.
When the IPV6_PKTINFO socket option is enabled, the received When the IPV6_RECVPKTINFO socket option is enabled, the received
interface index is always returned as the ipi6_ifindex member of the interface index is always returned as the ipi6_ifindex member of the
in6_pktinfo structure. in6_pktinfo structure.
6.2. Specifying/Receiving Source/Destination Address 6.2. Specifying/Receiving Source/Destination Address
The source IPv6 address can be specified by calling bind() before The source IPv6 address can be specified by calling bind() before
each output operation, but supplying the source address together with each output operation, but supplying the source address together with
the data requires less overhead (i.e., fewer system calls) and the data requires less overhead (i.e., fewer system calls) and
requires less state to be stored and protected in a multithreaded requires less state to be stored and protected in a multithreaded
application. application.
skipping to change at page 31, line 9 skipping to change at page 32, line 9
Nothing special need be done to specify the outgoing hop limit: just Nothing special need be done to specify the outgoing hop limit: just
specify the control information as ancillary data for sendmsg() or specify the control information as ancillary data for sendmsg() or
using setsockopt(). As specified in [RFC-2553], the interpretation using setsockopt(). As specified in [RFC-2553], the interpretation
of the integer hop limit value is of the integer hop limit value is
x < -1: return an error of EINVAL x < -1: return an error of EINVAL
x == -1: use kernel default x == -1: use kernel default
0 <= x <= 255: use x 0 <= x <= 255: use x
x >= 256: return an error of EINVAL 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 6.4. Specifying the Next Hop Address
The IPV6_NEXTHOP ancillary data object specifies the next hop for the The IPV6_NEXTHOP ancillary data object specifies the next hop for the
datagram as a socket address structure. In the cmsghdr structure datagram as a socket address structure. In the cmsghdr structure
containing this ancillary data, the cmsg_level member will be containing this ancillary data, the cmsg_level member will be
IPPROTO_IPV6, the cmsg_type member will be IPV6_NEXTHOP, and the 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 first byte of cmsg_data[] will be the first byte of the socket
address structure. address structure.
This is a privileged option. (Note: It is implementation defined and This is a privileged option. (Note: It is implementation defined and
beyond the scope of this document to define what "privileged" means. beyond the scope of this document to define what "privileged" means.
Unix systems use this term to mean the process must have an effective Unix systems use this term to mean the process must have an effective
user ID of 0.) user ID of 0.)
If the socket address structure contains an IPv6 address (e.g., the If the socket address structure contains an IPv6 address (e.g., the
sin6_family member is AF_INET6), then the node identified by that sin6_family member is AF_INET6), then the node identified by that
address must be a neighbor of the sending host. If that address address must be a neighbor of the sending host. If that address
equals the destination IPv6 address of the datagram, then this is equals the destination IPv6 address of the datagram, then this is
equivalent to the existing SO_DONTROUTE socket option. 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() 6.5. Additional Errors with sendmsg() and setsockopt()
With the IPV6_PKTINFO socket option there are no additional errors With the IPV6_PKTINFO socket option there are no additional errors
possible with the call to recvmsg(). But when specifying the possible with the call to recvmsg(). But when specifying the
outgoing interface or the source address, additional errors are outgoing interface or the source address, additional errors are
possible from sendmsg() or setsockopt(). Note that some possible from sendmsg() or setsockopt(). Note that some
implementations might only be able to return this type of errors for implementations might only be able to return this type of errors for
setsockopt(). The following are examples, but some of these may not setsockopt(). The following are examples, but some of these may not
be provided by some implementations, and some implementations may be provided by some implementations, and some implementations may
define additional errors: define additional errors:
skipping to change at page 32, line 21 skipping to change at page 33, line 29
as an extension header. There can be different types of Routing as an extension header. There can be different types of Routing
headers, but IPv6 currently defines only the Type 0 Routing header headers, but IPv6 currently defines only the Type 0 Routing header
[RFC-2460]. This type supports up to 127 intermediate nodes (limited [RFC-2460]. This type supports up to 127 intermediate nodes (limited
by the length field in the extension header). With this maximum by the length field in the extension header). With this maximum
number of intermediate nodes, a source, and a destination, there are number of intermediate nodes, a source, and a destination, there are
128 hops. 128 hops.
Source routing with IPv4 sockets API (the IP_OPTIONS socket option) Source routing with IPv4 sockets API (the IP_OPTIONS socket option)
requires the application to build the source route in the format that requires the application to build the source route in the format that
appears as the IPv4 header option, requiring intimate knowledge of appears as the IPv4 header option, requiring intimate knowledge of
the IPv4 options format. This IPv6 API, however, defines eight the IPv4 options format. This IPv6 API, however, defines six
functions that the application calls to build and examine a Routing functions that the application calls to build and examine a Routing
header, and the ability to use sticky options or ancillary data to header, and the ability to use sticky options or ancillary data to
communicate this information between the application and the kernel communicate this information between the application and the kernel
using the IPV6_RTHDR option. using the IPV6_RTHDR option.
Three functions build a Routing header: Three functions build a Routing header:
inet6_rth_space() - return #bytes required for Routing header inet6_rth_space() - return #bytes required for Routing header
inet6_rth_init() - initialize buffer data for Routing header inet6_rth_init() - initialize buffer data for Routing header
inet6_rth_add() - add one IPv6 address to the Routing header inet6_rth_add() - add one IPv6 address to the Routing header
skipping to change at page 34, line 4 skipping to change at page 35, line 10
is not supported by this implementation or the number of segments is is not supported by this implementation or the number of segments is
invalid for this type of Routing header. invalid for this type of Routing header.
(Note: This function returns the size but does not allocate the space (Note: This function returns the size but does not allocate the space
required for the ancillary data. This allows an application to required for the ancillary data. This allows an application to
allocate a larger buffer, if other ancillary data objects are allocate a larger buffer, if other ancillary data objects are
desired, since all the ancillary data objects must be specified to desired, since all the ancillary data objects must be specified to
sendmsg() as a single msg_control buffer.) sendmsg() as a single msg_control buffer.)
7.2. inet6_rth_init 7.2. inet6_rth_init
void *inet6_rth_init(void *bp, int bp_len, int type, int segments); 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 This function initializes the buffer pointed to by bp to contain a
Routing header of the specified type and sets ip6r0_len based on the 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 segments parameter. bp_len is only used to verify that the buffer is
large enough. The ip6r0_segleft field is set to zero; large enough. The ip6r_segleft field is set to zero; inet6_rth_add()
inet6_rth_add() will increment it. will increment it.
When the application uses ancillary data the application must When the application uses ancillary data the application must
initialize any cmsghdr fields. initialize any cmsghdr fields.
The caller must allocate the buffer and its size can be determined by The caller must allocate the buffer and its size can be determined by
calling inet6_rth_space(). calling inet6_rth_space().
Upon success the return value is the pointer to the buffer (bp), and Upon success the return value is the pointer to the buffer (bp), and
this is then used as the first argument to the next two functions. this is then used as the first argument to the inet6_rth_add()
Upon an error the return value is NULL. function. Upon an error the return value is NULL.
7.3. inet6_rth_add 7.3. inet6_rth_add
int inet6_rth_add(void *bp, const struct in6_addr *addr); 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 This function adds the IPv6 address pointed to by addr to the end of
the Routing header being constructed. the Routing header being constructed.
If successful, the segleft member of the Routing Header is updated to If successful, the segleft member of the Routing Header is updated to
account for the new address in the Routing header and the return 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 value of the function is 0. Upon an error the return value of the
function is -1. function is -1.
7.4. inet6_rth_reverse 7.4. inet6_rth_reverse
int inet6_rth_reverse(const void *in, void *out) int inet6_rth_reverse(const void *in, void *out);
This function takes a Routing header extension header (pointed to by This function takes a Routing header extension header (pointed to by
the first argument) and writes a new Routing header that sends the first argument) and writes a new Routing header that sends
datagrams along the reverse of that route. Both arguments are datagrams along the reverse of that route. The function reverses the
allowed to point to the same buffer (that is, the reversal can occur order of the addresses and sets the segleft member in the new Routing
in place). 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 The return value of the function is 0 on success, or -1 upon an
error. error.
7.5. inet6_rth_segments 7.5. inet6_rth_segments
int inet6_rth_segments(const void *bp); int inet6_rth_segments(const void *bp);
This function returns the number of segments (addresses) contained in This function returns the number of segments (addresses) contained in
the Routing header described by bp. On success the return value is the Routing header described by bp. On success the return value is
skipping to change at page 38, line 50 skipping to change at page 40, line 11
As described in Section 6 one set of Destination options can appear As described in Section 6 one set of Destination options can appear
before a Routing header, and one set can appear after a Routing 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 header (or in a packet with no Routing header). Each set can consist
of one or more options but each set is a single extension header. of one or more options but each set is a single extension header.
When using ancillary data a Destination options header is passed When using ancillary data a Destination options header is passed
between the application and the kernel as follows: The set preceding between the application and the kernel as follows: The set preceding
a Routing header are specified with the cmsg_level member is set to 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. IPPROTO_IPV6 and the cmsg_type member is set to IPV6_RTHDRDSTOPTS.
Any setsockopt or ancillary data for IPV6_RTHDRDSTOPTS is silently Any setsockopt or ancillary data for IPV6_RTHDRDSTOPTS is silently
ignore when sending packets unless a Routing header is also ignored when sending packets unless a Routing header is also
specified. specified.
The set of Destination options after a Routing header, which are also The set of Destination options after a Routing header, which are also
used when no Routing header is present, are specified with the 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 cmsg_level member is set to IPPROTO_IPV6 and the cmsg_type member is
set to IPV6_DSTOPTS. set to IPV6_DSTOPTS.
The Destination options are normally constructed using the The Destination options are normally constructed using the
inet6_opt_init(), inet6_opt_append(), inet6_opt_finish(), and inet6_opt_init(), inet6_opt_append(), inet6_opt_finish(), and
inet6_set_val() functions, described in Section 10. inet6_set_val() functions, described in Section 10.
skipping to change at page 39, line 42 skipping to change at page 41, line 5
the header. In order to only calculate the size the application must the header. In order to only calculate the size the application must
pass a NULL extbuf and a zero extlen to those functions. pass a NULL extbuf and a zero extlen to those functions.
10.1. inet6_opt_init 10.1. inet6_opt_init
int inet6_opt_init(void *extbuf, size_t extlen); int inet6_opt_init(void *extbuf, size_t extlen);
This function returns the number of bytes needed for the empty This function returns the number of bytes needed for the empty
extension header i.e. without any options. If extbuf is not NULL it extension header i.e. without any options. If extbuf is not NULL it
also initializes the extension header to have the correct length also initializes the extension header to have the correct length
field. If the extlen value is not a positive (i.e., non-zero) field. In that case if the extlen value is not a positive (i.e.,
multiple of 8 the function fails and returns -1. non-zero) multiple of 8 the function fails and returns -1.
10.2. inet6_opt_append 10.2. inet6_opt_append
int inet6_opt_append(void *extbuf, size_t extlen, int prevlen, int inet6_opt_append(void *extbuf, size_t extlen, int prevlen,
uint8_t type, size_t len, uint_t align, uint8_t type, size_t len, uint_t align,
void **databufp); void **databufp);
Prevlen should be the length returned by inet6_opt_init() or a Prevlen should be the length returned by inet6_opt_init() or a
previous inet6_opt_append(). This function returns the updated total previous inet6_opt_append(). This function returns the updated total
length taking into account adding an option with length 'len' and length taking into account adding an option with length 'len' and
alignment 'align'. If extbuf is not NULL then, in addition to alignment 'align'. If extbuf is not NULL then, in addition to
returning the length, the function inserts any needed pad option, returning the length, the function inserts any needed pad option,
initializes the option (setting the type and length fields) and initializes the option (setting the type and length fields) and
skipping to change at page 40, line 18 skipping to change at page 41, line 24
Prevlen should be the length returned by inet6_opt_init() or a Prevlen should be the length returned by inet6_opt_init() or a
previous inet6_opt_append(). This function returns the updated total previous inet6_opt_append(). This function returns the updated total
length taking into account adding an option with length 'len' and length taking into account adding an option with length 'len' and
alignment 'align'. If extbuf is not NULL then, in addition to alignment 'align'. If extbuf is not NULL then, in addition to
returning the length, the function inserts any needed pad option, returning the length, the function inserts any needed pad option,
initializes the option (setting the type and length fields) and initializes the option (setting the type and length fields) and
returns a pointer to the location for the option content in databufp. returns a pointer to the location for the option content in databufp.
If the option does not fit in the extension header buffer the If the option does not fit in the extension header buffer the
function returns -1. function returns -1.
type is the 8-bit option type. len is the length of the option data 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). (i.e. excluding the option type and option length fields).
Once inet6_opt_append() has been called the application can use the Once inet6_opt_append() has been called the application can use the
databuf directly, or use inet6_opt_set_val() to specify the content databuf directly, or use inet6_opt_set_val() to specify the content
of the option. of the option.
The option type must have a value from 2 to 255, inclusive. (0 and 1 The option type must have a value from 2 to 255, inclusive. (0 and 1
are reserved for the Pad1 and PadN options, respectively.) are reserved for the Pad1 and PadN options, respectively.)
The option data length must have a value between 0 and 255, The option data length must have a value between 0 and 255,
skipping to change at page 41, line 13 skipping to change at page 42, line 17
If the necessary pad does not fit in the extension header buffer the If the necessary pad does not fit in the extension header buffer the
function returns -1. function returns -1.
10.4. inet6_opt_set_val 10.4. inet6_opt_set_val
int inet6_opt_set_val(void *databuf, size_t offset, void *val, int inet6_opt_set_val(void *databuf, size_t offset, void *val,
int vallen); int vallen);
Databuf should be a pointer returned by inet6_opt_append(). This 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 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 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 inserted. Offset specifies where in the data portion of the option
the value should be inserted; the first byte after the option type the value should be inserted; the first byte after the option type
and length is accessed by specifying an offset of zero. and length is accessed by specifying an offset of zero.
The function returns the offset for the next field (i.e., offset + The function returns the offset for the next field (i.e., offset +
vallen) which can be used when composing option content with multiple vallen) which can be used when composing option content with multiple
fields. fields.
10.5. inet6_opt_next 10.5. inet6_opt_next
int inet6_opt_next(void *extbuf, size_t extlen, int prevlen, int inet6_opt_next(void *extbuf, size_t extlen, int prevlen,
uint8_t *typep, size_t *lenp, uint8_t *typep, size_t *lenp,
void **databufp); void **databufp);
This function parses received extension headers returning the next This function parses received option extension headers returning the
option. Extbuf and extlen specifies the extension header. Prevlen next option. Extbuf and extlen specifies the extension header.
should either be zero (for the first option) or the length returned Prevlen should either be zero (for the first option) or the length
by a previous call to inet6_opt_next() or inet6_opt_find(). It returned by a previous call to inet6_opt_next() or inet6_opt_find().
specifies the position where to continue scanning the extension It specifies the position where to continue scanning the extension
buffer. The next option is returned by updating typep, lenp, and buffer. The next option is returned by updating typep, lenp, and
databufp. This function returns the updated "previous" length databufp. This function returns the updated "previous" length
computed by advancing past the option that was returned. This computed by advancing past the option that was returned. This
returned "previous" length can then be passed to subsequent calls to returned "previous" length can then be passed to subsequent calls to
inet6_opt_next(). This function does not return any PAD1 or PADN inet6_opt_next(). This function does not return any PAD1 or PADN
options. When there are no more options the return value is -1. 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 10.6. inet6_opt_find
int inet6_opt_find(void *extbuf, size_t extlen, int prevlen, int inet6_opt_find(void *extbuf, size_t extlen, int prevlen,
uint8_t type, size_t *lenp, uint8_t type, size_t *lenp,
void **databufp); void **databufp);
This function is similar to the previously described inet6_opt_next() This function is similar to the previously described inet6_opt_next()
function, except this function lets the caller specify the option function, except this function lets the caller specify the option
type to be searched for, instead of always returning the next option type to be searched for, instead of always returning the next option
in the extension header. in the extension header.
If an option of the specified type is located, the function returns If an option of the specified type is located, the function returns
the updated "previous" total length computed by advancing past the the updated "previous" total length computed by advancing past the
option that was returned and past any options that didn't match the option that was returned and past any options that didn't match the
type. This returned "previous" length can then be passed to type. This returned "previous" length can then be passed to
subsequent calls to inet6_opt_find() for finding the next occurance subsequent calls to inet6_opt_find() for finding the next occurrence
of the same option type. of the same option type.
If an option of the specified type is not located, the return value If an option of the specified type is not located, the return value
is -1. If an error occurs, the return value is -1. is -1. If the option extension header is malformed, the return value
is -1.
10.7. inet6_opt_get_val 10.7. inet6_opt_get_val
int inet6_opt_get_val(void *databuf, size_t offset, void *val, int inet6_opt_get_val(void *databuf, size_t offset, void *val,
int vallen); int vallen);
Databuf should be a pointer returned by inet6_opt_next() or Databuf should be a pointer returned by inet6_opt_next() or
inet6_opt_find(). This function extracts data items of various sizes 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 (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 point to the destination for the extracted data. Offset specifies
from where in the data portion of the option the value should be from where in the data portion of the option the value should be
extracted; the first byte after the option type and length is extracted; the first byte after the option type and length is
accessed by specifying an offset of zero. accessed by specifying an offset of zero.
The function returns the offset for the next field (i.e., offset + The function returns the offset for the next field (i.e., offset +
vallen) which can be used when extracting option content with vallen) which can be used when extracting option content with
multiple fields. XXX Perhaps we should add a note to point out that multiple fields.
robust receivers should verify alignment before calling
inet6_opt_get_val(). XXX Or check alignment and fail by returning
-1?
11. Additional Advanced API Functions 11. Additional Advanced API Functions
11.1. Sending with the Minimum MTU 11.1. Sending with the Minimum MTU
Some applications might not want to incur the overhead of path MTU Some applications might not want to incur the overhead of path MTU
discovery, especially if the applications only send a single datagram discovery, especially if the applications only send a single datagram
to a destination. A potential example is a DNS server. to a destination. A potential example is a DNS server.
This specification defines a mechanism to avoid fragmentation by This specification defines a mechanism to avoid path MTU discovery by
sending at the minimum IPv6 MTU (1280 bytes). This can be enabled sending at the minimum IPv6 MTU [RFC-2460]. If the packet is larger
using the IPV6_USE_MIN_MTU socket option. 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; int on = 1;
setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, &on, sizeof(on)); setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, &on, sizeof(on));
By default, this socket option is disabled. Setting the value to 0 By default, this socket option is disabled. Setting the value to 0
also disables the option. This option can also be sent as ancillary also disables the option. This option can also be sent as ancillary
data. data.
11.2. Path MTU Discovery and UDP 11.2. Path MTU Discovery and UDP
skipping to change at page 43, line 47 skipping to change at page 45, line 6
cmsghdr with cmsg_type set to IPV6_PATHMTU, and cmsg_len will 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 indicate that cmsg_data is 4 bytes long. CMSG_DATA will point to an
integer carrying the path MTU to use. integer carrying the path MTU to use.
11.3. Neighbor Reachability and UDP 11.3. Neighbor Reachability and UDP
UDP and raw socket application might know that communication is UDP and raw socket application might know that communication is
making forward progress i.e. that the path from the node to the next making forward progress i.e. that the path from the node to the next
hop is working. In such a case the applications, similarly to TCP as hop is working. In such a case the applications, similarly to TCP as
specified in [RFC-2461], has the option indicate to the internet specified in [RFC-2461], has the option indicate to the internet
layer that the neighbor is reachable. See section 7.3.1 of layer that the neighbor is reachable. See section 7.3.1 of [RFC-
[RFC-2461]. This could save unneeded neighbor solicitation and 2461]. This could save unneeded neighbor solicitation and neighbor
neighbor advertisement messages. advertisement messages.
This is done by including an ancilary data item with cmsg_type being This is done by including an ancilary data item with cmsg_type being
IPV6_REACHCONF and with no attached CMSG_DATA. 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 12. Ordering of Ancillary Data and IPv6 Extension Headers
Three IPv6 extension headers can be specified by the application and Three IPv6 extension headers can be specified by the application and
returned to the application using ancillary data with sendmsg() and returned to the application using ancillary data with sendmsg() and
recvmsg(): the Routing header, Hop-by-Hop options, and Destination recvmsg(): the Routing header, Hop-by-Hop options, and Destination
options. When multiple ancillary data objects are transferred via options. When multiple ancillary data objects are transferred via
recvmsg() and these objects represent any of these three extension recvmsg() and these objects represent any of these three extension
headers, their placement in the control buffer is directly tied to headers, their placement in the control buffer is directly tied to
their location in the corresponding IPv6 datagram. This API imposes their location in the corresponding IPv6 datagram. This API imposes
some ordering constraints for using these ancillary data objects with some ordering constraints for using these ancillary data objects with
skipping to change at page 46, line 38 skipping to change at page 48, line 6
family is not supported. family is not supported.
15. Summary of New Definitions 15. Summary of New Definitions
The following list summarizes the constants and structure, The following list summarizes the constants and structure,
definitions discussed in this memo, sorted by header. definitions discussed in this memo, sorted by header.
<netinet/icmp6.h> ICMP6_DST_UNREACH <netinet/icmp6.h> ICMP6_DST_UNREACH
<netinet/icmp6.h> ICMP6_DST_UNREACH_ADDR <netinet/icmp6.h> ICMP6_DST_UNREACH_ADDR
<netinet/icmp6.h> ICMP6_DST_UNREACH_ADMIN <netinet/icmp6.h> ICMP6_DST_UNREACH_ADMIN
<netinet/icmp6.h> ICMP6_DST_UNREACH_BEYONDSCOPE
<netinet/icmp6.h> ICMP6_DST_UNREACH_NOPORT <netinet/icmp6.h> ICMP6_DST_UNREACH_NOPORT
<netinet/icmp6.h> ICMP6_DST_UNREACH_NOROUTE <netinet/icmp6.h> ICMP6_DST_UNREACH_NOROUTE
<netinet/icmp6.h> ICMP6_DST_UNREACH_BEYONDSCOPE
<netinet/icmp6.h> ICMP6_ECHO_REPLY <netinet/icmp6.h> ICMP6_ECHO_REPLY
<netinet/icmp6.h> ICMP6_ECHO_REQUEST <netinet/icmp6.h> ICMP6_ECHO_REQUEST
<netinet/icmp6.h> ICMP6_INFOMSG_MASK <netinet/icmp6.h> ICMP6_INFOMSG_MASK
<netinet/icmp6.h> ICMP6_MEMBERSHIP_QUERY
<netinet/icmp6.h> ICMP6_MEMBERSHIP_REDUCTION
<netinet/icmp6.h> ICMP6_MEMBERSHIP_REPORT
<netinet/icmp6.h> ICMP6_PACKET_TOO_BIG <netinet/icmp6.h> ICMP6_PACKET_TOO_BIG
<netinet/icmp6.h> ICMP6_PARAMPROB_HEADER <netinet/icmp6.h> ICMP6_PARAMPROB_HEADER
<netinet/icmp6.h> ICMP6_PARAMPROB_NEXTHEADER <netinet/icmp6.h> ICMP6_PARAMPROB_NEXTHEADER
<netinet/icmp6.h> ICMP6_PARAMPROB_OPTION <netinet/icmp6.h> ICMP6_PARAMPROB_OPTION
<netinet/icmp6.h> ICMP6_PARAM_PROB <netinet/icmp6.h> ICMP6_PARAM_PROB
<netinet/icmp6.h> ICMP6_ROUTER_RENUMBERING
<netinet/icmp6.h> ICMP6_RR_FLAGS_FORCEAPPLY
<netinet/icmp6.h> ICMP6_RR_FLAGS_PREVDONE
<netinet/icmp6.h> ICMP6_RR_FLAGS_REQRESULT
<netinet/icmp6.h> ICMP6_RR_FLAGS_SPECSITE
<netinet/icmp6.h> ICMP6_RR_FLAGS_TEST
<netinet/icmp6.h> ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME
<netinet/icmp6.h> ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME
<netinet/icmp6.h> ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME
<netinet/icmp6.h> ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME
<netinet/icmp6.h> ICMP6_RR_PCOUSE_RAFLAGS_AUTO
<netinet/icmp6.h> ICMP6_RR_PCOUSE_RAFLAGS_ONLINK
<netinet/icmp6.h> ICMP6_RR_RESULT_FLAGS_FORBIDDEN
<netinet/icmp6.h> ICMP6_RR_RESULT_FLAGS_FORBIDDEN
<netinet/icmp6.h> ICMP6_RR_RESULT_FLAGS_OOB
<netinet/icmp6.h> ICMP6_RR_RESULT_FLAGS_OOB
<netinet/icmp6.h> ICMP6_TIME_EXCEEDED <netinet/icmp6.h> ICMP6_TIME_EXCEEDED
<netinet/icmp6.h> ICMP6_TIME_EXCEED_REASSEMBLY <netinet/icmp6.h> ICMP6_TIME_EXCEED_REASSEMBLY
<netinet/icmp6.h> ICMP6_TIME_EXCEED_TRANSIT <netinet/icmp6.h> ICMP6_TIME_EXCEED_TRANSIT
<netinet/icmp6.h> MLD_LISTENER_QUERY
<netinet/icmp6.h> MLD_LISTENER_REDUCTION
<netinet/icmp6.h> MLD_LISTENER_REPORT
<netinet/icmp6.h> ND_NA_FLAG_OVERRIDE <netinet/icmp6.h> ND_NA_FLAG_OVERRIDE
<netinet/icmp6.h> ND_NA_FLAG_ROUTER <netinet/icmp6.h> ND_NA_FLAG_ROUTER
<netinet/icmp6.h> ND_NA_FLAG_SOLICITED <netinet/icmp6.h> ND_NA_FLAG_SOLICITED
<netinet/icmp6.h> ND_NEIGHBOR_ADVERT <netinet/icmp6.h> ND_NEIGHBOR_ADVERT
<netinet/icmp6.h> ND_NEIGHBOR_SOLICIT <netinet/icmp6.h> ND_NEIGHBOR_SOLICIT
<netinet/icmp6.h> ND_OPT_MTU <netinet/icmp6.h> ND_OPT_MTU
<netinet/icmp6.h> ND_OPT_PI_FLAG_AUTO <netinet/icmp6.h> ND_OPT_PI_FLAG_AUTO
<netinet/icmp6.h> ND_OPT_PI_FLAG_ONLINK <netinet/icmp6.h> ND_OPT_PI_FLAG_ONLINK
<netinet/icmp6.h> ND_OPT_PI_FLAG_ROUTER
<netinet/icmp6.h> ND_OPT_PI_FLAG_SITEPREF
<netinet/icmp6.h> ND_OPT_PREFIX_INFORMATION <netinet/icmp6.h> ND_OPT_PREFIX_INFORMATION
<netinet/icmp6.h> ND_OPT_REDIRECTED_HEADER <netinet/icmp6.h> ND_OPT_REDIRECTED_HEADER
<netinet/icmp6.h> ND_OPT_SOURCE_LINKADDR <netinet/icmp6.h> ND_OPT_SOURCE_LINKADDR
<netinet/icmp6.h> ND_OPT_TARGET_LINKADDR <netinet/icmp6.h> ND_OPT_TARGET_LINKADDR
<netinet/icmp6.h> ND_RA_FLAG_HOME_AGENT
<netinet/icmp6.h> ND_RA_FLAG_MANAGED <netinet/icmp6.h> ND_RA_FLAG_MANAGED
<netinet/icmp6.h> ND_RA_FLAG_OTHER <netinet/icmp6.h> ND_RA_FLAG_OTHER
<netinet/icmp6.h> ND_REDIRECT <netinet/icmp6.h> ND_REDIRECT
<netinet/icmp6.h> ND_ROUTER_ADVERT <netinet/icmp6.h> ND_ROUTER_ADVERT
<netinet/icmp6.h> ND_ROUTER_SOLICIT <netinet/icmp6.h> ND_ROUTER_SOLICIT
<netinet/icmp6.h> struct icmp6_filter{}; <netinet/icmp6.h> struct icmp6_filter{};
<netinet/icmp6.h> struct icmp6_hdr{}; <netinet/icmp6.h> struct icmp6_hdr{};
<netinet/icmp6.h> struct icmp6_router_renum{};
<netinet/icmp6.h> struct mld_hdr{};
<netinet/icmp6.h> struct nd_neighbor_advert{}; <netinet/icmp6.h> struct nd_neighbor_advert{};
<netinet/icmp6.h> struct nd_neighbor_solicit{}; <netinet/icmp6.h> struct nd_neighbor_solicit{};
<netinet/icmp6.h> struct nd_opt_hdr{}; <netinet/icmp6.h> struct nd_opt_hdr{};
<netinet/icmp6.h> struct nd_opt_mtu{}; <netinet/icmp6.h> struct nd_opt_mtu{};
<netinet/icmp6.h> struct nd_opt_prefix_info{}; <netinet/icmp6.h> struct nd_opt_prefix_info{};
<netinet/icmp6.h> struct nd_opt_rd_hdr{}; <netinet/icmp6.h> struct nd_opt_rd_hdr{};
<netinet/icmp6.h> struct nd_redirect{}; <netinet/icmp6.h> struct nd_redirect{};
<netinet/icmp6.h> struct nd_router_advert{}; <netinet/icmp6.h> struct nd_router_advert{};
<netinet/icmp6.h> struct nd_router_solicit{}; <netinet/icmp6.h> struct nd_router_solicit{};
<netinet/icmp6.h> struct rr_pco_match{};
<netinet/icmp6.h> struct rr_pco_use{};
<netinet/icmp6.h> struct rr_result{};
<netinet/in.h> IPPROTO_AH <netinet/in.h> IPPROTO_AH
<netinet/in.h> IPPROTO_DSTOPTS <netinet/in.h> IPPROTO_DSTOPTS
<netinet/in.h> IPPROTO_ESP <netinet/in.h> IPPROTO_ESP
<netinet/in.h> IPPROTO_FRAGMENT <netinet/in.h> IPPROTO_FRAGMENT
<netinet/in.h> IPPROTO_HOPOPTS <netinet/in.h> IPPROTO_HOPOPTS
<netinet/in.h> IPPROTO_ICMPV6 <netinet/in.h> IPPROTO_ICMPV6
<netinet/in.h> IPPROTO_IPV6 <netinet/in.h> IPPROTO_IPV6
<netinet/in.h> IPPROTO_NONE <netinet/in.h> IPPROTO_NONE
<netinet/in.h> IPPROTO_ROUTING <netinet/in.h> IPPROTO_ROUTING
<netinet/in.h> IPV6_CHECKSUM
<netinet/in.h> IPV6_DSTOPTS
<netinet/in.h> IPV6_HOPLIMIT
<netinet/in.h> IPV6_HOPOPTS
<netinet/in.h> IPV6_NEXTHOP
<netinet/in.h> IPV6_PATHMTU
<netinet/in.h> IPV6_PKTINFO
<netinet/in.h> IPV6_RECVDSTOPTS <netinet/in.h> IPV6_RECVDSTOPTS
<netinet/in.h> IPV6_RECVHOPLIMIT <netinet/in.h> IPV6_RECVHOPLIMIT
<netinet/in.h> IPV6_RECVHOPOPTS <netinet/in.h> IPV6_RECVHOPOPTS
<netinet/in.h> IPV6_RECVPKTINFO <netinet/in.h> IPV6_RECVPKTINFO
<netinet/in.h> IPV6_RECVRTHDR <netinet/in.h> IPV6_RECVRTHDR
<netinet/in.h> IPV6_RECVRTHDRDSTOPTS <netinet/in.h> IPV6_RECVRTHDRDSTOPTS
<netinet/in.h> IPV6_DSTOPTS
<netinet/in.h> IPV6_HOPLIMIT
<netinet/in.h> IPV6_HOPOPTS
<netinet/in.h> IPV6_NEXTHOP
<netinet/in.h> IPV6_PKTINFO
<netinet/in.h> IPV6_RTHDR <netinet/in.h> IPV6_RTHDR
<netinet/in.h> IPV6_RTHDRDSTOPTS <netinet/in.h> IPV6_RTHDRDSTOPTS
<netinet/in.h> IPV6_RTHDR_TYPE_0 <netinet/in.h> IPV6_RTHDR_TYPE_0
<netinet/in.h> IPV6_USE_MIN_MTU
<netinet/in.h> IPV6_RECVPATHMTU <netinet/in.h> IPV6_RECVPATHMTU
<netinet/in.h> IPV6_PATHMTU
<netinet/in.h> IPV6_REACHCONF <netinet/in.h> IPV6_REACHCONF
<netinet/in.h> IPV6_USE_MIN_MTU
<netinet/in.h> struct in6_pktinfo{}; <netinet/in.h> struct in6_pktinfo{};
<netinet/ip6.h> IP6F_MORE_FRAG
<netinet/ip6.h> IP6F_OFF_MASK <netinet/ip6.h> IP6F_OFF_MASK
<netinet/ip6.h> IP6F_RESERVED_MASK <netinet/ip6.h> IP6F_RESERVED_MASK
<netinet/ip6.h> IP6F_MORE_FRAG <netinet/ip6.h> IP6OPT_BINDING_ACK
<netinet/ip6.h> IP6OPT_BINDING_REQ
<netinet/ip6.h> IP6OPT_BINDING_UPDATE
<netinet/ip6.h> IP6OPT_EID
<netinet/ip6.h> IP6OPT_HOME_ADDRESS
<netinet/ip6.h> IP6OPT_JUMBO
<netinet/ip6.h> IP6OPT_JUMBO_LEN
<netinet/ip6.h> IP6OPT_MUTABLE
<netinet/ip6.h> IP6OPT_NSAP_ADDR
<netinet/ip6.h> IP6OPT_PAD1
<netinet/ip6.h> IP6OPT_PADN
<netinet/ip6.h> IP6OPT_ROUTER_ALERT
<netinet/ip6.h> IP6OPT_TUNNEL_LIMIT
<netinet/ip6.h> IP6OPT_TYPE_DISCARD
<netinet/ip6.h> IP6OPT_TYPE_FORCEICMP
<netinet/ip6.h> IP6OPT_TYPE_ICMP
<netinet/ip6.h> IP6OPT_TYPE_SKIP
<netinet/ip6.h> IP6_ALERT_AN
<netinet/ip6.h> IP6_ALERT_AN
<netinet/ip6.h> IP6_ALERT_MLD
<netinet/ip6.h> IP6_ALERT_MLD
<netinet/ip6.h> IP6_ALERT_RSVP
<netinet/ip6.h> IP6_ALERT_RSVP
<netinet/ip6.h> IP6_BUF_ACK
<netinet/ip6.h> IP6_BUF_COA
<netinet/ip6.h> IP6_BUF_HOME
<netinet/ip6.h> IP6_BUF_ROUTER
<netinet/ip6.h> struct ip6_dest{}; <netinet/ip6.h> struct ip6_dest{};
<netinet/ip6.h> struct ip6_ext{};
<netinet/ip6.h> struct ip6_frag{}; <netinet/ip6.h> struct ip6_frag{};
<netinet/ip6.h> struct ip6_hbh{}; <netinet/ip6.h> struct ip6_hbh{};
<netinet/ip6.h> struct ip6_hdr{}; <netinet/ip6.h> struct ip6_hdr{};
<netinet/ip6.h> struct ip6_opt{};
<netinet/ip6.h> struct ip6_opt_binding_ack{};
<netinet/ip6.h> struct ip6_opt_binding_request{};
<netinet/ip6.h> struct ip6_opt_binding_update{};
<netinet/ip6.h> struct ip6_opt_home_address{};
<netinet/ip6.h> struct ip6_opt_jumbo{};
<netinet/ip6.h> struct ip6_opt_nsap{};
<netinet/ip6.h> struct ip6_opt_router{};
<netinet/ip6.h> struct ip6_opt_tunnel{};
<netinet/ip6.h> struct ip6_rthdr{}; <netinet/ip6.h> struct ip6_rthdr{};
<netinet/ip6.h> struct ip6_rthdr0{}; <netinet/ip6.h> struct ip6_rthdr0{};
<sys/socket.h> struct cmsghdr{};
<sys/socket.h> struct msghdr{};
The following list summarizes the function and macro prototypes The following list summarizes the function and macro prototypes
discussed in this memo, sorted by header. discussed in this memo, sorted by header.
<netinet/icmp6.h> void ICMP6_FILTER_SETBLOCK(int, struct icmp6_filter *); <netinet/icmp6.h> void ICMP6_FILTER_SETBLOCK(int, struct icmp6_filter *);
<netinet/icmp6.h> void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *); <netinet/icmp6.h> void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *);
<netinet/icmp6.h> void ICMP6_FILTER_SETPASS(int, struct icmp6_filter *); <netinet/icmp6.h> void ICMP6_FILTER_SETPASS(int, struct icmp6_filter *);
<netinet/icmp6.h> void ICMP6_FILTER_SETPASSALL(struct icmp6_filter *); <netinet/icmp6.h> void ICMP6_FILTER_SETPASSALL(struct icmp6_filter *);
<netinet/icmp6.h> int ICMP6_FILTER_WILLBLOCK(int, <netinet/icmp6.h> int ICMP6_FILTER_WILLBLOCK(int,
const struct icmp6_filter *); const struct icmp6_filter *);
<netinet/icmp6.h> int ICMP6_FILTER_WILLPASS(int, <netinet/icmp6.h> int ICMP6_FILTER_WILLPASS(int,
const struct icmp6_filter *); const struct icmp6_filter *);
<netinet/in.h> int IN6_ARE_ADDR_EQUAL(const struct in6_addr *, <netinet/in.h> int IN6_ARE_ADDR_EQUAL(const struct in6_addr *,
const struct in6_addr *); const struct in6_addr *);
<netinet/in.h> int inet6_opt_append(void *, size_t, int, <netinet/in.h> int inet6_opt_append(void *, size_t, int,
uint8_t, size_t, uint_8, void **); uint8_t, size_t, uint_t, void **);
<netinet/in.h> int inet6_opt_get_val(void *, size_t, void *, int); <netinet/in.h> int inet6_opt_get_val(void *, size_t, void *, int);
<netinet/in.h> int inet6_opt_find(void *, size_t, int, uint8_t , <netinet/in.h> int inet6_opt_find(void *, size_t, int, uint8_t ,
size_t *, void **); size_t *, void **);
<netinet/in.h> int inet6_opt_finish(void *, size_t, int); <netinet/in.h> int inet6_opt_finish(void *, size_t, int);
<netinet/in.h> int inet6_opt_init(void *, size_t); <netinet/in.h> int inet6_opt_init(void *, size_t);
<netinet/in.h> int inet6_opt_next(void *, size_t, int, uint8_t *, <netinet/in.h> int inet6_opt_next(void *, size_t, int, uint8_t *,
size_t *, void **); size_t *, void **);
<netinet/in.h> int inet6_opt_set_val(void *, size_t, void *, int); <netinet/in.h> int inet6_opt_set_val(void *, size_t, void *, int);
<netinet/in.h> int inet6_rth_add(void *, <netinet/in.h> int inet6_rth_add(void *,
const struct in6_addr *); const struct in6_addr *);
<netinet/in.h> struct in6_addr inet6_rth_getaddr(const void *, <netinet/in.h> struct in6_addr inet6_rth_getaddr(const void *,
int); int);
<netinet/in.h> void *inet6_rth_init(void *, int, int, int); <netinet/in.h> void *inet6_rth_init(void *, int, int, int);
<netinet/in.h> int inet6_rth_reverse(const void *, void *); <netinet/in.h> int inet6_rth_reverse(const void *, void *);
<netinet/in.h> int inet6_rth_segments(const void *); <netinet/in.h> int inet6_rth_segments(const void *);
<netinet/in.h> size_t inet6_rth_space(int, int); <netinet/in.h> size_t inet6_rth_space(int, int);
<sys/socket.h> unsigned char *CMSG_DATA(const struct cmsghdr *); <netinet/ip6.h> int IP6OPT_TYPE(uint8_t);
<sys/socket.h> struct cmsghdr *CMSG_FIRSTHDR(const struct msghdr *);
<sys/socket.h> unsigned int CMSG_LEN(unsigned int); <sys/socket.h> unsigned int CMSG_LEN(unsigned int);
<sys/socket.h> struct cmsghdr *CMSG_NXTHDR(const struct msghdr *mhdr,
const struct cmsghdr *);
<sys/socket.h> unsigned int CMSG_SPACE(unsigned int); <sys/socket.h> unsigned int CMSG_SPACE(unsigned int);
<unistd.h> int rresvport_af(int *, int); <unistd.h> int rresvport_af(int *, int);
<unistd.h> int rcmd_af(char **, unsigned short, const char *, <unistd.h> int rcmd_af(char **, unsigned short, const char *,
const char *, const char *, int *, int); const char *, const char *, int *, int);
<unistd.h> int rexec_af(char **, unsigned short , const char *, <unistd.h> int rexec_af(char **, unsigned short , const char *,
const char *, const char *, int *, int); const char *, const char *, int *, int);
16. Security Considerations 16. Security Considerations
skipping to change at page 52, line 6 skipping to change at page 54, line 30
- Removed the constraints for jumbo option. - Removed the constraints for jumbo option.
- Moved the new CMSG macros and changes from the appendix. - Moved the new CMSG macros and changes from the appendix.
- Add text about inet6_opt_ depending on 2260 appendix B formatting - Add text about inet6_opt_ depending on 2260 appendix B formatting
rules i.e. largest field last in the option. rules i.e. largest field last in the option.
- Specified that getsockopt() of a sticky option returns what was - Specified that getsockopt() of a sticky option returns what was
set with setsockopt(). 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 18. TODO and Open Issues
Items left to do: 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
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 - Add credits for UDP MTU stuff
- Move information about mapping from inet6_opt to setsockopt and - Move information about mapping from inet6_opt to setsockopt and
cmsg. cmsg.
- Clarify IPV6_RTHDRDSTOPTS's interaction with IPV6_RTHDR. - Clarify IPV6_RTHDRDSTOPTS's interaction with IPV6_RTHDR.
- Make the new inet6_opt_set_val() and inet6_opt_get_val() check - Make the new inet6_opt_set_val() and inet6_opt_get_val() check
the length of the data item. 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: 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? - Anything special for mobility options? Restrict setting at API?
Filter out on receipt? If received what does the home address Filter out on receipt? If received what does the home address
option contain? option contain?
- Specify "change" for TCP especially when there are multiple HBH - Specify "change" for TCP especially when there are multiple HBH
option headers etc. option headers etc.
- Specify binding to scope-id => implies filtering of addresses - Specify binding to scope-id => implies filtering of addresses
with that scope if the address you are bound to is link-local with that scope if the address you are bound to is link-local
etc. What about conflicts with bound scope-id and sendto/connect etc. What about conflicts with bound scope-id and sendto/connect
skipping to change at page 52, line 47 skipping to change at page 56, line 19
- bind() and sin6_scope_id. Should have been in Basic API. Error - bind() and sin6_scope_id. Should have been in Basic API. Error
checks when bind/sendto sin6_scope_id does not match? checks when bind/sendto sin6_scope_id does not match?
- Specify notion of default multicast interface? In Basic API? - Specify notion of default multicast interface? In Basic API?
- What about site names and site ids? Need for interfaces to map? - What about site names and site ids? Need for interfaces to map?
Requires that site-prefixes pass name - does name need to use DNS Requires that site-prefixes pass name - does name need to use DNS
format to handle character sets? 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 19. References
[RFC-2460] Deering, S., Hinden, R., "Internet Protocol, Version 6 [RFC-2460] Deering, S., Hinden, R., "Internet Protocol, Version 6
(IPv6), Specification", RFC 2460, Dec. 1998. (IPv6), Specification", RFC 2460, Dec. 1998.
[RFC-2553] Gilligan, R. E., Thomson, S., Bound, J., Stevens, W., [RFC-2553] Gilligan, R. E., Thomson, S., Bound, J., Stevens, W.,
"Basic Socket Interface Extensions for IPv6", RFC 2553, "Basic Socket Interface Extensions for IPv6", RFC 2553,
March 1999. March 1999.
[RFC-1981] McCann, J., Deering, S., Mogul, J, "Path MTU Discovery [RFC-1981] McCann, J., Deering, S., Mogul, J, "Path MTU Discovery
for IP version 6", RFC 1981, Aug. 1996. for IP version 6", RFC 1981, Aug. 1996.
skipping to change at page 57, line 22 skipping to change at page 61, line 14
struct msghdr msg; struct msghdr msg;
struct cmsghdr *cmsgptr; struct cmsghdr *cmsgptr;
/* fill in msg */ /* fill in msg */
/* call recvmsg() */ /* call recvmsg() */
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
if (cmsgptr->cmsg_len == 0) {
/* Error handling */
break;
}
if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) { if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) {
u_char *ptr; u_char *ptr;
ptr = CMSG_DATA(cmsgptr); ptr = CMSG_DATA(cmsgptr);
/* process data pointed to by ptr */ /* process data pointed to by ptr */
} }
} }
We now describe the three Posix.1g macros, followed by two more that 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 new with this API: CMSG_SPACE() and CMSG_LEN(). All these
are defined as a result of including <sys/socket.h>. macros are defined as a result of including <sys/socket.h>.
22.3.1. CMSG_FIRSTHDR 22.3.1. CMSG_FIRSTHDR
struct cmsghdr *CMSG_FIRSTHDR(const struct msghdr *mhdr); struct cmsghdr *CMSG_FIRSTHDR(const struct msghdr *mhdr);
CMSG_FIRSTHDR() returns a pointer to the first cmsghdr structure in CMSG_FIRSTHDR() returns a pointer to the first cmsghdr structure in
the msghdr structure pointed to by mhdr. The macro returns NULL if the msghdr structure pointed to by mhdr. The macro returns NULL if
there is no ancillary data pointed to by the msghdr structure (that 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 is, if either msg_control is NULL or if msg_controllen is less than
the size of a cmsghdr structure). the size of a cmsghdr structure).
skipping to change at page 58, line 29 skipping to change at page 62, line 21
22.3.2. CMSG_NXTHDR 22.3.2. CMSG_NXTHDR
struct cmsghdr *CMSG_NXTHDR(const struct msghdr *mhdr, struct cmsghdr *CMSG_NXTHDR(const struct msghdr *mhdr,
const struct cmsghdr *cmsg); const struct cmsghdr *cmsg);
CMSG_NXTHDR() returns a pointer to the cmsghdr structure describing CMSG_NXTHDR() returns a pointer to the cmsghdr structure describing
the next ancillary data object. mhdr is a pointer to a msghdr 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 structure and cmsg is a pointer to a cmsghdr structure. If there is
not another ancillary data object, the return value is NULL. not another ancillary data object, the return value is NULL.
The following behavior of this macro is new to this API: if the value The following behavior of this macro is new to this API: if the
of the cmsg pointer is NULL, a pointer to the cmsghdr structure value of the cmsg pointer is NULL, a pointer to the cmsghdr structure
describing the first ancillary data object is returned. That is, describing the first ancillary data object is returned. That is,
CMSG_NXTHDR(mhdr, NULL) is equivalent to CMSG_FIRSTHDR(mhdr). If CMSG_NXTHDR(mhdr, NULL) is equivalent to CMSG_FIRSTHDR(mhdr). If
there are no ancillary data objects, the return value is NULL. This there are no ancillary data objects, the return value is NULL. This
provides an alternative way of coding the processing loop shown provides an alternative way of coding the processing loop shown
earlier: earlier:
struct msghdr msg; struct msghdr msg;
struct cmsghdr *cmsgptr = NULL; struct cmsghdr *cmsgptr = NULL;
/* fill in msg */ /* fill in msg */
/* call recvmsg() */ /* call recvmsg() */
while ((cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) != NULL) { while ((cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) != NULL) {
if (cmsgptr->cmsg_len == 0) {
/* Error handling */
break;
}
if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) { if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) {
u_char *ptr; u_char *ptr;
ptr = CMSG_DATA(cmsgptr); ptr = CMSG_DATA(cmsgptr);
/* process data pointed to by ptr */ /* process data pointed to by ptr */
} }
} }
One possible implementation could be: One possible implementation could be:
#define CMSG_NXTHDR(mhdr, cmsg) \ #define CMSG_NXTHDR(mhdr, cmsg) \
(((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \ (((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \
(((u_char *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) \ (((u_char *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) \
+ ALIGN_D(sizeof(struct cmsghdr)) > \ + ALIGN_D(sizeof(struct cmsghdr)) > \
(u_char *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \ (u_char *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \
(struct cmsghdr *)NULL : \ (struct cmsghdr *)NULL : \
(struct cmsghdr *)((u_char *)(cmsg) + ALIGN_H((cmsg)->cmsg_len)))) (struct cmsghdr *)((u_char *)(cmsg) + ALIGN_H((cmsg)->cmsg_len))))
skipping to change at page 62, line 19 skipping to change at page 65, line 36
int cmsglen; int cmsglen;
struct sockaddr_in6 I1, I2, I3, D; struct sockaddr_in6 I1, I2, I3, D;
extlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, 3); extlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, 3);
cmsglen = CMSG_SPACE(extlen); cmsglen = CMSG_SPACE(extlen);
cmsgptr = malloc(cmsglen); cmsgptr = malloc(cmsglen);
cmsgptr->cmsg_len = CMSG_LEN(extlen); cmsgptr->cmsg_len = CMSG_LEN(extlen);
cmsgptr->cmsg_level = IPPROTO_IPV6; cmsgptr->cmsg_level = IPPROTO_IPV6;
cmsgptr->cmsg_type = IPV6_RTHDR; cmsgptr->cmsg_type = IPV6_RTHDR;
optptr = CMSG_DATA(cmsgptr); extptr = CMSG_DATA(cmsgptr);
optptr = inet6_rth_init(optptr, optlen, IPV6_RTHDR_TYPE_0, 3); extptr = inet6_rth_init(extptr, extlen, IPV6_RTHDR_TYPE_0, 3);
inet6_rth_add(optptr, &I1.sin6_addr); inet6_rth_add(extptr, &I1.sin6_addr);
inet6_rth_add(optptr, &I2.sin6_addr); inet6_rth_add(extptr, &I2.sin6_addr);
inet6_rth_add(optptr, &I3.sin6_addr); inet6_rth_add(extptr, &I3.sin6_addr);
msg.msg_control = cmsgptr; msg.msg_control = cmsgptr;
msg.msg_controllen = cmsglen; msg.msg_controllen = cmsglen;
/* finish filling in msg{}, msg_name = D */ /* finish filling in msg{}, msg_name = D */
/* call sendmsg() */ /* call sendmsg() */
We also assume that the source address for the socket is not We also assume that the source address for the socket is not
specified (i.e., the asterisk in the figure). specified (i.e., the asterisk in the figure).
skipping to change at page 67, line 8 skipping to change at page 70, line 8
This example assumes that the application has enabled IPV6_RECVRTHDR This example assumes that the application has enabled IPV6_RECVRTHDR
socket option. The application prints and reverses a source route socket option. The application prints and reverses a source route
and uses that to echo the received data. and uses that to echo the received data.
struct sockaddr_in6 addr; struct sockaddr_in6 addr;
struct msghdr msg; struct msghdr msg;
struct iovec iov; struct iovec iov;
struct cmsghdr *cmsgptr; struct cmsghdr *cmsgptr;
size_t cmsgspace; size_t cmsgspace;
void *optptr; void *extptr;
int optlen; int extlen;
int segments; int segments;
int i; int i;
char databuf[8192]; char databuf[8192];
segments = 100; /* Enough */ segments = 100; /* Enough */
optlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, segments); extlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, segments);
cmsgspace = CMSG_SPACE(optlen); cmsgspace = CMSG_SPACE(extlen);
cmsgptr = malloc(cmsgspace); cmsgptr = malloc(cmsgspace);
if (cmsgptr == NULL) { if (cmsgptr == NULL) {
perror("malloc"); perror("malloc");
exit(1); exit(1);
} }
optptr = CMSG_DATA(cmsgptr); extptr = CMSG_DATA(cmsgptr);
msg.msg_control = (char *)cmsgptr; msg.msg_control = (char *)cmsgptr;
msg.msg_controllen = cmsgspace; msg.msg_controllen = cmsgspace;
msg.msg_name = (struct sockaddr *)&addr; msg.msg_name = (struct sockaddr *)&addr;
msg.msg_namelen = sizeof (addr); msg.msg_namelen = sizeof (addr);
msg.msg_iov = &iov; msg.msg_iov = &iov;
msg.msg_iovlen = 1; msg.msg_iovlen = 1;
iov.iov_base = databuf; iov.iov_base = databuf;
iov.iov_len = sizeof (databuf); iov.iov_len = sizeof (databuf);
msg.msg_flags = 0; msg.msg_flags = 0;
if (recvmsg(s, &msg, 0) == -1) { if (recvmsg(s, &msg, 0) == -1) {
perror("recvmsg"); perror("recvmsg");
return; return;
} }
if (msg.msg_controllen != 0 && if (msg.msg_controllen != 0 &&
cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_level == IPPROTO_IPV6 &&
cmsgptr->cmsg_type == IPV6_RTHDR) { cmsgptr->cmsg_type == IPV6_RTHDR) {
struct in6_addr *in6; struct in6_addr *in6;
char asciiname[INET6_ADDRSTRLEN]; char asciiname[INET6_ADDRSTRLEN];
struct ip6_rthdr0 *rthdr; struct ip6_rthdr *rthdr;
rthdr = (struct ip6_rthdr0 *)optptr; rthdr = (struct ip6_rthdr *)extptr;
segments = inet6_rth_segments(optptr); segments = inet6_rth_segments(extptr);
printf("route (%d segments, %d left): ", printf("route (%d segments, %d left): ",
segments, rthdr->ip6r0_segleft); segments, rthdr->ip6r_segleft);
for (i = 0; i < segments; i++) { for (i = 0; i < segments; i++) {
in6 = inet6_rth_getaddr(optptr, i); in6 = inet6_rth_getaddr(extptr, i);
if (in6 == NULL) if (in6 == NULL)
printf("<NULL> "); printf("<NULL> ");
else else
printf("%s ", inet_ntop(AF_INET6, printf("%s ", inet_ntop(AF_INET6,
(void *)in6->s6_addr, (void *)in6->s6_addr,
asciiname, INET6_ADDRSTRLEN)); asciiname, INET6_ADDRSTRLEN));
} }
if (inet6_rth_reverse(optptr, optptr) == -1) { if (inet6_rth_reverse(extptr, extptr) == -1) {
printf("reverse failed"); printf("reverse failed");
return; return;
} }
} }
iov.iov_base = databuf; iov.iov_base = databuf;
iov.iov_len = strlen(databuf); iov.iov_len = strlen(databuf);
if (sendmsg(s, &msg, 0) == -1) if (sendmsg(s, &msg, 0) == -1)
perror("sendmsg"); perror("sendmsg");
if (cmsgptr != NULL) if (cmsgptr != NULL)
free(cmsgptr); free(cmsgptr);
skipping to change at page 70, line 16 skipping to change at page 73, line 16
/* extbuf and extlen are now completely formatted */ /* extbuf and extlen are now completely formatted */
24.2. Parsing received options 24.2. Parsing received options
This example parses and prints the content of the two options in the This example parses and prints the content of the two options in the
previous example. previous example.
int int
print_opt(void *extbuf, size_t extlen) print_opt(void *extbuf, size_t extlen)
{ {
ip6_dest_t *ext; struct ip6_dest *ext;
int currentlen; int currentlen;
uint8_t type; uint8_t type;
size_t len; size_t len;
void *databuf; void *databuf;
size_t offset; size_t offset;
uint8_t value1; uint8_t value1;
uint16_t value2; uint16_t value2;
uint32_t value4; uint32_t value4;
uint64_t value8; uint64_t value8;
ext = (ip6_dest_t *)extbuf; ext = (struct ip6_dest *)extbuf;
printf("nxt %u, len %u (bytes %d)\n", ext->ip6d_nxt, printf("nxt %u, len %u (bytes %d)\n", ext->ip6d_nxt,
ext->ip6d_len, (ext->ip6d_len + 1) * 8); ext->ip6d_len, (ext->ip6d_len + 1) * 8);
currentlen = 0; currentlen = 0;
while (1) { while (1) {
currentlen = inet6_opt_next(extbuf, extlen, currentlen, currentlen = inet6_opt_next(extbuf, extlen, currentlen,
&type, &len, &databuf); &type, &len, &databuf);
if (currentlen == -1) if (currentlen == -1)
break; break;
printf("Received opt %u len %u\n", printf("Received opt %u len %u\n",
 End of changes. 121 change blocks. 
185 lines changed or deleted 371 lines changed or added

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