2 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
3 * Copyright (c) 1996-2018 The strace developers.
6 * SPDX-License-Identifier: LGPL-2.1-or-later
10 #include "print_fields.h"
12 #include <sys/socket.h>
13 #if defined ALPHA || defined SH || defined SH64
14 # include <linux/ioctl.h>
16 #include <linux/sockios.h>
17 #include <arpa/inet.h>
20 #include DEF_MPERS_TYPE(struct_ifconf)
21 #include DEF_MPERS_TYPE(struct_ifreq)
23 typedef struct ifconf struct_ifconf;
24 typedef struct ifreq struct_ifreq;
28 #include "xlat/iffflags.h"
30 #define XLAT_MACROS_ONLY
31 #include "xlat/arp_hardware_types.h"
32 #undef XLAT_MACROS_ONLY
35 print_ifname(const char *ifname)
37 print_quoted_string(ifname, IFNAMSIZ + 1, QUOTE_0_TERMINATED);
41 print_ifreq(struct tcb *const tcp, const unsigned int code,
42 const kernel_ulong_t arg, const struct_ifreq *const ifr)
47 PRINT_FIELD_SOCKADDR("", *ifr, ifr_addr);
51 PRINT_FIELD_SOCKADDR("", *ifr, ifr_dstaddr);
55 PRINT_FIELD_SOCKADDR("", *ifr, ifr_broadaddr);
59 PRINT_FIELD_SOCKADDR("", *ifr, ifr_netmask);
63 PRINT_FIELD_XVAL("ifr_hwaddr={", ifr->ifr_hwaddr, sa_family,
64 arp_hardware_types, "ARPHRD_???");
65 PRINT_FIELD_HWADDR_SZ(", ", ifr->ifr_hwaddr, sa_data,
66 sizeof(ifr->ifr_hwaddr.sa_data),
67 ifr->ifr_hwaddr.sa_family);
73 tprints("ifr_flags=");
74 printflags(iffflags, (unsigned short) ifr->ifr_flags, "IFF_???");
78 tprintf("ifr_metric=%d", ifr->ifr_metric);
82 tprintf("ifr_mtu=%d", ifr->ifr_mtu);
86 tprints("ifr_slave=");
87 print_ifname(ifr->ifr_slave);
91 tprintf("ifr_qlen=%d", ifr->ifr_qlen);
95 tprintf("ifr_map={mem_start=%#" PRI_klx ", "
96 "mem_end=%#" PRI_klx ", base_addr=%#x, "
97 "irq=%u, dma=%u, port=%u}",
98 (kernel_ulong_t) ifr->ifr_map.mem_start,
99 (kernel_ulong_t) ifr->ifr_map.mem_end,
100 (unsigned) ifr->ifr_map.base_addr,
101 (unsigned) ifr->ifr_map.irq,
102 (unsigned) ifr->ifr_map.dma,
103 (unsigned) ifr->ifr_map.port);
109 print_ifc_len(int len)
111 const unsigned int n = (unsigned int) len / sizeof(struct_ifreq);
113 if (len < 0 || n * sizeof(struct_ifreq) != (unsigned int) len)
116 tprintf("%u * sizeof(struct ifreq)", n);
122 print_ifconf_ifreq(struct tcb *tcp, void *elem_buf, size_t elem_size,
125 struct_ifreq *ifr = elem_buf;
127 tprints("{ifr_name=");
128 print_ifname(ifr->ifr_name);
129 PRINT_FIELD_SOCKADDR(", ", *ifr, ifr_addr);
136 * There are two different modes of operation:
138 * - Get buffer size. In this case, the callee sets ifc_buf to NULL,
139 * and the kernel returns the buffer size in ifc_len.
140 * - Get actual data. In this case, the callee specifies the buffer address
141 * in ifc_buf and its size in ifc_len. The kernel fills the buffer with
142 * the data, and its amount is returned in ifc_len.
144 * Note that, technically, the whole struct ifconf is overwritten,
145 * so ifc_buf could be different on exit, but current ioctl handler
146 * implementation does not touch it.
149 decode_ifconf(struct tcb *const tcp, const kernel_ulong_t addr)
151 struct_ifconf *entering_ifc = NULL;
153 entering(tcp) ? malloc(sizeof(*ifc)) : alloca(sizeof(*ifc));
156 entering_ifc = get_tcb_priv_data(tcp);
159 error_func_msg("where is my ifconf?");
164 if (!ifc || umove(tcp, addr, ifc) < 0) {
172 * We failed to fetch the structure on exiting syscall,
173 * print whatever was fetched on entering syscall.
175 if (!entering_ifc->ifc_buf)
176 print_ifc_len(entering_ifc->ifc_len);
178 tprints(", ifc_buf=");
179 printaddr(ptr_to_kulong(entering_ifc->ifc_buf));
184 return RVAL_IOCTL_DECODED;
188 tprints(", {ifc_len=");
190 print_ifc_len(ifc->ifc_len);
192 set_tcb_priv_data(tcp, ifc, free);
199 if (entering_ifc->ifc_buf && (entering_ifc->ifc_len != ifc->ifc_len))
201 if (!entering_ifc->ifc_buf || (entering_ifc->ifc_len != ifc->ifc_len))
202 print_ifc_len(ifc->ifc_len);
204 tprints(", ifc_buf=");
206 if (!entering_ifc->ifc_buf || syserror(tcp)) {
207 printaddr(ptr_to_kulong(entering_ifc->ifc_buf));
208 if (entering_ifc->ifc_buf != ifc->ifc_buf) {
210 printaddr(ptr_to_kulong(ifc->ifc_buf));
215 print_array(tcp, ptr_to_kulong(ifc->ifc_buf),
216 ifc->ifc_len / sizeof(struct_ifreq),
218 tfetch_mem, print_ifconf_ifreq, NULL);
223 return RVAL_IOCTL_DECODED;
226 MPERS_PRINTER_DECL(int, sock_ioctl,
227 struct tcb *tcp, const unsigned int code,
228 const kernel_ulong_t arg)
234 return decode_ifconf(tcp, arg);
251 printnum_int(tcp, arg, "%d");
266 printnum_int(tcp, arg, "%d");
291 if (umove_or_printaddr(tcp, arg, &ifr))
294 tprints("{ifr_name=");
295 print_ifname(ifr.ifr_name);
297 if (code == SIOCSIFNAME) {
298 tprints("ifr_newname=");
299 print_ifname(ifr.ifr_newname);
301 print_ifreq(tcp, code, arg, &ifr);
321 if (umove_or_printaddr(tcp, arg, &ifr))
324 if (SIOCGIFNAME == code) {
325 tprintf("{ifr_index=%d", ifr.ifr_ifindex);
327 tprints("{ifr_name=");
328 print_ifname(ifr.ifr_name);
338 if (umove(tcp, arg, &ifr) < 0) {
343 if (SIOCGIFNAME == code) {
344 tprints("ifr_name=");
345 print_ifname(ifr.ifr_name);
347 print_ifreq(tcp, code, arg, &ifr);
357 return RVAL_IOCTL_DECODED;