summaryrefslogtreecommitdiffstats
path: root/man3/cmsg.3
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--man3/cmsg.3261
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