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