📄 rfc2292.txt
字号:
setsockopt(fd, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on)); setsockopt(fd, IPPROTO_IPV6, IPV6_HOPOPTS, &on, sizeof(on)); setsockopt(fd, IPPROTO_IPV6, IPV6_DSTOPTS, &on, sizeof(on)); setsockopt(fd, IPPROTO_IPV6, IPV6_RTHDR, &on, sizeof(on)); When any of these options are enabled, the corresponding data is returned as control information by recvmsg(), as one or more ancillary data objects. Nothing special need be done to send any of this optional information; the application just calls sendmsg() and specifies one or more ancillary data objects as control information. We also summarize the three cmsghdr fields that describe the ancillary data objects: cmsg_level cmsg_type cmsg_data[] #times ------------ ------------ ------------------------ ------ IPPROTO_IPV6 IPV6_PKTINFO in6_pktinfo structure once IPPROTO_IPV6 IPV6_HOPLIMIT int once IPPROTO_IPV6 IPV6_NEXTHOP socket address structure once IPPROTO_IPV6 IPV6_HOPOPTS implementation dependent mult.Stevens & Thomas Informational [Page 23]RFC 2292 Advanced Sockets API for IPv6 February 1998 IPPROTO_IPV6 IPV6_DSTOPTS implementation dependent mult. IPPROTO_IPV6 IPV6_RTHDR implementation dependent once The final column indicates how many times an ancillary data object of that type can appear as control information. The Hop-by-Hop and Destination options can appear multiple times, while all the others can appear only one time. All these options are described in detail in following sections. All the constants beginning with IPV6_ are defined as a result of including the <netinet/in.h> header. (Note: We intentionally use the same constant for the cmsg_level member as is used as the second argument to getsockopt() and setsockopt() (what is called the "level"), and the same constant for the cmsg_type member as is used as the third argument to getsockopt() and setsockopt() (what is called the "option name"). This is consistent with the existing use of ancillary data in 4.4BSD: returning the destination address of an IPv4 datagram.) (Note: It is up to the implementation what it passes as ancillary data for the Hop-by-Hop option, Destination option, and Routing header option, since the API to these features is through a set of inet6_option_XXX() and inet6_rthdr_XXX() functions that we define later. These functions serve two purposes: to simplify the interface to these features (instead of requiring the application to know the intimate details of the extension header formats), and to hide the actual implementation from the application. Nevertheless, we show some examples of these features that store the actual extension header as the ancillary data. Implementations need not use this technique.)4.5. IPV6_PKTOPTIONS Socket Option The summary in the previous section assumes a UDP socket. Sending and receiving ancillary data is easy with UDP: the application calls sendmsg() and recvmsg() instead of sendto() and recvfrom(). But there might be cases where a TCP application wants to send or receive this optional information. For example, a TCP client might want to specify a Routing header and this needs to be done before calling connect(). Similarly a TCP server might want to know the received interface after accept() returns along with any Destination options.Stevens & Thomas Informational [Page 24]RFC 2292 Advanced Sockets API for IPv6 February 1998 A new socket option is defined that provides access to the optional information described in the previous section, but without using recvmsg() and sendmsg(). Setting the socket option specifies any of the optional output fields: setsockopt(fd, IPPROTO_IPV6, IPV6_PKTOPTIONS, &buf, len); The fourth argument points to a buffer containing one or more ancillary data objects, and the fifth argument is the total length of all these objects. The application fills in this buffer exactly as if the buffer were being passed to sendmsg() as control information. The options set by calling setsockopt() for IPV6_PKTOPTIONS are called "sticky" options because once set they apply to all packets sent on that socket. The application can call setsockopt() again to change all the sticky options, or it can call setsockopt() with a length of 0 to remove all the sticky options for the socket. The corresponding receive option getsockopt(fd, IPPROTO_IPV6, IPV6_PKTOPTIONS, &buf, &len); returns a buffer with one or more ancillary data objects for all the optional receive information that the application has previously specified that it wants to receive. The fourth argument points to the buffer that is filled in by the call. The fifth argument is a pointer to a value-result integer: when the function is called the integer specifies the size of the buffer pointed to by the fourth argument, and on return this integer contains the actual number of bytes that were returned. The application processes this buffer exactly as if the buffer were returned by recvmsg() as control information. To simplify this document, in the remaining sections when we say "can be specified as ancillary data to sendmsg()" we mean "can be specified as ancillary data to sendmsg() or specified as a sticky option using setsockopt() and the IPV6_PKTOPTIONS socket option". Similarly when we say "can be returned as ancillary data by recvmsg()" we mean "can be returned as ancillary data by recvmsg() or returned by getsockopt() with the IPV6_PKTOPTIONS socket option".4.5.1. TCP Sticky Options When using getsockopt() with the IPV6_PKTOPTIONS option and a TCP socket, only the options from the most recently received segment are retained and returned to the caller, and only after the socket option has been set. That is, TCP need not start saving a copy of the options until the application says to do so.Stevens & Thomas Informational [Page 25]RFC 2292 Advanced Sockets API for IPv6 February 1998 The application is not allowed to specify ancillary data in a call to sendmsg() on a TCP socket, and none of the ancillary data that we describe in this document is ever returned as control information by recvmsg() on a TCP socket.4.5.2. UDP and Raw Socket Sticky Options The IPV6_PKTOPTIONS socket option can also be used with a UDP socket or with a raw IPv6 socket, normally to set some of the options once, instead of with each call to sendmsg(). Unlike the TCP case, the sticky options can be overridden on a per- packet basis with ancillary data specified in a call to sendmsg() on a UDP or raw IPv6 socket. If any ancillary data is specified in a call to sendmsg(), none of the sticky options are sent with that datagram.5. Packet Information There are four pieces of information that an application can specify for an outgoing packet using ancillary data: 1. the source IPv6 address, 2. the outgoing interface index, 3. the outgoing hop limit, and 4. the next hop address. Three similar pieces of information can be returned for a received packet as ancillary data: 1. the destination IPv6 address, 2. the arriving interface index, and 3. the arriving hop limit. The first two pieces of information are contained in an in6_pktinfo structure that is sent as ancillary data with sendmsg() and received as ancillary data with recvmsg(). This structure is defined as a result of including the <netinet/in.h> header. struct in6_pktinfo { struct in6_addr ipi6_addr; /* src/dst IPv6 address */ unsigned int ipi6_ifindex; /* send/recv interface index */ }; In the cmsghdr structure containing this ancillary data, the cmsg_level member will be IPPROTO_IPV6, the cmsg_type member will be IPV6_PKTINFO, and the first byte of cmsg_data[] will be the first byte of the in6_pktinfo structure.Stevens & Thomas Informational [Page 26]RFC 2292 Advanced Sockets API for IPv6 February 1998 This information is returned as ancillary data by recvmsg() only if the application has enabled the IPV6_PKTINFO socket option: int on = 1; setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on)); Nothing special need be done to send this information: just specify the control information as ancillary data for sendmsg(). (Note: The hop limit is not contained in the in6_pktinfo structure for the following reason. Some UDP servers want to respond to client requests by sending their reply out the same interface on which the request was received and with the source IPv6 address of the reply equal to the destination IPv6 address of the request. To do this the application can enable just the IPV6_PKTINFO socket option and then use the received control information from recvmsg() as the outgoing control information for sendmsg(). The application need not examine or modify the in6_pktinfo structure at all. But if the hop limit were contained in this structure, the application would have to parse the received control information and change the hop limit member, since the received hop limit is not the desired value for an outgoing packet.)5.1. Specifying/Receiving the Interface Interfaces on an IPv6 node are identified by a small positive integer, as described in Section 4 of [RFC-2133]. That document also describes a function to map an interface name to its interface index, a function to map an interface index to its interface name, and a function to return all the interface names and indexes. Notice from this document that no interface is ever assigned an index of 0. When specifying the outgoing interface, if the ipi6_ifindex value is 0, the kernel will choose the outgoing interface. If the application specifies an outgoing interface for a multicast packet, the interface specified by the ancillary data overrides any interface specified by the IPV6_MULTICAST_IF socket option (described in [RFC-2133]), for that call to sendmsg() only. When the IPV6_PKTINFO socket option is enabled, the received interface index is always returned as the ipi6_ifindex member of the in6_pktinfo structure.5.2. Specifying/Receiving Source/Destination Address The source IPv6 address can be specified by calling bind() before each output operation, but supplying the source address together with the data requires less overhead (i.e., fewer system calls) andStevens & Thomas Informational [Page 27]RFC 2292 Advanced Sockets API for IPv6 February 1998 requires less state to be stored and protected in a multithreaded application. When specifying the source IPv6 address as ancillary data, if the ipi6_addr member of the in6_pktinfo structure is the unspecified address (IN6ADDR_ANY_INIT), then (a) if an address is currently bound to the socket, it is used as the source address, or (b) if no address is currently bound to the socket, the kernel will choose the source address. If the ipi6_addr member is not the unspecified address, but the socket has already bound a source address, then the ipi6_addr value overrides the already-bound source address for this output operation only. The kernel must verify that the requested source address is indeed a unicast address assigned to the node. When the in6_pktinfo structure is returned as ancillary data by recvmsg(), the ipi6_addr member contains the destination IPv6 address from the received packet.5.3. Specifying/Receiving the Hop Limit The outgoing hop limit is normally specified with either the IPV6_UNICAST_HOPS socket option or the IPV6_MULTICAST_HOPS socket option, both of which are described in [RFC-2133]. Specifying the hop limit as ancillary data lets the application override either the kernel's default or a previously specified value, for either a unicast destination or a multicast destination, for a single output operation. Returning the received hop limit is useful for programs such as Traceroute and for IPv6 applications that need to verify that the received hop limit is 255 (e.g., that the packet has not been forwarded). The received hop limit is returned as ancillary data by recvmsg() only if the application has enabled the IPV6_HOPLIMIT socket option: int on = 1; setsockopt(fd, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on)); In the cmsghdr structure containing this ancillary data, the cmsg_level member will be IPPROTO_IPV6, the cmsg_type member will be IPV6_HOPLIMIT, and the first byte of cmsg_data[] will be the first byte of the integer hop limit. Nothing special need be done to specify the outgoing hop limit: just specify the control information as ancillary data for sendmsg(). As specified in [RFC-2133], the interpretation of the integer hop limit value isStevens & Thomas Informational [Page 28]RFC 2292 Advanced Sockets API for IPv6 February 1998 x < -1: return an error of EINVAL x == -1: use kernel default 0 <= x <= 255: use x x >= 256: return an error of EINVAL5.4. Specifying the Next Hop Ad
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -