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

📄 rfc2292.txt

📁 netcat
💻 TXT
📖 第 1 页 / 共 5 页
字号:
Stevens & Thomas             Informational                     [Page 17]RFC 2292             Advanced Sockets API for IPv6         February 19984.1.  The msghdr Structure   The msghdr structure is used by the recvmsg() and sendmsg()   functions.  Its Posix.1g definition is:    struct msghdr {      void      *msg_name;        /* ptr to socket address structure */      socklen_t  msg_namelen;     /* size of socket address structure */      struct iovec  *msg_iov;     /* scatter/gather array */      size_t     msg_iovlen;      /* # elements in msg_iov */      void      *msg_control;     /* ancillary data */      socklen_t  msg_controllen;  /* ancillary data buffer length */      int        msg_flags;       /* flags on received message */    };   The structure is declared as a result of including <sys/socket.h>.   (Note: Before Posix.1g the two "void *" pointers were typically "char   *", and the two socklen_t members and the size_t member were   typically integers.  Earlier drafts of Posix.1g had the two socklen_t   members as size_t, but Draft 6.6 of Posix.1g, apparently the final   draft, changed these to socklen_t to simplify binary portability for   64-bit implementations and to align Posix.1g with X/Open's Networking   Services, Issue 5.  The change in msg_control to a "void *" pointer   affects any code that increments this pointer.)   Most Berkeley-derived implementations limit the amount of ancillary   data in a call to sendmsg() to no more than 108 bytes (an mbuf).   This API requires a minimum of 10240 bytes of ancillary data, but it   is recommended that the amount be limited only by the buffer space   reserved by the socket (which can be modified by the SO_SNDBUF socket   option).  (Note: This magic number 10240 was picked as a value that   should always be large enough.  108 bytes is clearly too small as the   maximum size of a Type 0 Routing header is 376 bytes.)4.2.  The cmsghdr Structure   The cmsghdr structure describes ancillary data objects transferred by   recvmsg() and sendmsg().  Its Posix.1g definition is:    struct cmsghdr {      socklen_t  cmsg_len;   /* #bytes, including this header */      int        cmsg_level; /* originating protocol */      int        cmsg_type;  /* protocol-specific type */                 /* followed by unsigned char cmsg_data[]; */    };   This structure is declared as a result of including <sys/socket.h>.Stevens & Thomas             Informational                     [Page 18]RFC 2292             Advanced Sockets API for IPv6         February 1998   As shown in this definition, normally there is no member with the   name cmsg_data[].  Instead, the data portion is accessed using the   CMSG_xxx() macros, as described shortly.  Nevertheless, it is common   to refer to the cmsg_data[] member.   (Note: Before Posix.1g the cmsg_len member was an integer, and not a   socklen_t.  See the Note in the previous section for why socklen_t is   used here.)   When ancillary data is sent or received, any number of ancillary data   objects can be specified by the msg_control and msg_controllen   members of the msghdr structure, because each object is preceded by a   cmsghdr structure defining the object's length (the cmsg_len member).   Historically Berkeley-derived implementations have passed only one   object at a time, but this API allows multiple objects to be passed   in a single call to sendmsg() or recvmsg().  The following example   shows two ancillary data objects in a control buffer.|<--------------------------- msg_controllen -------------------------->||                                                                       ||<----- ancillary data object ----->|<----- ancillary data object ----->||<---------- CMSG_SPACE() --------->|<---------- CMSG_SPACE() --------->||                                   |                                   ||<---------- cmsg_len ---------->|  |<--------- cmsg_len ----------->|  ||<--------- CMSG_LEN() --------->|  |<-------- CMSG_LEN() ---------->|  ||                                |  |                                |  |+-----+-----+-----+--+-----------+--+-----+-----+-----+--+-----------+--+|cmsg_|cmsg_|cmsg_|XX|           |XX|cmsg_|cmsg_|cmsg_|XX|           |XX||len  |level|type |XX|cmsg_data[]|XX|len  |level|type |XX|cmsg_data[]|XX|+-----+-----+-----+--+-----------+--+-----+-----+-----+--+-----------+--+ ^ |msg_controlpoints here   The fields shown as "XX" are possible padding, between the cmsghdr   structure and the data, and between the data and the next cmsghdr   structure, if required by the implementation.4.3.  Ancillary Data Object Macros   To aid in the manipulation of ancillary data objects, three macros   from 4.4BSD are defined by Posix.1g: CMSG_DATA(), CMSG_NXTHDR(), and   CMSG_FIRSTHDR().  Before describing these macros, we show the   following example of how they might be used with a call to recvmsg().    struct msghdr   msg;    struct cmsghdr  *cmsgptr;Stevens & Thomas             Informational                     [Page 19]RFC 2292             Advanced Sockets API for IPv6         February 1998    /* fill in msg */    /* call recvmsg() */    for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;         cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {        if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) {            u_char  *ptr;            ptr = CMSG_DATA(cmsgptr);            /* process data pointed to by ptr */        }    }   We now describe the three Posix.1g macros, followed by two more that   are new with this API: CMSG_SPACE() and CMSG_LEN().  All these macros   are defined as a result of including <sys/socket.h>.4.3.1.  CMSG_FIRSTHDR       struct cmsghdr *CMSG_FIRSTHDR(const struct msghdr *mhdr);   CMSG_FIRSTHDR() returns a pointer to the first cmsghdr structure in   the msghdr structure pointed to by mhdr.  The macro returns NULL if   there is no ancillary data pointed to the by msghdr structure (that   is, if either msg_control is NULL or if msg_controllen is less than   the size of a cmsghdr structure).   One possible implementation could be       #define CMSG_FIRSTHDR(mhdr) \           ( (mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \             (struct cmsghdr *)(mhdr)->msg_control : \             (struct cmsghdr *)NULL )   (Note: Most existing implementations do not test the value of   msg_controllen, and just return the value of msg_control.  The value   of msg_controllen must be tested, because if the application asks   recvmsg() to return ancillary data, by setting msg_control to point   to the application's buffer and setting msg_controllen to the length   of this buffer, the kernel indicates that no ancillary data is   available by setting msg_controllen to 0 on return.  It is also   easier to put this test into this macro, than making the application   perform the test.)Stevens & Thomas             Informational                     [Page 20]RFC 2292             Advanced Sockets API for IPv6         February 19984.3.2.  CMSG_NXTHDR       struct cmsghdr *CMSG_NXTHDR(const struct msghdr *mhdr,                                   const struct cmsghdr *cmsg);   CMSG_NXTHDR() returns a pointer to the cmsghdr structure describing   the next ancillary data object.  mhdr is a pointer to a msghdr   structure and cmsg is a pointer to a cmsghdr structure.  If there is   not another ancillary data object, the return value is NULL.   The following behavior of this macro is new to this API: if the value   of the cmsg pointer is NULL, a pointer to the cmsghdr structure   describing the first ancillary data object is returned.  That is,   CMSG_NXTHDR(mhdr, NULL) is equivalent to CMSG_FIRSTHDR(mhdr).  If   there are no ancillary data objects, the return value is NULL.  This   provides an alternative way of coding the processing loop shown   earlier:struct msghdr  msg;struct cmsghdr  *cmsgptr = NULL;/* fill in msg *//* call recvmsg() */while ((cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) != NULL) {    if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) {        u_char  *ptr;        ptr = CMSG_DATA(cmsgptr);        /* process data pointed to by ptr */    }}   One possible implementation could be:    #define CMSG_NXTHDR(mhdr, cmsg) \        ( ((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \          (((u_char *)(cmsg) + ALIGN((cmsg)->cmsg_len) \                             + ALIGN(sizeof(struct cmsghdr)) > \            (u_char *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \           (struct cmsghdr *)NULL : \           (struct cmsghdr *)((u_char *)(cmsg) + ALIGN((cmsg)->cmsg_len))) )   The macro ALIGN(), which is implementation dependent, rounds its   argument up to the next even multiple of whatever alignment is   required (probably a multiple of 4 or 8 bytes).Stevens & Thomas             Informational                     [Page 21]RFC 2292             Advanced Sockets API for IPv6         February 19984.3.3.  CMSG_DATA       unsigned char *CMSG_DATA(const struct cmsghdr *cmsg);   CMSG_DATA() returns a pointer to the data (what is called the   cmsg_data[] member, even though such a member is not defined in the   structure) following a cmsghdr structure.   One possible implementation could be:       #define CMSG_DATA(cmsg) ( (u_char *)(cmsg) + \                                 ALIGN(sizeof(struct cmsghdr)) )4.3.4.  CMSG_SPACE       unsigned int CMSG_SPACE(unsigned int length);   This macro is new with this API.  Given the length of an ancillary   data object, CMSG_SPACE() returns the space required by the object   and its cmsghdr structure, including any padding needed to satisfy   alignment requirements.  This macro can be used, for example, to   allocate space dynamically for the ancillary data.  This macro should   not be used to initialize the cmsg_len member of a cmsghdr structure;   instead use the CMSG_LEN() macro.   One possible implementation could be:       #define CMSG_SPACE(length) ( ALIGN(sizeof(struct cmsghdr)) + \                                    ALIGN(length) )4.3.5.  CMSG_LEN       unsigned int CMSG_LEN(unsigned int length);   This macro is new with this API.  Given the length of an ancillary   data object, CMSG_LEN() returns the value to store in the cmsg_len   member of the cmsghdr structure, taking into account any padding   needed to satisfy alignment requirements.   One possible implementation could be:       #define CMSG_LEN(length) ( ALIGN(sizeof(struct cmsghdr)) + length       )Stevens & Thomas             Informational                     [Page 22]RFC 2292             Advanced Sockets API for IPv6         February 1998   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));

⌨️ 快捷键说明

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