xref: /aosp_15_r20/external/strace/sock.c (revision cf84ac9a129d8ea9952db616b4e9b904c4bdde56)
1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <[email protected]>
3*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 1996-2018 The strace developers.
4*cf84ac9aSAndroid Build Coastguard Worker  * All rights reserved.
5*cf84ac9aSAndroid Build Coastguard Worker  *
6*cf84ac9aSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
7*cf84ac9aSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
8*cf84ac9aSAndroid Build Coastguard Worker  * are met:
9*cf84ac9aSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
10*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
11*cf84ac9aSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
12*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
13*cf84ac9aSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
14*cf84ac9aSAndroid Build Coastguard Worker  * 3. The name of the author may not be used to endorse or promote products
15*cf84ac9aSAndroid Build Coastguard Worker  *    derived from this software without specific prior written permission.
16*cf84ac9aSAndroid Build Coastguard Worker  *
17*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18*cf84ac9aSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19*cf84ac9aSAndroid Build Coastguard Worker  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20*cf84ac9aSAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21*cf84ac9aSAndroid Build Coastguard Worker  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22*cf84ac9aSAndroid Build Coastguard Worker  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23*cf84ac9aSAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24*cf84ac9aSAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25*cf84ac9aSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*cf84ac9aSAndroid Build Coastguard Worker  */
28*cf84ac9aSAndroid Build Coastguard Worker 
29*cf84ac9aSAndroid Build Coastguard Worker #include "defs.h"
30*cf84ac9aSAndroid Build Coastguard Worker #include "print_fields.h"
31*cf84ac9aSAndroid Build Coastguard Worker 
32*cf84ac9aSAndroid Build Coastguard Worker #include <sys/socket.h>
33*cf84ac9aSAndroid Build Coastguard Worker #if defined ALPHA || defined SH || defined SH64
34*cf84ac9aSAndroid Build Coastguard Worker # include <linux/ioctl.h>
35*cf84ac9aSAndroid Build Coastguard Worker #endif
36*cf84ac9aSAndroid Build Coastguard Worker #include <linux/sockios.h>
37*cf84ac9aSAndroid Build Coastguard Worker #include <arpa/inet.h>
38*cf84ac9aSAndroid Build Coastguard Worker #include <net/if.h>
39*cf84ac9aSAndroid Build Coastguard Worker 
40*cf84ac9aSAndroid Build Coastguard Worker #include DEF_MPERS_TYPE(struct_ifconf)
41*cf84ac9aSAndroid Build Coastguard Worker #include DEF_MPERS_TYPE(struct_ifreq)
42*cf84ac9aSAndroid Build Coastguard Worker 
43*cf84ac9aSAndroid Build Coastguard Worker typedef struct ifconf struct_ifconf;
44*cf84ac9aSAndroid Build Coastguard Worker typedef struct ifreq struct_ifreq;
45*cf84ac9aSAndroid Build Coastguard Worker 
46*cf84ac9aSAndroid Build Coastguard Worker #include MPERS_DEFS
47*cf84ac9aSAndroid Build Coastguard Worker 
48*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/iffflags.h"
49*cf84ac9aSAndroid Build Coastguard Worker 
50*cf84ac9aSAndroid Build Coastguard Worker #define XLAT_MACROS_ONLY
51*cf84ac9aSAndroid Build Coastguard Worker # include "xlat/arp_hardware_types.h"
52*cf84ac9aSAndroid Build Coastguard Worker #undef XLAT_MACROS_ONLY
53*cf84ac9aSAndroid Build Coastguard Worker 
54*cf84ac9aSAndroid Build Coastguard Worker static void
print_ifname(const char * ifname)55*cf84ac9aSAndroid Build Coastguard Worker print_ifname(const char *ifname)
56*cf84ac9aSAndroid Build Coastguard Worker {
57*cf84ac9aSAndroid Build Coastguard Worker 	print_quoted_string(ifname, IFNAMSIZ + 1, QUOTE_0_TERMINATED);
58*cf84ac9aSAndroid Build Coastguard Worker }
59*cf84ac9aSAndroid Build Coastguard Worker 
60*cf84ac9aSAndroid Build Coastguard Worker DIAG_PUSH_IGNORE_OVERRIDE_INIT
61*cf84ac9aSAndroid Build Coastguard Worker 
62*cf84ac9aSAndroid Build Coastguard Worker static void
print_ifreq(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg,const struct_ifreq * const ifr)63*cf84ac9aSAndroid Build Coastguard Worker print_ifreq(struct tcb *const tcp, const unsigned int code,
64*cf84ac9aSAndroid Build Coastguard Worker 	    const kernel_ulong_t arg, const struct_ifreq *const ifr)
65*cf84ac9aSAndroid Build Coastguard Worker {
66*cf84ac9aSAndroid Build Coastguard Worker 	switch (code) {
67*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFADDR:
68*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFADDR:
69*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_SOCKADDR("", *ifr, ifr_addr);
70*cf84ac9aSAndroid Build Coastguard Worker 		break;
71*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFDSTADDR:
72*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFDSTADDR:
73*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_SOCKADDR("", *ifr, ifr_dstaddr);
74*cf84ac9aSAndroid Build Coastguard Worker 		break;
75*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFBRDADDR:
76*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFBRDADDR:
77*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_SOCKADDR("", *ifr, ifr_broadaddr);
78*cf84ac9aSAndroid Build Coastguard Worker 		break;
79*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFNETMASK:
80*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFNETMASK:
81*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_SOCKADDR("", *ifr, ifr_netmask);
82*cf84ac9aSAndroid Build Coastguard Worker 		break;
83*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFHWADDR:
84*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFHWADDR: {
85*cf84ac9aSAndroid Build Coastguard Worker 		static uint8_t hwaddr_sizes[] = {
86*cf84ac9aSAndroid Build Coastguard Worker 			[0 ... ARPHRD_IEEE802_TR] = 255,
87*cf84ac9aSAndroid Build Coastguard Worker 
88*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_NETROM]     =  7 /* AX25_ADDR_LEN */,
89*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_ETHER]      =  6 /* ETH_ALEN */,
90*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_EETHER - no actual devices in Linux */
91*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_AX25]       =  7 /* AX25_ADDR_LEN */,
92*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_PRONET - no actual devices in Linux */
93*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_CHAOS - no actual devices in Linux */
94*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IEEE802]    =  6 /* FC_ALEN */,
95*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_ARCNET]     =  1 /* ARCNET_ALEN */,
96*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_APPLETLK - no actual devices in Linux */
97*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_DLCI]       = sizeof(short),
98*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_ATM - no explicit setting */
99*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_METRICOM - no actual devices in Linux */
100*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IEEE1394]   = 16 /* FWNET_ALEN */,
101*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_EUI64]      =  8 /* EUI64_ADDR_LEN */,
102*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_INFINIBAND] = 20 /* INFINIBAND_ALEN */,
103*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_SLIP]       =  0,
104*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_CSLIP - no actual devices in Linux */
105*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_SLIP6 - no actual devices in Linux */
106*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_CSLIP6 - no actual devices in Linux */
107*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_RSRVD - no actual devices in Linux */
108*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_ADAPT - no actual devices in Linux */
109*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_ROSE]       =  5 /* ROSE_ADDR_LEN */,
110*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_X25]        =  0,
111*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_HWX25 - no actual devices in Linux */
112*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_CAN]        =  0,
113*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_PPP]        =  0,
114*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_CISCO - no actual devices in Linux */
115*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_LAPB - no actual devices in Linux */
116*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_DDCMP - no actual devices in Linux */
117*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_RAWHDLC]    =  0,
118*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_RAWIP]      =  0,
119*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_TUNNEL]     =  4 /* IPIP */,
120*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_TUNNEL6]    = 16 /* sizeof(struct in6_addr) */,
121*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_FRAD - no actual devices in Linux */
122*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_SKIP - no actual devices in Linux */
123*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_LOOPBACK]   =  6 /* ETH_ALEN */,
124*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_LOCALTLK]   =  1 /* LTALK_ALEN */,
125*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_FDDI]       =  6 /* FDDI_K_ALEN */,
126*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_BIF - no actual devices in Linux */
127*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_SIT]        =  4,
128*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IPDDP]      =  0,
129*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IPGRE]      =  4,
130*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_PIMREG]     =  0,
131*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_HIPPI]      =  6 /* HIPPI_ALEN */,
132*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_ASH - no actual devices in Linux */
133*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_ECONET - no actual devices in Linux */
134*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IRDA]       =  4 /* LAP_ALEN */,
135*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_FCPP - no actual devices in Linux */
136*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_FCAL - no actual devices in Linux */
137*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_FCPL - no actual devices in Linux */
138*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_FCFABRIC - no actual devices in Linux */
139*cf84ac9aSAndroid Build Coastguard Worker 			/* ARPHRD_IEEE802_TR - no actual devices in Linux */
140*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IEEE80211]  =  6 /* ETH_ALEN */,
141*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IEEE80211_PRISM] = 6 /* ETH_ALEN */,
142*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IEEE80211_RADIOTAP] = 6 /* ETH_ALEN */,
143*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IEEE802154]
144*cf84ac9aSAndroid Build Coastguard Worker 				= 8 /* IEEE802154_EXTENDED_ADDR_LEN */,
145*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IEEE802154_MONITOR]
146*cf84ac9aSAndroid Build Coastguard Worker 				= 8 /* IEEE802154_EXTENDED_ADDR_LEN */,
147*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_PHONET]     =  1,
148*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_PHONET_PIPE] = 1,
149*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_CAIF]       =  0,
150*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_IP6GRE]     = 16 /* sizeof(struct in6_addr) */,
151*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_NETLINK]    =  0,
152*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_6LOWPAN]    =  8 /* EUI64_ADDR_LEN */
153*cf84ac9aSAndroid Build Coastguard Worker 				/* ^ or ETH_ALEN, depending on lltype */,
154*cf84ac9aSAndroid Build Coastguard Worker 			[ARPHRD_VSOCKMON]   =  0,
155*cf84ac9aSAndroid Build Coastguard Worker 		};
156*cf84ac9aSAndroid Build Coastguard Worker 
157*cf84ac9aSAndroid Build Coastguard Worker 		uint16_t proto = ifr->ifr_hwaddr.sa_family;
158*cf84ac9aSAndroid Build Coastguard Worker 		uint8_t sz = (proto < ARRAY_SIZE(hwaddr_sizes))
159*cf84ac9aSAndroid Build Coastguard Worker 				? hwaddr_sizes[proto] : 255;
160*cf84ac9aSAndroid Build Coastguard Worker 
161*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_XVAL_SORTED_SIZED("ifr_hwaddr={", ifr->ifr_hwaddr,
162*cf84ac9aSAndroid Build Coastguard Worker 					      sa_family, arp_hardware_types,
163*cf84ac9aSAndroid Build Coastguard Worker 					      arp_hardware_types_size,
164*cf84ac9aSAndroid Build Coastguard Worker 					      "ARPHRD_???");
165*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_MAC_SZ(", ", ifr->ifr_hwaddr, sa_data,
166*cf84ac9aSAndroid Build Coastguard Worker 				   MIN(sizeof(ifr->ifr_hwaddr.sa_data), sz));
167*cf84ac9aSAndroid Build Coastguard Worker 		tprints("}");
168*cf84ac9aSAndroid Build Coastguard Worker 		break;
169*cf84ac9aSAndroid Build Coastguard Worker 	}
170*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFFLAGS:
171*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFFLAGS:
172*cf84ac9aSAndroid Build Coastguard Worker 		tprints("ifr_flags=");
173*cf84ac9aSAndroid Build Coastguard Worker 		printflags(iffflags, (unsigned short) ifr->ifr_flags, "IFF_???");
174*cf84ac9aSAndroid Build Coastguard Worker 		break;
175*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFMETRIC:
176*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFMETRIC:
177*cf84ac9aSAndroid Build Coastguard Worker 		tprintf("ifr_metric=%d", ifr->ifr_metric);
178*cf84ac9aSAndroid Build Coastguard Worker 		break;
179*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFMTU:
180*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFMTU:
181*cf84ac9aSAndroid Build Coastguard Worker 		tprintf("ifr_mtu=%d", ifr->ifr_mtu);
182*cf84ac9aSAndroid Build Coastguard Worker 		break;
183*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFSLAVE:
184*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFSLAVE:
185*cf84ac9aSAndroid Build Coastguard Worker 		tprints("ifr_slave=");
186*cf84ac9aSAndroid Build Coastguard Worker 		print_ifname(ifr->ifr_slave);
187*cf84ac9aSAndroid Build Coastguard Worker 		break;
188*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFTXQLEN:
189*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFTXQLEN:
190*cf84ac9aSAndroid Build Coastguard Worker 		tprintf("ifr_qlen=%d", ifr->ifr_qlen);
191*cf84ac9aSAndroid Build Coastguard Worker 		break;
192*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFMAP:
193*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFMAP:
194*cf84ac9aSAndroid Build Coastguard Worker 		tprintf("ifr_map={mem_start=%#" PRI_klx ", "
195*cf84ac9aSAndroid Build Coastguard Worker 			"mem_end=%#" PRI_klx ", base_addr=%#x, "
196*cf84ac9aSAndroid Build Coastguard Worker 			"irq=%u, dma=%u, port=%u}",
197*cf84ac9aSAndroid Build Coastguard Worker 			(kernel_ulong_t) ifr->ifr_map.mem_start,
198*cf84ac9aSAndroid Build Coastguard Worker 			(kernel_ulong_t) ifr->ifr_map.mem_end,
199*cf84ac9aSAndroid Build Coastguard Worker 			(unsigned) ifr->ifr_map.base_addr,
200*cf84ac9aSAndroid Build Coastguard Worker 			(unsigned) ifr->ifr_map.irq,
201*cf84ac9aSAndroid Build Coastguard Worker 			(unsigned) ifr->ifr_map.dma,
202*cf84ac9aSAndroid Build Coastguard Worker 			(unsigned) ifr->ifr_map.port);
203*cf84ac9aSAndroid Build Coastguard Worker 		break;
204*cf84ac9aSAndroid Build Coastguard Worker 	}
205*cf84ac9aSAndroid Build Coastguard Worker }
206*cf84ac9aSAndroid Build Coastguard Worker 
207*cf84ac9aSAndroid Build Coastguard Worker DIAG_POP_IGNORE_OVERRIDE_INIT
208*cf84ac9aSAndroid Build Coastguard Worker 
209*cf84ac9aSAndroid Build Coastguard Worker static unsigned int
print_ifc_len(int len)210*cf84ac9aSAndroid Build Coastguard Worker print_ifc_len(int len)
211*cf84ac9aSAndroid Build Coastguard Worker {
212*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned int n = (unsigned int) len / sizeof(struct_ifreq);
213*cf84ac9aSAndroid Build Coastguard Worker 
214*cf84ac9aSAndroid Build Coastguard Worker 	if (len < 0 || n * sizeof(struct_ifreq) != (unsigned int) len)
215*cf84ac9aSAndroid Build Coastguard Worker 		tprintf("%d", len);
216*cf84ac9aSAndroid Build Coastguard Worker 	else
217*cf84ac9aSAndroid Build Coastguard Worker 		tprintf("%u * sizeof(struct ifreq)", n);
218*cf84ac9aSAndroid Build Coastguard Worker 
219*cf84ac9aSAndroid Build Coastguard Worker 	return n;
220*cf84ac9aSAndroid Build Coastguard Worker }
221*cf84ac9aSAndroid Build Coastguard Worker 
222*cf84ac9aSAndroid Build Coastguard Worker static bool
print_ifconf_ifreq(struct tcb * tcp,void * elem_buf,size_t elem_size,void * dummy)223*cf84ac9aSAndroid Build Coastguard Worker print_ifconf_ifreq(struct tcb *tcp, void *elem_buf, size_t elem_size,
224*cf84ac9aSAndroid Build Coastguard Worker 		   void *dummy)
225*cf84ac9aSAndroid Build Coastguard Worker {
226*cf84ac9aSAndroid Build Coastguard Worker 	struct_ifreq *ifr = elem_buf;
227*cf84ac9aSAndroid Build Coastguard Worker 
228*cf84ac9aSAndroid Build Coastguard Worker 	tprints("{ifr_name=");
229*cf84ac9aSAndroid Build Coastguard Worker 	print_ifname(ifr->ifr_name);
230*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_SOCKADDR(", ", *ifr, ifr_addr);
231*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
232*cf84ac9aSAndroid Build Coastguard Worker 
233*cf84ac9aSAndroid Build Coastguard Worker 	return true;
234*cf84ac9aSAndroid Build Coastguard Worker }
235*cf84ac9aSAndroid Build Coastguard Worker 
236*cf84ac9aSAndroid Build Coastguard Worker /*
237*cf84ac9aSAndroid Build Coastguard Worker  * There are two different modes of operation:
238*cf84ac9aSAndroid Build Coastguard Worker  *
239*cf84ac9aSAndroid Build Coastguard Worker  * - Get buffer size.  In this case, the callee sets ifc_buf to NULL,
240*cf84ac9aSAndroid Build Coastguard Worker  *   and the kernel returns the buffer size in ifc_len.
241*cf84ac9aSAndroid Build Coastguard Worker  * - Get actual data.  In this case, the callee specifies the buffer address
242*cf84ac9aSAndroid Build Coastguard Worker  *   in ifc_buf and its size in ifc_len.  The kernel fills the buffer with
243*cf84ac9aSAndroid Build Coastguard Worker  *   the data, and its amount is returned in ifc_len.
244*cf84ac9aSAndroid Build Coastguard Worker  *
245*cf84ac9aSAndroid Build Coastguard Worker  * Note that, technically, the whole struct ifconf is overwritten,
246*cf84ac9aSAndroid Build Coastguard Worker  * so ifc_buf could be different on exit, but current ioctl handler
247*cf84ac9aSAndroid Build Coastguard Worker  * implementation does not touch it.
248*cf84ac9aSAndroid Build Coastguard Worker  */
249*cf84ac9aSAndroid Build Coastguard Worker static int
decode_ifconf(struct tcb * const tcp,const kernel_ulong_t addr)250*cf84ac9aSAndroid Build Coastguard Worker decode_ifconf(struct tcb *const tcp, const kernel_ulong_t addr)
251*cf84ac9aSAndroid Build Coastguard Worker {
252*cf84ac9aSAndroid Build Coastguard Worker 	struct_ifconf *entering_ifc = NULL;
253*cf84ac9aSAndroid Build Coastguard Worker 	struct_ifconf *ifc =
254*cf84ac9aSAndroid Build Coastguard Worker 		entering(tcp) ? malloc(sizeof(*ifc)) : alloca(sizeof(*ifc));
255*cf84ac9aSAndroid Build Coastguard Worker 
256*cf84ac9aSAndroid Build Coastguard Worker 	if (exiting(tcp)) {
257*cf84ac9aSAndroid Build Coastguard Worker 		entering_ifc = get_tcb_priv_data(tcp);
258*cf84ac9aSAndroid Build Coastguard Worker 
259*cf84ac9aSAndroid Build Coastguard Worker 		if (!entering_ifc) {
260*cf84ac9aSAndroid Build Coastguard Worker 			error_func_msg("where is my ifconf?");
261*cf84ac9aSAndroid Build Coastguard Worker 			return 0;
262*cf84ac9aSAndroid Build Coastguard Worker 		}
263*cf84ac9aSAndroid Build Coastguard Worker 	}
264*cf84ac9aSAndroid Build Coastguard Worker 
265*cf84ac9aSAndroid Build Coastguard Worker 	if (!ifc || umove(tcp, addr, ifc) < 0) {
266*cf84ac9aSAndroid Build Coastguard Worker 		if (entering(tcp)) {
267*cf84ac9aSAndroid Build Coastguard Worker 			free(ifc);
268*cf84ac9aSAndroid Build Coastguard Worker 
269*cf84ac9aSAndroid Build Coastguard Worker 			tprints(", ");
270*cf84ac9aSAndroid Build Coastguard Worker 			printaddr(addr);
271*cf84ac9aSAndroid Build Coastguard Worker 		} else {
272*cf84ac9aSAndroid Build Coastguard Worker 			/*
273*cf84ac9aSAndroid Build Coastguard Worker 			 * We failed to fetch the structure on exiting syscall,
274*cf84ac9aSAndroid Build Coastguard Worker 			 * print whatever was fetched on entering syscall.
275*cf84ac9aSAndroid Build Coastguard Worker 			 */
276*cf84ac9aSAndroid Build Coastguard Worker 			if (!entering_ifc->ifc_buf)
277*cf84ac9aSAndroid Build Coastguard Worker 				print_ifc_len(entering_ifc->ifc_len);
278*cf84ac9aSAndroid Build Coastguard Worker 
279*cf84ac9aSAndroid Build Coastguard Worker 			tprints(", ifc_buf=");
280*cf84ac9aSAndroid Build Coastguard Worker 			printaddr(ptr_to_kulong(entering_ifc->ifc_buf));
281*cf84ac9aSAndroid Build Coastguard Worker 
282*cf84ac9aSAndroid Build Coastguard Worker 			tprints("}");
283*cf84ac9aSAndroid Build Coastguard Worker 		}
284*cf84ac9aSAndroid Build Coastguard Worker 
285*cf84ac9aSAndroid Build Coastguard Worker 		return RVAL_IOCTL_DECODED;
286*cf84ac9aSAndroid Build Coastguard Worker 	}
287*cf84ac9aSAndroid Build Coastguard Worker 
288*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
289*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", {ifc_len=");
290*cf84ac9aSAndroid Build Coastguard Worker 		if (ifc->ifc_buf)
291*cf84ac9aSAndroid Build Coastguard Worker 			print_ifc_len(ifc->ifc_len);
292*cf84ac9aSAndroid Build Coastguard Worker 
293*cf84ac9aSAndroid Build Coastguard Worker 		set_tcb_priv_data(tcp, ifc, free);
294*cf84ac9aSAndroid Build Coastguard Worker 
295*cf84ac9aSAndroid Build Coastguard Worker 		return 0;
296*cf84ac9aSAndroid Build Coastguard Worker 	}
297*cf84ac9aSAndroid Build Coastguard Worker 
298*cf84ac9aSAndroid Build Coastguard Worker 	/* exiting */
299*cf84ac9aSAndroid Build Coastguard Worker 
300*cf84ac9aSAndroid Build Coastguard Worker 	if (entering_ifc->ifc_buf && (entering_ifc->ifc_len != ifc->ifc_len))
301*cf84ac9aSAndroid Build Coastguard Worker 		tprints(" => ");
302*cf84ac9aSAndroid Build Coastguard Worker 	if (!entering_ifc->ifc_buf || (entering_ifc->ifc_len != ifc->ifc_len))
303*cf84ac9aSAndroid Build Coastguard Worker 		print_ifc_len(ifc->ifc_len);
304*cf84ac9aSAndroid Build Coastguard Worker 
305*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", ifc_buf=");
306*cf84ac9aSAndroid Build Coastguard Worker 
307*cf84ac9aSAndroid Build Coastguard Worker 	if (!entering_ifc->ifc_buf || syserror(tcp)) {
308*cf84ac9aSAndroid Build Coastguard Worker 		printaddr(ptr_to_kulong(entering_ifc->ifc_buf));
309*cf84ac9aSAndroid Build Coastguard Worker 		if (entering_ifc->ifc_buf != ifc->ifc_buf) {
310*cf84ac9aSAndroid Build Coastguard Worker 			tprints(" => ");
311*cf84ac9aSAndroid Build Coastguard Worker 			printaddr(ptr_to_kulong(ifc->ifc_buf));
312*cf84ac9aSAndroid Build Coastguard Worker 		}
313*cf84ac9aSAndroid Build Coastguard Worker 	} else {
314*cf84ac9aSAndroid Build Coastguard Worker 		struct_ifreq ifr;
315*cf84ac9aSAndroid Build Coastguard Worker 
316*cf84ac9aSAndroid Build Coastguard Worker 		print_array(tcp, ptr_to_kulong(ifc->ifc_buf),
317*cf84ac9aSAndroid Build Coastguard Worker 			    ifc->ifc_len / sizeof(struct_ifreq),
318*cf84ac9aSAndroid Build Coastguard Worker 			    &ifr, sizeof(ifr),
319*cf84ac9aSAndroid Build Coastguard Worker 			    tfetch_mem, print_ifconf_ifreq, NULL);
320*cf84ac9aSAndroid Build Coastguard Worker 	}
321*cf84ac9aSAndroid Build Coastguard Worker 
322*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
323*cf84ac9aSAndroid Build Coastguard Worker 
324*cf84ac9aSAndroid Build Coastguard Worker 	return RVAL_IOCTL_DECODED;
325*cf84ac9aSAndroid Build Coastguard Worker }
326*cf84ac9aSAndroid Build Coastguard Worker 
MPERS_PRINTER_DECL(int,sock_ioctl,struct tcb * tcp,const unsigned int code,const kernel_ulong_t arg)327*cf84ac9aSAndroid Build Coastguard Worker MPERS_PRINTER_DECL(int, sock_ioctl,
328*cf84ac9aSAndroid Build Coastguard Worker 		   struct tcb *tcp, const unsigned int code,
329*cf84ac9aSAndroid Build Coastguard Worker 		   const kernel_ulong_t arg)
330*cf84ac9aSAndroid Build Coastguard Worker {
331*cf84ac9aSAndroid Build Coastguard Worker 	struct_ifreq ifr;
332*cf84ac9aSAndroid Build Coastguard Worker 
333*cf84ac9aSAndroid Build Coastguard Worker 	switch (code) {
334*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFCONF:
335*cf84ac9aSAndroid Build Coastguard Worker 		return decode_ifconf(tcp, arg);
336*cf84ac9aSAndroid Build Coastguard Worker 
337*cf84ac9aSAndroid Build Coastguard Worker #ifdef SIOCBRADDBR
338*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCBRADDBR:
339*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCBRDELBR:
340*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
341*cf84ac9aSAndroid Build Coastguard Worker 		printstr(tcp, arg);
342*cf84ac9aSAndroid Build Coastguard Worker 		break;
343*cf84ac9aSAndroid Build Coastguard Worker #endif
344*cf84ac9aSAndroid Build Coastguard Worker 
345*cf84ac9aSAndroid Build Coastguard Worker #ifdef FIOSETOWN
346*cf84ac9aSAndroid Build Coastguard Worker 	case FIOSETOWN:
347*cf84ac9aSAndroid Build Coastguard Worker #endif
348*cf84ac9aSAndroid Build Coastguard Worker #ifdef SIOCSPGRP
349*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSPGRP:
350*cf84ac9aSAndroid Build Coastguard Worker #endif
351*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
352*cf84ac9aSAndroid Build Coastguard Worker 		printnum_int(tcp, arg, "%d");
353*cf84ac9aSAndroid Build Coastguard Worker 		break;
354*cf84ac9aSAndroid Build Coastguard Worker 
355*cf84ac9aSAndroid Build Coastguard Worker #ifdef FIOGETOWN
356*cf84ac9aSAndroid Build Coastguard Worker 	case FIOGETOWN:
357*cf84ac9aSAndroid Build Coastguard Worker #endif
358*cf84ac9aSAndroid Build Coastguard Worker #ifdef SIOCGPGRP
359*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGPGRP:
360*cf84ac9aSAndroid Build Coastguard Worker #endif
361*cf84ac9aSAndroid Build Coastguard Worker #ifdef SIOCATMARK
362*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCATMARK:
363*cf84ac9aSAndroid Build Coastguard Worker #endif
364*cf84ac9aSAndroid Build Coastguard Worker 		if (entering(tcp))
365*cf84ac9aSAndroid Build Coastguard Worker 			return 0;
366*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
367*cf84ac9aSAndroid Build Coastguard Worker 		printnum_int(tcp, arg, "%d");
368*cf84ac9aSAndroid Build Coastguard Worker 		break;
369*cf84ac9aSAndroid Build Coastguard Worker 
370*cf84ac9aSAndroid Build Coastguard Worker #ifdef SIOCBRADDIF
371*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCBRADDIF:
372*cf84ac9aSAndroid Build Coastguard Worker #endif
373*cf84ac9aSAndroid Build Coastguard Worker #ifdef SIOCBRDELIF
374*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCBRDELIF:
375*cf84ac9aSAndroid Build Coastguard Worker #endif
376*cf84ac9aSAndroid Build Coastguard Worker 		/* no arguments */
377*cf84ac9aSAndroid Build Coastguard Worker 		break;
378*cf84ac9aSAndroid Build Coastguard Worker 
379*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFNAME:
380*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFADDR:
381*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFDSTADDR:
382*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFBRDADDR:
383*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFNETMASK:
384*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFFLAGS:
385*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFMETRIC:
386*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFMTU:
387*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFSLAVE:
388*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFHWADDR:
389*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFTXQLEN:
390*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCSIFMAP:
391*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
392*cf84ac9aSAndroid Build Coastguard Worker 		if (umove_or_printaddr(tcp, arg, &ifr))
393*cf84ac9aSAndroid Build Coastguard Worker 			break;
394*cf84ac9aSAndroid Build Coastguard Worker 
395*cf84ac9aSAndroid Build Coastguard Worker 		tprints("{ifr_name=");
396*cf84ac9aSAndroid Build Coastguard Worker 		print_ifname(ifr.ifr_name);
397*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
398*cf84ac9aSAndroid Build Coastguard Worker 		if (code == SIOCSIFNAME) {
399*cf84ac9aSAndroid Build Coastguard Worker 			tprints("ifr_newname=");
400*cf84ac9aSAndroid Build Coastguard Worker 			print_ifname(ifr.ifr_newname);
401*cf84ac9aSAndroid Build Coastguard Worker 		} else {
402*cf84ac9aSAndroid Build Coastguard Worker 			print_ifreq(tcp, code, arg, &ifr);
403*cf84ac9aSAndroid Build Coastguard Worker 		}
404*cf84ac9aSAndroid Build Coastguard Worker 		tprints("}");
405*cf84ac9aSAndroid Build Coastguard Worker 		break;
406*cf84ac9aSAndroid Build Coastguard Worker 
407*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFNAME:
408*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFINDEX:
409*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFADDR:
410*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFDSTADDR:
411*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFBRDADDR:
412*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFNETMASK:
413*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFFLAGS:
414*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFMETRIC:
415*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFMTU:
416*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFSLAVE:
417*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFHWADDR:
418*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFTXQLEN:
419*cf84ac9aSAndroid Build Coastguard Worker 	case SIOCGIFMAP:
420*cf84ac9aSAndroid Build Coastguard Worker 		if (entering(tcp)) {
421*cf84ac9aSAndroid Build Coastguard Worker 			tprints(", ");
422*cf84ac9aSAndroid Build Coastguard Worker 			if (umove_or_printaddr(tcp, arg, &ifr))
423*cf84ac9aSAndroid Build Coastguard Worker 				break;
424*cf84ac9aSAndroid Build Coastguard Worker 
425*cf84ac9aSAndroid Build Coastguard Worker 			if (SIOCGIFNAME == code) {
426*cf84ac9aSAndroid Build Coastguard Worker 				tprintf("{ifr_index=%d", ifr.ifr_ifindex);
427*cf84ac9aSAndroid Build Coastguard Worker 			} else {
428*cf84ac9aSAndroid Build Coastguard Worker 				tprints("{ifr_name=");
429*cf84ac9aSAndroid Build Coastguard Worker 				print_ifname(ifr.ifr_name);
430*cf84ac9aSAndroid Build Coastguard Worker 			}
431*cf84ac9aSAndroid Build Coastguard Worker 			return 0;
432*cf84ac9aSAndroid Build Coastguard Worker 		} else {
433*cf84ac9aSAndroid Build Coastguard Worker 			if (syserror(tcp)) {
434*cf84ac9aSAndroid Build Coastguard Worker 				tprints("}");
435*cf84ac9aSAndroid Build Coastguard Worker 				break;
436*cf84ac9aSAndroid Build Coastguard Worker 			}
437*cf84ac9aSAndroid Build Coastguard Worker 
438*cf84ac9aSAndroid Build Coastguard Worker 			tprints(", ");
439*cf84ac9aSAndroid Build Coastguard Worker 			if (umove(tcp, arg, &ifr) < 0) {
440*cf84ac9aSAndroid Build Coastguard Worker 				tprints("???}");
441*cf84ac9aSAndroid Build Coastguard Worker 				break;
442*cf84ac9aSAndroid Build Coastguard Worker 			}
443*cf84ac9aSAndroid Build Coastguard Worker 
444*cf84ac9aSAndroid Build Coastguard Worker 			if (SIOCGIFNAME == code) {
445*cf84ac9aSAndroid Build Coastguard Worker 				tprints("ifr_name=");
446*cf84ac9aSAndroid Build Coastguard Worker 				print_ifname(ifr.ifr_name);
447*cf84ac9aSAndroid Build Coastguard Worker 			} else {
448*cf84ac9aSAndroid Build Coastguard Worker 				print_ifreq(tcp, code, arg, &ifr);
449*cf84ac9aSAndroid Build Coastguard Worker 			}
450*cf84ac9aSAndroid Build Coastguard Worker 			tprints("}");
451*cf84ac9aSAndroid Build Coastguard Worker 			break;
452*cf84ac9aSAndroid Build Coastguard Worker 		}
453*cf84ac9aSAndroid Build Coastguard Worker 
454*cf84ac9aSAndroid Build Coastguard Worker 	default:
455*cf84ac9aSAndroid Build Coastguard Worker 		return RVAL_DECODED;
456*cf84ac9aSAndroid Build Coastguard Worker 	}
457*cf84ac9aSAndroid Build Coastguard Worker 
458*cf84ac9aSAndroid Build Coastguard Worker 	return RVAL_IOCTL_DECODED;
459*cf84ac9aSAndroid Build Coastguard Worker }
460