xref: /openbsd-src/share/man/man3/CMSG_DATA.3 (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1.\"	$OpenBSD: CMSG_DATA.3,v 1.5 2008/03/24 16:11:07 deraadt Exp $
2.\" Written by Jared Yanovich <jaredy@openbsd.org>
3.\" Public domain, July 3, 2005
4.Dd $Mdocdate: March 24 2008 $
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;
98
99memset(&msg, 0, sizeof(msg));
100msg.msg_control = &cmsgbuf.buf;
101msg.msg_controllen = sizeof(cmsgbuf.buf);
102
103cmsg = CMSG_FIRSTHDR(&msg);
104cmsg->cmsg_len = CMSG_LEN(sizeof(int));
105cmsg->cmsg_level = SOL_SOCKET;
106cmsg->cmsg_type = SCM_RIGHTS;
107*(int *)CMSG_DATA(cmsg) = fd;
108
109if (sendmsg(s, &msg, 0) == -1)
110	err(1, "sendmsg");
111.Ed
112.Pp
113And an example that receives and decomposes the control message:
114.Bd -literal -offset indent
115struct msghdr	 msg;
116struct cmsghdr	*cmsg;
117union {
118	struct cmsghdr hdr;
119	unsigned char	 buf[CMSG_SPACE(sizeof(int))];
120} cmsgbuf;
121
122memset(&msg, 0, sizeof(msg));
123msg.msg_control = &cmsgbuf.buf;
124msg.msg_controllen = sizeof(cmsgbuf.buf);
125
126if (recvmsg(s, &msg, 0) == -1)
127	err(1, "recvmsg");
128if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC))
129	errx(1, "control message truncated");
130for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
131    cmsg = CMSG_NXTHDR(&msg, cmsg)) {
132	if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
133	    cmsg->cmsg_level == SOL_SOCKET &&
134	    cmsg->cmsg_type == SCM_RIGHTS) {
135		fd = *(int *)CMSG_DATA(cmsg);
136		/* Do something with the descriptor. */
137	}
138}
139.Ed
140.Sh SEE ALSO
141.Xr recvmsg 2 ,
142.Xr sendmsg 2 ,
143.Xr socket 2
144.Sh HISTORY
145The control message API first appeared in
146.Bx 4.2 .
147