⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfc2292.txt

📁 RFC 的详细文档!
💻 TXT
📖 第 1 页 / 共 5 页
字号:


   Note the difference between CMSG_SPACE() and CMSG_LEN(), shown also
   in the figure in Section 4.2: the former accounts for any required
   padding at the end of the ancillary data object and the latter is the
   actual length to store in the cmsg_len member of the ancillary data
   object.

4.4.  Summary of Options Described Using Ancillary Data

   There are six types of optional information described in this
   document that are passed between the application and the kernel using
   ancillary data:

       1.  the send/receive interface and source/destination address,
       2.  the hop limit,
       3.  next hop address,
       4.  Hop-by-Hop options,
       5.  Destination options, and
       6.  Routing header.

   First, to receive any of this optional information (other than the
   next hop address, which can only be set), the application must call
   setsockopt() to turn on the corresponding flag:

       int  on = 1;

       setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO,  &on, sizeof(on));
       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) and



Stevens & 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -