diff options
Diffstat (limited to '')
-rw-r--r-- | man3/cmsg.3 | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/man3/cmsg.3 b/man3/cmsg.3 new file mode 100644 index 0000000..3ca7d1d --- /dev/null +++ b/man3/cmsg.3 @@ -0,0 +1,261 @@ +.\" SPDX-License-Identifier: Linux-man-pages-1-para +.\" +.\" This man page is Copyright (C) 1999 Andi Kleen <ak@muc.de>. +.\" +.\" $Id: cmsg.3,v 1.8 2000/12/20 18:10:31 ak Exp $ +.TH CMSG 3 2023-07-15 "Linux man-pages 6.05.01" +.SH NAME +CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR \- access ancillary data +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.B #include <sys/socket.h> +.PP +.BI "struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *" msgh ); +.BI "struct cmsghdr *CMSG_NXTHDR(struct msghdr *" msgh , +.BR " struct cmsghdr *" cmsg ); +.BI "size_t CMSG_ALIGN(size_t " length ); +.BI "size_t CMSG_SPACE(size_t " length ); +.BI "size_t CMSG_LEN(size_t " length ); +.BI "unsigned char *CMSG_DATA(struct cmsghdr *" cmsg ); +.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 cmsghdr +structures with appended data. +See the specific protocol man pages for the available control message types. +The maximum ancillary buffer size allowed per socket can be set using +.IR /proc/sys/net/core/optmem_max ; +see +.BR socket (7). +.PP +The +.I cmsghdr +structure is defined as follows: +.PP +.in +4n +.EX +struct cmsghdr { + size_t cmsg_len; /* Data byte count, including header + (type is socklen_t in POSIX) */ + int cmsg_level; /* Originating protocol */ + int cmsg_type; /* Protocol\-specific type */ +/* followed by + unsigned char cmsg_data[]; */ +}; +.EE +.in +.PP +The sequence of +.I cmsghdr +structures should never be accessed directly. +Instead, use only the following macros: +.TP +.BR CMSG_FIRSTHDR () +returns a pointer to the first +.I cmsghdr +in the ancillary +data buffer associated with the passed +.IR msghdr . +It returns NULL if there isn't enough space for a +.I cmsghdr +in the buffer. +.TP +.BR CMSG_NXTHDR () +returns the next valid +.I cmsghdr +after the passed +.IR cmsghdr . +It returns NULL when there isn't enough space left in the buffer. +.IP +When initializing a buffer that will contain a series of +.I cmsghdr +structures (e.g., to be sent with +.BR sendmsg (2)), +that buffer should first be zero-initialized +to ensure the correct operation of +.BR CMSG_NXTHDR (). +.TP +.BR CMSG_ALIGN (), +given a length, returns it including the required alignment. +This is a +constant expression. +.TP +.BR CMSG_SPACE () +returns the number of bytes an ancillary element with payload of the +passed data length occupies. +This is a constant expression. +.TP +.BR CMSG_DATA () +returns a pointer to the data portion of a +.IR cmsghdr . +The pointer returned cannot be assumed to be suitably aligned for +accessing arbitrary payload data types. +Applications should not cast it to a pointer type matching the payload, +but should instead use +.BR memcpy (3) +to copy data to or from a suitably declared object. +.TP +.BR CMSG_LEN () +returns the value to store in the +.I cmsg_len +member of the +.I 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 +.I msghdr +with the length of the control message buffer. +Use +.BR CMSG_FIRSTHDR () +on the +.I msghdr +to get the first control message and +.BR CMSG_NXTHDR () +to get all subsequent ones. +In each control message, initialize +.I cmsg_len +(with +.BR CMSG_LEN ()), +the other +.I cmsghdr +header fields, and the data portion using +.BR CMSG_DATA (). +Finally, the +.I msg_controllen +field of the +.I 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 +.IR msghdr , +see +.BR recvmsg (2). +.SH VERSIONS +For portability, ancillary data should be accessed using only the macros +described here. +.PP +In Linux, +.BR CMSG_LEN (), +.BR CMSG_DATA (), +and +.BR CMSG_ALIGN () +are constant expressions (assuming their argument is constant), +meaning that these values can be used to declare the size of global variables. +This may not be portable, however. +.SH STANDARDS +.TP +.BR CMSG_FIRSTHDR () +.TQ +.BR CMSG_NXTHDR () +.TQ +.BR CMSG_DATA () +POSIX.1-2008. +.TP +.BR CMSG_SPACE () +.TQ +.BR CMSG_LEN () +.TQ +.BR CMSG_ALIGN () +Linux. +.SH HISTORY +This ancillary data model conforms to the POSIX.1g draft, 4.4BSD-Lite, +the IPv6 advanced API described in RFC\ 2292 and SUSv2. +.PP +.BR CMSG_SPACE () +and +.BR CMSG_LEN () +.\" https://www.austingroupbugs.net/view.php?id=978#c3242 +will be included in the next POSIX release (Issue 8). +.SH EXAMPLES +This code looks for the +.B IP_TTL +option in a received ancillary buffer: +.PP +.in +4n +.EX +struct msghdr msgh; +struct cmsghdr *cmsg; +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) { + memcpy(&receive_ttl, CMSG_DATA(cmsg), sizeof(received_ttl)); + break; + } +} +\& +if (cmsg == NULL) { + /* Error: IP_TTL not enabled or small buffer or I/O error */ +} +.EE +.in +.PP +The code below passes an array of file descriptors over a +UNIX domain socket using +.BR SCM_RIGHTS : +.PP +.in +4n +.EX +struct msghdr msg = { 0 }; +struct cmsghdr *cmsg; +int myfds[NUM_FD]; /* Contains the file descriptors to pass */ +char iobuf[1]; +struct iovec io = { + .iov_base = iobuf, + .iov_len = sizeof(iobuf) +}; +union { /* Ancillary data buffer, wrapped in a union + in order to ensure it is suitably aligned */ + char buf[CMSG_SPACE(sizeof(myfds))]; + struct cmsghdr align; +} u; +\& +msg.msg_iov = &io; +msg.msg_iovlen = 1; +msg.msg_control = u.buf; +msg.msg_controllen = sizeof(u.buf); +cmsg = CMSG_FIRSTHDR(&msg); +cmsg\->cmsg_level = SOL_SOCKET; +cmsg\->cmsg_type = SCM_RIGHTS; +cmsg\->cmsg_len = CMSG_LEN(sizeof(myfds)); +memcpy(CMSG_DATA(cmsg), myfds, sizeof(myfds)); +.EE +.in +.PP +For a complete code example that shows passing of file descriptors +over a UNIX domain socket, see +.BR seccomp_unotify (2). +.SH SEE ALSO +.BR recvmsg (2), +.BR sendmsg (2) +.PP +RFC\ 2292 |