| .\" This man page is Copyright (C) 1999 Andi Kleen <ak@muc.de>. |
| .\" Permission is granted to distribute possibly modified copies |
| .\" of this page provided the header is included verbatim, |
| .\" and in case of nontrivial modification author and date |
| .\" of the modification is added to the header. |
| .\" $Id: cmsg.3,v 1.8 2000/12/20 18:10:31 ak Exp $ |
| .TH CMSG 3 1998-10-02 "Linux Man Page" "Linux Programmer's Manual" |
| .SH NAME |
| CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR \- Access ancillary data |
| .SH SYNOPSIS |
| .B #include <sys/socket.h> |
| .br |
| .sp 2 |
| .BI "struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *" msgh ); |
| .br |
| .BI "struct cmsghdr *CMSG_NXTHDR(struct msghdr *" msgh ", struct cmsghdr *" cmsg ); |
| .br |
| .BI "size_t CMSG_ALIGN(size_t " length ); |
| .br |
| .BI "size_t CMSG_SPACE(size_t " length ); |
| .br |
| .BI "size_t CMSG_LEN(size_t " length ); |
| .br |
| .BI "unsigned char *CMSG_DATA(struct cmsghdr *" cmsg ); |
| .sp |
| .nf |
| .ta 8n 20n 32n |
| 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[]; */ |
| }; |
| .ta |
| .fi |
| .SH DESCRIPTION |
| These macros are used to create and access control messages (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 |
| .BR sendmsg (2) |
| and received by calling |
| .BR recvmsg (2). |
| See their manual pages for more information. |
| .PP |
| Ancillary data is a sequence of |
| .I 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 |
| .B net.core.optmem_max |
| sysctl; see |
| .BR socket (7). |
| .PP |
| .BR CMSG_FIRSTHDR () |
| returns a pointer to the first |
| .B cmsghdr |
| in the ancillary |
| data buffer associated with the passed |
| .BR msghdr . |
| .PP |
| .BR CMSG_NXTHDR () |
| returns the next valid |
| .B cmsghdr |
| after the passed |
| .B cmsghdr . |
| It returns NULL when there isn't enough space left in the buffer. |
| .PP |
| .BR CMSG_ALIGN (), |
| given a length, returns it including the required alignment. This is a |
| constant expression. |
| .PP |
| .BR CMSG_SPACE () |
| returns the number of bytes an ancillary element with payload of the passed data length |
| occupies. This is a constant expression. |
| .PP |
| .B CMSG_DATA |
| returns a pointer to the data portion of a |
| .BR cmsghdr . |
| .PP |
| .B CMSG_LEN |
| returns the value to store in the |
| .I cmsg_len |
| member of the |
| .B cmsghdr |
| structure, taking into account any necessary |
| alignment. It takes the data length as an argument. This is a constant |
| expression. |
| .PP |
| To create ancillary data, first initialize the |
| .I msg_controllen |
| member of the |
| .B msghdr |
| with the length of the control message buffer. Use |
| .BR CMSG_FIRSTHDR () |
| on the |
| .B msghdr |
| to get the first control message and |
| .B CMSG_NEXTHDR |
| to get all subsequent ones. |
| In each control message, initialize |
| .I cmsg_len |
| (with |
| .BR CMSG_LEN ), |
| the other |
| .B cmsghdr |
| header fields, and the data portion using |
| .BR CMSG_DATA . |
| Finally, the |
| .I msg_controllen |
| field of the |
| .B msghdr |
| should be set to the sum of the |
| .BR CMSG_SPACE () |
| of the length of |
| all control messages in the buffer. |
| For more information on the |
| .BR msghdr , |
| see |
| .BR recvmsg (2). |
| .PP |
| When the control message buffer is too short to store all messages, the |
| .B MSG_CTRUNC |
| flag is set in the |
| .I msg_flags |
| member of the |
| .BR msghdr . |
| .SH EXAMPLE |
| This code looks for the |
| .B IP_TTL |
| option in a received ancillary buffer: |
| .PP |
| .RS |
| .nf |
| .ta 8n 16n 32n |
| 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 == IPPROTO_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. |
| */ |
| } |
| .ta |
| .fi |
| .RE |
| .PP |
| The code below passes an array of file descriptors over a Unix socket using |
| .BR SCM_RIGHTS : |
| .PP |
| .RS |
| .nf |
| .ta 8n 16n 32n |
| 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; |
| .ta |
| .fi |
| .RE |
| .SH NOTES |
| For portability, ancillary data should be accessed only using the macros |
| described here. |
| .BR CMSG_ALIGN () |
| is a Linux extension and should be not used in portable programs. |
| .PP |
| In Linux, |
| .BR CMSG_LEN , |
| .BR CMSG_DATA , |
| and |
| .BR 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. |
| .SH "CONFORMS TO" |
| This ancillary data model conforms to the POSIX.1003.1g draft, 4.4BSD-Lite, |
| the IPv6 advanced API described in RFC\ 2292 and the Single Unix specification v2. |
| .B |
| CMSG_ALIGN |
| is a Linux extension. |
| .SH "SEE ALSO" |
| .BR recvmsg (2), |
| .BR sendmsg (2) |
| .PP |
| RFC\ 2292 |