xref: /aosp_15_r20/external/strace/tests-mx32/ioctl_sock_gifconf.c (revision cf84ac9a129d8ea9952db616b4e9b904c4bdde56)
1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker  * Check decoding of SIOCGIFCONF command of ioctl syscall.
3*cf84ac9aSAndroid Build Coastguard Worker  *
4*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2016 Eugene Syromyatnikov <[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 
33*cf84ac9aSAndroid Build Coastguard Worker #include <stdio.h>
34*cf84ac9aSAndroid Build Coastguard Worker #include <string.h>
35*cf84ac9aSAndroid Build Coastguard Worker 
36*cf84ac9aSAndroid Build Coastguard Worker #include <arpa/inet.h>
37*cf84ac9aSAndroid Build Coastguard Worker #include <net/if.h>
38*cf84ac9aSAndroid Build Coastguard Worker #include <sys/ioctl.h>
39*cf84ac9aSAndroid Build Coastguard Worker #include <sys/socket.h>
40*cf84ac9aSAndroid Build Coastguard Worker 
41*cf84ac9aSAndroid Build Coastguard Worker #define MAX_STRLEN 1
42*cf84ac9aSAndroid Build Coastguard Worker 
43*cf84ac9aSAndroid Build Coastguard Worker static void
print_ifc_len(int val)44*cf84ac9aSAndroid Build Coastguard Worker print_ifc_len(int val)
45*cf84ac9aSAndroid Build Coastguard Worker {
46*cf84ac9aSAndroid Build Coastguard Worker 	if (val % (int) sizeof(struct ifreq))
47*cf84ac9aSAndroid Build Coastguard Worker 		printf("%d", val);
48*cf84ac9aSAndroid Build Coastguard Worker 	else
49*cf84ac9aSAndroid Build Coastguard Worker 		printf("%d * sizeof(struct ifreq)",
50*cf84ac9aSAndroid Build Coastguard Worker 		       val / (int) sizeof(struct ifreq));
51*cf84ac9aSAndroid Build Coastguard Worker }
52*cf84ac9aSAndroid Build Coastguard Worker 
53*cf84ac9aSAndroid Build Coastguard Worker static void
print_ifconf(struct ifconf * ifc,int in_len,char * in_buf,long rc)54*cf84ac9aSAndroid Build Coastguard Worker print_ifconf(struct ifconf *ifc, int in_len, char *in_buf, long rc)
55*cf84ac9aSAndroid Build Coastguard Worker {
56*cf84ac9aSAndroid Build Coastguard Worker 	if (in_buf) {
57*cf84ac9aSAndroid Build Coastguard Worker 		printf("{ifc_len=");
58*cf84ac9aSAndroid Build Coastguard Worker 		print_ifc_len(in_len);
59*cf84ac9aSAndroid Build Coastguard Worker 
60*cf84ac9aSAndroid Build Coastguard Worker 		if (in_len != ifc->ifc_len) {
61*cf84ac9aSAndroid Build Coastguard Worker 			printf(" => ");
62*cf84ac9aSAndroid Build Coastguard Worker 			print_ifc_len(ifc->ifc_len);
63*cf84ac9aSAndroid Build Coastguard Worker 		}
64*cf84ac9aSAndroid Build Coastguard Worker 	} else {
65*cf84ac9aSAndroid Build Coastguard Worker 		printf("{ifc_len=");
66*cf84ac9aSAndroid Build Coastguard Worker 		print_ifc_len(ifc->ifc_len);
67*cf84ac9aSAndroid Build Coastguard Worker 	}
68*cf84ac9aSAndroid Build Coastguard Worker 
69*cf84ac9aSAndroid Build Coastguard Worker 	printf(", ifc_buf=");
70*cf84ac9aSAndroid Build Coastguard Worker 
71*cf84ac9aSAndroid Build Coastguard Worker 	if ((rc < 0) || !in_buf) {
72*cf84ac9aSAndroid Build Coastguard Worker 		if (in_buf)
73*cf84ac9aSAndroid Build Coastguard Worker 			printf("%p", in_buf);
74*cf84ac9aSAndroid Build Coastguard Worker 		else
75*cf84ac9aSAndroid Build Coastguard Worker 			printf("NULL");
76*cf84ac9aSAndroid Build Coastguard Worker 	} else {
77*cf84ac9aSAndroid Build Coastguard Worker 		int i;
78*cf84ac9aSAndroid Build Coastguard Worker 
79*cf84ac9aSAndroid Build Coastguard Worker 		printf("[");
80*cf84ac9aSAndroid Build Coastguard Worker 		for (i = 0; i < (ifc->ifc_len) &&
81*cf84ac9aSAndroid Build Coastguard Worker 		    i < (int) (MAX_STRLEN * sizeof(struct ifreq));
82*cf84ac9aSAndroid Build Coastguard Worker 		    i += sizeof(struct ifreq)) {
83*cf84ac9aSAndroid Build Coastguard Worker 			struct ifreq *ifr = (struct ifreq *) (ifc->ifc_buf + i);
84*cf84ac9aSAndroid Build Coastguard Worker 			struct sockaddr_in *const sa_in =
85*cf84ac9aSAndroid Build Coastguard Worker 				(struct sockaddr_in *) &(ifr->ifr_addr);
86*cf84ac9aSAndroid Build Coastguard Worker 
87*cf84ac9aSAndroid Build Coastguard Worker 			if (i)
88*cf84ac9aSAndroid Build Coastguard Worker 				printf(", ");
89*cf84ac9aSAndroid Build Coastguard Worker 			printf("{ifr_name=\"%s\", ifr_addr={sa_family=AF_INET, "
90*cf84ac9aSAndroid Build Coastguard Worker 			       "sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}"
91*cf84ac9aSAndroid Build Coastguard Worker 			       "}", ifr->ifr_name, ntohs(sa_in->sin_port),
92*cf84ac9aSAndroid Build Coastguard Worker 			       inet_ntoa(sa_in->sin_addr));
93*cf84ac9aSAndroid Build Coastguard Worker 		}
94*cf84ac9aSAndroid Build Coastguard Worker 
95*cf84ac9aSAndroid Build Coastguard Worker 		if ((size_t) (ifc->ifc_len - i) >= sizeof(struct ifreq))
96*cf84ac9aSAndroid Build Coastguard Worker 			printf(", ...");
97*cf84ac9aSAndroid Build Coastguard Worker 
98*cf84ac9aSAndroid Build Coastguard Worker 		printf("]");
99*cf84ac9aSAndroid Build Coastguard Worker 	}
100*cf84ac9aSAndroid Build Coastguard Worker 
101*cf84ac9aSAndroid Build Coastguard Worker 	printf("}");
102*cf84ac9aSAndroid Build Coastguard Worker }
103*cf84ac9aSAndroid Build Coastguard Worker 
104*cf84ac9aSAndroid Build Coastguard Worker static void
gifconf_ioctl(int fd,struct ifconf * ifc,bool ifc_valid)105*cf84ac9aSAndroid Build Coastguard Worker gifconf_ioctl(int fd, struct ifconf *ifc, bool ifc_valid)
106*cf84ac9aSAndroid Build Coastguard Worker {
107*cf84ac9aSAndroid Build Coastguard Worker 	const char *errstr;
108*cf84ac9aSAndroid Build Coastguard Worker 	int in_len;
109*cf84ac9aSAndroid Build Coastguard Worker 	char *in_buf;
110*cf84ac9aSAndroid Build Coastguard Worker 	long rc;
111*cf84ac9aSAndroid Build Coastguard Worker 
112*cf84ac9aSAndroid Build Coastguard Worker 	if (ifc_valid) {
113*cf84ac9aSAndroid Build Coastguard Worker 		in_len = ifc->ifc_len;
114*cf84ac9aSAndroid Build Coastguard Worker 		in_buf = ifc->ifc_buf;
115*cf84ac9aSAndroid Build Coastguard Worker 	}
116*cf84ac9aSAndroid Build Coastguard Worker 
117*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, SIOCGIFCONF, ifc);
118*cf84ac9aSAndroid Build Coastguard Worker 	errstr = sprintrc(rc);
119*cf84ac9aSAndroid Build Coastguard Worker 
120*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, SIOCGIFCONF, ", fd);
121*cf84ac9aSAndroid Build Coastguard Worker 	if (ifc_valid) {
122*cf84ac9aSAndroid Build Coastguard Worker 		print_ifconf(ifc, in_len, in_buf, rc);
123*cf84ac9aSAndroid Build Coastguard Worker 	} else {
124*cf84ac9aSAndroid Build Coastguard Worker 		if (ifc)
125*cf84ac9aSAndroid Build Coastguard Worker 			printf("%p", ifc);
126*cf84ac9aSAndroid Build Coastguard Worker 		else
127*cf84ac9aSAndroid Build Coastguard Worker 			printf("NULL");
128*cf84ac9aSAndroid Build Coastguard Worker 	}
129*cf84ac9aSAndroid Build Coastguard Worker 
130*cf84ac9aSAndroid Build Coastguard Worker 	printf(") = %s\n", errstr);
131*cf84ac9aSAndroid Build Coastguard Worker }
132*cf84ac9aSAndroid Build Coastguard Worker 
133*cf84ac9aSAndroid Build Coastguard Worker int
main(int argc,char * argv[])134*cf84ac9aSAndroid Build Coastguard Worker main(int argc, char *argv[])
135*cf84ac9aSAndroid Build Coastguard Worker {
136*cf84ac9aSAndroid Build Coastguard Worker 	struct ifreq *ifr = tail_alloc(2 * sizeof(*ifr));
137*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(struct ifconf, ifc);
138*cf84ac9aSAndroid Build Coastguard Worker 
139*cf84ac9aSAndroid Build Coastguard Worker 	struct sockaddr_in addr;
140*cf84ac9aSAndroid Build Coastguard Worker 	int fd;
141*cf84ac9aSAndroid Build Coastguard Worker 
142*cf84ac9aSAndroid Build Coastguard Worker 	memset(&addr, 0, sizeof(addr));
143*cf84ac9aSAndroid Build Coastguard Worker 	addr.sin_family = AF_INET;
144*cf84ac9aSAndroid Build Coastguard Worker 	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
145*cf84ac9aSAndroid Build Coastguard Worker 
146*cf84ac9aSAndroid Build Coastguard Worker 	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
147*cf84ac9aSAndroid Build Coastguard Worker 		perror_msg_and_skip("socket AF_INET");
148*cf84ac9aSAndroid Build Coastguard Worker 
149*cf84ac9aSAndroid Build Coastguard Worker 	gifconf_ioctl(fd, NULL, false);
150*cf84ac9aSAndroid Build Coastguard Worker 	gifconf_ioctl(fd, ifc + 1, false);
151*cf84ac9aSAndroid Build Coastguard Worker 
152*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_len = 3141592653U;
153*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_buf = NULL;
154*cf84ac9aSAndroid Build Coastguard Worker 	gifconf_ioctl(fd, ifc, true);
155*cf84ac9aSAndroid Build Coastguard Worker 
156*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_len = 0;
157*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_buf = (char *) (ifr + 2);
158*cf84ac9aSAndroid Build Coastguard Worker 	gifconf_ioctl(fd, ifc, true);
159*cf84ac9aSAndroid Build Coastguard Worker 
160*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_len = 1;
161*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_buf = (char *) (ifr + 1);
162*cf84ac9aSAndroid Build Coastguard Worker 	gifconf_ioctl(fd, ifc, true);
163*cf84ac9aSAndroid Build Coastguard Worker 
164*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_len = 1 * sizeof(*ifr);
165*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_buf = (char *) (ifr + 1);
166*cf84ac9aSAndroid Build Coastguard Worker 	gifconf_ioctl(fd, ifc, true);
167*cf84ac9aSAndroid Build Coastguard Worker 
168*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_len = 2 * sizeof(*ifr);
169*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_buf = (char *) (ifr + 1);
170*cf84ac9aSAndroid Build Coastguard Worker 	gifconf_ioctl(fd, ifc, true);
171*cf84ac9aSAndroid Build Coastguard Worker 
172*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_len = 2 * sizeof(*ifr) + 2;
173*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_buf = (char *) ifr;
174*cf84ac9aSAndroid Build Coastguard Worker 	gifconf_ioctl(fd, ifc, true);
175*cf84ac9aSAndroid Build Coastguard Worker 
176*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_len = 3 * sizeof(*ifr) + 4;
177*cf84ac9aSAndroid Build Coastguard Worker 	ifc->ifc_buf = (char *) ifr;
178*cf84ac9aSAndroid Build Coastguard Worker 	gifconf_ioctl(fd, ifc, true);
179*cf84ac9aSAndroid Build Coastguard Worker 
180*cf84ac9aSAndroid Build Coastguard Worker 	puts("+++ exited with 0 +++");
181*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
182*cf84ac9aSAndroid Build Coastguard Worker }
183