Access ancillary data.


       #include <sys/socket.h>

       struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
       struct cmsghdr *CMSG_NXTHDR(struct  msghdr  *msgh,  struct
       cmsghdr *cmsg);
       size_t CMSG_ALIGN(size_t length);
       size_t CMSG_SPACE(size_t length);
       size_t CMSG_LEN(size_t length);
       void *CMSG_DATA(struct cmsghdr *cmsg);

       struct cmsghdr {
               socklen_t   cmsg_len;   /* data byte count, including header */
               int         cmsg_level; /* originating protocol */
               int         cmsg_type;  /* protocol-specific type */
       /* followed by
               u_char      cmsg_data[]; */


       These  macros  are  used to create and access control mes­
       sages (also called ancillary data) that are not a part  of
       the  socket payload.  This control information may include
       the interface the packet was received on,  various  rarely
       used  header  fields,  an extended error description, or a
       file descriptor to  be  passed  to  another  process.  For
       instance,  control messages can be used to send additional
       header fields such as IP options.  Ancillary data is  sent
       by  calling  sendmsg(2)  or  received  by recvmsg(2).  See
       their manual pages for more information.

       Ancillary data is a sequence of struct cmsghdr  structures
       with  appended data. This sequence should be accessed only
       using the macros described in this manual page  and  never
       directly.   See  the  specific  protocol man pages for the
       available control message types.   The  maximum  ancillary
       buffer  size  allowed  per  socket  can  be  set using the
       net.core.optmem_max sysctl; see socket(4).

       To create ancillary data, first  initialize  the  msg_con­
       trollen  member  of the msghdr with the length of the con­
       trol message buffer. Then use CMSG_FIRSTHDR on the  msghdr
       to  get  the  first  control  message, initialize cmsg_len
       (with CMSG_LEN), the other cmsghdr header fields, and  the
       data  portion  using CMSG_DATA.  Then get the next cmsghdr
       using CMSG_NXTHDR or NULL when you ran out of buffer  mem­
       ory. Finally the msg_controllen field of the msghdr should
       be set to the sum of the CMSG_SPACE of the length  of  all

       CMSG_FIRSTHDR returns a pointer to the  first  cmsghdr  in
       the  ancillary  data  buffer  associated  with  the passed

       CMSG_NXTHDR returns  the  next  valid  cmsghdr  after  the
       passed  cmsghdr.   It  returns NULL when there is no valid
       data header left.  This macro decrements the msghdr length
       field by the cmsghdr length.

       CMSG_ALIGN,  given  a  length,  returns  it  including the
       required alignment. This is a constant expression.

       CMSG_SPACE returns the number of bytes an  ancillary  ele­
       ment with payload of the passed data length occupies. This
       is a constant expression.

       CMSG_DATA returns a pointer to the data portion of a  cms­

       CMSG_LEN returns the value to store in the cmsg_len member
       of the cmsghdr structure, taking into account  any  neces­
       sary  alignment.  It takes the data length as an argument.
       This is a constant expression.


       When the control message buffer is too short to store  all
       messages, the MSG_CTRUNC flag is set in the msg_flags mem­
       ber of the msghdr.


       This code looks for the IP_TTL option in a received ancil­
       lary buffer:

              struct msghdr msgh;
              struct cmsghdr *cmsg;
              int *ttlptr;
              int received_ttl;

              /* Receive auxiliary data in msgh */
              for (cmsg = CMSG_FIRSTHDR(&msgh);
                   cmsg != NULL;
                   cmsg = CMSG_NXTHDR(&msgh,cmsg) {
                      if (cmsg->cmsg_level == SOL_IP
                        && cmsg->cmsg_type == IP_TTL) {
                              ttlptr = (int *) CMSG_DATA(cmsg);
                              received_ttl = *ttlptr;
              if (cmsg == NULL) {
                      /* Error: IP_TTL not enabled or buffer too short or IO error. */

       using SCM_RIGHTS:

              struct msghdr msg = {0};
              struct cmsghdr *cmsg;
              int myfds[NUM_FD]; /* Contains the file descriptors to pass. */
              char buf[CMSG_SPACE(sizeof myfds)];  /* ancillary data buffer */
              int *fdptr;

              msg.msg_control = buf;
              msg.msg_controllen = sizeof buf;
              cmsg = CMSG_FIRSTHDR(&msg);
              cmsg->cmsg_level = SOL_SOCKET;
              cmsg->cmsg_type = SCM_RIGHTS;
              cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD);
              /* Initialize the payload: */
              fdptr = (int *)CMSG_DATA(cmsg);
              memcpy(fdptr, myfds, NUM_FD * sizeof(int));
              /* Sum of the length of all control messages in the buffer: */
              msg.msg_controllen = cmsg->cmsg_len;


       For portability, ancillary data should  be  accessed  only
       using  the  macros  described here.  CMSG_ALIGN is a Linux
       extension and should be not used in portable programs.

       In Linux, CMSG_LEN, CMSG_DATA, and CMSG_ALIGN are constant
       expressions  (assuming  their argument is constant) - this
       could be used to declare the  size  of  global  variables.
       This may be not portable, however.


       This  ancillary  data  model conforms to the POSIX.1003.1g
       draft, 4.4BSD-Lite, the IPv6  advanced  API  described  in
       RFC2292  and the Single Unix specification v2.  CMSG_ALIGN
       is a Linux extension.


       sendmsg(2), recvmsg(2) RFC2292