blob: ef6def454a39c81607f11ea9d90f153c1d6442c7 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000026 */
27
28#include "defs.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000029#include <sys/socket.h>
Roland McGrath5687ff12004-07-12 07:13:06 +000030#include <linux/sockios.h>
Roland McGrath5687ff12004-07-12 07:13:06 +000031#include <arpa/inet.h>
Denys Vlasenkoc36c3522012-02-25 02:47:15 +010032#if defined(ALPHA) || defined(SH) || defined(SH64)
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010033# if defined(HAVE_SYS_IOCTL_H)
Denys Vlasenkoc36c3522012-02-25 02:47:15 +010034# include <sys/ioctl.h>
35# elif defined(HAVE_IOCTLS_H)
36# include <ioctls.h>
37# endif
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000038#endif
Roland McGrath5687ff12004-07-12 07:13:06 +000039#include <net/if.h>
40
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000041#include "xlat/iffflags.h"
Roland McGrathe6a432d2005-02-02 20:25:17 +000042
Roland McGrathe6a432d2005-02-02 20:25:17 +000043static void
Denys Vlasenko12014262011-05-30 14:00:14 +020044print_addr(struct tcb *tcp, long addr, struct ifreq *ifr)
Roland McGrathe6a432d2005-02-02 20:25:17 +000045{
46 if (ifr->ifr_addr.sa_family == AF_INET) {
47 struct sockaddr_in *sinp;
48 sinp = (struct sockaddr_in *) &ifr->ifr_addr;
49 tprintf("inet_addr(\"%s\")", inet_ntoa(sinp->sin_addr));
50 } else
51 printstr(tcp, addr, sizeof(ifr->ifr_addr.sa_data));
52}
53
Dmitry V. Levin81e45152015-01-24 20:58:23 +000054static void
55print_ifname(const char *ifname)
56{
57 print_quoted_string(ifname, IFNAMSIZ + 1, QUOTE_0_TERMINATED);
58}
59
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000060int
Dmitry V. Levinc7afb482015-01-19 18:44:21 +000061sock_ioctl(struct tcb *tcp, const unsigned int code, long arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000062{
Roland McGrath5687ff12004-07-12 07:13:06 +000063 struct ifreq ifr;
64 struct ifconf ifc;
Roland McGrathe6a432d2005-02-02 20:25:17 +000065 const char *str = NULL;
66 unsigned char *bytes;
Roland McGrath5687ff12004-07-12 07:13:06 +000067
68 if (entering(tcp)) {
Dmitry V. Levin788c0d62014-10-31 19:36:01 +000069 switch (code) {
70 case SIOCGIFCONF:
Dmitry V. Levin652e4482007-03-21 14:18:17 +000071 if (umove(tcp, tcp->u_arg[2], &ifc) >= 0
72 && ifc.ifc_buf == NULL)
Roland McGrath5687ff12004-07-12 07:13:06 +000073 tprintf(", {%d -> ", ifc.ifc_len);
74 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +020075 tprints(", {");
Dmitry V. Levin788c0d62014-10-31 19:36:01 +000076 break;
77 case SIOCSIFNAME:
78 if (umove(tcp, tcp->u_arg[2], &ifr) < 0)
79 tprintf(", %#lx", tcp->u_arg[2]);
Dmitry V. Levin81e45152015-01-24 20:58:23 +000080 else {
81 tprints(", {ifr_name=");
82 print_ifname(ifr.ifr_name);
83 tprints(", ifr_newname=");
84 print_ifname(ifr.ifr_newname);
85 tprints("}");
86 }
Dmitry V. Levin788c0d62014-10-31 19:36:01 +000087 break;
Roland McGrath5687ff12004-07-12 07:13:06 +000088 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000089 return 0;
Roland McGrath5687ff12004-07-12 07:13:06 +000090 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000091
92 switch (code) {
93#ifdef SIOCSHIWAT
94 case SIOCSHIWAT:
95#endif
96#ifdef SIOCGHIWAT
97 case SIOCGHIWAT:
98#endif
99#ifdef SIOCSLOWAT
100 case SIOCSLOWAT:
101#endif
102#ifdef SIOCGLOWAT
103 case SIOCGLOWAT:
104#endif
105#ifdef FIOSETOWN
106 case FIOSETOWN:
107#endif
108#ifdef FIOGETOWN
109 case FIOGETOWN:
110#endif
111#ifdef SIOCSPGRP
112 case SIOCSPGRP:
113#endif
114#ifdef SIOCGPGRP
115 case SIOCGPGRP:
116#endif
117#ifdef SIOCATMARK
118 case SIOCATMARK:
119#endif
120 printnum(tcp, arg, ", %#d");
Dmitry V. Levin788c0d62014-10-31 19:36:01 +0000121 case SIOCSIFNAME:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000122 return 1;
Roland McGrath5687ff12004-07-12 07:13:06 +0000123 case SIOCGIFNAME:
124 case SIOCGIFINDEX:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000125 case SIOCGIFADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000126 case SIOCSIFADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000127 case SIOCGIFDSTADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000128 case SIOCSIFDSTADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000129 case SIOCGIFBRDADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000130 case SIOCSIFBRDADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000131 case SIOCGIFNETMASK:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000132 case SIOCSIFNETMASK:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000133 case SIOCGIFFLAGS:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000134 case SIOCSIFFLAGS:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000135 case SIOCGIFMETRIC:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000136 case SIOCSIFMETRIC:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000137 case SIOCGIFMTU:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000138 case SIOCSIFMTU:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000139 case SIOCGIFSLAVE:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000140 case SIOCSIFSLAVE:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000141 case SIOCGIFHWADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000142 case SIOCSIFHWADDR:
Dmitry V. Levin40284242007-03-21 13:52:14 +0000143 case SIOCGIFTXQLEN:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000144 case SIOCSIFTXQLEN:
Dmitry V. Levinecdd0bb2007-03-21 13:57:50 +0000145 case SIOCGIFMAP:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000146 case SIOCSIFMAP:
Dmitry V. Levin652e4482007-03-21 14:18:17 +0000147 if (umove(tcp, tcp->u_arg[2], &ifr) < 0)
148 tprintf(", %#lx", tcp->u_arg[2]);
149 else if (syserror(tcp)) {
Mike Frysingerf27263d2014-10-21 08:34:08 -0400150 if (code == SIOCGIFNAME) {
151 tprintf(", {ifr_index=%d, ifr_name=???}",
152 ifr.ifr_ifindex);
153 } else {
Dmitry V. Levin81e45152015-01-24 20:58:23 +0000154 tprints(", {ifr_name=");
155 print_ifname(ifr.ifr_name);
156 tprints(", ???}");
Mike Frysingerf27263d2014-10-21 08:34:08 -0400157 }
158 } else if (code == SIOCGIFNAME) {
Dmitry V. Levin81e45152015-01-24 20:58:23 +0000159 tprintf(", {ifr_index=%d, ifr_name=", ifr.ifr_ifindex);
160 print_ifname(ifr.ifr_name);
161 tprints("}");
Mike Frysingerf27263d2014-10-21 08:34:08 -0400162 } else {
Dmitry V. Levin81e45152015-01-24 20:58:23 +0000163 tprints(", {ifr_name=");
164 print_ifname(ifr.ifr_name);
165 tprints(", ");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000166 switch (code) {
167 case SIOCGIFINDEX:
168 tprintf("ifr_index=%d", ifr.ifr_ifindex);
169 break;
170 case SIOCGIFADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000171 case SIOCSIFADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000172 str = "ifr_addr";
173 case SIOCGIFDSTADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000174 case SIOCSIFDSTADDR:
175 if (!str)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000176 str = "ifr_dstaddr";
177 case SIOCGIFBRDADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000178 case SIOCSIFBRDADDR:
179 if (!str)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000180 str = "ifr_broadaddr";
181 case SIOCGIFNETMASK:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000182 case SIOCSIFNETMASK:
183 if (!str)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000184 str = "ifr_netmask";
185 tprintf("%s={", str);
186 printxval(addrfams,
187 ifr.ifr_addr.sa_family,
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000188 "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200189 tprints(", ");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000190 print_addr(tcp, ((long) tcp->u_arg[2]
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200191 + offsetof(struct ifreq,
Roland McGrathe6a432d2005-02-02 20:25:17 +0000192 ifr_addr.sa_data)),
193 &ifr);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200194 tprints("}");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000195 break;
196 case SIOCGIFHWADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000197 case SIOCSIFHWADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000198 /* XXX Are there other hardware addresses
199 than 6-byte MACs? */
200 bytes = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
201 tprintf("ifr_hwaddr=%02x:%02x:%02x:%02x:%02x:%02x",
202 bytes[0], bytes[1], bytes[2],
203 bytes[3], bytes[4], bytes[5]);
204 break;
205 case SIOCGIFFLAGS:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000206 case SIOCSIFFLAGS:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200207 tprints("ifr_flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000208 printflags(iffflags, ifr.ifr_flags, "IFF_???");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000209 break;
210 case SIOCGIFMETRIC:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000211 case SIOCSIFMETRIC:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000212 tprintf("ifr_metric=%d", ifr.ifr_metric);
213 break;
214 case SIOCGIFMTU:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000215 case SIOCSIFMTU:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000216 tprintf("ifr_mtu=%d", ifr.ifr_mtu);
217 break;
218 case SIOCGIFSLAVE:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000219 case SIOCSIFSLAVE:
Dmitry V. Levin81e45152015-01-24 20:58:23 +0000220 tprints("ifr_slave=");
221 print_ifname(ifr.ifr_slave);
Roland McGrathe6a432d2005-02-02 20:25:17 +0000222 break;
Dmitry V. Levin40284242007-03-21 13:52:14 +0000223 case SIOCGIFTXQLEN:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000224 case SIOCSIFTXQLEN:
Dmitry V. Levin40284242007-03-21 13:52:14 +0000225 tprintf("ifr_qlen=%d", ifr.ifr_qlen);
226 break;
Dmitry V. Levinecdd0bb2007-03-21 13:57:50 +0000227 case SIOCGIFMAP:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000228 case SIOCSIFMAP:
Dmitry V. Levinecdd0bb2007-03-21 13:57:50 +0000229 tprintf("ifr_map={mem_start=%#lx, "
230 "mem_end=%#lx, base_addr=%#x, "
231 "irq=%u, dma=%u, port=%u}",
232 ifr.ifr_map.mem_start,
233 ifr.ifr_map.mem_end,
234 (unsigned) ifr.ifr_map.base_addr,
235 (unsigned) ifr.ifr_map.irq,
236 (unsigned) ifr.ifr_map.dma,
237 (unsigned) ifr.ifr_map.port);
238 break;
Roland McGrathe6a432d2005-02-02 20:25:17 +0000239 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200240 tprints("}");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000241 }
Roland McGrath5687ff12004-07-12 07:13:06 +0000242 return 1;
243 case SIOCGIFCONF:
Dmitry V. Levin652e4482007-03-21 14:18:17 +0000244 if (umove(tcp, tcp->u_arg[2], &ifc) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200245 tprints("???}");
Dmitry V. Levin652e4482007-03-21 14:18:17 +0000246 return 1;
247 }
Roland McGrath5687ff12004-07-12 07:13:06 +0000248 tprintf("%d, ", ifc.ifc_len);
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000249 if (syserror(tcp)) {
Roland McGrath5687ff12004-07-12 07:13:06 +0000250 tprintf("%lx", (unsigned long) ifc.ifc_buf);
251 } else if (ifc.ifc_buf == NULL) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200252 tprints("NULL");
Roland McGrath5687ff12004-07-12 07:13:06 +0000253 } else {
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000254 unsigned int i;
255 unsigned int nifra = ifc.ifc_len / sizeof(struct ifreq);
Roland McGrath5687ff12004-07-12 07:13:06 +0000256 struct ifreq ifra[nifra];
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000257
258 if (umoven(tcp, (unsigned long) ifc.ifc_buf,
259 sizeof(ifra), (char *) ifra) < 0) {
260 tprintf("%lx}", (unsigned long) ifc.ifc_buf);
261 return 1;
262 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200263 tprints("{");
Roland McGrath5687ff12004-07-12 07:13:06 +0000264 for (i = 0; i < nifra; ++i ) {
265 if (i > 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200266 tprints(", ");
Dmitry V. Levin81e45152015-01-24 20:58:23 +0000267 tprints("{");
268 print_ifname(ifra[i].ifr_newname);
269 tprints(", {");
Roland McGrath5687ff12004-07-12 07:13:06 +0000270 if (verbose(tcp)) {
271 printxval(addrfams,
272 ifra[i].ifr_addr.sa_family,
273 "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200274 tprints(", ");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000275 print_addr(tcp, ((long) tcp->u_arg[2]
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200276 + offsetof(struct ifreq,
Roland McGrathe6a432d2005-02-02 20:25:17 +0000277 ifr_addr.sa_data)
278 + ((char *) &ifra[i]
279 - (char *) &ifra[0])),
280 &ifra[i]);
Roland McGrath5687ff12004-07-12 07:13:06 +0000281 } else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200282 tprints("...");
283 tprints("}}");
Roland McGrath5687ff12004-07-12 07:13:06 +0000284 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200285 tprints("}");
Roland McGrath5687ff12004-07-12 07:13:06 +0000286 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200287 tprints("}");
Roland McGrath5687ff12004-07-12 07:13:06 +0000288 return 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000289 default:
290 return 0;
291 }
292}
Dmitry V. Levinb5e88d42012-02-20 17:02:38 +0000293
294int
295sys_socketcall(struct tcb *tcp)
296{
297 return printargs(tcp);
298}