xref: /aosp_15_r20/external/strace/tests-m32/msg_control.c (revision cf84ac9a129d8ea9952db616b4e9b904c4bdde56)
1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker  * Check decoding of struct msghdr ancillary data.
3*cf84ac9aSAndroid Build Coastguard Worker  *
4*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2016 Dmitry V. Levin <[email protected]>
5*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2016-2018 The strace developers.
6*cf84ac9aSAndroid Build Coastguard Worker  * All rights reserved.
7*cf84ac9aSAndroid Build Coastguard Worker  *
8*cf84ac9aSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
9*cf84ac9aSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
10*cf84ac9aSAndroid Build Coastguard Worker  * are met:
11*cf84ac9aSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
12*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
13*cf84ac9aSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
14*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
15*cf84ac9aSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
16*cf84ac9aSAndroid Build Coastguard Worker  * 3. The name of the author may not be used to endorse or promote products
17*cf84ac9aSAndroid Build Coastguard Worker  *    derived from this software without specific prior written permission.
18*cf84ac9aSAndroid Build Coastguard Worker  *
19*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20*cf84ac9aSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*cf84ac9aSAndroid Build Coastguard Worker  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22*cf84ac9aSAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23*cf84ac9aSAndroid Build Coastguard Worker  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24*cf84ac9aSAndroid Build Coastguard Worker  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25*cf84ac9aSAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26*cf84ac9aSAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27*cf84ac9aSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*cf84ac9aSAndroid Build Coastguard Worker  */
30*cf84ac9aSAndroid Build Coastguard Worker 
31*cf84ac9aSAndroid Build Coastguard Worker #include "tests.h"
32*cf84ac9aSAndroid Build Coastguard Worker #include <errno.h>
33*cf84ac9aSAndroid Build Coastguard Worker #include <limits.h>
34*cf84ac9aSAndroid Build Coastguard Worker #include <stddef.h>
35*cf84ac9aSAndroid Build Coastguard Worker #include <stdio.h>
36*cf84ac9aSAndroid Build Coastguard Worker #include <string.h>
37*cf84ac9aSAndroid Build Coastguard Worker #include <unistd.h>
38*cf84ac9aSAndroid Build Coastguard Worker #include <sys/socket.h>
39*cf84ac9aSAndroid Build Coastguard Worker #include <net/if.h>
40*cf84ac9aSAndroid Build Coastguard Worker #include <netinet/in.h>
41*cf84ac9aSAndroid Build Coastguard Worker #include <arpa/inet.h>
42*cf84ac9aSAndroid Build Coastguard Worker 
43*cf84ac9aSAndroid Build Coastguard Worker #include "xlat.h"
44*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/scmvals.h"
45*cf84ac9aSAndroid Build Coastguard Worker 
46*cf84ac9aSAndroid Build Coastguard Worker #ifndef SOL_IP
47*cf84ac9aSAndroid Build Coastguard Worker # define SOL_IP 0
48*cf84ac9aSAndroid Build Coastguard Worker #endif
49*cf84ac9aSAndroid Build Coastguard Worker #ifndef SOL_TCP
50*cf84ac9aSAndroid Build Coastguard Worker # define SOL_TCP 6
51*cf84ac9aSAndroid Build Coastguard Worker #endif
52*cf84ac9aSAndroid Build Coastguard Worker 
53*cf84ac9aSAndroid Build Coastguard Worker #ifndef SCM_SECURITY
54*cf84ac9aSAndroid Build Coastguard Worker # define SCM_SECURITY 3
55*cf84ac9aSAndroid Build Coastguard Worker #endif
56*cf84ac9aSAndroid Build Coastguard Worker 
57*cf84ac9aSAndroid Build Coastguard Worker #define MIN_SIZE_OF(type, member) \
58*cf84ac9aSAndroid Build Coastguard Worker 	(offsetof(type, member) + sizeof(((type *) 0)->member))
59*cf84ac9aSAndroid Build Coastguard Worker 
60*cf84ac9aSAndroid Build Coastguard Worker static struct cmsghdr *
get_cmsghdr(void * const page,const size_t len)61*cf84ac9aSAndroid Build Coastguard Worker get_cmsghdr(void *const page, const size_t len)
62*cf84ac9aSAndroid Build Coastguard Worker {
63*cf84ac9aSAndroid Build Coastguard Worker 	return page - CMSG_ALIGN(len);
64*cf84ac9aSAndroid Build Coastguard Worker }
65*cf84ac9aSAndroid Build Coastguard Worker 
66*cf84ac9aSAndroid Build Coastguard Worker static void
print_fds(const struct cmsghdr * const cmsg,const size_t cmsg_len)67*cf84ac9aSAndroid Build Coastguard Worker print_fds(const struct cmsghdr *const cmsg, const size_t cmsg_len)
68*cf84ac9aSAndroid Build Coastguard Worker {
69*cf84ac9aSAndroid Build Coastguard Worker 	size_t nfd = cmsg_len > CMSG_LEN(0)
70*cf84ac9aSAndroid Build Coastguard Worker 		     ? (cmsg_len - CMSG_LEN(0)) / sizeof(int) : 0;
71*cf84ac9aSAndroid Build Coastguard Worker 	if (!nfd)
72*cf84ac9aSAndroid Build Coastguard Worker 		return;
73*cf84ac9aSAndroid Build Coastguard Worker 
74*cf84ac9aSAndroid Build Coastguard Worker 	printf(", cmsg_data=[");
75*cf84ac9aSAndroid Build Coastguard Worker 	int *fdp = (int *) CMSG_DATA(cmsg);
76*cf84ac9aSAndroid Build Coastguard Worker 	size_t i;
77*cf84ac9aSAndroid Build Coastguard Worker 	for (i = 0; i < nfd; ++i) {
78*cf84ac9aSAndroid Build Coastguard Worker 		if (i)
79*cf84ac9aSAndroid Build Coastguard Worker 			printf(", ");
80*cf84ac9aSAndroid Build Coastguard Worker #if !VERBOSE
81*cf84ac9aSAndroid Build Coastguard Worker 		if (i >= DEFAULT_STRLEN) {
82*cf84ac9aSAndroid Build Coastguard Worker 			printf("...");
83*cf84ac9aSAndroid Build Coastguard Worker 			break;
84*cf84ac9aSAndroid Build Coastguard Worker 		}
85*cf84ac9aSAndroid Build Coastguard Worker #endif
86*cf84ac9aSAndroid Build Coastguard Worker 		printf("%d", fdp[i]);
87*cf84ac9aSAndroid Build Coastguard Worker 	}
88*cf84ac9aSAndroid Build Coastguard Worker 	printf("]");
89*cf84ac9aSAndroid Build Coastguard Worker }
90*cf84ac9aSAndroid Build Coastguard Worker 
91*cf84ac9aSAndroid Build Coastguard Worker static void
test_scm_rights1(struct msghdr * const mh,const size_t msg_controllen,void * const page,const void * const src,const size_t cmsg_len)92*cf84ac9aSAndroid Build Coastguard Worker test_scm_rights1(struct msghdr *const mh,
93*cf84ac9aSAndroid Build Coastguard Worker 		 const size_t msg_controllen,
94*cf84ac9aSAndroid Build Coastguard Worker 		 void *const page,
95*cf84ac9aSAndroid Build Coastguard Worker 		 const void *const src,
96*cf84ac9aSAndroid Build Coastguard Worker 		 const size_t cmsg_len)
97*cf84ac9aSAndroid Build Coastguard Worker {
98*cf84ac9aSAndroid Build Coastguard Worker 	const size_t aligned_cms_len =
99*cf84ac9aSAndroid Build Coastguard Worker 		cmsg_len > CMSG_LEN(0) ? CMSG_ALIGN(cmsg_len) : CMSG_LEN(0);
100*cf84ac9aSAndroid Build Coastguard Worker 	if (cmsg_len >= CMSG_LEN(0)
101*cf84ac9aSAndroid Build Coastguard Worker 	    && aligned_cms_len + CMSG_LEN(0) <= msg_controllen)
102*cf84ac9aSAndroid Build Coastguard Worker 		return;
103*cf84ac9aSAndroid Build Coastguard Worker 
104*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *cmsg = get_cmsghdr(page, msg_controllen);
105*cf84ac9aSAndroid Build Coastguard Worker 
106*cf84ac9aSAndroid Build Coastguard Worker 	if (msg_controllen >= MIN_SIZE_OF(struct cmsghdr, cmsg_len))
107*cf84ac9aSAndroid Build Coastguard Worker 		cmsg->cmsg_len = cmsg_len;
108*cf84ac9aSAndroid Build Coastguard Worker 	if (msg_controllen >= MIN_SIZE_OF(struct cmsghdr, cmsg_level))
109*cf84ac9aSAndroid Build Coastguard Worker 		cmsg->cmsg_level = SOL_SOCKET;
110*cf84ac9aSAndroid Build Coastguard Worker 	if (msg_controllen >= MIN_SIZE_OF(struct cmsghdr, cmsg_type))
111*cf84ac9aSAndroid Build Coastguard Worker 		cmsg->cmsg_type = SCM_RIGHTS;
112*cf84ac9aSAndroid Build Coastguard Worker 
113*cf84ac9aSAndroid Build Coastguard Worker 	size_t src_len =
114*cf84ac9aSAndroid Build Coastguard Worker 		cmsg_len < msg_controllen ? cmsg_len : msg_controllen;
115*cf84ac9aSAndroid Build Coastguard Worker 	if (src_len > CMSG_LEN(0))
116*cf84ac9aSAndroid Build Coastguard Worker 		memcpy(CMSG_DATA(cmsg), src, src_len - CMSG_LEN(0));
117*cf84ac9aSAndroid Build Coastguard Worker 
118*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
119*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = msg_controllen;
120*cf84ac9aSAndroid Build Coastguard Worker 
121*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
122*cf84ac9aSAndroid Build Coastguard Worker 	int saved_errno = errno;
123*cf84ac9aSAndroid Build Coastguard Worker 
124*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
125*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0");
126*cf84ac9aSAndroid Build Coastguard Worker 	if (msg_controllen < CMSG_LEN(0)) {
127*cf84ac9aSAndroid Build Coastguard Worker 		if (msg_controllen)
128*cf84ac9aSAndroid Build Coastguard Worker 			printf(", msg_control=%p", cmsg);
129*cf84ac9aSAndroid Build Coastguard Worker 	} else {
130*cf84ac9aSAndroid Build Coastguard Worker 		printf(", msg_control=[{cmsg_len=%lu, cmsg_level=SOL_SOCKET"
131*cf84ac9aSAndroid Build Coastguard Worker 		       ", cmsg_type=SCM_RIGHTS", (unsigned long) cmsg_len);
132*cf84ac9aSAndroid Build Coastguard Worker 		print_fds(cmsg, src_len);
133*cf84ac9aSAndroid Build Coastguard Worker 		printf("}");
134*cf84ac9aSAndroid Build Coastguard Worker 		if (aligned_cms_len < msg_controllen)
135*cf84ac9aSAndroid Build Coastguard Worker 			printf(", ... /* %p */", (void *) cmsg + aligned_cms_len);
136*cf84ac9aSAndroid Build Coastguard Worker 		printf("]");
137*cf84ac9aSAndroid Build Coastguard Worker 	}
138*cf84ac9aSAndroid Build Coastguard Worker 
139*cf84ac9aSAndroid Build Coastguard Worker 	errno = saved_errno;
140*cf84ac9aSAndroid Build Coastguard Worker 	printf(", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
141*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) msg_controllen, rc, errno2name());
142*cf84ac9aSAndroid Build Coastguard Worker }
143*cf84ac9aSAndroid Build Coastguard Worker 
144*cf84ac9aSAndroid Build Coastguard Worker static void
test_scm_rights2(struct msghdr * const mh,const size_t msg_controllen,void * const page,const int * const * const src,const size_t * const cmsg_len)145*cf84ac9aSAndroid Build Coastguard Worker test_scm_rights2(struct msghdr *const mh,
146*cf84ac9aSAndroid Build Coastguard Worker 		 const size_t msg_controllen,
147*cf84ac9aSAndroid Build Coastguard Worker 		 void *const page,
148*cf84ac9aSAndroid Build Coastguard Worker 		 const int *const *const src,
149*cf84ac9aSAndroid Build Coastguard Worker 		 const size_t *const cmsg_len)
150*cf84ac9aSAndroid Build Coastguard Worker {
151*cf84ac9aSAndroid Build Coastguard Worker 	const size_t aligned_cms_len[2] = {
152*cf84ac9aSAndroid Build Coastguard Worker 		cmsg_len[0] > CMSG_LEN(0) ? CMSG_ALIGN(cmsg_len[0]) : CMSG_LEN(0),
153*cf84ac9aSAndroid Build Coastguard Worker 		cmsg_len[1] > CMSG_LEN(0) ? CMSG_ALIGN(cmsg_len[1]) : CMSG_LEN(0)
154*cf84ac9aSAndroid Build Coastguard Worker 	};
155*cf84ac9aSAndroid Build Coastguard Worker 	if (cmsg_len[0] < CMSG_LEN(0)
156*cf84ac9aSAndroid Build Coastguard Worker 	    || aligned_cms_len[0] + CMSG_LEN(0) > msg_controllen
157*cf84ac9aSAndroid Build Coastguard Worker 	    || aligned_cms_len[0] + aligned_cms_len[1] + CMSG_LEN(0) <= msg_controllen)
158*cf84ac9aSAndroid Build Coastguard Worker 		return;
159*cf84ac9aSAndroid Build Coastguard Worker 
160*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *const cmsg[2] = {
161*cf84ac9aSAndroid Build Coastguard Worker 		get_cmsghdr(page, msg_controllen),
162*cf84ac9aSAndroid Build Coastguard Worker 		(void *) get_cmsghdr(page, msg_controllen) + aligned_cms_len[0]
163*cf84ac9aSAndroid Build Coastguard Worker 	};
164*cf84ac9aSAndroid Build Coastguard Worker 	cmsg[0]->cmsg_len = cmsg_len[0];
165*cf84ac9aSAndroid Build Coastguard Worker 	cmsg[0]->cmsg_level = SOL_SOCKET;
166*cf84ac9aSAndroid Build Coastguard Worker 	cmsg[0]->cmsg_type = SCM_RIGHTS;
167*cf84ac9aSAndroid Build Coastguard Worker 	if (cmsg_len[0] > CMSG_LEN(0))
168*cf84ac9aSAndroid Build Coastguard Worker 		memcpy(CMSG_DATA(cmsg[0]), src[0], cmsg_len[0] - CMSG_LEN(0));
169*cf84ac9aSAndroid Build Coastguard Worker 
170*cf84ac9aSAndroid Build Coastguard Worker 	const size_t msg_controllen1 = msg_controllen - aligned_cms_len[0];
171*cf84ac9aSAndroid Build Coastguard Worker 	if (msg_controllen1 >= MIN_SIZE_OF(struct cmsghdr, cmsg_len))
172*cf84ac9aSAndroid Build Coastguard Worker 		cmsg[1]->cmsg_len = cmsg_len[1];
173*cf84ac9aSAndroid Build Coastguard Worker 	if (msg_controllen >= MIN_SIZE_OF(struct cmsghdr, cmsg_level))
174*cf84ac9aSAndroid Build Coastguard Worker 		cmsg[1]->cmsg_level = SOL_SOCKET;
175*cf84ac9aSAndroid Build Coastguard Worker 	if (msg_controllen >= MIN_SIZE_OF(struct cmsghdr, cmsg_type))
176*cf84ac9aSAndroid Build Coastguard Worker 		cmsg[1]->cmsg_type = SCM_RIGHTS;
177*cf84ac9aSAndroid Build Coastguard Worker 	size_t src1_len =
178*cf84ac9aSAndroid Build Coastguard Worker 		cmsg_len[1] < msg_controllen1 ? cmsg_len[1] : msg_controllen1;
179*cf84ac9aSAndroid Build Coastguard Worker 	if (src1_len > CMSG_LEN(0))
180*cf84ac9aSAndroid Build Coastguard Worker 		memcpy(CMSG_DATA(cmsg[1]), src[1], src1_len - CMSG_LEN(0));
181*cf84ac9aSAndroid Build Coastguard Worker 
182*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg[0];
183*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = msg_controllen;
184*cf84ac9aSAndroid Build Coastguard Worker 
185*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
186*cf84ac9aSAndroid Build Coastguard Worker 	int saved_errno = errno;
187*cf84ac9aSAndroid Build Coastguard Worker 
188*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
189*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%lu"
190*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS",
191*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) cmsg_len[0]);
192*cf84ac9aSAndroid Build Coastguard Worker 	print_fds(cmsg[0], cmsg_len[0]);
193*cf84ac9aSAndroid Build Coastguard Worker 	printf("}, {cmsg_len=%lu, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS",
194*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) cmsg_len[1]);
195*cf84ac9aSAndroid Build Coastguard Worker 	print_fds(cmsg[1], src1_len);
196*cf84ac9aSAndroid Build Coastguard Worker 	printf("}");
197*cf84ac9aSAndroid Build Coastguard Worker 	if (aligned_cms_len[1] < msg_controllen1)
198*cf84ac9aSAndroid Build Coastguard Worker 		printf(", ... /* %p */", (void *) cmsg[1] + aligned_cms_len[1]);
199*cf84ac9aSAndroid Build Coastguard Worker 	printf("]");
200*cf84ac9aSAndroid Build Coastguard Worker 
201*cf84ac9aSAndroid Build Coastguard Worker 	errno = saved_errno;
202*cf84ac9aSAndroid Build Coastguard Worker 	printf(", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
203*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) msg_controllen, rc, errno2name());
204*cf84ac9aSAndroid Build Coastguard Worker }
205*cf84ac9aSAndroid Build Coastguard Worker 
206*cf84ac9aSAndroid Build Coastguard Worker static void
test_scm_rights3(struct msghdr * const mh,void * const page,const size_t nfds)207*cf84ac9aSAndroid Build Coastguard Worker test_scm_rights3(struct msghdr *const mh, void *const page, const size_t nfds)
208*cf84ac9aSAndroid Build Coastguard Worker {
209*cf84ac9aSAndroid Build Coastguard Worker 	const size_t len = CMSG_SPACE(sizeof(int) * nfds);
210*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *cmsg = get_cmsghdr(page, len);
211*cf84ac9aSAndroid Build Coastguard Worker 
212*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(sizeof(int) * nfds);
213*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_SOCKET;
214*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = SCM_RIGHTS;
215*cf84ac9aSAndroid Build Coastguard Worker 	int *fdp = (int *) CMSG_DATA(cmsg);
216*cf84ac9aSAndroid Build Coastguard Worker 	size_t i;
217*cf84ac9aSAndroid Build Coastguard Worker 	for (i = 0; i < nfds; ++i)
218*cf84ac9aSAndroid Build Coastguard Worker 		fdp[i] = i;
219*cf84ac9aSAndroid Build Coastguard Worker 
220*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
221*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
222*cf84ac9aSAndroid Build Coastguard Worker 
223*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
224*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
225*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
226*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS",
227*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len);
228*cf84ac9aSAndroid Build Coastguard Worker 	print_fds(cmsg, cmsg->cmsg_len);
229*cf84ac9aSAndroid Build Coastguard Worker 	printf("}], msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
230*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) len, rc, errno2name());
231*cf84ac9aSAndroid Build Coastguard Worker }
232*cf84ac9aSAndroid Build Coastguard Worker 
233*cf84ac9aSAndroid Build Coastguard Worker static void
test_scm_timestamp(struct msghdr * const mh,void * const page)234*cf84ac9aSAndroid Build Coastguard Worker test_scm_timestamp(struct msghdr *const mh, void *const page)
235*cf84ac9aSAndroid Build Coastguard Worker {
236*cf84ac9aSAndroid Build Coastguard Worker 	size_t len = CMSG_SPACE(sizeof(struct timeval));
237*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *cmsg = get_cmsghdr(page, len);
238*cf84ac9aSAndroid Build Coastguard Worker 
239*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(sizeof(struct timeval));
240*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_SOCKET;
241*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = SCM_TIMESTAMP;
242*cf84ac9aSAndroid Build Coastguard Worker 	struct timeval *tv = (struct timeval *) CMSG_DATA(cmsg);
243*cf84ac9aSAndroid Build Coastguard Worker 	tv->tv_sec = 123456789;
244*cf84ac9aSAndroid Build Coastguard Worker 	tv->tv_usec = 987654;
245*cf84ac9aSAndroid Build Coastguard Worker 
246*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
247*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
248*cf84ac9aSAndroid Build Coastguard Worker 
249*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
250*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
251*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
252*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMP"
253*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_data={tv_sec=%lld, tv_usec=%llu}}]"
254*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
255*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len,
256*cf84ac9aSAndroid Build Coastguard Worker 	       (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec),
257*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) len, rc, errno2name());
258*cf84ac9aSAndroid Build Coastguard Worker 
259*cf84ac9aSAndroid Build Coastguard Worker 	len = CMSG_SPACE(sizeof(struct timeval) - sizeof(long));
260*cf84ac9aSAndroid Build Coastguard Worker 	cmsg = get_cmsghdr(page, len);
261*cf84ac9aSAndroid Build Coastguard Worker 
262*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(sizeof(struct timeval) - sizeof(long));
263*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_SOCKET;
264*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = SCM_TIMESTAMP;
265*cf84ac9aSAndroid Build Coastguard Worker 
266*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
267*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
268*cf84ac9aSAndroid Build Coastguard Worker 
269*cf84ac9aSAndroid Build Coastguard Worker 	rc = sendmsg(-1, mh, 0);
270*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
271*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
272*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMP, cmsg_data=?}]"
273*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
274*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len,
275*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) len, rc, errno2name());
276*cf84ac9aSAndroid Build Coastguard Worker }
277*cf84ac9aSAndroid Build Coastguard Worker 
278*cf84ac9aSAndroid Build Coastguard Worker static void
test_scm_timestampns(struct msghdr * const mh,void * const page)279*cf84ac9aSAndroid Build Coastguard Worker test_scm_timestampns(struct msghdr *const mh, void *const page)
280*cf84ac9aSAndroid Build Coastguard Worker {
281*cf84ac9aSAndroid Build Coastguard Worker 	size_t len = CMSG_SPACE(sizeof(struct timespec));
282*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *cmsg = get_cmsghdr(page, len);
283*cf84ac9aSAndroid Build Coastguard Worker 
284*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(sizeof(struct timespec));
285*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_SOCKET;
286*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = SCM_TIMESTAMPNS;
287*cf84ac9aSAndroid Build Coastguard Worker 	struct timespec *ts = (struct timespec *) CMSG_DATA(cmsg);
288*cf84ac9aSAndroid Build Coastguard Worker 	ts->tv_sec = 123456789;
289*cf84ac9aSAndroid Build Coastguard Worker 	ts->tv_nsec = 987654321;
290*cf84ac9aSAndroid Build Coastguard Worker 
291*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
292*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
293*cf84ac9aSAndroid Build Coastguard Worker 
294*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
295*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
296*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
297*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMPNS"
298*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_data={tv_sec=%lld, tv_nsec=%llu}}]"
299*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
300*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len,
301*cf84ac9aSAndroid Build Coastguard Worker 	       (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec),
302*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) len, rc, errno2name());
303*cf84ac9aSAndroid Build Coastguard Worker 
304*cf84ac9aSAndroid Build Coastguard Worker 	len = CMSG_SPACE(sizeof(struct timespec) - sizeof(long));
305*cf84ac9aSAndroid Build Coastguard Worker 	cmsg = get_cmsghdr(page, len);
306*cf84ac9aSAndroid Build Coastguard Worker 
307*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(sizeof(struct timespec) - sizeof(long));
308*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_SOCKET;
309*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = SCM_TIMESTAMPNS;
310*cf84ac9aSAndroid Build Coastguard Worker 
311*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
312*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
313*cf84ac9aSAndroid Build Coastguard Worker 
314*cf84ac9aSAndroid Build Coastguard Worker 	rc = sendmsg(-1, mh, 0);
315*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
316*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
317*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMPNS"
318*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_data=?}]"
319*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
320*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len,
321*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) len, rc, errno2name());
322*cf84ac9aSAndroid Build Coastguard Worker }
323*cf84ac9aSAndroid Build Coastguard Worker 
324*cf84ac9aSAndroid Build Coastguard Worker static void
test_scm_timestamping(struct msghdr * const mh,void * const page)325*cf84ac9aSAndroid Build Coastguard Worker test_scm_timestamping(struct msghdr *const mh, void *const page)
326*cf84ac9aSAndroid Build Coastguard Worker {
327*cf84ac9aSAndroid Build Coastguard Worker 	size_t len = CMSG_SPACE(3 * sizeof(struct timespec));
328*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *cmsg = get_cmsghdr(page, len);
329*cf84ac9aSAndroid Build Coastguard Worker 
330*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(3 * sizeof(struct timespec));
331*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_SOCKET;
332*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = SCM_TIMESTAMPING;
333*cf84ac9aSAndroid Build Coastguard Worker 	struct timespec *ts = (struct timespec *) CMSG_DATA(cmsg);
334*cf84ac9aSAndroid Build Coastguard Worker 	ts[0].tv_sec = 123456789;
335*cf84ac9aSAndroid Build Coastguard Worker 	ts[0].tv_nsec = 987654321;
336*cf84ac9aSAndroid Build Coastguard Worker 	ts[1].tv_sec = 123456790;
337*cf84ac9aSAndroid Build Coastguard Worker 	ts[1].tv_nsec = 987654320;
338*cf84ac9aSAndroid Build Coastguard Worker 	ts[2].tv_sec = 123456791;
339*cf84ac9aSAndroid Build Coastguard Worker 	ts[2].tv_nsec = 987654319;
340*cf84ac9aSAndroid Build Coastguard Worker 
341*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
342*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
343*cf84ac9aSAndroid Build Coastguard Worker 
344*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
345*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
346*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
347*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMPING"
348*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_data=[{tv_sec=%lld, tv_nsec=%llu}"
349*cf84ac9aSAndroid Build Coastguard Worker 	       ", {tv_sec=%lld, tv_nsec=%llu}, {tv_sec=%lld, tv_nsec=%llu}]}]"
350*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
351*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len, (long long) ts[0].tv_sec,
352*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(ts[0].tv_nsec),
353*cf84ac9aSAndroid Build Coastguard Worker 	       (long long) ts[1].tv_sec,
354*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(ts[1].tv_nsec),
355*cf84ac9aSAndroid Build Coastguard Worker 	       (long long) ts[2].tv_sec,
356*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(ts[2].tv_nsec),
357*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) len, rc, errno2name());
358*cf84ac9aSAndroid Build Coastguard Worker 
359*cf84ac9aSAndroid Build Coastguard Worker 	len = CMSG_SPACE(3 * sizeof(struct timespec) - sizeof(long));
360*cf84ac9aSAndroid Build Coastguard Worker 	cmsg = get_cmsghdr(page, len);
361*cf84ac9aSAndroid Build Coastguard Worker 
362*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(3 * sizeof(struct timespec) - sizeof(long));
363*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_SOCKET;
364*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = SCM_TIMESTAMPING;
365*cf84ac9aSAndroid Build Coastguard Worker 
366*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
367*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
368*cf84ac9aSAndroid Build Coastguard Worker 
369*cf84ac9aSAndroid Build Coastguard Worker 	rc = sendmsg(-1, mh, 0);
370*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
371*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
372*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_TIMESTAMPING"
373*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_data=?}]"
374*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
375*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len,
376*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) len, rc, errno2name());
377*cf84ac9aSAndroid Build Coastguard Worker }
378*cf84ac9aSAndroid Build Coastguard Worker 
379*cf84ac9aSAndroid Build Coastguard Worker static void
print_security(const struct cmsghdr * const cmsg,const size_t cmsg_len)380*cf84ac9aSAndroid Build Coastguard Worker print_security(const struct cmsghdr *const cmsg, const size_t cmsg_len)
381*cf84ac9aSAndroid Build Coastguard Worker {
382*cf84ac9aSAndroid Build Coastguard Worker 	int n = cmsg_len > CMSG_LEN(0) ? cmsg_len - CMSG_LEN(0) : 0;
383*cf84ac9aSAndroid Build Coastguard Worker 	if (!n)
384*cf84ac9aSAndroid Build Coastguard Worker 		return;
385*cf84ac9aSAndroid Build Coastguard Worker 
386*cf84ac9aSAndroid Build Coastguard Worker 	printf(", cmsg_data=\"%.*s\"", n, CMSG_DATA(cmsg));
387*cf84ac9aSAndroid Build Coastguard Worker }
388*cf84ac9aSAndroid Build Coastguard Worker 
389*cf84ac9aSAndroid Build Coastguard Worker static void
test_scm_security(struct msghdr * const mh,const size_t msg_controllen,void * const page,const void * const src,const size_t cmsg_len,const int cmsg_level,const char * const cmsg_level_str)390*cf84ac9aSAndroid Build Coastguard Worker test_scm_security(struct msghdr *const mh,
391*cf84ac9aSAndroid Build Coastguard Worker 		  const size_t msg_controllen,
392*cf84ac9aSAndroid Build Coastguard Worker 		  void *const page,
393*cf84ac9aSAndroid Build Coastguard Worker 		  const void *const src,
394*cf84ac9aSAndroid Build Coastguard Worker 		  const size_t cmsg_len,
395*cf84ac9aSAndroid Build Coastguard Worker 		  const int cmsg_level,
396*cf84ac9aSAndroid Build Coastguard Worker 		  const char *const cmsg_level_str)
397*cf84ac9aSAndroid Build Coastguard Worker {
398*cf84ac9aSAndroid Build Coastguard Worker 	const size_t aligned_cms_len =
399*cf84ac9aSAndroid Build Coastguard Worker 		cmsg_len > CMSG_LEN(0) ? CMSG_ALIGN(cmsg_len) : CMSG_LEN(0);
400*cf84ac9aSAndroid Build Coastguard Worker 	if (cmsg_len >= CMSG_LEN(0)
401*cf84ac9aSAndroid Build Coastguard Worker 	    && aligned_cms_len + CMSG_LEN(0) <= msg_controllen)
402*cf84ac9aSAndroid Build Coastguard Worker 		return;
403*cf84ac9aSAndroid Build Coastguard Worker 
404*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *cmsg = get_cmsghdr(page, msg_controllen);
405*cf84ac9aSAndroid Build Coastguard Worker 
406*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = cmsg_len;
407*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = cmsg_level;
408*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = SCM_SECURITY;
409*cf84ac9aSAndroid Build Coastguard Worker 
410*cf84ac9aSAndroid Build Coastguard Worker 	size_t src_len =
411*cf84ac9aSAndroid Build Coastguard Worker 		cmsg_len < msg_controllen ? cmsg_len : msg_controllen;
412*cf84ac9aSAndroid Build Coastguard Worker 	if (src_len > CMSG_LEN(0))
413*cf84ac9aSAndroid Build Coastguard Worker 		memcpy(CMSG_DATA(cmsg), src, src_len - CMSG_LEN(0));
414*cf84ac9aSAndroid Build Coastguard Worker 
415*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
416*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = msg_controllen;
417*cf84ac9aSAndroid Build Coastguard Worker 
418*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
419*cf84ac9aSAndroid Build Coastguard Worker 	int saved_errno = errno;
420*cf84ac9aSAndroid Build Coastguard Worker 
421*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
422*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%lu, cmsg_level=%s"
423*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_type=SCM_SECURITY",
424*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) cmsg_len, cmsg_level_str);
425*cf84ac9aSAndroid Build Coastguard Worker 	print_security(cmsg, src_len);
426*cf84ac9aSAndroid Build Coastguard Worker 	printf("}");
427*cf84ac9aSAndroid Build Coastguard Worker 	if (aligned_cms_len < msg_controllen)
428*cf84ac9aSAndroid Build Coastguard Worker 		printf(", ... /* %p */", (void *) cmsg + aligned_cms_len);
429*cf84ac9aSAndroid Build Coastguard Worker 	printf("]");
430*cf84ac9aSAndroid Build Coastguard Worker 
431*cf84ac9aSAndroid Build Coastguard Worker 	errno = saved_errno;
432*cf84ac9aSAndroid Build Coastguard Worker 	printf(", msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
433*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) msg_controllen, rc, errno2name());
434*cf84ac9aSAndroid Build Coastguard Worker }
435*cf84ac9aSAndroid Build Coastguard Worker 
436*cf84ac9aSAndroid Build Coastguard Worker static void
test_unknown_type(struct msghdr * const mh,void * const page,const int cmsg_level,const char * const cmsg_level_str,const char * const cmsg_type_str)437*cf84ac9aSAndroid Build Coastguard Worker test_unknown_type(struct msghdr *const mh,
438*cf84ac9aSAndroid Build Coastguard Worker 		  void *const page,
439*cf84ac9aSAndroid Build Coastguard Worker 		  const int cmsg_level,
440*cf84ac9aSAndroid Build Coastguard Worker 		  const char *const cmsg_level_str,
441*cf84ac9aSAndroid Build Coastguard Worker 		  const char *const cmsg_type_str)
442*cf84ac9aSAndroid Build Coastguard Worker {
443*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *cmsg = get_cmsghdr(page, CMSG_LEN(0));
444*cf84ac9aSAndroid Build Coastguard Worker 
445*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(0);
446*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = cmsg_level;
447*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = 0xfacefeed;
448*cf84ac9aSAndroid Build Coastguard Worker 
449*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
450*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = cmsg->cmsg_len;
451*cf84ac9aSAndroid Build Coastguard Worker 
452*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
453*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
454*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u, cmsg_level=%s"
455*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_type=%#x /* %s */}], msg_controllen=%u, msg_flags=0}"
456*cf84ac9aSAndroid Build Coastguard Worker 	       ", 0) = %d %s (%m)\n",
457*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len, cmsg_level_str, cmsg->cmsg_type,
458*cf84ac9aSAndroid Build Coastguard Worker 	       cmsg_type_str, (unsigned) mh->msg_controllen, rc, errno2name());
459*cf84ac9aSAndroid Build Coastguard Worker }
460*cf84ac9aSAndroid Build Coastguard Worker 
461*cf84ac9aSAndroid Build Coastguard Worker static void
test_sol_socket(struct msghdr * const mh,void * const page)462*cf84ac9aSAndroid Build Coastguard Worker test_sol_socket(struct msghdr *const mh, void *const page)
463*cf84ac9aSAndroid Build Coastguard Worker {
464*cf84ac9aSAndroid Build Coastguard Worker 	static const int fds0[] = { -10, -11, -12, -13 };
465*cf84ac9aSAndroid Build Coastguard Worker 	static const int fds1[] = { -15, -16, -17, -18 };
466*cf84ac9aSAndroid Build Coastguard Worker 	size_t msg_controllen, max_msg_controllen;
467*cf84ac9aSAndroid Build Coastguard Worker 
468*cf84ac9aSAndroid Build Coastguard Worker 	max_msg_controllen = CMSG_SPACE(sizeof(fds0)) + sizeof(*fds0) - 1;
469*cf84ac9aSAndroid Build Coastguard Worker 	for (msg_controllen = 0;
470*cf84ac9aSAndroid Build Coastguard Worker 	     msg_controllen <= max_msg_controllen;
471*cf84ac9aSAndroid Build Coastguard Worker 	     msg_controllen++) {
472*cf84ac9aSAndroid Build Coastguard Worker 		size_t cmsg_len;
473*cf84ac9aSAndroid Build Coastguard Worker 
474*cf84ac9aSAndroid Build Coastguard Worker 		for (cmsg_len = 0;
475*cf84ac9aSAndroid Build Coastguard Worker 		     cmsg_len <= msg_controllen + CMSG_LEN(0);
476*cf84ac9aSAndroid Build Coastguard Worker 		     cmsg_len++) {
477*cf84ac9aSAndroid Build Coastguard Worker 			test_scm_rights1(mh, msg_controllen,
478*cf84ac9aSAndroid Build Coastguard Worker 					 page, fds0, cmsg_len);
479*cf84ac9aSAndroid Build Coastguard Worker 		}
480*cf84ac9aSAndroid Build Coastguard Worker 	}
481*cf84ac9aSAndroid Build Coastguard Worker 
482*cf84ac9aSAndroid Build Coastguard Worker 	max_msg_controllen =
483*cf84ac9aSAndroid Build Coastguard Worker 		CMSG_SPACE(sizeof(fds0)) + CMSG_SPACE(sizeof(fds1)) +
484*cf84ac9aSAndroid Build Coastguard Worker 		sizeof(*fds0) - 1;
485*cf84ac9aSAndroid Build Coastguard Worker 	for (msg_controllen = CMSG_LEN(0) * 2;
486*cf84ac9aSAndroid Build Coastguard Worker 	     msg_controllen <= max_msg_controllen;
487*cf84ac9aSAndroid Build Coastguard Worker 	     msg_controllen++) {
488*cf84ac9aSAndroid Build Coastguard Worker 		static const int *const fdps[] = { fds0, fds1 };
489*cf84ac9aSAndroid Build Coastguard Worker 		size_t cmsg_len[2];
490*cf84ac9aSAndroid Build Coastguard Worker 
491*cf84ac9aSAndroid Build Coastguard Worker 		for (cmsg_len[0] = CMSG_LEN(0);
492*cf84ac9aSAndroid Build Coastguard Worker 		     CMSG_ALIGN(cmsg_len[0]) + CMSG_LEN(0) <= msg_controllen
493*cf84ac9aSAndroid Build Coastguard Worker 		     && CMSG_ALIGN(cmsg_len[0]) <= CMSG_SPACE(sizeof(fds0));
494*cf84ac9aSAndroid Build Coastguard Worker 		     cmsg_len[0]++) {
495*cf84ac9aSAndroid Build Coastguard Worker 			const size_t msg_controllen1 =
496*cf84ac9aSAndroid Build Coastguard Worker 				msg_controllen - CMSG_ALIGN(cmsg_len[0]);
497*cf84ac9aSAndroid Build Coastguard Worker 
498*cf84ac9aSAndroid Build Coastguard Worker 			for (cmsg_len[1] = 0;
499*cf84ac9aSAndroid Build Coastguard Worker 			     cmsg_len[1] <= msg_controllen1 + CMSG_LEN(0);
500*cf84ac9aSAndroid Build Coastguard Worker 			     cmsg_len[1]++) {
501*cf84ac9aSAndroid Build Coastguard Worker 				test_scm_rights2(mh, msg_controllen,
502*cf84ac9aSAndroid Build Coastguard Worker 						 page, fdps, cmsg_len);
503*cf84ac9aSAndroid Build Coastguard Worker 			}
504*cf84ac9aSAndroid Build Coastguard Worker 		}
505*cf84ac9aSAndroid Build Coastguard Worker 	}
506*cf84ac9aSAndroid Build Coastguard Worker 
507*cf84ac9aSAndroid Build Coastguard Worker 	static const char text[16] = "0123456789abcdef";
508*cf84ac9aSAndroid Build Coastguard Worker 	max_msg_controllen = CMSG_SPACE(sizeof(text)) + CMSG_LEN(0) - 1;
509*cf84ac9aSAndroid Build Coastguard Worker 	for (msg_controllen = CMSG_LEN(0);
510*cf84ac9aSAndroid Build Coastguard Worker 	     msg_controllen <= max_msg_controllen;
511*cf84ac9aSAndroid Build Coastguard Worker 	     msg_controllen++) {
512*cf84ac9aSAndroid Build Coastguard Worker 		size_t cmsg_len;
513*cf84ac9aSAndroid Build Coastguard Worker 
514*cf84ac9aSAndroid Build Coastguard Worker 		for (cmsg_len = 0;
515*cf84ac9aSAndroid Build Coastguard Worker 		     cmsg_len <= msg_controllen + CMSG_LEN(0)
516*cf84ac9aSAndroid Build Coastguard Worker 		     && cmsg_len <= CMSG_LEN(sizeof(text));
517*cf84ac9aSAndroid Build Coastguard Worker 		     cmsg_len++) {
518*cf84ac9aSAndroid Build Coastguard Worker 			test_scm_security(mh, msg_controllen,
519*cf84ac9aSAndroid Build Coastguard Worker 					  page, text, cmsg_len,
520*cf84ac9aSAndroid Build Coastguard Worker 					  ARG_STR(SOL_SOCKET));
521*cf84ac9aSAndroid Build Coastguard Worker 		}
522*cf84ac9aSAndroid Build Coastguard Worker 	}
523*cf84ac9aSAndroid Build Coastguard Worker 
524*cf84ac9aSAndroid Build Coastguard Worker 	test_scm_rights3(mh, page, DEFAULT_STRLEN - 1);
525*cf84ac9aSAndroid Build Coastguard Worker 	test_scm_rights3(mh, page, DEFAULT_STRLEN);
526*cf84ac9aSAndroid Build Coastguard Worker 	test_scm_rights3(mh, page, DEFAULT_STRLEN + 1);
527*cf84ac9aSAndroid Build Coastguard Worker 
528*cf84ac9aSAndroid Build Coastguard Worker 	test_scm_timestamp(mh, page);
529*cf84ac9aSAndroid Build Coastguard Worker 	test_scm_timestampns(mh, page);
530*cf84ac9aSAndroid Build Coastguard Worker 	test_scm_timestamping(mh, page);
531*cf84ac9aSAndroid Build Coastguard Worker 
532*cf84ac9aSAndroid Build Coastguard Worker 	test_unknown_type(mh, page, ARG_STR(SOL_SOCKET), "SCM_???");
533*cf84ac9aSAndroid Build Coastguard Worker }
534*cf84ac9aSAndroid Build Coastguard Worker 
535*cf84ac9aSAndroid Build Coastguard Worker static void
test_ip_pktinfo(struct msghdr * const mh,void * const page,const int cmsg_type,const char * const cmsg_type_str)536*cf84ac9aSAndroid Build Coastguard Worker test_ip_pktinfo(struct msghdr *const mh, void *const page,
537*cf84ac9aSAndroid Build Coastguard Worker 		const int cmsg_type, const char *const cmsg_type_str)
538*cf84ac9aSAndroid Build Coastguard Worker {
539*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned int len = CMSG_SPACE(sizeof(struct in_pktinfo));
540*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *const cmsg = get_cmsghdr(page, len);
541*cf84ac9aSAndroid Build Coastguard Worker 
542*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
543*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_IP;
544*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = cmsg_type;
545*cf84ac9aSAndroid Build Coastguard Worker 
546*cf84ac9aSAndroid Build Coastguard Worker 	struct in_pktinfo *const info = (struct in_pktinfo *) CMSG_DATA(cmsg);
547*cf84ac9aSAndroid Build Coastguard Worker 	info->ipi_ifindex = ifindex_lo();
548*cf84ac9aSAndroid Build Coastguard Worker 	info->ipi_spec_dst.s_addr = inet_addr("1.2.3.4");
549*cf84ac9aSAndroid Build Coastguard Worker 	info->ipi_addr.s_addr = inet_addr("5.6.7.8");
550*cf84ac9aSAndroid Build Coastguard Worker 
551*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
552*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
553*cf84ac9aSAndroid Build Coastguard Worker 
554*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
555*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
556*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u, cmsg_level=SOL_IP"
557*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_type=%s, cmsg_data={ipi_ifindex=%s"
558*cf84ac9aSAndroid Build Coastguard Worker 	       ", ipi_spec_dst=inet_addr(\"%s\")"
559*cf84ac9aSAndroid Build Coastguard Worker 	       ", ipi_addr=inet_addr(\"%s\")}}]"
560*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n",
561*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len, cmsg_type_str,
562*cf84ac9aSAndroid Build Coastguard Worker 	       IFINDEX_LO_STR, "1.2.3.4", "5.6.7.8", len, rc, errno2name());
563*cf84ac9aSAndroid Build Coastguard Worker }
564*cf84ac9aSAndroid Build Coastguard Worker 
565*cf84ac9aSAndroid Build Coastguard Worker static void
test_ip_uint(struct msghdr * const mh,void * const page,const int cmsg_type,const char * const cmsg_type_str)566*cf84ac9aSAndroid Build Coastguard Worker test_ip_uint(struct msghdr *const mh, void *const page,
567*cf84ac9aSAndroid Build Coastguard Worker 	     const int cmsg_type, const char *const cmsg_type_str)
568*cf84ac9aSAndroid Build Coastguard Worker {
569*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned int len = CMSG_SPACE(sizeof(int));
570*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *const cmsg = get_cmsghdr(page, len);
571*cf84ac9aSAndroid Build Coastguard Worker 
572*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
573*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_IP;
574*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = cmsg_type;
575*cf84ac9aSAndroid Build Coastguard Worker 
576*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int *u = (void *) CMSG_DATA(cmsg);
577*cf84ac9aSAndroid Build Coastguard Worker 	*u = 0xfacefeed;
578*cf84ac9aSAndroid Build Coastguard Worker 
579*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
580*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
581*cf84ac9aSAndroid Build Coastguard Worker 
582*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
583*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
584*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
585*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_IP, cmsg_type=%s, cmsg_data=[%u]}]"
586*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n",
587*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len, cmsg_type_str, *u, len,
588*cf84ac9aSAndroid Build Coastguard Worker 	       rc, errno2name());
589*cf84ac9aSAndroid Build Coastguard Worker }
590*cf84ac9aSAndroid Build Coastguard Worker 
591*cf84ac9aSAndroid Build Coastguard Worker static void
test_ip_uint8_t(struct msghdr * const mh,void * const page,const int cmsg_type,const char * const cmsg_type_str)592*cf84ac9aSAndroid Build Coastguard Worker test_ip_uint8_t(struct msghdr *const mh, void *const page,
593*cf84ac9aSAndroid Build Coastguard Worker 		const int cmsg_type, const char *const cmsg_type_str)
594*cf84ac9aSAndroid Build Coastguard Worker {
595*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned int len = CMSG_SPACE(1);
596*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *const cmsg = get_cmsghdr(page, len);
597*cf84ac9aSAndroid Build Coastguard Worker 
598*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(1);
599*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_IP;
600*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = cmsg_type;
601*cf84ac9aSAndroid Build Coastguard Worker 	*CMSG_DATA(cmsg) = 'A';
602*cf84ac9aSAndroid Build Coastguard Worker 
603*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
604*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
605*cf84ac9aSAndroid Build Coastguard Worker 
606*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
607*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
608*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
609*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_IP, cmsg_type=%s, cmsg_data=[%#x]}]"
610*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n",
611*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len, cmsg_type_str,
612*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) (uint8_t) 'A', len, rc, errno2name());
613*cf84ac9aSAndroid Build Coastguard Worker }
614*cf84ac9aSAndroid Build Coastguard Worker 
615*cf84ac9aSAndroid Build Coastguard Worker static void
print_ip_opts(const void * const cmsg_data,const unsigned int data_len)616*cf84ac9aSAndroid Build Coastguard Worker print_ip_opts(const void *const cmsg_data, const unsigned int data_len)
617*cf84ac9aSAndroid Build Coastguard Worker {
618*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned char *const opts = cmsg_data;
619*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int i;
620*cf84ac9aSAndroid Build Coastguard Worker 	for (i = 0; i < data_len; ++i) {
621*cf84ac9aSAndroid Build Coastguard Worker 		if (i)
622*cf84ac9aSAndroid Build Coastguard Worker 			printf(", ");
623*cf84ac9aSAndroid Build Coastguard Worker #if !VERBOSE
624*cf84ac9aSAndroid Build Coastguard Worker 		if (i >= DEFAULT_STRLEN) {
625*cf84ac9aSAndroid Build Coastguard Worker 			printf("...");
626*cf84ac9aSAndroid Build Coastguard Worker 			break;
627*cf84ac9aSAndroid Build Coastguard Worker 		}
628*cf84ac9aSAndroid Build Coastguard Worker #endif
629*cf84ac9aSAndroid Build Coastguard Worker 		printf("0x%02x", opts[i]);
630*cf84ac9aSAndroid Build Coastguard Worker 	}
631*cf84ac9aSAndroid Build Coastguard Worker }
632*cf84ac9aSAndroid Build Coastguard Worker 
633*cf84ac9aSAndroid Build Coastguard Worker static void
test_ip_opts(struct msghdr * const mh,void * const page,const int cmsg_type,const char * const cmsg_type_str,const unsigned int opts_len)634*cf84ac9aSAndroid Build Coastguard Worker test_ip_opts(struct msghdr *const mh, void *const page,
635*cf84ac9aSAndroid Build Coastguard Worker 	     const int cmsg_type, const char *const cmsg_type_str,
636*cf84ac9aSAndroid Build Coastguard Worker 	     const unsigned int opts_len)
637*cf84ac9aSAndroid Build Coastguard Worker {
638*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int len = CMSG_SPACE(opts_len);
639*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *cmsg = get_cmsghdr(page, len);
640*cf84ac9aSAndroid Build Coastguard Worker 
641*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(opts_len);
642*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_IP;
643*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = cmsg_type;
644*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int i;
645*cf84ac9aSAndroid Build Coastguard Worker 	for (i = 0; i < opts_len; ++i)
646*cf84ac9aSAndroid Build Coastguard Worker 		CMSG_DATA(cmsg)[i] = 'A' + i;
647*cf84ac9aSAndroid Build Coastguard Worker 
648*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
649*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
650*cf84ac9aSAndroid Build Coastguard Worker 
651*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
652*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
653*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
654*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_IP, cmsg_type=%s, cmsg_data=[",
655*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len, cmsg_type_str);
656*cf84ac9aSAndroid Build Coastguard Worker 	print_ip_opts(CMSG_DATA(cmsg), opts_len);
657*cf84ac9aSAndroid Build Coastguard Worker 	printf("]}], msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n",
658*cf84ac9aSAndroid Build Coastguard Worker 	       len, rc, errno2name());
659*cf84ac9aSAndroid Build Coastguard Worker }
660*cf84ac9aSAndroid Build Coastguard Worker 
661*cf84ac9aSAndroid Build Coastguard Worker #ifdef IP_CHECKSUM
662*cf84ac9aSAndroid Build Coastguard Worker struct sock_ee {
663*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t ee_errno;
664*cf84ac9aSAndroid Build Coastguard Worker 	uint8_t  ee_origin;
665*cf84ac9aSAndroid Build Coastguard Worker 	uint8_t  ee_type;
666*cf84ac9aSAndroid Build Coastguard Worker 	uint8_t  ee_code;
667*cf84ac9aSAndroid Build Coastguard Worker 	uint8_t  ee_pad;
668*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t ee_info;
669*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t ee_data;
670*cf84ac9aSAndroid Build Coastguard Worker 	struct sockaddr_in offender;
671*cf84ac9aSAndroid Build Coastguard Worker };
672*cf84ac9aSAndroid Build Coastguard Worker 
673*cf84ac9aSAndroid Build Coastguard Worker static void
test_ip_recverr(struct msghdr * const mh,void * const page,const int cmsg_type,const char * const cmsg_type_str)674*cf84ac9aSAndroid Build Coastguard Worker test_ip_recverr(struct msghdr *const mh, void *const page,
675*cf84ac9aSAndroid Build Coastguard Worker 		const int cmsg_type, const char *const cmsg_type_str)
676*cf84ac9aSAndroid Build Coastguard Worker {
677*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned int len = CMSG_SPACE(sizeof(struct sock_ee));
678*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *const cmsg = get_cmsghdr(page, len);
679*cf84ac9aSAndroid Build Coastguard Worker 
680*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sock_ee));
681*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_IP;
682*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = cmsg_type;
683*cf84ac9aSAndroid Build Coastguard Worker 
684*cf84ac9aSAndroid Build Coastguard Worker 	struct sock_ee *const e = (struct sock_ee *) CMSG_DATA(cmsg);
685*cf84ac9aSAndroid Build Coastguard Worker 	e->ee_errno = 0xdeadbeef;
686*cf84ac9aSAndroid Build Coastguard Worker 	e->ee_origin = 2;
687*cf84ac9aSAndroid Build Coastguard Worker 	e->ee_type = 3;
688*cf84ac9aSAndroid Build Coastguard Worker 	e->ee_code = 4;
689*cf84ac9aSAndroid Build Coastguard Worker 	e->ee_info = 0xfacefeed;
690*cf84ac9aSAndroid Build Coastguard Worker 	e->ee_data = 0xbadc0ded;
691*cf84ac9aSAndroid Build Coastguard Worker 	e->offender.sin_family = AF_INET,
692*cf84ac9aSAndroid Build Coastguard Worker 	e->offender.sin_port = htons(12345),
693*cf84ac9aSAndroid Build Coastguard Worker 	e->offender.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
694*cf84ac9aSAndroid Build Coastguard Worker 
695*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
696*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
697*cf84ac9aSAndroid Build Coastguard Worker 
698*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
699*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
700*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u, cmsg_level=SOL_IP"
701*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_type=%s, cmsg_data={ee_errno=%u, ee_origin=%u"
702*cf84ac9aSAndroid Build Coastguard Worker 	       ", ee_type=%u, ee_code=%u, ee_info=%u, ee_data=%u"
703*cf84ac9aSAndroid Build Coastguard Worker 	       ", offender={sa_family=AF_INET, sin_port=htons(%hu)"
704*cf84ac9aSAndroid Build Coastguard Worker 	       ", sin_addr=inet_addr(\"127.0.0.1\")}}}]"
705*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n",
706*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len, cmsg_type_str,
707*cf84ac9aSAndroid Build Coastguard Worker 	       e->ee_errno, e->ee_origin, e->ee_type,
708*cf84ac9aSAndroid Build Coastguard Worker 	       e->ee_code, e->ee_info, e->ee_data,
709*cf84ac9aSAndroid Build Coastguard Worker 	       ntohs(e->offender.sin_port),
710*cf84ac9aSAndroid Build Coastguard Worker 	       len, rc, errno2name());
711*cf84ac9aSAndroid Build Coastguard Worker }
712*cf84ac9aSAndroid Build Coastguard Worker #endif
713*cf84ac9aSAndroid Build Coastguard Worker 
714*cf84ac9aSAndroid Build Coastguard Worker #ifdef IP_ORIGDSTADDR
715*cf84ac9aSAndroid Build Coastguard Worker static void
test_ip_origdstaddr(struct msghdr * const mh,void * const page,const int cmsg_type,const char * const cmsg_type_str)716*cf84ac9aSAndroid Build Coastguard Worker test_ip_origdstaddr(struct msghdr *const mh, void *const page,
717*cf84ac9aSAndroid Build Coastguard Worker 		    const int cmsg_type, const char *const cmsg_type_str)
718*cf84ac9aSAndroid Build Coastguard Worker {
719*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned int len = CMSG_SPACE(sizeof(struct sockaddr_in));
720*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *const cmsg = get_cmsghdr(page, len);
721*cf84ac9aSAndroid Build Coastguard Worker 
722*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sockaddr_in));
723*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_IP;
724*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = cmsg_type;
725*cf84ac9aSAndroid Build Coastguard Worker 
726*cf84ac9aSAndroid Build Coastguard Worker 	struct sockaddr_in *const sin = (struct sockaddr_in *) CMSG_DATA(cmsg);
727*cf84ac9aSAndroid Build Coastguard Worker 	sin->sin_family = AF_INET,
728*cf84ac9aSAndroid Build Coastguard Worker 	sin->sin_port = htons(12345),
729*cf84ac9aSAndroid Build Coastguard Worker 	sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
730*cf84ac9aSAndroid Build Coastguard Worker 
731*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
732*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
733*cf84ac9aSAndroid Build Coastguard Worker 
734*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
735*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
736*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u, cmsg_level=SOL_IP"
737*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_type=%s, cmsg_data={sa_family=AF_INET"
738*cf84ac9aSAndroid Build Coastguard Worker 	       ", sin_port=htons(%hu), sin_addr=inet_addr(\"127.0.0.1\")}}]"
739*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_controllen=%u, msg_flags=0}, 0) = %d %s (%m)\n",
740*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len, cmsg_type_str,
741*cf84ac9aSAndroid Build Coastguard Worker 	       ntohs(sin->sin_port), len, rc, errno2name());
742*cf84ac9aSAndroid Build Coastguard Worker }
743*cf84ac9aSAndroid Build Coastguard Worker #endif
744*cf84ac9aSAndroid Build Coastguard Worker 
745*cf84ac9aSAndroid Build Coastguard Worker static void
test_sol_ip(struct msghdr * const mh,void * const page)746*cf84ac9aSAndroid Build Coastguard Worker test_sol_ip(struct msghdr *const mh, void *const page)
747*cf84ac9aSAndroid Build Coastguard Worker {
748*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_pktinfo(mh, page, ARG_STR(IP_PKTINFO));
749*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_uint(mh, page, ARG_STR(IP_TTL));
750*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_uint8_t(mh, page, ARG_STR(IP_TOS));
751*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RECVOPTS), 1);
752*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RECVOPTS), 2);
753*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RECVOPTS), 3);
754*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RECVOPTS), 4);
755*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), 5);
756*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), 6);
757*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), 7);
758*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), 8);
759*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), DEFAULT_STRLEN - 1);
760*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), DEFAULT_STRLEN);
761*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_opts(mh, page, ARG_STR(IP_RETOPTS), DEFAULT_STRLEN + 1);
762*cf84ac9aSAndroid Build Coastguard Worker #ifdef IP_CHECKSUM
763*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_recverr(mh, page, ARG_STR(IP_RECVERR));
764*cf84ac9aSAndroid Build Coastguard Worker #endif
765*cf84ac9aSAndroid Build Coastguard Worker #ifdef IP_ORIGDSTADDR
766*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_origdstaddr(mh, page, ARG_STR(IP_ORIGDSTADDR));
767*cf84ac9aSAndroid Build Coastguard Worker #endif
768*cf84ac9aSAndroid Build Coastguard Worker #ifdef IP_CHECKSUM
769*cf84ac9aSAndroid Build Coastguard Worker 	test_ip_uint(mh, page, ARG_STR(IP_CHECKSUM));
770*cf84ac9aSAndroid Build Coastguard Worker #endif
771*cf84ac9aSAndroid Build Coastguard Worker 	test_scm_security(mh, CMSG_LEN(0), page, 0, CMSG_LEN(0),
772*cf84ac9aSAndroid Build Coastguard Worker 			  ARG_STR(SOL_IP));
773*cf84ac9aSAndroid Build Coastguard Worker 	test_unknown_type(mh, page, ARG_STR(SOL_IP), "IP_???");
774*cf84ac9aSAndroid Build Coastguard Worker }
775*cf84ac9aSAndroid Build Coastguard Worker 
776*cf84ac9aSAndroid Build Coastguard Worker static void
test_unknown_level(struct msghdr * const mh,void * const page)777*cf84ac9aSAndroid Build Coastguard Worker test_unknown_level(struct msghdr *const mh, void *const page)
778*cf84ac9aSAndroid Build Coastguard Worker {
779*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *cmsg = get_cmsghdr(page, CMSG_LEN(0));
780*cf84ac9aSAndroid Build Coastguard Worker 
781*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = CMSG_LEN(0);
782*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_TCP;
783*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = 0xdeadbeef;
784*cf84ac9aSAndroid Build Coastguard Worker 
785*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
786*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = cmsg->cmsg_len;
787*cf84ac9aSAndroid Build Coastguard Worker 
788*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
789*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
790*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u, cmsg_level=%s"
791*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_type=%#x}], msg_controllen=%u, msg_flags=0}"
792*cf84ac9aSAndroid Build Coastguard Worker 	       ", 0) = %d %s (%m)\n",
793*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len, "SOL_TCP", cmsg->cmsg_type,
794*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) mh->msg_controllen, rc, errno2name());
795*cf84ac9aSAndroid Build Coastguard Worker }
796*cf84ac9aSAndroid Build Coastguard Worker 
797*cf84ac9aSAndroid Build Coastguard Worker static void
test_big_len(struct msghdr * const mh)798*cf84ac9aSAndroid Build Coastguard Worker test_big_len(struct msghdr *const mh)
799*cf84ac9aSAndroid Build Coastguard Worker {
800*cf84ac9aSAndroid Build Coastguard Worker 	int optmem_max;
801*cf84ac9aSAndroid Build Coastguard Worker 
802*cf84ac9aSAndroid Build Coastguard Worker 	if (read_int_from_file("/proc/sys/net/core/optmem_max", &optmem_max)
803*cf84ac9aSAndroid Build Coastguard Worker 	    || optmem_max <= 0 || optmem_max > 0x100000)
804*cf84ac9aSAndroid Build Coastguard Worker 		optmem_max = sizeof(long long) * (2 * IOV_MAX + 512);
805*cf84ac9aSAndroid Build Coastguard Worker 	optmem_max = (optmem_max + sizeof(long long) - 1)
806*cf84ac9aSAndroid Build Coastguard Worker 		     & ~(sizeof(long long) - 1);
807*cf84ac9aSAndroid Build Coastguard Worker 
808*cf84ac9aSAndroid Build Coastguard Worker 	const size_t len = optmem_max * 2;
809*cf84ac9aSAndroid Build Coastguard Worker 	struct cmsghdr *const cmsg = tail_alloc(len);
810*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_len = len;
811*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_level = SOL_SOCKET;
812*cf84ac9aSAndroid Build Coastguard Worker 	cmsg->cmsg_type = SCM_RIGHTS;
813*cf84ac9aSAndroid Build Coastguard Worker 
814*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = cmsg;
815*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = len;
816*cf84ac9aSAndroid Build Coastguard Worker 
817*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, mh, 0);
818*cf84ac9aSAndroid Build Coastguard Worker 	if (EBADF != errno)
819*cf84ac9aSAndroid Build Coastguard Worker 		perror_msg_and_skip("sendmsg");
820*cf84ac9aSAndroid Build Coastguard Worker 
821*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
822*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
823*cf84ac9aSAndroid Build Coastguard Worker 	       ", cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS",
824*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned) cmsg->cmsg_len);
825*cf84ac9aSAndroid Build Coastguard Worker 	print_fds(cmsg, optmem_max);
826*cf84ac9aSAndroid Build Coastguard Worker 	printf("}, ...], msg_controllen=%lu, msg_flags=0}, 0) = %d %s (%m)\n",
827*cf84ac9aSAndroid Build Coastguard Worker 	       (unsigned long) len, rc, errno2name());
828*cf84ac9aSAndroid Build Coastguard Worker }
829*cf84ac9aSAndroid Build Coastguard Worker 
main(int ac,const char ** av)830*cf84ac9aSAndroid Build Coastguard Worker int main(int ac, const char **av)
831*cf84ac9aSAndroid Build Coastguard Worker {
832*cf84ac9aSAndroid Build Coastguard Worker 	int rc = sendmsg(-1, 0, 0);
833*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, NULL, 0) = %d %s (%m)\n", rc, errno2name());
834*cf84ac9aSAndroid Build Coastguard Worker 
835*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(struct msghdr, mh);
836*cf84ac9aSAndroid Build Coastguard Worker 	memset(mh, 0, sizeof(*mh));
837*cf84ac9aSAndroid Build Coastguard Worker 	test_big_len(mh);
838*cf84ac9aSAndroid Build Coastguard Worker 
839*cf84ac9aSAndroid Build Coastguard Worker 	rc = sendmsg(-1, mh + 1, 0);
840*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, %p, 0) = %d %s (%m)\n",
841*cf84ac9aSAndroid Build Coastguard Worker 	       mh + 1, rc, errno2name());
842*cf84ac9aSAndroid Build Coastguard Worker 
843*cf84ac9aSAndroid Build Coastguard Worker 	void *page = tail_alloc(1) + 1;
844*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_control = page;
845*cf84ac9aSAndroid Build Coastguard Worker 	mh->msg_controllen = CMSG_LEN(0);
846*cf84ac9aSAndroid Build Coastguard Worker 	rc = sendmsg(-1, mh, 0);
847*cf84ac9aSAndroid Build Coastguard Worker 	printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
848*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_iovlen=0, msg_control=%p, msg_controllen=%u"
849*cf84ac9aSAndroid Build Coastguard Worker 	       ", msg_flags=0}, 0) = %d %s (%m)\n",
850*cf84ac9aSAndroid Build Coastguard Worker 	       page, (unsigned) CMSG_LEN(0), rc, errno2name());
851*cf84ac9aSAndroid Build Coastguard Worker 
852*cf84ac9aSAndroid Build Coastguard Worker 	test_sol_socket(mh, page);
853*cf84ac9aSAndroid Build Coastguard Worker 	test_sol_ip(mh, page);
854*cf84ac9aSAndroid Build Coastguard Worker 	test_unknown_level(mh, page);
855*cf84ac9aSAndroid Build Coastguard Worker 
856*cf84ac9aSAndroid Build Coastguard Worker 	puts("+++ exited with 0 +++");
857*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
858*cf84ac9aSAndroid Build Coastguard Worker }
859