cmsg(3)





NAME

       CMSG_ALIGN,   CMSG_SPACE,   CMSG_NXTHDR,  CMSG_FIRSTHDR  -
       Access ancillary data.


SYNOPSIS

       #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
               unsigned char           cmsg_data[]; */
       };


DESCRIPTION

       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, a set
       of file descriptors or unix  credentials.   For  instance,
       control  messages  can  be  used to send additional header
       fields such as IP options.   Ancillary  data  is  sent  by
       calling  sendmsg(2)  and  received  by calling recvmsg(2).
       See their manual pages for more information.

       Ancillary data is a sequence of struct cmsghdr  structures
       with  appended data. This sequence should only be accessed
       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(7).

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

       CMSG_NXTHDR returns  the  next  valid  cmsghdr  after  the
       passed  cmsghdr.   It returns NULL when there isn't enough
       space left in the buffer.

       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­
       ghdr.

       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.

       To  create  ancillary  data, first initialize the msg_con­
       trollen member of the msghdr with the length of  the  con­
       trol  message  buffer.  Use CMSG_FIRSTHDR on the msghdr to
       get the first control message and CMSG_NEXTHDR to get  all
       subsequent  ones.   In  each  control  message, initialize
       cmsg_len (with CMSG_LEN), the other cmsghdr header fields,
       and  the  data  portion  using  CMSG_DATA.   Finally,  the
       msg_controllen field of the msghdr should be  set  to  the
       sum  of  the  CMSG_SPACE of the length of all control mes­
       sages in the buffer.  For more information on the  msghdr,
       see recvmsg(2).

       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.


EXAMPLE

       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;
                              break;
                      }
              }
              if (cmsg == NULL) {
                      /* Error: IP_TTL not enabled or small buffer
                       * or I/O error.
                       */
              }




       The code below passes an array of file descriptors over  a
       Unix socket 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;


NOTES

       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.


CONFORMS TO

       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.


SEE ALSO

       sendmsg(2), recvmsg(2)

       RFC 2292
















Man(1) output converted with man2html