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