idnits 2.17.1 draft-ietf-ipngwg-rfc2292bis-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** Looks like you're using RFC 2026 boilerplate. This must be updated to follow RFC 3978/3979, as updated by RFC 4748. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- ** Missing expiration date. The document expiration date should appear on the first and last page. == No 'Intended status' indicated for this document; assuming Proposed Standard == It seems as if not all pages are separated by form feeds - found 0 form feeds but 71 pages Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** The document seems to lack separate sections for Informative/Normative References. All references will be assumed normative when checking for downward references. ** There are 162 instances of too long lines in the document, the longest one being 12 characters in excess of 72. ** The abstract seems to contain references ([RFC-2553]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. == There are 5 instances of lines with non-RFC2606-compliant FQDNs in the document. ** The document seems to lack a both a reference to RFC 2119 and the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. RFC 2119 keyword, line 826: '... via raw sockets MUST be in network by...' Miscellaneous warnings: ---------------------------------------------------------------------------- == Line 278 has weird spacing: '...ip6_vfc ip6_...' == Line 279 has weird spacing: '...p6_flow ip6_c...' == Line 280 has weird spacing: '...p6_plen ip6_c...' == Line 281 has weird spacing: '...ip6_nxt ip6_...' == Line 282 has weird spacing: '...p6_hlim ip6_c...' == (39 more instances...) -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (Oct 22, 1999) is 8953 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '4' on line 501 -- Looks like a reference, but probably isn't: '2' on line 2819 -- Looks like a reference, but probably isn't: '16' on line 484 -- Looks like a reference, but probably isn't: '1' on line 2811 -- Looks like a reference, but probably isn't: '0' on line 705 -- Looks like a reference, but probably isn't: '8' on line 995 -- Looks like a reference, but probably isn't: '3' on line 2827 -- Looks like a reference, but probably isn't: '8192' on line 2852 ** Obsolete normative reference: RFC 2460 (Obsoleted by RFC 8200) ** Obsolete normative reference: RFC 2553 (Obsoleted by RFC 3493) ** Obsolete normative reference: RFC 1981 (Obsoleted by RFC 8201) ** Obsolete normative reference: RFC 2461 (Obsoleted by RFC 4861) Summary: 11 errors (**), 0 flaws (~~), 9 warnings (==), 11 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 1 INTERNET-DRAFT W. Richard Stevens (Consultant) 2 Expires: December 24, 1999 Matt Thomas (Consultant) 3 Obsoletes RFC 2292 Erik Nordmark (Sun) 4 Oct 22, 1999 6 Advanced Sockets API for IPv6 7 9 Abstract 11 A separate specification [RFC-2553] contain changes to the sockets 12 API to support IP version 6. Those changes are for TCP and UDP-based 13 applications and will support most end-user applications in use 14 today: Telnet and FTP clients and servers, HTTP clients and servers, 15 and the like. 17 But another class of applications exists that will also be run under 18 IPv6. We call these "advanced" applications and today this includes 19 programs such as Ping, Traceroute, routing daemons, multicast routing 20 daemons, router discovery daemons, and the like. The API feature 21 typically used by these programs that make them "advanced" is a raw 22 socket to access ICMPv4, IGMPv4, or IPv4, along with some knowledge 23 of the packet header formats used by these protocols. To provide 24 portability for applications that use raw sockets under IPv6, some 25 standardization is needed for the advanced API features. 27 There are other features of IPv6 that some applications will need to 28 access: interface identification (specifying the outgoing interface 29 and determining the incoming interface) and IPv6 extension headers 30 that are not addressed in [RFC-2553]: The Routing header (source 31 routing), Hop-by-Hop options, and Destination options. This document 32 provides API access to these features too. 34 Status of this Memo 36 This document is an Internet-Draft and is in full conformance with 37 all provisions of Section 10 of RFC2026. 39 Internet-Drafts are working documents of the Internet Engineering 40 Task Force (IETF), its areas, and its working groups. Note that 41 other groups may also distribute working documents as Internet- 42 Drafts. 44 Internet-Drafts are draft documents valid for a maximum of six months 45 and may be updated, replaced, or obsoleted by other documents at any 46 time. It is inappropriate to use Internet-Drafts as reference 47 material or to cite them other than as "work in progress." 49 The list of current Internet-Drafts can be accessed at 50 http://www.ietf.org/ietf/1id-abstracts.txt 52 The list of Internet-Draft Shadow Directories can be accessed at 53 http://www.ietf.org/shadow.html. 55 This Internet Draft expires April 22, 2000. 57 Table of Contents 59 1. Introduction .................................................... 6 61 2. Common Structures and Definitions ............................... 7 62 2.1. The ip6_hdr Structure ...................................... 8 63 2.1.1. IPv6 Next Header Values ............................. 8 64 2.1.2. IPv6 Extension Headers .............................. 9 65 2.1.3. IPv6 Options ........................................ 10 66 2.2. The icmp6_hdr Structure .................................... 12 67 2.2.1. ICMPv6 Type and Code Values ......................... 13 68 2.2.2. ICMPv6 Neighbor Discovery Type and Code Values ...... 14 69 2.2.3. Multicast Listener Discovery Type and Code Values ... 16 70 2.2.4. ICMPv6 Router Renumbering Type and Code Values ...... 17 71 2.3. Address Testing Macros ..................................... 19 72 2.4. Protocols File ............................................. 19 74 3. IPv6 Raw Sockets ................................................ 20 75 3.1. Checksums .................................................. 21 76 3.2. ICMPv6 Type Filtering ...................................... 21 78 4. Access to IPv6 and Extension Headers ............................ 24 79 4.1. TCP Implications ........................................... 26 80 4.2. UDP and Raw Socket Implications ............................ 27 82 5. Extensions to Socket Ancillary Data ............................. 27 84 6. Packet Information .............................................. 28 85 6.1. Specifying/Receiving the Interface ......................... 29 86 6.2. Specifying/Receiving Source/Destination Address ............ 29 87 6.3. Specifying/Receiving the Hop Limit ......................... 30 88 6.4. Specifying the Next Hop Address ............................ 31 89 6.5. Additional Errors with sendmsg() and setsockopt() .......... 31 91 7. Routing Header Option ........................................... 32 92 7.1. inet6_rth_space ............................................ 33 93 7.2. inet6_rth_init ............................................. 33 94 7.3. inet6_rth_add .............................................. 34 95 7.4. inet6_rth_reverse .......................................... 34 96 7.5. inet6_rth_segments ......................................... 35 97 7.6. inet6_rth_getaddr .......................................... 35 99 8. Hop-By-Hop Options .............................................. 35 100 8.1. Receiving Hop-by-Hop Options ............................... 36 101 8.2. Sending Hop-by-Hop Options ................................. 37 103 9. Destination Options ............................................. 37 104 9.1. Receiving Destination Options .............................. 37 105 9.2. Sending Destination Options ................................ 38 107 10. Hop-by-Hop and Destination Options Processing ................... 39 108 10.1. inet6_opt_init ............................................ 39 109 10.2. inet6_opt_append .......................................... 39 110 10.3. inet6_opt_finish .......................................... 40 111 10.4. inet6_opt_set_val ......................................... 41 112 10.5. inet6_opt_next ............................................ 41 113 10.6. inet6_opt_find ............................................ 41 114 10.7. inet6_opt_get_val ......................................... 42 116 11. Additional Advanced API Functions ............................... 42 117 11.1. Sending with the Minimum MTU .............................. 42 118 11.2. Path MTU Discovery and UDP ................................ 43 119 11.3. Neighbor Reachability and UDP ............................. 43 121 12. Ordering of Ancillary Data and IPv6 Extension Headers ........... 44 123 13. IPv6-Specific Options with IPv4-Mapped IPv6 Addresses ........... 44 125 14. Extended interfaces for rresvport, rcmd and rexec ............... 45 126 14.1. rresvport_af .............................................. 45 127 14.2. rcmd_af ................................................... 45 128 14.3. rexec_af .................................................. 46 130 15. Summary of New Definitions ...................................... 46 132 16. Security Considerations ......................................... 49 134 17. Change History .................................................. 49 136 18. TODO and Open Issues ............................................ 52 138 19. References ...................................................... 52 140 20. Acknowledgments ................................................. 53 142 21. Authors' Addresses .............................................. 53 144 22. Appendix A: Ancillary Data Overview ............................. 54 145 22.1. The msghdr Structure ...................................... 54 146 22.2. The cmsghdr Structure ..................................... 55 147 22.3. Ancillary Data Object Macros .............................. 57 148 22.3.1. CMSG_FIRSTHDR ...................................... 57 149 22.3.2. CMSG_NXTHDR ........................................ 58 150 22.3.3. CMSG_DATA .......................................... 59 151 22.3.4. CMSG_SPACE ......................................... 60 152 22.3.5. CMSG_LEN ........................................... 60 154 23. Appendix B: Examples using the inet6_rth_XXX() functions ........ 61 155 23.1. Sending a Routing Header .................................. 61 156 23.2. Receiving Routing Headers ................................. 66 158 24. Appendix C: Examples using the inet6_opt_XXX() functions ........ 68 159 24.1. Building options .......................................... 68 160 24.2. Parsing received options .................................. 70 162 1. Introduction 164 A separate specification [RFC-2553] contain changes to the sockets 165 API to support IP version 6. Those changes are for TCP and UDP-based 166 applications. This document defines some the "advanced" features of 167 the sockets API that are required for applications to take advantage 168 of additional features of IPv6. 170 Today, the portability of applications using IPv4 raw sockets is 171 quite high, but this is mainly because most IPv4 implementations 172 started from a common base (the Berkeley source code) or at least 173 started with the Berkeley header files. This allows programs such as 174 Ping and Traceroute, for example, to compile with minimal effort on 175 many hosts that support the sockets API. With IPv6, however, there 176 is no common source code base that implementors are starting from, 177 and the possibility for divergence at this level between different 178 implementations is high. To avoid a complete lack of portability 179 amongst applications that use raw IPv6 sockets, some standardization 180 is necessary. 182 There are also features from the basic IPv6 specification that are 183 not addressed in [RFC-2553]: sending and receiving Routing headers, 184 Hop-by-Hop options, and Destination options, specifying the outgoing 185 interface, and being told of the receiving interface. 187 This document can be divided into the following main sections. 189 1. Definitions of the basic constants and structures required for 190 applications to use raw IPv6 sockets. This includes structure 191 definitions for the IPv6 and ICMPv6 headers and all associated 192 constants (e.g., values for the Next Header field). 194 2. Some basic semantic definitions for IPv6 raw sockets. For 195 example, a raw ICMPv4 socket requires the application to 196 calculate and store the ICMPv4 header checksum. But with IPv6 197 this would require the application to choose the source IPv6 198 address because the source address is part of the pseudo header 199 that ICMPv6 now uses for its checksum computation. It should be 200 defined that with a raw ICMPv6 socket the kernel always 201 calculates and stores the ICMPv6 header checksum. 203 3. Packet information: how applications can obtain the received 204 interface, destination address, and received hop limit, along 205 with specifying these values on a per-packet basis. There are a 206 class of applications that need this capability and the technique 207 should be portable. 209 4. Access to the optional Routing header, Hop-by-Hop, and 210 Destination extension headers. 212 5. Additional features required for improved IPv6 application 213 portability. 215 The packet information along with access to the extension headers 216 (Routing header, Hop-by-Hop options, and Destination options) are 217 specified using the "ancillary data" fields that were added to the 218 4.3BSD Reno sockets API in 1990. The reason is that these ancillary 219 data fields are part of the Posix.1g standard and should therefore be 220 adopted by most vendors. 222 This document does not address application access to either the 223 authentication header or the encapsulating security payload header. 225 All examples in this document omit error checking in favor of brevity 226 and clarity. 228 We note that many of the functions and socket options defined in this 229 document may have error returns that are not defined in this 230 document. Many of these possible error returns will be recognized 231 only as implementations proceed. 233 Datatypes in this document follow the Posix.1g format: intN_t means a 234 signed integer of exactly N bits (e.g., int16_t) and uintN_t means an 235 unsigned integer of exactly N bits (e.g., uint32_t). 237 Note that we use the (unofficial) terminology ICMPv4, IGMPv4, and 238 ARPv4 to avoid any confusion with the newer ICMPv6 protocol. 240 2. Common Structures and Definitions 242 Many advanced applications examine fields in the IPv6 header and set 243 and examine fields in the various ICMPv6 headers. Common structure 244 definitions for these protocol headers are required, along with 245 common constant definitions for the structure members. 247 This API assumes that the fields in the protocol headers are left in 248 the network byte order, which is big-endian for the Internet 249 protocols. If not, then either these constants or the fields being 250 tested must be converted at run-time, using something like htons() or 251 htonl(). 253 Two new header files are defined: and 254 . 256 When an include file is specified, that include file is allowed to 257 include other files that do the actual declaration or definition. 259 2.1. The ip6_hdr Structure 261 The following structure is defined as a result of including 262 . Note that this is a new header. 264 struct ip6_hdr { 265 union { 266 struct ip6_hdrctl { 267 uint32_t ip6_un1_flow; /* 4 bits version, 8 bits TC, 24 bits flow-ID */ 268 uint16_t ip6_un1_plen; /* payload length */ 269 uint8_t ip6_un1_nxt; /* next header */ 270 uint8_t ip6_un1_hlim; /* hop limit */ 271 } ip6_un1; 272 uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits tclass */ 273 } ip6_ctlun; 274 struct in6_addr ip6_src; /* source address */ 275 struct in6_addr ip6_dst; /* destination address */ 276 }; 278 #define ip6_vfc ip6_ctlun.ip6_un2_vfc 279 #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow 280 #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen 281 #define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt 282 #define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim 283 #define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim 285 2.1.1. IPv6 Next Header Values 287 IPv6 defines many new values for the Next Header field. The 288 following constants are defined as a result of including 289 . 291 #define IPPROTO_HOPOPTS 0 /* IPv6 Hop-by-Hop options */ 292 #define IPPROTO_IPV6 41 /* IPv6 header */ 293 #define IPPROTO_ROUTING 43 /* IPv6 Routing header */ 294 #define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ 295 #define IPPROTO_ESP 50 /* encapsulating security payload */ 296 #define IPPROTO_AH 51 /* authentication header */ 297 #define IPPROTO_ICMPV6 58 /* ICMPv6 */ 298 #define IPPROTO_NONE 59 /* IPv6 no next header */ 299 #define IPPROTO_DSTOPTS 60 /* IPv6 Destination options */ 301 Berkeley-derived IPv4 implementations also define IPPROTO_IP to be 0. 303 This should not be a problem since IPPROTO_IP is used only with IPv4 304 sockets and IPPROTO_HOPOPTS only with IPv6 sockets. 306 2.1.2. IPv6 Extension Headers 308 Six extension headers are defined for IPv6. We define structures for 309 all except the Authentication header and Encapsulating Security 310 Payload header, both of which are beyond the scope of this document. 311 The following structures are defined as a result of including 312 . 314 /* Hop-by-Hop options header */ 315 struct ip6_hbh { 316 uint8_t ip6h_nxt; /* next header */ 317 uint8_t ip6h_len; /* length in units of 8 octets */ 318 /* followed by options */ 319 }; 321 /* Destination options header */ 322 struct ip6_dest { 323 uint8_t ip6d_nxt; /* next header */ 324 uint8_t ip6d_len; /* length in units of 8 octets */ 325 /* followed by options */ 326 }; 328 /* Routing header */ 329 struct ip6_rthdr { 330 uint8_t ip6r_nxt; /* next header */ 331 uint8_t ip6r_len; /* length in units of 8 octets */ 332 uint8_t ip6r_type; /* routing type */ 333 uint8_t ip6r_segleft; /* segments left */ 334 /* followed by routing type specific data */ 335 }; 337 /* Type 0 Routing header */ 338 struct ip6_rthdr0 { 339 uint8_t ip6r0_nxt; /* next header */ 340 uint8_t ip6r0_len; /* length in units of 8 octets */ 341 uint8_t ip6r0_type; /* always zero */ 342 uint8_t ip6r0_segleft; /* segments left */ 343 uint32_t ip6r0_reserved; /* reserved field */ 344 /* followed by up to 127 struct in6_addr */ 345 }; 347 /* Fragment header */ 348 struct ip6_frag { 349 uint8_t ip6f_nxt; /* next header */ 350 uint8_t ip6f_reserved; /* reserved field */ 351 uint16_t ip6f_offlg; /* offset, reserved, and flag */ 352 uint32_t ip6f_ident; /* identification */ 353 }; 355 #if BYTE_ORDER == BIG_ENDIAN 356 #define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */ 357 #define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */ 358 #define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */ 359 #else /* BYTE_ORDER == LITTLE_ENDIAN */ 360 #define IP6F_OFF_MASK 0xf8ff /* mask out offset from _offlg */ 361 #define IP6F_RESERVED_MASK 0x0600 /* reserved bits in ip6f_offlg */ 362 #define IP6F_MORE_FRAG 0x0100 /* more-fragments flag */ 363 #endif 365 2.1.3. IPv6 Options 367 Eleven options are defined for IPv6 at the time of writing this 368 document. We define structures for all except the unspecified EID 369 option. The following structures are defined as a result of 370 including . 372 /* IPv6 options */ 373 structip6_opt { 374 uint8_tip6o_type; 375 uint8_tip6o_len; 376 }; 378 /* 379 * The high-order 3 bits of the option type define the behavior 380 * when processing an unknown option and whether or not the option 381 * content changes in flight. 382 */ 383 #defineIP6OPT_TYPE(o)((o) & 0xc0) 384 #defineIP6OPT_TYPE_SKIP0x00 385 #defineIP6OPT_TYPE_DISCARD0x40 386 #defineIP6OPT_TYPE_FORCEICMP0x80 387 #defineIP6OPT_TYPE_ICMP0xc0 388 #defineIP6OPT_MUTABLE0x20 390 #defineIP6OPT_PAD10x00/* 00 0 00000 */ 391 #defineIP6OPT_PADN0x01/* 00 0 00001 */ 392 #defineIP6OPT_JUMBO0xc2/* 11 0 00010 = 194 */ 393 #defineIP6OPT_NSAP_ADDR0xc3/* 11 0 00011 */ 394 #defineIP6OPT_TUNNEL_LIMIT0x04/* 00 0 00100 */ 395 #defineIP6OPT_ROUTER_ALERT0x05/* 00 0 00101 */ 396 #defineIP6OPT_BINDING_UPDATE0xc6/* 11 0 00110 */ 397 #defineIP6OPT_BINDING_ACK0x07/* 00 0 00111 */ 398 #defineIP6OPT_BINDING_REQ0x08/* 00 0 01000 */ 399 #defineIP6OPT_HOME_ADDRESS0xc9/* 11 0 01001 */ 400 #defineIP6OPT_EID0x8a/* 10 0 01010 */ 402 /* Jumbo Payload Option */ 403 structip6_opt_jumbo { 404 uint8_tip6oj_type; 405 uint8_tip6oj_len; 406 uint8_t ip6oj_jumbo_len[4]; 407 }; 408 #defineIP6OPT_JUMBO_LEN6 410 /* NSAP Address Option */ 411 structip6_opt_nsap { 412 uint8_tip6on_type; 413 uint8_tip6on_len; 414 uint8_t ip6on_src_nsap_len; 415 uint8_t ip6on_dst_nsap_len; 416 /* followed by source NSAP */ 417 /* followed by destination NSAP */ 418 }; 420 /* Tunnel Limit Option */ 421 structip6_opt_tunnel { 422 uint8_tip6ot_type; 423 uint8_tip6ot_len; 424 uint8_t ip6ot_encap_limit; 425 }; 427 /* Router Alert Option */ 428 structip6_opt_router { 429 uint8_tip6or_type; 430 uint8_tip6or_len; 431 uint8_t ip6or_value[2]; 432 }; 434 /* Router alert values (in network byte order) */ 435 #ifdef _BIG_ENDIAN 436 #defineIP6_ALERT_MLD0x0000 437 #defineIP6_ALERT_RSVP0x0001 438 #defineIP6_ALERT_AN0x0002 439 #else 440 #defineIP6_ALERT_MLD0x0000 441 #defineIP6_ALERT_RSVP0x0100 442 #defineIP6_ALERT_AN0x0200 443 #endif 444 /* Binding Update Option */ 445 structip6_opt_binding_update { 446 uint8_tip6ou_type; 447 uint8_tip6ou_len; 448 uint8_t ip6ou_flags; 449 uint8_t ip6ou_prefixlen; 450 uint8_t ip6ou_seqno[2]; 451 uint8_t ip6ou_lifetime[4]; 452 uint8_t ip6ou_coa[16];/* Optional based on flags */ 453 /* followed by sub-options */ 454 }; 456 /* Binding Update Flags */ 457 #defineIP6_BUF_ACK0x80/* Request a binding ack */ 458 #defineIP6_BUF_HOME0x40/* Home Registration */ 459 #defineIP6_BUF_COA0x20/* Care-of-address present in option */ 460 #defineIP6_BUF_ROUTER0x10/* Sending mobile node is a router */ 462 /* Binding Ack Option */ 463 structip6_opt_binding_ack { 464 uint8_tip6oa_type; 465 uint8_tip6oa_len; 466 uint8_t ip6oa_status; 467 uint8_t ip6oa_seqno[2]; 468 uint8_t ip6oa_lifetime[4]; 469 uint8_t ip6oa_refresh[4]; 470 /* followed by sub-options */ 471 }; 473 /* Binding Request Option */ 474 structip6_opt_binding_request { 475 uint8_tip6or_type; 476 uint8_tip6or_len; 477 /* followed by sub-options */ 478 }; 480 /* Home Address Option */ 481 structip6_opt_home_address { 482 uint8_tip6oh_type; 483 uint8_tip6oh_len; 484 uint8_t ip6oh_addr[16];/* Home Address */ 485 /* followed by sub-options */ 486 }; 488 2.2. The icmp6_hdr Structure 489 The ICMPv6 header is needed by numerous IPv6 applications including 490 Ping, Traceroute, router discovery daemons, and neighbor discovery 491 daemons. The following structure is defined as a result of including 492 . Note that this is a new header. 494 struct icmp6_hdr { 495 uint8_t icmp6_type; /* type field */ 496 uint8_t icmp6_code; /* code field */ 497 uint16_t icmp6_cksum; /* checksum field */ 498 union { 499 uint32_t icmp6_un_data32[1]; /* type-specific field */ 500 uint16_t icmp6_un_data16[2]; /* type-specific field */ 501 uint8_t icmp6_un_data8[4]; /* type-specific field */ 502 } icmp6_dataun; 503 }; 505 #define icmp6_data32 icmp6_dataun.icmp6_un_data32 506 #define icmp6_data16 icmp6_dataun.icmp6_un_data16 507 #define icmp6_data8 icmp6_dataun.icmp6_un_data8 508 #define icmp6_pptr icmp6_data32[0] /* parameter prob */ 509 #define icmp6_mtu icmp6_data32[0] /* packet too big */ 510 #define icmp6_id icmp6_data16[0] /* echo request/reply */ 511 #define icmp6_seq icmp6_data16[1] /* echo request/reply */ 512 #define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */ 514 2.2.1. ICMPv6 Type and Code Values 516 In addition to a common structure for the ICMPv6 header, common 517 definitions are required for the ICMPv6 type and code fields. The 518 following constants are also defined as a result of including 519 . 521 #define ICMP6_DST_UNREACH 1 522 #define ICMP6_PACKET_TOO_BIG 2 523 #define ICMP6_TIME_EXCEEDED 3 524 #define ICMP6_PARAM_PROB 4 526 #define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */ 528 #define ICMP6_ECHO_REQUEST 128 529 #define ICMP6_ECHO_REPLY 129 530 #define ICMP6_MEMBERSHIP_QUERY 130 531 #define ICMP6_MEMBERSHIP_REPORT 131 532 #define ICMP6_MEMBERSHIP_REDUCTION 132 534 #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ 535 #define ICMP6_DST_UNREACH_ADMIN 1 /* communication with */ 536 /* destination */ 537 /* admin. prohibited */ 538 #define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ 539 #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ 540 #define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */ 542 #define ICMP6_TIME_EXCEED_TRANSIT 0 /* Hop Limit == 0 in transit */ 543 #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */ 545 #define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ 546 #define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized Next Header */ 547 #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */ 549 The five ICMP message types defined by IPv6 neighbor discovery 550 (133-137) are defined in the next section. 552 2.2.2. ICMPv6 Neighbor Discovery Type and Code Values 554 The following structures and definitions are defined as a result of 555 including . 557 #define ND_ROUTER_SOLICIT 133 558 #define ND_ROUTER_ADVERT 134 559 #define ND_NEIGHBOR_SOLICIT 135 560 #define ND_NEIGHBOR_ADVERT 136 561 #define ND_REDIRECT 137 563 struct nd_router_solicit { /* router solicitation */ 564 struct icmp6_hdr nd_rs_hdr; 565 /* could be followed by options */ 566 }; 568 #define nd_rs_type nd_rs_hdr.icmp6_type 569 #define nd_rs_code nd_rs_hdr.icmp6_code 570 #define nd_rs_cksum nd_rs_hdr.icmp6_cksum 571 #define nd_rs_reserved nd_rs_hdr.icmp6_data32[0] 573 struct nd_router_advert { /* router advertisement */ 574 struct icmp6_hdr nd_ra_hdr; 575 uint32_t nd_ra_reachable; /* reachable time */ 576 uint32_t nd_ra_retransmit; /* retransmit timer */ 577 /* could be followed by options */ 578 }; 580 #define nd_ra_type nd_ra_hdr.icmp6_type 581 #define nd_ra_code nd_ra_hdr.icmp6_code 582 #define nd_ra_cksum nd_ra_hdr.icmp6_cksum 583 #define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0] 584 #define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1] 585 #define ND_RA_FLAG_MANAGED 0x80 586 #define ND_RA_FLAG_OTHER 0x40 587 #define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1] 589 struct nd_neighbor_solicit { /* neighbor solicitation */ 590 struct icmp6_hdr nd_ns_hdr; 591 struct in6_addr nd_ns_target; /* target address */ 592 /* could be followed by options */ 593 }; 595 #define nd_ns_type nd_ns_hdr.icmp6_type 596 #define nd_ns_code nd_ns_hdr.icmp6_code 597 #define nd_ns_cksum nd_ns_hdr.icmp6_cksum 598 #define nd_ns_reserved nd_ns_hdr.icmp6_data32[0] 600 struct nd_neighbor_advert { /* neighbor advertisement */ 601 struct icmp6_hdr nd_na_hdr; 602 struct in6_addr nd_na_target; /* target address */ 603 /* could be followed by options */ 604 }; 606 #define nd_na_type nd_na_hdr.icmp6_type 607 #define nd_na_code nd_na_hdr.icmp6_code 608 #define nd_na_cksum nd_na_hdr.icmp6_cksum 609 #define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0] 610 #if BYTE_ORDER == BIG_ENDIAN 611 #define ND_NA_FLAG_ROUTER 0x80000000 612 #define ND_NA_FLAG_SOLICITED 0x40000000 613 #define ND_NA_FLAG_OVERRIDE 0x20000000 614 #else /* BYTE_ORDER == LITTLE_ENDIAN */ 615 #define ND_NA_FLAG_ROUTER 0x00000080 616 #define ND_NA_FLAG_SOLICITED 0x00000040 617 #define ND_NA_FLAG_OVERRIDE 0x00000020 618 #endif 620 struct nd_redirect { /* redirect */ 621 struct icmp6_hdr nd_rd_hdr; 622 struct in6_addr nd_rd_target; /* target address */ 623 struct in6_addr nd_rd_dst; /* destination address */ 624 /* could be followed by options */ 625 }; 627 #define nd_rd_type nd_rd_hdr.icmp6_type 628 #define nd_rd_code nd_rd_hdr.icmp6_code 629 #define nd_rd_cksum nd_rd_hdr.icmp6_cksum 630 #define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] 632 struct nd_opt_hdr { /* Neighbor discovery option header */ 633 uint8_t nd_opt_type; 634 uint8_t nd_opt_len; /* in units of 8 octets */ 635 /* followed by option specific data */ 636 }; 638 #define ND_OPT_SOURCE_LINKADDR 1 639 #define ND_OPT_TARGET_LINKADDR 2 640 #define ND_OPT_PREFIX_INFORMATION 3 641 #define ND_OPT_REDIRECTED_HEADER 4 642 #define ND_OPT_MTU 5 644 struct nd_opt_prefix_info { /* prefix information */ 645 uint8_t nd_opt_pi_type; 646 uint8_t nd_opt_pi_len; 647 uint8_t nd_opt_pi_prefix_len; 648 uint8_t nd_opt_pi_flags_reserved; 649 uint32_t nd_opt_pi_valid_time; 650 uint32_t nd_opt_pi_preferred_time; 651 uint32_t nd_opt_pi_reserved2; 652 struct in6_addr nd_opt_pi_prefix; 653 }; 655 #define ND_OPT_PI_FLAG_ONLINK 0x80 656 #define ND_OPT_PI_FLAG_AUTO 0x40 658 struct nd_opt_rd_hdr { /* redirected header */ 659 uint8_t nd_opt_rh_type; 660 uint8_t nd_opt_rh_len; 661 uint16_t nd_opt_rh_reserved1; 662 uint32_t nd_opt_rh_reserved2; 663 /* followed by IP header and data */ 664 }; 666 struct nd_opt_mtu { /* MTU option */ 667 uint8_t nd_opt_mtu_type; 668 uint8_t nd_opt_mtu_len; 669 uint16_t nd_opt_mtu_reserved; 670 uint32_t nd_opt_mtu_mtu; 671 }; 673 We note that the nd_na_flags_reserved flags have the same byte 674 ordering problems as we discussed with ip6f_offlg. 676 2.2.3. Multicast Listener Discovery Type and Code Values 677 The following structures and definitions are defined as a result of 678 including . 680 struct mld_hdr { 681 struct icmp6_hdr mld_hdr; 682 struct in6_addr mld_addr; /* multicast address */ 683 }; 684 #define mld_type mld_hdr.icmp6_type 685 #define mld_code mld_hdr.icmp6_code 686 #define mld_cksum mld_hdr.icmp6_cksum 687 #define mld_maxdelay mld_hdr.icmp6_data16[0] 688 #define mld_reserved mld_hdr.icmp6_data16[1] 690 2.2.4. ICMPv6 Router Renumbering Type and Code Values 692 The following structures and definitions are defined as a result of 693 including . 695 struct icmp6_router_renum { /* router renumbering header */ 696 struct icmp6_hdr rr_hdr; 697 u_int8_t rr_segnum; 698 u_int8_t rr_flags; 699 u_int16_t rr_maxdelay; 700 u_int32_t rr_reserved; 701 }; 702 #define rr_type rr_hdr.icmp6_type 703 #define rr_code rr_hdr.icmp6_code 704 #define rr_cksum rr_hdr.icmp6_cksum 705 #define rr_seqnum rr_hdr.icmp6_data32[0] 707 /* Router renumbering flags */ 708 #define ICMP6_RR_FLAGS_TEST 0x80 709 #define ICMP6_RR_FLAGS_REQRESULT 0x40 710 #define ICMP6_RR_FLAGS_FORCEAPPLY 0x20 711 #define ICMP6_RR_FLAGS_SPECSITE 0x10 712 #define ICMP6_RR_FLAGS_PREVDONE 0x08 714 struct rr_pco_match { /* match prefix part */ 715 u_int8_t rpm_code; 716 u_int8_t rpm_len; 717 u_int8_t rpm_ordinal; 718 u_int8_t rpm_matchlen; 719 u_int8_t rpm_minlen; 720 u_int8_t rpm_maxlen; 721 u_int16_t rpm_reserved; 722 struct in6_addr rpm_prefix; 723 }; 725 /* PCI code values */ 726 #define RPM_PCO_ADD 1 727 #define RPM_PCO_CHANGE 2 728 #define RPM_PCO_SETGLOBAL 3 730 struct rr_pco_use { /* use prefix part */ 731 u_int8_t rpu_uselen; 732 u_int8_t rpu_keeplen; 733 u_int8_t rpu_ramask; 734 u_int8_t rpu_raflags; 735 u_int32_t rpu_vltime; 736 u_int32_t rpu_pltime; 737 u_int32_t rpu_flags; 738 struct in6_addr rpu_prefix; 739 }; 740 #define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20 741 #define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10 743 #if BYTE_ORDER == BIG_ENDIAN 744 #define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000 745 #define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000 746 #elif BYTE_ORDER == LITTLE_ENDIAN 747 #define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80 748 #define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40 749 #endif 751 struct rr_result { /* router renumbering result message */ 752 u_int16_t rrr_flags; 753 u_int8_t rrr_ordinal; 754 u_int8_t rrr_matchedlen; 755 u_int32_t rrr_ifid; 756 struct in6_addr rrr_prefix; 757 }; 759 #if BYTE_ORDER == BIG_ENDIAN 760 #define ICMP6_RR_RESULT_FLAGS_OOB 0x0002 761 #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001 762 #elif BYTE_ORDER == LITTLE_ENDIAN 763 #define ICMP6_RR_RESULT_FLAGS_OOB 0x0200 764 #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100 765 #endif 767 2.3. Address Testing Macros 769 The basic API ([RFC-2553]) defines some macros for testing an IPv6 770 address for certain properties. This API extends those definitions 771 with additional address testing macros, defined as a result of 772 including . 774 int IN6_ARE_ADDR_EQUAL(const struct in6_addr *, 775 const struct in6_addr *); 777 This macro returns non-zero if the addresses are equal; otherwise it 778 returns zero. 780 2.4. Protocols File 782 Many hosts provide the file /etc/protocols that contains the names of 783 the various IP protocols and their protocol number (e.g., the value 784 of the protocol field in the IPv4 header for that protocol, such as 1 785 for ICMP). Some programs then call the function getprotobyname() to 786 obtain the protocol value that is then specified as the third 787 argument to the socket() function. For example, the Ping program 788 contains code of the form 790 struct protoent *proto; 792 proto = getprotobyname("icmp"); 794 s = socket(PF_INET, SOCK_RAW, proto->p_proto); 796 Common names are required for the new IPv6 protocols in this file, to 797 provide portability of applications that call the getprotoXXX() 798 functions. 800 We define the following protocol names with the values shown. These 801 are taken from ftp://ftp.isi.edu/in-notes/iana/assignments/protocol- 802 numbers. 804 hopopt 0 # hop-by-hop options for ipv6 805 ipv6 41 # ipv6 806 ipv6-route 43 # routing header for ipv6 807 ipv6-frag 44 # fragment header for ipv6 808 esp 50 # encapsulating security payload for ipv6 809 ah 51 # authentication header for ipv6 810 ipv6-icmp 58 # icmp for ipv6 811 ipv6-nonxt 59 # no next header for ipv6 812 ipv6-opts 60 # destination options for ipv6 814 3. IPv6 Raw Sockets 816 Raw sockets bypass the transport layer (TCP or UDP). With IPv4, raw 817 sockets are used to access ICMPv4, IGMPv4, and to read and write IPv4 818 datagrams containing a protocol field that the kernel does not 819 process. An example of the latter is a routing daemon for OSPF, 820 since it uses IPv4 protocol field 89. With IPv6 raw sockets will be 821 used for ICMPv6 and to read and write IPv6 datagrams containing a 822 Next Header field that the kernel does not process. Examples of the 823 latter are a routing daemon for OSPF for IPv6 and RSVP (protocol 824 field 46). 826 All data sent via raw sockets MUST be in network byte order and all 827 data received via raw sockets will be in network byte order. This 828 differs from the IPv4 raw sockets, which did not specify a byte 829 ordering and used the host's byte order for certain IP header fields. 831 Another difference from IPv4 raw sockets is that complete packets 832 (that is, IPv6 packets with extension headers) cannot be sent or 833 received using the IPv6 raw sockets API. Instead, ancillary data 834 objects are used to transfer the extension headers and hoplimit 835 information, as described in Section 6. Should an application need 836 access to the complete IPv6 packet, some other technique, such as the 837 datalink interfaces BPF or DLPI, must be used. 839 All fields in the IPv6 header that an application might want to 840 change (i.e., everything other than the version number) can be 841 modified using ancillary data and/or socket options by the 842 application for output. All fields in a received IPv6 header (other 843 than the version number and Next Header fields) and all extension 844 headers are also made available to the application as ancillary data 845 on input. Hence there is no need for a socket option similar to the 846 IPv4 IP_HDRINCL socket option and on receipt the application will 847 only receive the payload i.e. the data after the IPv6 header and all 848 the extension headers. 850 When writing to a raw socket the kernel will automatically fragment 851 the packet if its size exceeds the path MTU, inserting the required 852 fragmentation headers. On input the kernel reassembles received 853 fragments, so the reader of a raw socket never sees any fragment 854 headers. 856 When we say "an ICMPv6 raw socket" we mean a socket created by 857 calling the socket function with the three arguments PF_INET6, 858 SOCK_RAW, and IPPROTO_ICMPV6. 860 Most IPv4 implementations give special treatment to a raw socket 861 created with a third argument to socket() of IPPROTO_RAW, whose value 862 is normally 255, to have it mean that the application will send down 863 complete packets including the IPv4 header. (Note: This feature was 864 added to IPv4 in 1988 by Van Jacobson to support traceroute, allowing 865 a complete IP header to be passed by the application, before the 866 IP_HDRINCL socket option was added.) We note that this value has no 867 special meaning to an IPv6 raw socket (and the IANA currently 868 reserves the value of 255 when used as a next-header field). 870 3.1. Checksums 872 The kernel will calculate and insert the ICMPv6 checksum for ICMPv6 873 raw sockets, since this checksum is mandatory. 875 For other raw IPv6 sockets (that is, for raw IPv6 sockets created 876 with a third argument other than IPPROTO_ICMPV6), the application 877 must set the new IPV6_CHECKSUM socket option to have the kernel (1) 878 compute and store a checksum for output, and (2) verify the received 879 checksum on input, discarding the packet if the checksum is in error. 880 This option prevents applications from having to perform source 881 address selection on the packets they send. The checksum will 882 incorporate the IPv6 pseudo-header, defined in Section 8.1 of 883 [RFC-2460]. This new socket option also specifies an integer offset 884 into the user data of where the checksum is located. 886 int offset = 2; 887 setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); 889 By default, this socket option is disabled. Setting the offset to -1 890 also disables the option. By disabled we mean (1) the kernel will 891 not calculate and store a checksum for outgoing packets, and (2) the 892 kernel will not verify a checksum for received packets. 894 An attempt to set IPV6_CHECKSUM for an ICMPv6 socket will fail. 896 (Note: Since the checksum is always calculated by the kernel for an 897 ICMPv6 socket, applications are not able to generate ICMPv6 packets 898 with incorrect checksums (presumably for testing purposes) using this 899 API.) 901 3.2. ICMPv6 Type Filtering 903 ICMPv4 raw sockets receive most ICMPv4 messages received by the 904 kernel. (We say "most" and not "all" because Berkeley-derived 905 kernels never pass echo requests, timestamp requests, or address mask 906 requests to a raw socket. Instead these three messages are processed 907 entirely by the kernel.) But ICMPv6 is a superset of ICMPv4, also 908 including the functionality of IGMPv4 and ARPv4. This means that an 909 ICMPv6 raw socket can potentially receive many more messages than 910 would be received with an ICMPv4 raw socket: ICMP messages similar to 911 ICMPv4, along with neighbor solicitations, neighbor advertisements, 912 and the three multicast listener discovery messages. 914 Most applications using an ICMPv6 raw socket care about only a small 915 subset of the ICMPv6 message types. To transfer extraneous ICMPv6 916 messages from the kernel to user can incur a significant overhead. 917 Therefore this API includes a method of filtering ICMPv6 messages by 918 the ICMPv6 type field. 920 Each ICMPv6 raw socket has an associated filter whose datatype is 921 defined as 923 struct icmp6_filter; 925 This structure, along with the macros and constants defined later in 926 this section, are defined as a result of including the 927 . 929 The current filter is fetched and stored using getsockopt() and 930 setsockopt() with a level of IPPROTO_ICMPV6 and an option name of 931 ICMP6_FILTER. 933 Six macros operate on an icmp6_filter structure: 935 void ICMP6_FILTER_SETPASSALL (struct icmp6_filter *); 936 void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *); 938 void ICMP6_FILTER_SETPASS ( int, struct icmp6_filter *); 939 void ICMP6_FILTER_SETBLOCK( int, struct icmp6_filter *); 941 int ICMP6_FILTER_WILLPASS (int, 942 const struct icmp6_filter *); 943 int ICMP6_FILTER_WILLBLOCK(int, 944 const struct icmp6_filter *); 946 The first argument to the last four macros (an integer) is an ICMPv6 947 message type, between 0 and 255. The pointer argument to all six 948 macros is a pointer to a filter that is modified by the first four 949 macros examined by the last two macros. 951 The first two macros, SETPASSALL and SETBLOCKALL, let us specify that 952 all ICMPv6 messages are passed to the application or that all ICMPv6 953 messages are blocked from being passed to the application. 955 The next two macros, SETPASS and SETBLOCK, let us specify that 956 messages of a given ICMPv6 type should be passed to the application 957 or not passed to the application (blocked). 959 The final two macros, WILLPASS and WILLBLOCK, return true or false 960 depending whether the specified message type is passed to the 961 application or blocked from being passed to the application by the 962 filter pointed to by the second argument. 964 When an ICMPv6 raw socket is created, it will by default pass all 965 ICMPv6 message types to the application. 967 As an example, a program that wants to receive only router 968 advertisements could execute the following: 970 struct icmp6_filter myfilt; 972 fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6); 974 ICMP6_FILTER_SETBLOCKALL(&myfilt); 975 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &myfilt); 976 setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &myfilt, sizeof(myfilt)); 978 The filter structure is declared and then initialized to block all 979 messages types. The filter structure is then changed to allow router 980 advertisement messages to be passed to the application and the filter 981 is installed using setsockopt(). 983 The icmp6_filter structure is similar to the fd_set datatype used 984 with the select() function in the sockets API. The icmp6_filter 985 structure is an opaque datatype and the application should not care 986 how it is implemented. All the application does with this datatype 987 is allocate a variable of this type, pass a pointer to a variable of 988 this type to getsockopt() and setsockopt(), and operate on a variable 989 of this type using the six macros that we just defined. 991 Nevertheless, it is worth showing a simple implementation of this 992 datatype and the six macros. 994 struct icmp6_filter { 995 uint32_t icmp6_filt[8]; /* 8*32 = 256 bits */ 996 }; 998 #define ICMP6_FILTER_WILLPASS(type, filterp) \ 999 ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0) 1000 #define ICMP6_FILTER_WILLBLOCK(type, filterp) \ 1001 ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0) 1002 #define ICMP6_FILTER_SETPASS(type, filterp) \ 1003 ((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))) 1004 #define ICMP6_FILTER_SETBLOCK(type, filterp) \ 1005 ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))) 1006 #define ICMP6_FILTER_SETPASSALL(filterp) \ 1007 memset((filterp), 0xFF, sizeof(struct icmp6_filter)) 1008 #define ICMP6_FILTER_SETBLOCKALL(filterp) \ 1009 memset((filterp), 0, sizeof(struct icmp6_filter)) 1011 (Note: These sample definitions have two limitations that an 1012 implementation may want to change. The first four macros evaluate 1013 their first argument two times. The second two macros require the 1014 inclusion of the header for the memset() function.) 1016 4. Access to IPv6 and Extension Headers 1018 Applications need to be able to control IPv6 header and extension 1019 header content when sending as well as being able to receive the 1020 content of these headers. This is done by defining socket option 1021 types which can be used both with setsockopt and with ancillary data. 1022 Ancillary data is discussed in Appendix A. The following optional 1023 information can be exchanged between the application and the kernel: 1025 1. The send/receive interface and source/destination address, 1026 2. The hop limit, 1027 3. Next hop address, 1028 4. Routing header. 1029 5. Hop-by-Hop options, and 1030 6. Destination options (both before and after a Routing header). 1032 First, to receive any of this optional information (other than the 1033 next hop address, which can only be set), the application must call 1034 setsockopt() to turn on the corresponding flag: 1036 int on = 1; 1038 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)); 1039 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on)); 1040 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on)); 1041 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &on, sizeof(on)); 1042 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &on, sizeof(on)); 1043 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, 1044 &on, sizeof(on)); 1046 When any of these options are enabled, the corresponding data is 1047 returned as control information by recvmsg(), as one or more 1048 ancillary data objects. 1050 Two different mechanisms exist for sending this optional information: 1052 1. Using setsockopt to specify the option content for a socket. 1053 These are known an "sticky" options since they affect all 1054 transmitted packets on the socket until either the a new 1055 setsockopt is done or the options are overridden using ancillary 1056 data. 1058 2. Using ancillary data to specify the option content for a single 1059 datagram. This only applies to datagram and raw sockets; not to 1060 TCP sockets. 1062 The three socket option parameters and the three cmsghdr fields that 1063 describe the options/ancillary data objects are summarized as: 1065 opt level/ optname/ optval/ 1066 cmsg_level cmsg_type cmsg_data[] 1067 ------------ ------------ ------------------------ 1068 IPPROTO_IPV6 IPV6_PKTINFO in6_pktinfo structure 1069 IPPROTO_IPV6 IPV6_HOPLIMIT int 1070 IPPROTO_IPV6 IPV6_NEXTHOP socket address structure 1071 IPPROTO_IPV6 IPV6_RTHDR ip6_rthdr structure 1072 IPPROTO_IPV6 IPV6_HOPOPTS ip6_hbh structure 1073 IPPROTO_IPV6 IPV6_DSTOPTS ip6_dest structure 1074 IPPROTO_IPV6 IPV6_RTHDRDSTOPTS ip6_dest structure 1076 All these options are described in detail in Section 6, 7, 8 and 9. 1077 All the constants beginning with IPV6_ are defined as a result of 1078 including the . 1080 Issuing getsockopt() for the above options will return the sticky 1081 option value i.e. the value set with setsockopt(). 1083 Note: We intentionally use the same constant for the cmsg_level 1084 member as is used as the second argument to getsockopt() and 1085 setsockopt() (what is called the "level"), and the same constant for 1086 the cmsg_type member as is used as the third argument to getsockopt() 1087 and setsockopt() (what is called the "option name"). 1089 The application does not explicitly need to access the data 1090 structures for the Routing header option, Hop-by-Hop option, and 1091 Destination options, since the API to these features is through a set 1092 of inet6_rth_XXX() and inet6_opt_XXX() functions that we define in 1093 Section 8 and Section 10. Those functions simplify the interface to 1094 these features instead of requiring the application to know the 1095 intimate details of the extension header formats. 1097 4.1. TCP Implications 1099 It is not possible to use ancillary data to transmit the above 1100 options for TCP since there is not a one-to-one mapping between send 1101 operations and the TCP segments being transmitted. Instead an 1102 application can use setsockopt to specify them as sticky options. 1103 When the application uses setsockopt to specify the above options it 1104 is expected that TCP will start using the new information when 1105 sending segments. However, TCP may or may not use the new 1106 information when retransmitting segments that were originally sent 1107 when the old sticky options were in effect. 1109 Applications using TCP can use ancillary data (after enabling the 1110 desired IPV6_RECVxxx options) to receive the IPv6 and extension 1111 header information. However, since there is not a one-to-one mapping 1112 between received TCP segments and recv operations seen by the 1113 application, when different TCP segments have different IPv6 and 1114 extension headers the application might not be able to observe all 1115 received headers. For efficiency reasons it is recommended that a 1116 TCP implementation not send ancillary data items with every received 1117 segment but instead try to detect the points in the data stream when 1118 the requested IPv6 and extension header content changes and only send 1119 a single ancillary data item at the time of the change. Also, TCP 1120 should send ancillary data items at the start of the connection and 1121 when the application enables a new IPV6_RECVxxx option. 1123 For example, assume an application has enabled IPV6_RECVHOPLIMIT 1124 before a connection is established. Then the first recvmsg() would 1125 have an IPV6_HOPLIMIT item indicating the hop limit in the first data 1126 segment. Should the hoplimit in the received data segment change a 1127 subsequent recvmsg() will also have an IPV6_HOPLIMIT item. However, 1128 the application must be prepared to handle ancillary data items even 1129 though the hop limit did not change. Note that should the hop limit 1130 in received ACK-only segments be different than the hop limit in data 1131 segments the application might only be able to observe the hop limit 1132 in the received data segments. 1134 The above example was for hop limit but the application should be 1135 prepared to handle the corresponding behavior for the other option 1136 information. 1138 The above recvmsg() behavior allows the application to detect changes 1139 in the received IPv6 and extension headers without resorting to 1140 periodic getsockopt() calls. 1142 4.2. UDP and Raw Socket Implications 1144 The receive behavior for UDP and raw sockets is quite 1145 straightforward. After the application has enabled an IPV6_RECVxxx 1146 socket option it will receive ancillary data items for every 1147 recvmsg() call containing the requested information. However, if the 1148 information is not present in the packet the ancillary data item will 1149 not be included. For example, if the application enables 1150 IPV6_RECVRTHDR and a received datagram does not contain a Routing 1151 header there will not be an IPV6_RTHDR ancillary data item. Note 1152 that due to buffering in the socket implementation there might be 1153 some packets queued when an IPV6_RECVxxx option is enabled and they 1154 might not have the ancillary data information. 1156 For sending the application has the choice between using sticky 1157 options and ancillary data. The application can also use both having 1158 the sticky options specify the "default" and using ancillary data to 1159 override the default options. Note that if any ancillary data is 1160 specified in a call to sendmsg(), all of the sticky options are 1161 overridden for that datagram. For example, if the application has 1162 set IPV6_RTHDR using a sticky option and later passes IPV6_HOPLIMIT 1163 as ancillary data this will override the IPV6_RTHDR sticky option and 1164 no Routing header will be sent with that datagram. 1166 5. Extensions to Socket Ancillary Data 1168 This specification uses ancillary data as defined in Posix.1g which 1169 the following compatible extensions: 1171 - CMSG_NEXTHDR has been extended to handle a NULL 2nd argument to 1172 mean "get the first header". See Section 22.3.2. 1174 - A new CMSG_SPACE macro is defined. It is used to determine how 1175 much space need to be allocated for an ancillary data item. See 1176 Section 22.3.4. 1178 - A new CMSG_LEN macro is defined. It returns the value to store 1179 in the cmsg_len member of the cmsghdr structure, taking into 1180 account any padding needed to satisfy alignment requirements. 1181 See Section 22.3.5. 1183 6. Packet Information 1185 There are four pieces of information that an application can specify 1186 for an outgoing packet using ancillary data: 1188 1. the source IPv6 address, 1189 2. the outgoing interface index, 1190 3. the outgoing hop limit, and 1191 4. the next hop address. 1193 Three similar pieces of information can be returned for a received 1194 packet as ancillary data: 1196 1. the destination IPv6 address, 1197 2. the arriving interface index, and 1198 3. the arriving hop limit. 1200 The first two pieces of information are contained in an in6_pktinfo 1201 structure that is set with setsockopt() or sent as ancillary data 1202 with sendmsg() and received as ancillary data with recvmsg(). This 1203 structure is defined as a result of including the . 1205 struct in6_pktinfo { 1206 struct in6_addr ipi6_addr; /* src/dst IPv6 address */ 1207 unsigned int ipi6_ifindex; /* send/recv interface index */ 1208 }; 1210 In the socket option and cmsghdr level will be IPPROTO_IPV6, the type 1211 will be IPV6_PKTINFO, and the first byte of the option value and 1212 cmsg_data[] will be the first byte of the in6_pktinfo structure. An 1213 application can clear any sticky IPV6_PKTINFO option by either doing 1214 a setsockopt for option with optlen being zero, or by doing a 1215 "regular" setsockopt with ipi6_addr being in6addr_any and 1216 ipi6_ifindex being zero. 1218 This information is returned as ancillary data by recvmsg() only if 1219 the application has enabled the IPV6_RECVPKTINFO socket option: 1221 int on = 1; 1222 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)); 1224 (Note: The hop limit is not contained in the in6_pktinfo structure 1225 for the following reason. Some UDP servers want to respond to client 1226 requests by sending their reply out the same interface on which the 1227 request was received and with the source IPv6 address of the reply 1228 equal to the destination IPv6 address of the request. To do this the 1229 application can enable just the IPV6_RECVPKTINFO socket option and 1230 then use the received control information from recvmsg() as the 1231 outgoing control information for sendmsg(). The application need not 1232 examine or modify the in6_pktinfo structure at all. But if the hop 1233 limit were contained in this structure, the application would have to 1234 parse the received control information and change the hop limit 1235 member, since the received hop limit is not the desired value for an 1236 outgoing packet.) 1238 6.1. Specifying/Receiving the Interface 1240 Interfaces on an IPv6 node are identified by a small positive 1241 integer, as described in Section 4 of [RFC-2553]. That document also 1242 describes a function to map an interface name to its interface index, 1243 a function to map an interface index to its interface name, and a 1244 function to return all the interface names and indexes. Notice from 1245 this document that no interface is ever assigned an index of 0. 1247 When specifying the outgoing interface, if the ipi6_ifindex value is 1248 0, the kernel will choose the outgoing interface. If the application 1249 specifies an outgoing interface for a multicast packet, the interface 1250 specified by the ancillary data overrides any interface specified by 1251 the IPV6_MULTICAST_IF socket option (described in [RFC-2553]), for 1252 that call to sendmsg() only. 1254 When the IPV6_PKTINFO socket option is enabled, the received 1255 interface index is always returned as the ipi6_ifindex member of the 1256 in6_pktinfo structure. 1258 6.2. Specifying/Receiving Source/Destination Address 1260 The source IPv6 address can be specified by calling bind() before 1261 each output operation, but supplying the source address together with 1262 the data requires less overhead (i.e., fewer system calls) and 1263 requires less state to be stored and protected in a multithreaded 1264 application. 1266 When specifying the source IPv6 address as ancillary data, if the 1267 ipi6_addr member of the in6_pktinfo structure is the unspecified 1268 address (IN6ADDR_ANY_INIT or in6addr_any), then (a) if an address is 1269 currently bound to the socket, it is used as the source address, or 1270 (b) if no address is currently bound to the socket, the kernel will 1271 choose the source address. If the ipi6_addr member is not the 1272 unspecified address, but the socket has already bound a source 1273 address, then the ipi6_addr value overrides the already-bound source 1274 address for this output operation only. 1276 The kernel must verify that the requested source address is indeed a 1277 unicast address assigned to the node. 1279 When the in6_pktinfo structure is returned as ancillary data by 1280 recvmsg(), the ipi6_addr member contains the destination IPv6 address 1281 from the received packet. 1283 6.3. Specifying/Receiving the Hop Limit 1285 The outgoing hop limit is normally specified with either the 1286 IPV6_UNICAST_HOPS socket option or the IPV6_MULTICAST_HOPS socket 1287 option, both of which are described in [RFC-2553]. Specifying the 1288 hop limit as ancillary data lets the application override either the 1289 kernel's default or a previously specified value, for either a 1290 unicast destination or a multicast destination, for a single output 1291 operation. Returning the received hop limit is useful for programs 1292 such as Traceroute and for IPv6 applications that need to verify that 1293 the received hop limit is 255 (e.g., that the packet has not been 1294 forwarded). 1296 The received hop limit is returned as ancillary data by recvmsg() 1297 only if the application has enabled the IPV6_RECVHOPLIMIT socket 1298 option: 1300 int on = 1; 1301 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on)); 1303 In the cmsghdr structure containing this ancillary data, the 1304 cmsg_level member will be IPPROTO_IPV6, the cmsg_type member will be 1305 IPV6_HOPLIMIT, and the first byte of cmsg_data[] will be the first 1306 byte of the integer hop limit. 1308 Nothing special need be done to specify the outgoing hop limit: just 1309 specify the control information as ancillary data for sendmsg() or 1310 using setsockopt(). As specified in [RFC-2553], the interpretation 1311 of the integer hop limit value is 1312 x < -1: return an error of EINVAL 1313 x == -1: use kernel default 1314 0 <= x <= 255: use x 1315 x >= 256: return an error of EINVAL 1317 6.4. Specifying the Next Hop Address 1319 The IPV6_NEXTHOP ancillary data object specifies the next hop for the 1320 datagram as a socket address structure. In the cmsghdr structure 1321 containing this ancillary data, the cmsg_level member will be 1322 IPPROTO_IPV6, the cmsg_type member will be IPV6_NEXTHOP, and the 1323 first byte of cmsg_data[] will be the first byte of the socket 1324 address structure. 1326 This is a privileged option. (Note: It is implementation defined and 1327 beyond the scope of this document to define what "privileged" means. 1328 Unix systems use this term to mean the process must have an effective 1329 user ID of 0.) 1331 If the socket address structure contains an IPv6 address (e.g., the 1332 sin6_family member is AF_INET6), then the node identified by that 1333 address must be a neighbor of the sending host. If that address 1334 equals the destination IPv6 address of the datagram, then this is 1335 equivalent to the existing SO_DONTROUTE socket option. 1337 6.5. Additional Errors with sendmsg() and setsockopt() 1339 With the IPV6_PKTINFO socket option there are no additional errors 1340 possible with the call to recvmsg(). But when specifying the 1341 outgoing interface or the source address, additional errors are 1342 possible from sendmsg() or setsockopt(). Note that some 1343 implementations might only be able to return this type of errors for 1344 setsockopt(). The following are examples, but some of these may not 1345 be provided by some implementations, and some implementations may 1346 define additional errors: 1348 ENXIO The interface specified by ipi6_ifindex does not exist. 1350 ENETDOWN The interface specified by ipi6_ifindex is not enabled 1351 for IPv6 use. 1353 EADDRNOTAVAIL ipi6_ifindex specifies an interface but the address 1354 ipi6_addr is not available for use on that interface. 1356 EHOSTUNREACH No route to the destination exists over the interface 1357 specified by ifi6_ifindex. 1359 7. Routing Header Option 1361 Source routing in IPv6 is accomplished by specifying a Routing header 1362 as an extension header. There can be different types of Routing 1363 headers, but IPv6 currently defines only the Type 0 Routing header 1364 [RFC-2460]. This type supports up to 127 intermediate nodes (limited 1365 by the length field in the extension header). With this maximum 1366 number of intermediate nodes, a source, and a destination, there are 1367 128 hops. 1369 Source routing with IPv4 sockets API (the IP_OPTIONS socket option) 1370 requires the application to build the source route in the format that 1371 appears as the IPv4 header option, requiring intimate knowledge of 1372 the IPv4 options format. This IPv6 API, however, defines eight 1373 functions that the application calls to build and examine a Routing 1374 header, and the ability to use sticky options or ancillary data to 1375 communicate this information between the application and the kernel 1376 using the IPV6_RTHDR option. 1378 Three functions build a Routing header: 1380 inet6_rth_space() - return #bytes required for Routing header 1381 inet6_rth_init() - initialize buffer data for Routing header 1382 inet6_rth_add() - add one IPv6 address to the Routing header 1384 Three functions deal with a returned Routing header: 1386 inet6_rth_reverse() - reverse a Routing header 1387 inet6_rth_segments() - return #segments in a Routing header 1388 inet6_rth_getaddr() - fetch one address from a Routing header 1390 The function prototypes for these functions are defined as a result 1391 of including the . 1393 To receive a Routing header the application must enable the 1394 IPV6_RECVRTHDR socket option: 1396 int on = 1; 1397 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on)); 1399 To send a Routing header the application specifies it either as 1400 ancillary data in a call to sendmsg() or using setsockopt(). 1402 The application can remove any sticky Routing header by calling 1403 setsockopt() for IPV6_RTHDR with a zero option length. 1405 When using ancillary data a Routing header is passed between the 1406 application and the kernel as follows: The cmsg_level member has a 1407 value of IPPROTO_IPV6 and the cmsg_type member has a value of 1408 IPV6_RTHDR. The contents of the cmsg_data[] member is implementation 1409 dependent and should not be accessed directly by the application, but 1410 should be accessed using the six functions that we are about to 1411 describe. 1413 The following constant is defined as a result of including the 1414 : 1416 #define IPV6_RTHDR_TYPE_0 0 /* IPv6 Routing header type 0 */ 1418 When a Routing header is specified, the destination address specified 1419 for connect(), sendto(), or sendmsg() is the final destination 1420 address of the datagram. The Routing header then contains the 1421 addresses of all the intermediate nodes. 1423 7.1. inet6_rth_space 1425 size_t inet6_rth_space(int type, int segments); 1427 This function returns the number of bytes required to hold a Routing 1428 header of the specified type containing the specified number of 1429 segments (addresses). For an IPv6 Type 0 Routing header, the number 1430 of segments must be between 0 and 127, inclusive. The return value 1431 is just the space for the Routing header. When the application uses 1432 ancillary data it must pass the returned length to CMSG_LEN() to 1433 determine how much memory is needed for the ancillary data object 1434 (including the cmsghdr structure). 1436 If the return value is 0, then either the type of the Routing header 1437 is not supported by this implementation or the number of segments is 1438 invalid for this type of Routing header. 1440 (Note: This function returns the size but does not allocate the space 1441 required for the ancillary data. This allows an application to 1442 allocate a larger buffer, if other ancillary data objects are 1443 desired, since all the ancillary data objects must be specified to 1444 sendmsg() as a single msg_control buffer.) 1446 7.2. inet6_rth_init 1447 void *inet6_rth_init(void *bp, int bp_len, int type, int segments); 1449 This function initializes the buffer pointed to by bp to contain a 1450 Routing header of the specified type and sets ip6r0_len based on the 1451 segments parameter. bp_len is only used to verify that the buffer is 1452 large enough. The ip6r0_segleft field is set to zero; 1453 inet6_rth_add() will increment it. 1455 When the application uses ancillary data the application must 1456 initialize any cmsghdr fields. 1458 The caller must allocate the buffer and its size can be determined by 1459 calling inet6_rth_space(). 1461 Upon success the return value is the pointer to the buffer (bp), and 1462 this is then used as the first argument to the next two functions. 1463 Upon an error the return value is NULL. 1465 7.3. inet6_rth_add 1467 int inet6_rth_add(void *bp, const struct in6_addr *addr); 1469 This function adds the IPv6 address pointed to by addr to the end of 1470 the Routing header being constructed. 1472 If successful, the segleft member of the Routing Header is updated to 1473 account for the new address in the Routing header and the return 1474 value of the function is 0. Upon an error the return value of the 1475 function is -1. 1477 7.4. inet6_rth_reverse 1479 int inet6_rth_reverse(const void *in, void *out) 1481 This function takes a Routing header extension header (pointed to by 1482 the first argument) and writes a new Routing header that sends 1483 datagrams along the reverse of that route. Both arguments are 1484 allowed to point to the same buffer (that is, the reversal can occur 1485 in place). 1487 The return value of the function is 0 on success, or -1 upon an 1488 error. 1490 7.5. inet6_rth_segments 1492 int inet6_rth_segments(const void *bp); 1494 This function returns the number of segments (addresses) contained in 1495 the Routing header described by bp. On success the return value is 1496 zero or greater. The return value of the function is -1 upon an 1497 error. 1499 7.6. inet6_rth_getaddr 1501 struct in6_addr *inet6_rth_getaddr(const void *bp, int index); 1503 This function returns a pointer to the IPv6 address specified by 1504 index (which must have a value between 0 and one less than the value 1505 returned by inet6_rth_segments()) in the Routing header described by 1506 bp. An application should first call inet6_rth_segments() to obtain 1507 the number of segments in the Routing header. 1509 Upon an error the return value of the function is NULL. 1511 8. Hop-By-Hop Options 1513 A variable number of Hop-by-Hop options can appear in a single Hop- 1514 by-Hop options header. Each option in the header is TLV-encoded with 1515 a type, length, and value. 1517 Today only four Hop-by-Hop options are defined for IPv6 [RFC-2460]: 1518 Jumbo Payload, Pad1, PadN, and router-alert. The two pad options are 1519 for alignment purposes and are automatically inserted by the 1520 inet6_opt_XXX() routines and ignored by the inet6_opt_XXX() routines 1521 on the receive side. 1523 This section of the API is therefore defined for future Hop-by-Hop 1524 options (as well as destination options) that an application may need 1525 to specify and receive. This IPv6 API defines seven functions that 1526 the application calls to build and examine a Hop-by_Hop options 1527 header, and the ability to use sticky options or ancillary data to 1528 communicate this information between the application and the kernel. 1529 This uses the IPV6_HOPOPTS for hob-by-hop options. 1531 Four functions build a options header: 1533 inet6_opt_init() - initialize buffer data for options header 1534 inet6_opt_append() - add one TLV option to the options header 1535 inet6_opt_finish() - finish adding TLV options to the options header 1536 inet6_opt_set_val() - add one component of the option content to the option 1538 Three functions deal with a returned options header: 1540 inet6_opt_next() - extract the next option from the options header 1541 inet6_opt_find() - extract an option of a specified type from the header 1542 inet6_opt_get_val() - retrieve one component of the option content 1544 Individual Hop-by-Hop options (and Destination options, which are 1545 described in Section 9 and are very similar to the Hop-by-Hop 1546 options) may have specific alignment requirements. For example, the 1547 4-byte Jumbo Payload length should appear on a 4-byte boundary, and 1548 IPv6 addresses are normally aligned on an 8-byte boundary. These 1549 requirements and the terminology used with these options are 1550 discussed in Section 4.2 and Appendix B of [RFC-2460]. The alignment 1551 of first byte of each option is specified by two values, called x and 1552 y, written as "xn + y". This states that the option must appear at 1553 an integer multiple of x bytes from the beginning of the options 1554 header (x can have the values 1, 2, 4, or 8), plus y bytes (y can 1555 have a value between 0 and 7, inclusive). The Pad1 and PadN options 1556 are inserted as needed to maintain the required alignment. The 1557 functions below need to know the alignment of the end of the option 1558 (which is always in the form "xn," where x can have the values 1, 2, 1559 4, or 8) and the total size of the data portion of the option. These 1560 are passed as the "align" and "len" arguments to inet6_opt_append(). 1562 Multiple Hop-by-Hop options must be specified by the application by 1563 placing them in a single extension header. 1565 Finally, we note that use of some Hop-by-Hop options or some 1566 Destination options, might require special privilege. That is, 1567 normal applications (without special privilege) might be forbidden 1568 from setting certain options in outgoing packets, and might never see 1569 certain options in received packets. 1571 8.1. Receiving Hop-by-Hop Options 1573 To receive Hop-by-Hop options the application must enable the 1574 IPV6_RECVHOPOPTS socket option: 1576 int on = 1; 1577 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &on, sizeof(on)); 1579 When using ancillary data a Hop-by-hop options is passed between the 1580 application and the kernel as follows: The cmsg_level member will be 1581 IPPROTO_IPV6 and the cmsg_type member will be IPV6_HOPOPTS. These 1582 options are then processed by calling the inet6_opt_next(), 1583 inet6_opt_find(), and inet6_opt_get_val() functions, described in 1584 Section 10.6. 1586 8.2. Sending Hop-by-Hop Options 1588 To send a Hop-by-Hop options header, the application specifies the 1589 header either as ancillary data in a call to sendmsg() or using 1590 setsockopt(). 1592 The application can remove any sticky Hop-by-Hop extension header by 1593 calling setsockopt() for IPV6_HOPOPTS with a zero option length. 1595 All the Hop-by-Hop options must specified by a single ancillary data 1596 object. The cmsg_level member is set to IPPROTO_IPV6 and the 1597 cmsg_type member is set to IPV6_HOPOPTS. The option is normally 1598 constructed using the inet6_opt_init(), inet6_opt_append(), 1599 inet6_opt_finish(), and inet6_set_val() functions, described in 1600 Section 10. 1602 Additional errors may be possible from sendmsg() and setsockopt() if 1603 the specified option is in error. 1605 9. Destination Options 1607 A variable number of Destination options can appear in one or more 1608 Destination option headers. As defined in [RFC-2460], a Destination 1609 options header appearing before a Routing header is processed by the 1610 first destination plus any subsequent destinations specified in the 1611 Routing header, while a Destination options header appearing after a 1612 Routing header is processed only by the final destination. As with 1613 the Hop-by-Hop options, each option in a Destination options header 1614 is TLV-encoded with a type, length, and value. 1616 Today no Destination options are defined for IPv6 [RFC-2460], 1617 although proposals exist to use Destination options with Mobile IPv6. 1619 9.1. Receiving Destination Options 1620 To receive Destination options appearing after a Routing header (or 1621 in a packet without a Routing header) the application must enable the 1622 IPV6_RECVDSTOPTS socket option: 1624 int on = 1; 1625 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &on, sizeof(on)); 1627 To receive Destination options appearing before a Routing header the 1628 application must enable the IPV6_RECVRTHDRDSTOPTS socket option: 1630 int on = 1; 1631 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, 1632 &on, sizeof(on)); 1634 All the Destination options appearing before a Routing header are 1635 returned as one ancillary data object described by a cmsghdr 1636 structure (with cmsg_type set to IPV6_RTHDRDSTOPTS) and all the 1637 Destination options appearing after a Routing header (or in a packet 1638 without a Routing header) are returned as another ancillary data 1639 object described by a cmsghdr structure (with cmsg_type set to 1640 IPV6_DSTOPTS). For all these ancillary data objects, the cmsg_level 1641 member will be IPPROTO_IPV6. 1643 These options are then processed by calling the inet6_opt_next(), 1644 inet6_opt_find(), and inet6_opt_get_value() functions. 1646 9.2. Sending Destination Options 1648 To send a Destination options header, the application specifies it 1649 either as ancillary data in a call to sendmsg() or using 1650 setsockopt(). 1652 The application can remove any sticky Destination extension header by 1653 calling setsockopt() for IPV6_RTHDRDSTOPTS/IPV6_DSTOPTS with a zero 1654 option length. 1656 As described in Section 6 one set of Destination options can appear 1657 before a Routing header, and one set can appear after a Routing 1658 header (or in a packet with no Routing header). Each set can consist 1659 of one or more options but each set is a single extension header. 1661 When using ancillary data a Destination options header is passed 1662 between the application and the kernel as follows: The set preceding 1663 a Routing header are specified with the cmsg_level member is set to 1664 IPPROTO_IPV6 and the cmsg_type member is set to IPV6_RTHDRDSTOPTS. 1665 Any setsockopt or ancillary data for IPV6_RTHDRDSTOPTS is silently 1666 ignore when sending packets unless a Routing header is also 1667 specified. 1669 The set of Destination options after a Routing header, which are also 1670 used when no Routing header is present, are specified with the 1671 cmsg_level member is set to IPPROTO_IPV6 and the cmsg_type member is 1672 set to IPV6_DSTOPTS. 1674 The Destination options are normally constructed using the 1675 inet6_opt_init(), inet6_opt_append(), inet6_opt_finish(), and 1676 inet6_set_val() functions, described in Section 10. 1678 Additional errors may be possible from sendmsg() and setsockopt() if 1679 the specified option is in error. 1681 10. Hop-by-Hop and Destination Options Processing 1683 Building and parsing the Hop-by-Hop and Destination options is 1684 complicated for the reasons given earlier. We therefore define a set 1685 of functions to help the application. These functions assume the 1686 formatting rules specified in Appendix B in [RFC-2460] i.e. that the 1687 largest field is placed last in the option. 1689 The function prototypes for these functions are defined as a result 1690 of including the . 1692 The first 3 functions (init, append, and finish) are used both to 1693 calculate the needed buffer size for the options, and to actually 1694 encode the options once the application has allocated a buffer for 1695 the header. In order to only calculate the size the application must 1696 pass a NULL extbuf and a zero extlen to those functions. 1698 10.1. inet6_opt_init 1700 int inet6_opt_init(void *extbuf, size_t extlen); 1702 This function returns the number of bytes needed for the empty 1703 extension header i.e. without any options. If extbuf is not NULL it 1704 also initializes the extension header to have the correct length 1705 field. If the extlen value is not a positive (i.e., non-zero) 1706 multiple of 8 the function fails and returns -1. 1708 10.2. inet6_opt_append 1709 int inet6_opt_append(void *extbuf, size_t extlen, int prevlen, 1710 uint8_t type, size_t len, uint_t align, 1711 void **databufp); 1713 Prevlen should be the length returned by inet6_opt_init() or a 1714 previous inet6_opt_append(). This function returns the updated total 1715 length taking into account adding an option with length 'len' and 1716 alignment 'align'. If extbuf is not NULL then, in addition to 1717 returning the length, the function inserts any needed pad option, 1718 initializes the option (setting the type and length fields) and 1719 returns a pointer to the location for the option content in databufp. 1720 If the option does not fit in the extension header buffer the 1721 function returns -1. 1723 type is the 8-bit option type. len is the length of the option data 1724 (i.e. excluding the option type and option length fields). 1726 Once inet6_opt_append() has been called the application can use the 1727 databuf directly, or use inet6_opt_set_val() to specify the content 1728 of the option. 1730 The option type must have a value from 2 to 255, inclusive. (0 and 1 1731 are reserved for the Pad1 and PadN options, respectively.) 1733 The option data length must have a value between 0 and 255, 1734 inclusive, and is the length of the option data that follows. 1736 The align parameter must have a value of 1, 2, 4, or 8. The align 1737 value can not exceed the value of len. 1739 10.3. inet6_opt_finish 1741 int inet6_opt_finish(void *extbuf, size_t extlen, int prevlen); 1743 Prevlen should be the length returned by inet6_opt_init() or 1744 inet6_opt_append(). This function returns the updated total length 1745 taking into account the final padding of the extension header to make 1746 it a multiple of 8 bytes. If extbuf is not NULL the function also 1747 initializes the option by inserting a Pad1 or PadN option of the 1748 proper length. 1750 If the necessary pad does not fit in the extension header buffer the 1751 function returns -1. 1753 10.4. inet6_opt_set_val 1755 int inet6_opt_set_val(void *databuf, size_t offset, void *val, 1756 int vallen); 1758 Databuf should be a pointer returned by inet6_opt_append(). This 1759 function inserts data items of various sizes (1, 2, 4, or 8 bytes) in 1760 the data portion of the option. val should point to the data to be 1761 inserted. Offset specifies where in the data portion of the option 1762 the value should be inserted; the first byte after the option type 1763 and length is accessed by specifying an offset of zero. 1765 The function returns the offset for the next field (i.e., offset + 1766 vallen) which can be used when composing option content with multiple 1767 fields. 1769 10.5. inet6_opt_next 1771 int inet6_opt_next(void *extbuf, size_t extlen, int prevlen, 1772 uint8_t *typep, size_t *lenp, 1773 void **databufp); 1775 This function parses received extension headers returning the next 1776 option. Extbuf and extlen specifies the extension header. Prevlen 1777 should either be zero (for the first option) or the length returned 1778 by a previous call to inet6_opt_next() or inet6_opt_find(). It 1779 specifies the position where to continue scanning the extension 1780 buffer. The next option is returned by updating typep, lenp, and 1781 databufp. This function returns the updated "previous" length 1782 computed by advancing past the option that was returned. This 1783 returned "previous" length can then be passed to subsequent calls to 1784 inet6_opt_next(). This function does not return any PAD1 or PADN 1785 options. When there are no more options the return value is -1. 1787 10.6. inet6_opt_find 1789 int inet6_opt_find(void *extbuf, size_t extlen, int prevlen, 1790 uint8_t type, size_t *lenp, 1791 void **databufp); 1793 This function is similar to the previously described inet6_opt_next() 1794 function, except this function lets the caller specify the option 1795 type to be searched for, instead of always returning the next option 1796 in the extension header. 1798 If an option of the specified type is located, the function returns 1799 the updated "previous" total length computed by advancing past the 1800 option that was returned and past any options that didn't match the 1801 type. This returned "previous" length can then be passed to 1802 subsequent calls to inet6_opt_find() for finding the next occurance 1803 of the same option type. 1805 If an option of the specified type is not located, the return value 1806 is -1. If an error occurs, the return value is -1. 1808 10.7. inet6_opt_get_val 1810 int inet6_opt_get_val(void *databuf, size_t offset, void *val, 1811 int vallen); 1813 Databuf should be a pointer returned by inet6_opt_next() or 1814 inet6_opt_find(). This function extracts data items of various sizes 1815 (1, 2, 4, or 8 bytes) in the data portion of the option. val should 1816 point to the destination for the extracted data. Offset specifies 1817 from where in the data portion of the option the value should be 1818 extracted; the first byte after the option type and length is 1819 accessed by specifying an offset of zero. 1821 The function returns the offset for the next field (i.e., offset + 1822 vallen) which can be used when extracting option content with 1823 multiple fields. XXX Perhaps we should add a note to point out that 1824 robust receivers should verify alignment before calling 1825 inet6_opt_get_val(). XXX Or check alignment and fail by returning 1826 -1? 1828 11. Additional Advanced API Functions 1830 11.1. Sending with the Minimum MTU 1832 Some applications might not want to incur the overhead of path MTU 1833 discovery, especially if the applications only send a single datagram 1834 to a destination. A potential example is a DNS server. 1836 This specification defines a mechanism to avoid fragmentation by 1837 sending at the minimum IPv6 MTU (1280 bytes). This can be enabled 1838 using the IPV6_USE_MIN_MTU socket option. 1840 int on = 1; 1841 setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, &on, sizeof(on)); 1843 By default, this socket option is disabled. Setting the value to 0 1844 also disables the option. This option can also be sent as ancillary 1845 data. 1847 11.2. Path MTU Discovery and UDP 1849 UDP and raw socket applications need to be able to determine the 1850 "maximum send transport-message size" (Section 5.1 of [RFC-1981]) to 1851 a given destination so that those applications can participate in 1852 path MTU discovery. This lets those applications send smaller 1853 datagrams to the destination, avoiding fragmentation. 1855 This is accomplished using a new ancillary data item (IPV6_PATHMTU) 1856 which is delivered to recvmsg() without any actual data. The 1857 application enable the receipt of IPV6_PATHMTU ancillary data items 1858 by enabing IPV6_RECVPATHMTU. 1860 int on = 1; 1861 setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPATHMTU, &on, sizeof(on)); 1863 By default, this socket option is disabled. Setting the value to 0 1864 also disables the option. 1866 When the application is sending packets too big for the path MTU 1867 recvmsg will return zero (indicating no data) but there will be a 1868 cmsghdr with cmsg_type set to IPV6_PATHMTU, and cmsg_len will 1869 indicate that cmsg_data is 4 bytes long. CMSG_DATA will point to an 1870 integer carrying the path MTU to use. 1872 11.3. Neighbor Reachability and UDP 1874 UDP and raw socket application might know that communication is 1875 making forward progress i.e. that the path from the node to the next 1876 hop is working. In such a case the applications, similarly to TCP as 1877 specified in [RFC-2461], has the option indicate to the internet 1878 layer that the neighbor is reachable. See section 7.3.1 of 1879 [RFC-2461]. This could save unneeded neighbor solicitation and 1880 neighbor advertisement messages. 1882 This is done by including an ancilary data item with cmsg_type being 1883 IPV6_REACHCONF and with no attached CMSG_DATA. 1885 12. Ordering of Ancillary Data and IPv6 Extension Headers 1887 Three IPv6 extension headers can be specified by the application and 1888 returned to the application using ancillary data with sendmsg() and 1889 recvmsg(): the Routing header, Hop-by-Hop options, and Destination 1890 options. When multiple ancillary data objects are transferred via 1891 recvmsg() and these objects represent any of these three extension 1892 headers, their placement in the control buffer is directly tied to 1893 their location in the corresponding IPv6 datagram. This API imposes 1894 some ordering constraints for using these ancillary data objects with 1895 sendmsg(). 1897 All Hop-by-Hop options must be specified in a single ancillary data 1898 object. Should multiple hop-by-hop ancillary data objects be 1899 specified the implementation might choose an arbitrary one or drop 1900 the packet. 1902 All Destination options that precede a Routing header must be 1903 specified in a single ancillary data object. If there is no Routing 1904 header ancillary data object the IPV6_RTHDRDSTOPTS object will be 1905 silently ignored. 1907 All Destination options that follow a Routing header (or are used 1908 without a Routing header) must be specified in a single ancillary 1909 data object. 1911 If Destination options are specified in the control buffer after a 1912 Routing header, or if Destination options are specified without a 1913 Routing header, the kernel will place those Destination options after 1914 an authentication header and/or an encapsulating security payload 1915 header, if present. 1917 13. IPv6-Specific Options with IPv4-Mapped IPv6 Addresses 1919 The various socket options and ancillary data specifications defined 1920 in this document apply only to true IPv6 sockets. It is possible to 1921 create an IPv6 socket that actually sends and receives IPv4 packets, 1922 using IPv4-mapped IPv6 addresses, but the mapping of the options 1923 defined in this document to an IPv4 datagram is beyond the scope of 1924 this document. 1926 In general, attempting to specify an IPv6-only option, such as the 1927 Hop-by-Hop options, Destination options, or Routing header on an IPv6 1928 socket that is using IPv4-mapped IPv6 addresses, will probably result 1929 in an error. Some implementations, however, may provide access to 1930 the packet information (source/destination address, send/receive 1931 interface, and hop limit) on an IPv6 socket that is using IPv4-mapped 1932 IPv6 addresses. 1934 14. Extended interfaces for rresvport, rcmd and rexec 1936 TBD 1938 14.1. rresvport_af 1940 The rresvport() function is used by the rcmd() function, and this 1941 function is in turn called by many of the "r" commands such as 1942 rlogin. While new applications are not being written to use the 1943 rcmd() function, legacy applications such as rlogin will continue to 1944 use it and these will be ported to IPv6. 1946 rresvport() creates an IPv4/TCP socket and binds a "reserved port" to 1947 the socket. Instead of defining an IPv6 version of this function we 1948 define a new function that takes an address family as its argument. 1950 #include 1952 int rresvport_af(int *port, int family); 1954 This function behaves the same as the existing rresvport() function, 1955 but instead of creating an AF_INET TCP socket, it can also create an 1956 AF_INET6 TCP socket. The family argument is either AF_INET or 1957 AF_INET6, and a new error return is EAFNOSUPPORT if the address 1958 family is not supported. 1960 (Note: There is little consensus on which header defines the 1961 rresvport() and rcmd() function prototypes. 4.4BSD defines it in 1962 , others in , and others don't define the function 1963 prototypes at all.) 1965 14.2. rcmd_af 1967 The existing rcmd() function can not transparently use AF_INET6 1968 sockets since the an application would not be prepared to handle 1969 AF_INET6 addresses returned by e.g. getpeername on the file 1970 descriptor created by rcmd. Thus a new function is needed. 1972 int rcmd_af(char **ahost, unsigned short rport, const char *locuser, 1973 const char *remuser, const char *cmd, int *fd2p, int af) 1975 This function behaves the same as the existing rcmd() function, but 1976 instead of creating an AF_INET TCP socket, it can also create an 1977 AF_INET6 TCP socket. The family argument is either AF_INET or 1978 AF_INET6, and a new error return is EAFNOSUPPORT if the address 1979 family is not supported. 1981 14.3. rexec_af 1983 The existing rexec() function can not transparently use AF_INET6 1984 sockets since the an application would not be prepared to handle 1985 AF_INET6 addresses returned by e.g. getpeername on the file 1986 descriptor created by rexec. Thus a new function is needed. 1988 int rexec_af(char **ahost, unsigned short rport, const char *name, 1989 const char *pass, const char *cmd, int *fd2p, int af) 1991 This function behaves the same as the existing rexec() function, but 1992 instead of creating an AF_INET TCP socket, it can also create an 1993 AF_INET6 TCP socket. The family argument is either AF_INET or 1994 AF_INET6, and a new error return is EAFNOSUPPORT if the address 1995 family is not supported. 1997 15. Summary of New Definitions 1999 The following list summarizes the constants and structure, 2000 definitions discussed in this memo, sorted by header. 2002 ICMP6_DST_UNREACH 2003 ICMP6_DST_UNREACH_ADDR 2004 ICMP6_DST_UNREACH_ADMIN 2005 ICMP6_DST_UNREACH_NOPORT 2006 ICMP6_DST_UNREACH_NOROUTE 2007 ICMP6_DST_UNREACH_BEYONDSCOPE 2008 ICMP6_ECHO_REPLY 2009 ICMP6_ECHO_REQUEST 2010 ICMP6_INFOMSG_MASK 2011 ICMP6_MEMBERSHIP_QUERY 2012 ICMP6_MEMBERSHIP_REDUCTION 2013 ICMP6_MEMBERSHIP_REPORT 2014 ICMP6_PACKET_TOO_BIG 2015 ICMP6_PARAMPROB_HEADER 2016 ICMP6_PARAMPROB_NEXTHEADER 2017 ICMP6_PARAMPROB_OPTION 2018 ICMP6_PARAM_PROB 2019 ICMP6_TIME_EXCEEDED 2020 ICMP6_TIME_EXCEED_REASSEMBLY 2021 ICMP6_TIME_EXCEED_TRANSIT 2022 ND_NA_FLAG_OVERRIDE 2023 ND_NA_FLAG_ROUTER 2024 ND_NA_FLAG_SOLICITED 2025 ND_NEIGHBOR_ADVERT 2026 ND_NEIGHBOR_SOLICIT 2027 ND_OPT_MTU 2028 ND_OPT_PI_FLAG_AUTO 2029 ND_OPT_PI_FLAG_ONLINK 2030 ND_OPT_PREFIX_INFORMATION 2031 ND_OPT_REDIRECTED_HEADER 2032 ND_OPT_SOURCE_LINKADDR 2033 ND_OPT_TARGET_LINKADDR 2034 ND_RA_FLAG_MANAGED 2035 ND_RA_FLAG_OTHER 2036 ND_REDIRECT 2037 ND_ROUTER_ADVERT 2038 ND_ROUTER_SOLICIT 2040 struct icmp6_filter{}; 2041 struct icmp6_hdr{}; 2042 struct nd_neighbor_advert{}; 2043 struct nd_neighbor_solicit{}; 2044 struct nd_opt_hdr{}; 2045 struct nd_opt_mtu{}; 2046 struct nd_opt_prefix_info{}; 2047 struct nd_opt_rd_hdr{}; 2048 struct nd_redirect{}; 2049 struct nd_router_advert{}; 2050 struct nd_router_solicit{}; 2052 IPPROTO_AH 2053 IPPROTO_DSTOPTS 2054 IPPROTO_ESP 2055 IPPROTO_FRAGMENT 2056 IPPROTO_HOPOPTS 2057 IPPROTO_ICMPV6 2058 IPPROTO_IPV6 2059 IPPROTO_NONE 2060 IPPROTO_ROUTING 2061 IPV6_RECVDSTOPTS 2062 IPV6_RECVHOPLIMIT 2063 IPV6_RECVHOPOPTS 2064 IPV6_RECVPKTINFO 2065 IPV6_RECVRTHDR 2066 IPV6_RECVRTHDRDSTOPTS 2067 IPV6_DSTOPTS 2068 IPV6_HOPLIMIT 2069 IPV6_HOPOPTS 2070 IPV6_NEXTHOP 2071 IPV6_PKTINFO 2072 IPV6_RTHDR 2073 IPV6_RTHDRDSTOPTS 2074 IPV6_RTHDR_TYPE_0 2075 IPV6_USE_MIN_MTU 2076 IPV6_RECVPATHMTU 2077 IPV6_PATHMTU 2078 IPV6_REACHCONF 2079 struct in6_pktinfo{}; 2081 IP6F_OFF_MASK 2082 IP6F_RESERVED_MASK 2083 IP6F_MORE_FRAG 2084 struct ip6_dest{}; 2085 struct ip6_frag{}; 2086 struct ip6_hbh{}; 2087 struct ip6_hdr{}; 2088 struct ip6_rthdr{}; 2089 struct ip6_rthdr0{}; 2091 struct cmsghdr{}; 2092 struct msghdr{}; 2094 The following list summarizes the function and macro prototypes 2095 discussed in this memo, sorted by header. 2097 void ICMP6_FILTER_SETBLOCK(int, struct icmp6_filter *); 2098 void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *); 2099 void ICMP6_FILTER_SETPASS(int, struct icmp6_filter *); 2100 void ICMP6_FILTER_SETPASSALL(struct icmp6_filter *); 2101 int ICMP6_FILTER_WILLBLOCK(int, 2102 const struct icmp6_filter *); 2103 int ICMP6_FILTER_WILLPASS(int, 2104 const struct icmp6_filter *); 2106 int IN6_ARE_ADDR_EQUAL(const struct in6_addr *, 2107 const struct in6_addr *); 2109 int inet6_opt_append(void *, size_t, int, 2110 uint8_t, size_t, uint_8, void **); 2111 int inet6_opt_get_val(void *, size_t, void *, int); 2112 int inet6_opt_find(void *, size_t, int, uint8_t , 2113 size_t *, void **); 2114 int inet6_opt_finish(void *, size_t, int); 2115 int inet6_opt_init(void *, size_t); 2116 int inet6_opt_next(void *, size_t, int, uint8_t *, 2117 size_t *, void **); 2118 int inet6_opt_set_val(void *, size_t, void *, int); 2120 int inet6_rth_add(void *, 2121 const struct in6_addr *); 2122 struct in6_addr inet6_rth_getaddr(const void *, 2123 int); 2124 void *inet6_rth_init(void *, int, int, int); 2125 int inet6_rth_reverse(const void *, void *); 2126 int inet6_rth_segments(const void *); 2127 size_t inet6_rth_space(int, int); 2129 unsigned char *CMSG_DATA(const struct cmsghdr *); 2130 struct cmsghdr *CMSG_FIRSTHDR(const struct msghdr *); 2131 unsigned int CMSG_LEN(unsigned int); 2132 struct cmsghdr *CMSG_NXTHDR(const struct msghdr *mhdr, 2133 const struct cmsghdr *); 2134 unsigned int CMSG_SPACE(unsigned int); 2136 int rresvport_af(int *, int); 2137 int rcmd_af(char **, unsigned short, const char *, 2138 const char *, const char *, int *, int); 2139 int rexec_af(char **, unsigned short , const char *, 2140 const char *, const char *, int *, int); 2142 16. Security Considerations 2144 The setting of certain Hop-by-Hop options and Destination options may 2145 be restricted to privileged processes. Similarly some Hop-by-Hop 2146 options and Destination options may not be returned to nonprivileged 2147 applications. 2149 The ability to specify an arbitrary source address using IPV6_PKTINFO 2150 must be prevented; at least for non-privileged processes. 2152 17. Change History 2154 Changes from RFC 2292: 2156 - Removed the IPV6_PKTOPTIONS socket option by allowing sticky 2157 options to be set with individual setsockopt calls. This 2158 simplifies the protocol stack implementation by not having to 2159 handle options within options and also clarifies the failure 2160 semantics when some option is incorrectly formatted. 2162 - Added the IPV6_RTHDRDSTOPTS for a Destination header before the 2163 Routing header. This is necessary to allow setting these 2164 Destination headers without IPV6_PKTOPTIONS. 2166 - Removed the ability to be able to specify Hop-by-Hop and 2167 Destination options using multiple ancillary data items. The 2168 application, using the inet6_option_*() routines, is responsible 2169 for formatting the whole extension header. This removes the need 2170 for the protocol stack to somehow guess the alignment 2171 restrictions on options when concatenating them together. 2173 - Added separate IPV6_RECVxxx options to enable the receipt of the 2174 corresponding ancillary data items. This makes the API cleaner 2175 since it allows the application to retrieve with getsockopt the 2176 sticky options it has set with setsockopt. 2178 - Clarified how sticky options are turned off. 2180 - Clarified how and when TCP returns ancillary data. 2182 - Removed the support for the loose/strict Routing header since 2183 that has been removed from the IPv6 specification. 2185 - Modified the inet6_rthdr_XXX() functions to not assume a cmsghdr 2186 structure in order to work with both sticky options and ancillary 2187 data. Renamed the functions to inet6_rth_XXX() to allow 2188 implementations to provide both the old and new functions. 2190 - Modified the inet6_option_XXX() functions to not assume a cmsghdr 2191 structure in order to work with both sticky options and ancillary 2192 data. Renamed the functions to inet6_opt_XXX() to allow 2193 implementations to provide both the old and new functions. 2195 - The new inet6_opt_XXX() functions were made different that the 2196 old as to not require structure declarations but instead use 2197 functions to add the individual fields to the option. 2199 - Changed inet6_rthdr_getaddr() to operate on index O through N-1 2200 (used to be 1 through N). 2202 - Changed the comments in the struct ip6_hdr from "priority" to 2203 "traffic class". 2205 - Clarified the alignment issues involving ancillary data to allow 2206 for separate alignment of cmsghdr structures and the data. Made 2207 CMSG_SPACE() return an upper bound on the needed space. 2209 - Added rcmd_af() and rexec_af(). 2211 Changes since -00: 2213 - Changed ICMP unreachable code 2 name to be "beyond scope of 2214 source address". 2216 - Added motivation for rcmd_af() and rexec_af(). 2218 - Added option definitions (IP6OPT_PAD1 etc) to ip6.h. 2220 - Added MLD and router renumbering definitions to icmp6.h 2222 - Removed ip6r0_addr field - replaced by a comment. 2224 - Made the content of IPV6_RTHDR, IPV6_HOPOPTS etc be specified as 2225 the extension header format (struct ip6_rthdr etc) instead of the 2226 previous "implementation dependent". 2228 - Removed attempt at RFC 2292 compatibility. 2230 - Excluded pad options from inet6_opt_next(). 2232 - Added IPV6_USE_MIN_MTU socket option for applications to avoid 2233 fragmentation by sending at the minimum IPv6 MTU. 2235 - Added MTU notification so that UDP and raw socket applications 2236 can participate in path MTU discovery. 2238 - Added Reachability confirmation for UDP and raw socket 2239 applications. 2241 - Clarified that if the application asks for e.g., IPV6_RTHDR and a 2242 received datagram does not contain a Routing header an 2243 implementation will exclude the IPV6_RTHDR ancillary data item. 2245 - Removed the constraints for jumbo option. 2247 - Moved the new CMSG macros and changes from the appendix. 2249 - Add text about inet6_opt_ depending on 2260 appendix B formatting 2250 rules i.e. largest field last in the option. 2252 - Specified that getsockopt() of a sticky option returns what was 2253 set with setsockopt(). 2255 18. TODO and Open Issues 2257 Items left to do: 2259 - Add credits for UDP MTU stuff 2261 - Move information about mapping from inet6_opt to setsockopt and 2262 cmsg. 2264 - Clarify IPV6_RTHDRDSTOPTS's interaction with IPV6_RTHDR. 2266 - Make the new inet6_opt_set_val() and inet6_opt_get_val() check 2267 the length of the data item. 2269 Open issues: 2271 - Anything special for mobility options? Restrict setting at API? 2272 Filter out on receipt? If received what does the home address 2273 option contain? 2275 - Specify "change" for TCP especially when there are multiple HBH 2276 option headers etc. 2278 - Specify binding to scope-id => implies filtering of addresses 2279 with that scope if the address you are bound to is link-local 2280 etc. What about conflicts with bound scope-id and sendto/connect 2281 scope-id? 2283 - Specify order for ifindex selection. Put in separate section. 2284 Different cases for sending to link-local (scope_id including 2285 nexthop scope_id) and global. Is multicast different? 2287 - bind() and sin6_scope_id. Should have been in Basic API. Error 2288 checks when bind/sendto sin6_scope_id does not match? 2290 - Specify notion of default multicast interface? In Basic API? 2292 - What about site names and site ids? Need for interfaces to map? 2293 Requires that site-prefixes pass name - does name need to use DNS 2294 format to handle character sets? 2296 19. References 2298 [RFC-2460] Deering, S., Hinden, R., "Internet Protocol, Version 6 2299 (IPv6), Specification", RFC 2460, Dec. 1998. 2301 [RFC-2553] Gilligan, R. E., Thomson, S., Bound, J., Stevens, W., 2302 "Basic Socket Interface Extensions for IPv6", RFC 2553, 2303 March 1999. 2305 [RFC-1981] McCann, J., Deering, S., Mogul, J, "Path MTU Discovery 2306 for IP version 6", RFC 1981, Aug. 1996. 2308 [RFC-2461] Narten, T., Nordmark, E., Simpson, W., "Neighbor 2309 Discovery for IP Version 6 (IPv6)", RFC 2461, Dec. 1998. 2311 20. Acknowledgments 2313 Matt Thomas and Jim Bound have been working on the technical details 2314 in this draft for over a year. Keith Sklower is the original 2315 implementor of ancillary data in the BSD networking code. Craig Metz 2316 provided lots of feedback, suggestions, and comments based on his 2317 implementing many of these features as the document was being 2318 written. 2320 The following provided comments on earlier drafts: Pascal Anelli, 2321 Hamid Asayesh, Ran Atkinson, Karl Auerbach, Hamid Asayesh, Jim Bound, 2322 Don Coolidge, Matt Crawford, Sam T. Denton, Richard Draves, Francis 2323 Dupont, Bob Gilligan, Jun-ichiro Hagino, Gerri Harter, Tim Hartrick, 2324 Bob Halley, Masaki Hirabaru, Yoshinobu Inoue, Mukesh Kacker, A. N. 2325 Kuznetsov, Sam Manthorpe, Pedro Marques, Jack McCann, der Mouse, John 2326 Moy, Thomas Narten, Steve Parker, Charles Perkins, Ken Powell, Tom 2327 Pusateri, Pedro Roque, Sameer Shah, Peter Sjodin, Stephen P. 2328 Spackman, Jinmei Tatuya, Karen Tracey, Sowmini Varadhan, Quaizar 2329 Vohra, Carl Williams, Steve Wise, Eric Wong, Farrell Woods, Kazu 2330 Yamamoto, and Vlad Yasevich. 2332 21. Authors' Addresses 2334 W. Richard Stevens 2335 1202 E. Paseo del Zorro 2336 Tucson, AZ 85718 2337 Email: rstevens@kohala.com 2338 Matt Thomas 2339 3am Software Foundry 2340 8053 Park Villa Circle 2341 Cupertino, CA 95014 2342 Email: matt@3am-software.com 2344 Erik Nordmark 2345 Sun Microsystems, Inc. 2346 901 San Antonio Road 2347 Palo Alto, CA 94303, USA 2348 Email: erik.nordmark@eng.sun.com 2350 22. Appendix A: Ancillary Data Overview 2352 4.2BSD allowed file descriptors to be transferred between separate 2353 processes across a UNIX domain socket using the sendmsg() and 2354 recvmsg() functions. Two members of the msghdr structure, 2355 msg_accrights and msg_accrightslen, were used to send and receive the 2356 descriptors. When the OSI protocols were added to 4.3BSD Reno in 2357 1990 the names of these two fields in the msghdr structure were 2358 changed to msg_control and msg_controllen, because they were used by 2359 the OSI protocols for "control information", although the comments in 2360 the source code call this "ancillary data". 2362 Other than the OSI protocols, the use of ancillary data has been 2363 rare. In 4.4BSD, for example, the only use of ancillary data with 2364 IPv4 is to return the destination address of a received UDP datagram 2365 if the IP_RECVDSTADDR socket option is set. With Unix domain sockets 2366 ancillary data is still used to send and receive descriptors. 2368 Nevertheless the ancillary data fields of the msghdr structure 2369 provide a clean way to pass information in addition to the data that 2370 is being read or written. The inclusion of the msg_control and 2371 msg_controllen members of the msghdr structure along with the cmsghdr 2372 structure that is pointed to by the msg_control member is required by 2373 the Posix.1g sockets API standard. 2375 22.1. The msghdr Structure 2377 The msghdr structure is used by the recvmsg() and sendmsg() 2378 functions. Its Posix.1g definition is: 2380 struct msghdr { 2381 void *msg_name; /* ptr to socket address structure */ 2382 socklen_t msg_namelen; /* size of socket address structure */ 2383 struct iovec *msg_iov; /* scatter/gather array */ 2384 size_t msg_iovlen; /* # elements in msg_iov */ 2385 void *msg_control; /* ancillary data */ 2386 socklen_t msg_controllen; /* ancillary data buffer length */ 2387 int msg_flags; /* flags on received message */ 2388 }; 2390 The structure is declared as a result of including . 2392 (Note: Before Posix.1g the two "void *" pointers were typically "char 2393 *", and the two socklen_t members and the size_t member were 2394 typically integers. Earlier drafts of Posix.1g had the two socklen_t 2395 members as size_t, but Draft 6.6 of Posix.1g, apparently the final 2396 draft, changed these to socklen_t to simplify binary portability for 2397 64-bit implementations and to align Posix.1g with X/Open's Networking 2398 Services, Issue 5. The change in msg_control to a "void *" pointer 2399 affects any code that increments this pointer.) 2401 (Note: Before Posix.1g the cmsg_len member was an integer, and not a 2402 socklen_t. See the Note in the previous section for why socklen_t is 2403 used here.) 2405 Most Berkeley-derived implementations limit the amount of ancillary 2406 data in a call to sendmsg() to no more than 108 bytes (an mbuf). 2407 This API requires a minimum of 10240 bytes of ancillary data, but it 2408 is recommended that the amount be limited only by the buffer space 2409 reserved by the socket (which can be modified by the SO_SNDBUF socket 2410 option). (Note: This magic number 10240 was picked as a value that 2411 should always be large enough. 108 bytes is clearly too small as the 2412 maximum size of a Routing header is 2048 bytes.) 2414 22.2. The cmsghdr Structure 2416 The cmsghdr structure describes ancillary data objects transferred by 2417 recvmsg() and sendmsg(). Its Posix.1g definition is: 2419 struct cmsghdr { 2420 socklen_t cmsg_len; /* #bytes, including this header */ 2421 int cmsg_level; /* originating protocol */ 2422 int cmsg_type; /* protocol-specific type */ 2423 /* followed by unsigned char cmsg_data[]; */ 2424 }; 2426 This structure is declared as a result of including . 2428 As shown in this definition, normally there is no member with the 2429 name cmsg_data[]. Instead, the data portion is accessed using the 2430 CMSG_xxx() macros, as described in Section 22.3. Nevertheless, it is 2431 common to refer to the cmsg_data[] member. 2433 When ancillary data is sent or received, any number of ancillary data 2434 objects can be specified by the msg_control and msg_controllen 2435 members of the msghdr structure, because each object is preceded by a 2436 cmsghdr structure defining the object's length (the cmsg_len member). 2437 Historically Berkeley-derived implementations have passed only one 2438 object at a time, but this API allows multiple objects to be passed 2439 in a single call to sendmsg() or recvmsg(). The following example 2440 shows two ancillary data objects in a control buffer. 2442 |<--------------------------- msg_controllen -------------------------->| 2443 | OR | 2444 |<--------------------------- msg_controllen ----------------------->| 2445 | | 2446 |<----- ancillary data object ----->|<----- ancillary data object ----->| 2447 |<------ min CMSG_SPACE() --------->|<------ min CMSG_SPACE() --------->| 2448 | | | 2449 |<---------- cmsg_len ---------->| |<--------- cmsg_len ----------->| | 2450 |<--------- CMSG_LEN() --------->| |<-------- CMSG_LEN() ---------->| | 2451 | | | | | 2452 +-----+-----+-----+--+-----------+--+-----+-----+-----+--+-----------+--+ 2453 |cmsg_|cmsg_|cmsg_|XX| |XX|cmsg_|cmsg_|cmsg_|XX| |XX| 2454 |len |level|type |XX|cmsg_data[]|XX|len |level|type |XX|cmsg_data[]|XX| 2455 +-----+-----+-----+--+-----------+--+-----+-----+-----+--+-----------+--+ 2456 ^ 2457 | 2458 msg_control 2459 points here 2461 The fields shown as "XX" are possible padding, between the cmsghdr 2462 structure and the data, and between the data and the next cmsghdr 2463 structure, if required by the implementation. While sending an 2464 application may or may not include padding at the end of last 2465 ancillary data in msg_controllen and implementations must accept both 2466 as valid. On receiving a portable application must provide space for 2467 padding at the end of the last ancillary data as implementations may 2468 copy out the padding at the end of the control message buffer and 2469 include it in the received msg_controllen. When recvmsg() is called 2470 if msg_controllen is too small for all the ancillary data items 2471 including any trailing padding after the last item an implementation 2472 may set MSG_CTRUNC. 2474 22.3. Ancillary Data Object Macros 2476 To aid in the manipulation of ancillary data objects, three macros 2477 from 4.4BSD are defined by Posix.1g: CMSG_DATA(), CMSG_NXTHDR(), and 2478 CMSG_FIRSTHDR(). Before describing these macros, we show the 2479 following example of how they might be used with a call to recvmsg(). 2481 struct msghdr msg; 2482 struct cmsghdr *cmsgptr; 2484 /* fill in msg */ 2486 /* call recvmsg() */ 2488 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; 2489 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { 2490 if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) { 2491 u_char *ptr; 2493 ptr = CMSG_DATA(cmsgptr); 2494 /* process data pointed to by ptr */ 2495 } 2496 } 2498 We now describe the three Posix.1g macros, followed by two more that 2499 are new with this API: CMSG_SPACE() and CMSG_LEN(). All these macros 2500 are defined as a result of including . 2502 22.3.1. CMSG_FIRSTHDR 2504 struct cmsghdr *CMSG_FIRSTHDR(const struct msghdr *mhdr); 2506 CMSG_FIRSTHDR() returns a pointer to the first cmsghdr structure in 2507 the msghdr structure pointed to by mhdr. The macro returns NULL if 2508 there is no ancillary data pointed to by the msghdr structure (that 2509 is, if either msg_control is NULL or if msg_controllen is less than 2510 the size of a cmsghdr structure). 2512 One possible implementation could be 2513 #define CMSG_FIRSTHDR(mhdr) \ 2514 ( (mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \ 2515 (struct cmsghdr *)(mhdr)->msg_control : \ 2516 (struct cmsghdr *)NULL ) 2518 (Note: Most existing implementations do not test the value of 2519 msg_controllen, and just return the value of msg_control. The value 2520 of msg_controllen must be tested, because if the application asks 2521 recvmsg() to return ancillary data, by setting msg_control to point 2522 to the application's buffer and setting msg_controllen to the length 2523 of this buffer, the kernel indicates that no ancillary data is 2524 available by setting msg_controllen to 0 on return. It is also 2525 easier to put this test into this macro, than making the application 2526 perform the test.) 2528 22.3.2. CMSG_NXTHDR 2530 struct cmsghdr *CMSG_NXTHDR(const struct msghdr *mhdr, 2531 const struct cmsghdr *cmsg); 2533 CMSG_NXTHDR() returns a pointer to the cmsghdr structure describing 2534 the next ancillary data object. mhdr is a pointer to a msghdr 2535 structure and cmsg is a pointer to a cmsghdr structure. If there is 2536 not another ancillary data object, the return value is NULL. 2538 The following behavior of this macro is new to this API: if the value 2539 of the cmsg pointer is NULL, a pointer to the cmsghdr structure 2540 describing the first ancillary data object is returned. That is, 2541 CMSG_NXTHDR(mhdr, NULL) is equivalent to CMSG_FIRSTHDR(mhdr). If 2542 there are no ancillary data objects, the return value is NULL. This 2543 provides an alternative way of coding the processing loop shown 2544 earlier: 2546 struct msghdr msg; 2547 struct cmsghdr *cmsgptr = NULL; 2549 /* fill in msg */ 2551 /* call recvmsg() */ 2553 while ((cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) != NULL) { 2554 if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) { 2555 u_char *ptr; 2557 ptr = CMSG_DATA(cmsgptr); 2558 /* process data pointed to by ptr */ 2559 } 2560 } 2562 One possible implementation could be: 2564 #define CMSG_NXTHDR(mhdr, cmsg) \ 2565 (((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \ 2566 (((u_char *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) \ 2567 + ALIGN_D(sizeof(struct cmsghdr)) > \ 2568 (u_char *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \ 2569 (struct cmsghdr *)NULL : \ 2570 (struct cmsghdr *)((u_char *)(cmsg) + ALIGN_H((cmsg)->cmsg_len)))) 2572 The macros ALIGN_H() and ALIGN_D(), which are implementation 2573 dependent, round their arguments up to the next even multiple of 2574 whatever alignment is required for the start of the cmsghdr structure 2575 and the data, respectively. (This is probably a multiple of 4 or 8 2576 bytes.) They are often the same macro in implementations platforms 2577 where alignment requirement for header and data is chosen to be 2578 identical. 2580 22.3.3. CMSG_DATA 2582 unsigned char *CMSG_DATA(const struct cmsghdr *cmsg); 2584 CMSG_DATA() returns a pointer to the data (what is called the 2585 cmsg_data[] member, even though such a member is not defined in the 2586 structure) following a cmsghdr structure. 2588 One possible implementation could be: 2590 #define CMSG_DATA(cmsg) ( (u_char *)(cmsg) + \ 2591 ALIGN_D(sizeof(struct cmsghdr)) ) 2593 22.3.4. CMSG_SPACE 2595 unsigned int CMSG_SPACE(unsigned int length); 2597 This macro is new with this API. Given the length of an ancillary 2598 data object, CMSG_SPACE() returns an upper bound on the space 2599 required by the object and its cmsghdr structure, including any 2600 padding needed to satisfy alignment requirements. This macro can be 2601 used, for example, when allocating space dynamically for the 2602 ancillary data. This macro should not be used to initialize the 2603 cmsg_len member of a cmsghdr structure; instead use the CMSG_LEN() 2604 macro. 2606 One possible implementation could be: 2608 #define CMSG_SPACE(length) ( ALIGN_D(sizeof(struct cmsghdr)) + \ 2609 ALIGN_H(length) ) 2611 22.3.5. CMSG_LEN 2613 unsigned int CMSG_LEN(unsigned int length); 2615 This macro is new with this API. Given the length of an ancillary 2616 data object, CMSG_LEN() returns the value to store in the cmsg_len 2617 member of the cmsghdr structure, taking into account any padding 2618 needed to satisfy alignment requirements. 2620 One possible implementation could be: 2622 #define CMSG_LEN(length) ( ALIGN_D(sizeof(struct cmsghdr)) + length ) 2624 Note the difference between CMSG_SPACE() and CMSG_LEN(), shown also 2625 in the figure in Section 4.2: the former accounts for any required 2626 padding at the end of the ancillary data object and the latter is the 2627 actual length to store in the cmsg_len member of the ancillary data 2628 object. 2630 23. Appendix B: Examples using the inet6_rth_XXX() functions 2632 Here we show an example for both sending Routing headers and 2633 processing and reversing a received Routing header. 2635 23.1. Sending a Routing Header 2637 As an example of these Routing header functions defined in this 2638 document, we go through the function calls for the example on p. 17 2639 of [RFC-2460]. The source is S, the destination is D, and the three 2640 intermediate nodes are I1, I2, and I3. 2642 S -----> I1 -----> I2 -----> I3 -----> D 2644 src: * S S S S S 2645 dst: D I1 I2 I3 D D 2646 A[1]: I1 I2 I1 I1 I1 I1 2647 A[2]: I2 I3 I3 I2 I2 I2 2648 A[3]: I3 D D D I3 I3 2649 #seg: 3 3 2 1 0 3 2651 src and dst are the source and destination IPv6 addresses in the IPv6 2652 header. A[1], A[2], and A[3] are the three addresses in the Routing 2653 header. #seg is the Segments Left field in the Routing header. 2655 The six values in the column beneath node S are the values in the 2656 Routing header specified by the sending application using sendmsg() 2657 of setsockopt(). The function calls by the sender would look like: 2659 void *extptr; 2660 int extlen; 2661 struct msghdr msg; 2662 struct cmsghdr *cmsgptr; 2663 int cmsglen; 2664 struct sockaddr_in6 I1, I2, I3, D; 2666 extlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, 3); 2667 cmsglen = CMSG_SPACE(extlen); 2668 cmsgptr = malloc(cmsglen); 2669 cmsgptr->cmsg_len = CMSG_LEN(extlen); 2670 cmsgptr->cmsg_level = IPPROTO_IPV6; 2671 cmsgptr->cmsg_type = IPV6_RTHDR; 2673 optptr = CMSG_DATA(cmsgptr); 2674 optptr = inet6_rth_init(optptr, optlen, IPV6_RTHDR_TYPE_0, 3); 2676 inet6_rth_add(optptr, &I1.sin6_addr); 2677 inet6_rth_add(optptr, &I2.sin6_addr); 2678 inet6_rth_add(optptr, &I3.sin6_addr); 2680 msg.msg_control = cmsgptr; 2681 msg.msg_controllen = cmsglen; 2683 /* finish filling in msg{}, msg_name = D */ 2684 /* call sendmsg() */ 2686 We also assume that the source address for the socket is not 2687 specified (i.e., the asterisk in the figure). 2689 The four columns of six values that are then shown between the five 2690 nodes are the values of the fields in the packet while the packet is 2691 in transit between the two nodes. Notice that before the packet is 2692 sent by the source node S, the source address is chosen (replacing 2693 the asterisk), I1 becomes the destination address of the datagram, 2694 the two addresses A[2] and A[3] are "shifted up", and D is moved to 2695 A[3]. 2697 The columns of values that are shown beneath the destination node are 2698 the values returned by recvmsg(), assuming the application has 2699 enabled both the IPV6_RECVPKTINFO and IPV6_RECVRTHDR socket options. 2700 The source address is S (contained in the sockaddr_in6 structure 2701 pointed to by the msg_name member), the destination address is D 2702 (returned as an ancillary data object in an in6_pktinfo structure), 2703 and the ancillary data object specifying the Routing header will 2704 contain three addresses (I1, I2, and I3). The number of segments in 2705 the Routing header is known from the Hdr Ext Len field in the Routing 2706 header (a value of 6, indicating 3 addresses). 2708 The return value from inet6_rth_segments() will be 3 and 2709 inet6_rth_getaddr(0) will return I1, inet6_rth_getaddr(1) will return 2710 I2, and inet6_rth_getaddr(2) will return I3, 2712 If the receiving application then calls inet6_rth_reverse(), the 2713 order of the three addresses will become I3, I2, and I1. 2715 We can also show what an implementation might store in the ancillary 2716 data object as the Routing header is being built by the sending 2717 process. If we assume a 32-bit architecture where sizeof(struct 2718 cmsghdr) equals 12, with a desired alignment of 4-byte boundaries, 2719 then the call to inet6_rth_space(3) returns 68: 12 bytes for the 2720 cmsghdr structure and 56 bytes for the Routing header (8 + 3*16). 2722 The call to inet6_rth_init() initializes the ancillary data object to 2723 contain a Type 0 Routing header: 2725 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2726 | cmsg_len = 20 | 2727 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2728 | cmsg_level = IPPROTO_IPV6 | 2729 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2730 | cmsg_type = IPV6_RTHDR | 2731 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2732 | Next Header | Hdr Ext Len=6 | Routing Type=0| Seg Left=0 | 2733 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2734 | Reserved | 2735 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2737 The first call to inet6_rth_add() adds I1 to the list. 2739 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2740 | cmsg_len = 36 | 2741 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2742 | cmsg_level = IPPROTO_IPV6 | 2743 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2744 | cmsg_type = IPV6_RTHDR | 2745 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2746 | Next Header | Hdr Ext Len=6 | Routing Type=0| Seg Left=1 | 2747 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2748 | Reserved | 2749 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2750 | | 2751 + + 2752 | | 2753 + Address[1] = I1 + 2754 | | 2755 + + 2756 | | 2757 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2759 cmsg_len is incremented by 16, and the Segments Left field is 2760 incremented by 1. 2762 The next call to inet6_rth_add() adds I2 to the list. 2764 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2765 | cmsg_len = 52 | 2766 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2767 | cmsg_level = IPPROTO_IPV6 | 2768 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2769 | cmsg_type = IPV6_RTHDR | 2770 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2771 | Next Header | Hdr Ext Len=6 | Routing Type=0| Seg Left=2 | 2772 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2773 | Reserved | 2774 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2775 | | 2776 + + 2777 | | 2778 + Address[1] = I1 + 2779 | | 2780 + + 2781 | | 2782 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2783 | | 2784 + + 2785 | | 2786 + Address[2] = I2 + 2787 | | 2788 + + 2789 | | 2790 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2792 cmsg_len is incremented by 16, and the Segments Left field is 2793 incremented by 1. 2795 The last call to inet6_rth_add() adds I3 to the list. 2797 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2798 | cmsg_len = 68 | 2799 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2800 | cmsg_level = IPPROTO_IPV6 | 2801 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2802 | cmsg_type = IPV6_RTHDR | 2803 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2804 | Next Header | Hdr Ext Len=6 | Routing Type=0| Seg Left=3 | 2805 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2806 | Reserved | 2807 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2808 | | 2809 + + 2810 | | 2811 + Address[1] = I1 + 2812 | | 2813 + + 2814 | | 2815 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2816 | | 2817 + + 2818 | | 2819 + Address[2] = I2 + 2820 | | 2821 + + 2822 | | 2823 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2824 | | 2825 + + 2826 | | 2827 + Address[3] = I3 + 2828 | | 2829 + + 2830 | | 2831 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2833 cmsg_len is incremented by 16, and the Segments Left field is 2834 incremented by 1. 2836 23.2. Receiving Routing Headers 2838 This example assumes that the application has enabled IPV6_RECVRTHDR 2839 socket option. The application prints and reverses a source route 2840 and uses that to echo the received data. 2842 struct sockaddr_in6 addr; 2843 struct msghdr msg; 2844 struct iovec iov; 2845 struct cmsghdr *cmsgptr; 2846 size_t cmsgspace; 2847 void *optptr; 2848 int optlen; 2850 int segments; 2851 int i; 2852 char databuf[8192]; 2854 segments = 100; /* Enough */ 2855 optlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, segments); 2856 cmsgspace = CMSG_SPACE(optlen); 2857 cmsgptr = malloc(cmsgspace); 2858 if (cmsgptr == NULL) { 2859 perror("malloc"); 2860 exit(1); 2861 } 2862 optptr = CMSG_DATA(cmsgptr); 2864 msg.msg_control = (char *)cmsgptr; 2865 msg.msg_controllen = cmsgspace; 2866 msg.msg_name = (struct sockaddr *)&addr; 2867 msg.msg_namelen = sizeof (addr); 2868 msg.msg_iov = &iov; 2869 msg.msg_iovlen = 1; 2870 iov.iov_base = databuf; 2871 iov.iov_len = sizeof (databuf); 2872 msg.msg_flags = 0; 2873 if (recvmsg(s, &msg, 0) == -1) { 2874 perror("recvmsg"); 2875 return; 2876 } 2877 if (msg.msg_controllen != 0 && 2878 cmsgptr->cmsg_level == IPPROTO_IPV6 && 2879 cmsgptr->cmsg_type == IPV6_RTHDR) { 2880 struct in6_addr *in6; 2881 char asciiname[INET6_ADDRSTRLEN]; 2882 struct ip6_rthdr0 *rthdr; 2884 rthdr = (struct ip6_rthdr0 *)optptr; 2885 segments = inet6_rth_segments(optptr); 2886 printf("route (%d segments, %d left): ", 2887 segments, rthdr->ip6r0_segleft); 2888 for (i = 0; i < segments; i++) { 2889 in6 = inet6_rth_getaddr(optptr, i); 2890 if (in6 == NULL) 2891 printf(" "); 2892 else 2893 printf("%s ", inet_ntop(AF_INET6, 2894 (void *)in6->s6_addr, 2895 asciiname, INET6_ADDRSTRLEN)); 2896 } 2897 if (inet6_rth_reverse(optptr, optptr) == -1) { 2898 printf("reverse failed"); 2899 return; 2900 } 2901 } 2902 iov.iov_base = databuf; 2903 iov.iov_len = strlen(databuf); 2904 if (sendmsg(s, &msg, 0) == -1) 2905 perror("sendmsg"); 2906 if (cmsgptr != NULL) 2907 free(cmsgptr); 2909 Note: The above example is a simple illustration. It skips some 2910 error checks involving the MSG_TRUNC and MSG_CTRUNC flags. 2912 24. Appendix C: Examples using the inet6_opt_XXX() functions 2914 This shows how Hop-by-Hop and Destination options can be both built 2915 as well as parsed using the inet6_opt_XXX() functions. This examples 2916 assume that there are defined values for OPT_X and OPT_Y. 2918 24.1. Building options 2920 We now provide an example that builds two Hop-by-Hop options using 2921 the example in Appendix B of [RFC-2460]. 2923 void *extbuf; 2924 size_t extlen; 2925 int currentlen; 2926 void *databuf; 2927 size_t offset; 2928 uint8_t value1; 2929 uint16_t value2; 2930 uint32_t value4; 2931 uint64_t value8; 2933 /* Estimate the length */ 2934 currentlen = inet6_opt_init(NULL, 0); 2935 if (currentlen == -1) 2936 return (-1); 2938 currentlen = inet6_opt_append(NULL, 0, currentlen, OPT_X, 12, 8, NULL); 2939 if (currentlen == -1) 2940 return (-1); 2941 currentlen = inet6_opt_append(NULL, 0, currentlen, OPT_Y, 7, 4, NULL); 2942 if (currentlen == -1) 2943 return (-1); 2944 currentlen = inet6_opt_finish(NULL, 0, currentlen); 2945 if (currentlen == -1) 2946 return (-1); 2947 extlen = currentlen; 2949 extbuf = malloc(extlen); 2950 if (extbuf == NULL) { 2951 perror("malloc"); 2952 return (-1); 2953 } 2954 currentlen = inet6_opt_init(extbuf, extlen); 2955 if (currentlen == -1) 2956 return (-1); 2958 currentlen = inet6_opt_append(extbuf, extlen, currentlen, 2959 OPT_X, 12, 8, &databuf); 2960 if (currentlen == -1) 2961 return (-1); 2962 /* Insert value 0x12345678 for 4-octet field */ 2963 offset = 0; 2964 value4 = 0x12345678; 2965 offset = inet6_opt_set_val(databuf, offset, &value4, sizeof (value4)); 2966 /* Insert value 0x0102030405060708 for 8-octet field */ 2967 value8 = 0x0102030405060708; 2968 offset = inet6_opt_set_val(databuf, offset, &value8, sizeof (value8)); 2970 currentlen = inet6_opt_append(extbuf, extlen, currentlen, 2971 OPT_Y, 7, 4, &databuf); 2972 if (currentlen == -1) 2973 return (-1); 2974 /* Insert value 0x01 for 1-octet field */ 2975 offset = 0; 2976 value1 = 0x01; 2977 offset = inet6_opt_set_val(databuf, offset, &value1, sizeof (value1)); 2978 /* Insert value 0x1331 for 2-octet field */ 2979 value2 = 0x1331; 2980 offset = inet6_opt_set_val(databuf, offset, &value2, sizeof (value2)); 2981 /* Insert value 0x01020304 for 4-octet field */ 2982 value4 = 0x01020304; 2983 offset = inet6_opt_set_val(databuf, offset, &value4, sizeof (value4)); 2985 currentlen = inet6_opt_finish(extbuf, extlen, currentlen); 2986 if (currentlen == -1) 2987 return (-1); 2988 /* extbuf and extlen are now completely formatted */ 2990 24.2. Parsing received options 2992 This example parses and prints the content of the two options in the 2993 previous example. 2995 int 2996 print_opt(void *extbuf, size_t extlen) 2997 { 2998 ip6_dest_t *ext; 2999 int currentlen; 3000 uint8_t type; 3001 size_t len; 3002 void *databuf; 3003 size_t offset; 3004 uint8_t value1; 3005 uint16_t value2; 3006 uint32_t value4; 3007 uint64_t value8; 3009 ext = (ip6_dest_t *)extbuf; 3010 printf("nxt %u, len %u (bytes %d)\n", ext->ip6d_nxt, 3011 ext->ip6d_len, (ext->ip6d_len + 1) * 8); 3013 currentlen = 0; 3014 while (1) { 3015 currentlen = inet6_opt_next(extbuf, extlen, currentlen, 3016 &type, &len, &databuf); 3017 if (currentlen == -1) 3018 break; 3019 printf("Received opt %u len %u\n", 3020 type, len); 3021 switch (type) { 3022 case OPT_X: 3023 offset = 0; 3024 offset = inet6_opt_get_val(databuf, offset, 3025 &value4, sizeof (value4)); 3026 printf("X 4-byte field %x\n", value4); 3027 offset = inet6_opt_get_val(databuf, offset, 3028 &value8, sizeof (value8)); 3029 printf("X 8-byte field %llx\n", value8); 3030 break; 3031 case OPT_Y: 3033 offset = 0; 3034 offset = inet6_opt_get_val(databuf, offset, 3035 &value1, sizeof (value1)); 3036 printf("Y 1-byte field %x\n", value1); 3037 offset = inet6_opt_get_val(databuf, offset, 3038 &value2, sizeof (value2)); 3039 printf("Y 2-byte field %x\n", value2); 3040 offset = inet6_opt_get_val(databuf, offset, 3041 &value4, sizeof (value4)); 3042 printf("Y 4-byte field %x\n", value4); 3043 break; 3044 default: 3045 printf("Unknown option %u\n", type); 3046 break; 3047 } 3048 } 3049 return (0); 3050 }