diff options
Diffstat (limited to 'man3/cmsg.3')
-rw-r--r-- | man3/cmsg.3 | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/man3/cmsg.3 b/man3/cmsg.3 new file mode 100644 index 000000000..a8a74eb71 --- /dev/null +++ b/man3/cmsg.3 @@ -0,0 +1,219 @@ +.\" 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 +.B 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 +.B CMSG_FIRSTHDR +returns a pointer to the first +.B cmsghdr +in the ancillary +data buffer associated with the passed +.BR msghdr . +.PP +.B CMSG_NXTHDR +returns the next valid +.B cmsghdr +after the passed +.B cmsghdr. +It returns +.B 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 +.B 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 +.B 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 +.B 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 == 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. + */ +} +.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. +.B CMSG_ALIGN +is a Linux extension and should be not used in portable programs. +.PP +In Linux, +.BR CMSG_LEN , +.BR CMSG_DATA , +and +.B 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 RFC2292 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 |