xref: /openbsd/share/man/man3/CMSG_DATA.3 (revision f6aab3d8)
1.\"	$OpenBSD: CMSG_DATA.3,v 1.6 2017/04/03 19:40:43 otto Exp $
2.\" Written by Jared Yanovich <jaredy@openbsd.org>
3.\" Public domain, July 3, 2005
4.Dd $Mdocdate: April 3 2017 $
5.Dt CMSG_DATA 3
6.Os
7.Sh NAME
8.Nm CMSG_DATA ,
9.Nm CMSG_FIRSTHDR ,
10.Nm CMSG_LEN ,
11.Nm CMSG_NXTHDR ,
12.Nm CMSG_SPACE
13.Nd socket control message routines
14.Sh SYNOPSIS
15.In sys/socket.h
16.Ft void *
17.Fn CMSG_DATA "struct cmsghdr *"
18.Ft struct cmsghdr *
19.Fn CMSG_FIRSTHDR "struct msghdr *"
20.Ft size_t
21.Fn CMSG_LEN "size_t"
22.Ft struct cmsghdr *
23.Fn CMSG_NXTHDR "struct msghdr *" "struct cmsghdr *"
24.Ft size_t
25.Fn CMSG_SPACE "size_t"
26.Sh DESCRIPTION
27The control message API is used to construct ancillary data objects for
28use in control messages sent and received across sockets.
29.Pp
30Control messages are passed around by the
31.Xr recvmsg 2
32and
33.Xr sendmsg 2
34system calls.
35The
36.Vt cmsghdr
37structure, described in
38.Xr recvmsg 2 ,
39is used to specify a chain of control messages.
40.Pp
41These routines should be used instead of directly accessing the control
42message header members and data buffers as they ensure that necessary
43alignment constraints are met.
44.Pp
45The following routines are provided:
46.Bl -tag -width Ds
47.It Fn CMSG_DATA cmsg
48This routine accesses the data portion of the control message header
49.Fa cmsg .
50It ensures proper alignment constraints on the beginning of ancillary
51data are met.
52.It Fn CMSG_FIRSTHDR mhdr
53This routine accesses the first control message attached to the
54message
55.Fa msg .
56If no control messages are attached to the message, this routine
57returns
58.Dv NULL .
59.It Fn CMSG_LEN len
60This routine determines the size in bytes of a control message,
61which includes the control message header.
62.Fa len
63specifies the length of the data held by the control message.
64This value is what is normally stored in the
65.Fa cmsg_len
66of each control message.
67This routine accounts for any alignment constraints on the beginning of
68ancillary data.
69.It Fn CMSG_NXTHDR mhdr cmsg
70This routine returns the location of the control message following
71.Fa cmsg
72in the message
73.Fa mhdr .
74If
75.Fa cmsg
76is the last control message in the chain, this routine returns
77.Dv NULL .
78.It Fn CMSG_SPACE len
79This routine determines the size in bytes needed to hold a control
80message and its contents of length
81.Fa len ,
82which includes the control message header.
83This value is what is normally stored in
84.Fa msg_msgcontrollen .
85This routine accounts for any alignment constraints on the beginning of
86ancillary data as well as any needed to pad the next control message.
87.El
88.Sh EXAMPLES
89The following example constructs a control message containing a file
90descriptor and passes it over a socket:
91.Bd -literal -offset indent
92struct msghdr	 msg;
93struct cmsghdr	*cmsg;
94union {
95	struct cmsghdr hdr;
96	unsigned char	 buf[CMSG_SPACE(sizeof(int))];
97} cmsgbuf;
98struct iovec io_vector[1];
99
100io_vector[0].iov_base = &ch;
101io_vector[0].iov_len = 1;
102
103memset(&msg, 0, sizeof(msg));
104msg.msg_control = &cmsgbuf.buf;
105msg.msg_controllen = sizeof(cmsgbuf.buf);
106msg.msg_iov = io_vector;
107msg.msg_iovlen = 1;
108
109cmsg = CMSG_FIRSTHDR(&msg);
110cmsg->cmsg_len = CMSG_LEN(sizeof(int));
111cmsg->cmsg_level = SOL_SOCKET;
112cmsg->cmsg_type = SCM_RIGHTS;
113*(int *)CMSG_DATA(cmsg) = fd;
114
115if (sendmsg(s, &msg, 0) == -1)
116	err(1, "sendmsg");
117.Ed
118.Pp
119And an example that receives and decomposes the control message:
120.Bd -literal -offset indent
121struct msghdr	 msg;
122struct cmsghdr	*cmsg;
123union {
124	struct cmsghdr hdr;
125	unsigned char	 buf[CMSG_SPACE(sizeof(int))];
126} cmsgbuf;
127struct iovec io_vector[1];
128
129io_vector[0].iov_base = &ch;
130io_vector[0].iov_len = 1;
131
132memset(&msg, 0, sizeof(msg));
133msg.msg_control = &cmsgbuf.buf;
134msg.msg_controllen = sizeof(cmsgbuf.buf);
135msg.msg_iov = io_vector;
136msg.msg_iovlen = 1;
137
138if (recvmsg(s, &msg, 0) == -1)
139	err(1, "recvmsg");
140if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC))
141	errx(1, "control message truncated");
142for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
143    cmsg = CMSG_NXTHDR(&msg, cmsg)) {
144	if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
145	    cmsg->cmsg_level == SOL_SOCKET &&
146	    cmsg->cmsg_type == SCM_RIGHTS) {
147		fd = *(int *)CMSG_DATA(cmsg);
148		/* Do something with the descriptor. */
149	}
150}
151.Ed
152.Sh SEE ALSO
153.Xr recvmsg 2 ,
154.Xr sendmsg 2 ,
155.Xr socket 2
156.Sh HISTORY
157The control message API first appeared in
158.Bx 4.2 .
159