blob: 9c6fe96e442d07945e5adff8794d5fcdaed61bdb [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
Roland McGrathe6a432d2005-02-02 20:25:17 +000041static const struct xlat iffflags[] = {
42 { IFF_UP, "IFF_UP" },
43 { IFF_BROADCAST, "IFF_BROADCAST" },
44 { IFF_DEBUG, "IFF_DEBUG" },
45 { IFF_LOOPBACK, "IFF_LOOPBACK" },
46 { IFF_POINTOPOINT, "IFF_POINTOPOINT" },
47 { IFF_NOTRAILERS, "IFF_NOTRAILERS" },
48 { IFF_RUNNING, "IFF_RUNNING" },
49 { IFF_NOARP, "IFF_NOARP" },
50 { IFF_PROMISC, "IFF_PROMISC" },
51 { IFF_ALLMULTI, "IFF_ALLMULTI" },
52 { IFF_MASTER, "IFF_MASTER" },
53 { IFF_SLAVE, "IFF_SLAVE" },
54 { IFF_MULTICAST, "IFF_MULTICAST" },
55 { IFF_PORTSEL, "IFF_PORTSEL" },
56 { IFF_AUTOMEDIA, "IFF_AUTOMEDIA" },
57 { 0, NULL }
58};
59
Roland McGrathe6a432d2005-02-02 20:25:17 +000060static void
Denys Vlasenko12014262011-05-30 14:00:14 +020061print_addr(struct tcb *tcp, long addr, struct ifreq *ifr)
Roland McGrathe6a432d2005-02-02 20:25:17 +000062{
63 if (ifr->ifr_addr.sa_family == AF_INET) {
64 struct sockaddr_in *sinp;
65 sinp = (struct sockaddr_in *) &ifr->ifr_addr;
66 tprintf("inet_addr(\"%s\")", inet_ntoa(sinp->sin_addr));
67 } else
68 printstr(tcp, addr, sizeof(ifr->ifr_addr.sa_data));
69}
70
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000071int
Dmitry V. Levin40284242007-03-21 13:52:14 +000072sock_ioctl(struct tcb *tcp, long code, long arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000073{
Roland McGrath5687ff12004-07-12 07:13:06 +000074 struct ifreq ifr;
75 struct ifconf ifc;
Roland McGrathe6a432d2005-02-02 20:25:17 +000076 const char *str = NULL;
77 unsigned char *bytes;
Roland McGrath5687ff12004-07-12 07:13:06 +000078
79 if (entering(tcp)) {
80 if (code == SIOCGIFCONF) {
Dmitry V. Levin652e4482007-03-21 14:18:17 +000081 if (umove(tcp, tcp->u_arg[2], &ifc) >= 0
82 && ifc.ifc_buf == NULL)
Roland McGrath5687ff12004-07-12 07:13:06 +000083 tprintf(", {%d -> ", ifc.ifc_len);
84 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +020085 tprints(", {");
Roland McGrath5687ff12004-07-12 07:13:06 +000086 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000087 return 0;
Roland McGrath5687ff12004-07-12 07:13:06 +000088 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000089
90 switch (code) {
91#ifdef SIOCSHIWAT
92 case SIOCSHIWAT:
93#endif
94#ifdef SIOCGHIWAT
95 case SIOCGHIWAT:
96#endif
97#ifdef SIOCSLOWAT
98 case SIOCSLOWAT:
99#endif
100#ifdef SIOCGLOWAT
101 case SIOCGLOWAT:
102#endif
103#ifdef FIOSETOWN
104 case FIOSETOWN:
105#endif
106#ifdef FIOGETOWN
107 case FIOGETOWN:
108#endif
109#ifdef SIOCSPGRP
110 case SIOCSPGRP:
111#endif
112#ifdef SIOCGPGRP
113 case SIOCGPGRP:
114#endif
115#ifdef SIOCATMARK
116 case SIOCATMARK:
117#endif
118 printnum(tcp, arg, ", %#d");
119 return 1;
Roland McGrath5687ff12004-07-12 07:13:06 +0000120 case SIOCGIFNAME:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000121 case SIOCSIFNAME:
Roland McGrath5687ff12004-07-12 07:13:06 +0000122 case SIOCGIFINDEX:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000123 case SIOCGIFADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000124 case SIOCSIFADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000125 case SIOCGIFDSTADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000126 case SIOCSIFDSTADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000127 case SIOCGIFBRDADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000128 case SIOCSIFBRDADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000129 case SIOCGIFNETMASK:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000130 case SIOCSIFNETMASK:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000131 case SIOCGIFFLAGS:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000132 case SIOCSIFFLAGS:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000133 case SIOCGIFMETRIC:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000134 case SIOCSIFMETRIC:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000135 case SIOCGIFMTU:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000136 case SIOCSIFMTU:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000137 case SIOCGIFSLAVE:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000138 case SIOCSIFSLAVE:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000139 case SIOCGIFHWADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000140 case SIOCSIFHWADDR:
Dmitry V. Levin40284242007-03-21 13:52:14 +0000141 case SIOCGIFTXQLEN:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000142 case SIOCSIFTXQLEN:
Dmitry V. Levinecdd0bb2007-03-21 13:57:50 +0000143 case SIOCGIFMAP:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000144 case SIOCSIFMAP:
Dmitry V. Levin652e4482007-03-21 14:18:17 +0000145 if (umove(tcp, tcp->u_arg[2], &ifr) < 0)
146 tprintf(", %#lx", tcp->u_arg[2]);
147 else if (syserror(tcp)) {
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000148 if (code == SIOCGIFNAME || code == SIOCSIFNAME)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000149 tprintf(", {ifr_index=%d, ifr_name=???}", ifr.ifr_ifindex);
150 else
151 tprintf(", {ifr_name=\"%s\", ???}", ifr.ifr_name);
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000152 } else if (code == SIOCGIFNAME || code == SIOCSIFNAME)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000153 tprintf(", {ifr_index=%d, ifr_name=\"%s\"}",
Roland McGrath5687ff12004-07-12 07:13:06 +0000154 ifr.ifr_ifindex, ifr.ifr_name);
Roland McGrathe6a432d2005-02-02 20:25:17 +0000155 else {
156 tprintf(", {ifr_name=\"%s\", ", ifr.ifr_name);
157 switch (code) {
158 case SIOCGIFINDEX:
159 tprintf("ifr_index=%d", ifr.ifr_ifindex);
160 break;
161 case SIOCGIFADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000162 case SIOCSIFADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000163 str = "ifr_addr";
164 case SIOCGIFDSTADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000165 case SIOCSIFDSTADDR:
166 if (!str)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000167 str = "ifr_dstaddr";
168 case SIOCGIFBRDADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000169 case SIOCSIFBRDADDR:
170 if (!str)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000171 str = "ifr_broadaddr";
172 case SIOCGIFNETMASK:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000173 case SIOCSIFNETMASK:
174 if (!str)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000175 str = "ifr_netmask";
176 tprintf("%s={", str);
177 printxval(addrfams,
178 ifr.ifr_addr.sa_family,
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000179 "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200180 tprints(", ");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000181 print_addr(tcp, ((long) tcp->u_arg[2]
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200182 + offsetof(struct ifreq,
Roland McGrathe6a432d2005-02-02 20:25:17 +0000183 ifr_addr.sa_data)),
184 &ifr);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200185 tprints("}");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000186 break;
187 case SIOCGIFHWADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000188 case SIOCSIFHWADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000189 /* XXX Are there other hardware addresses
190 than 6-byte MACs? */
191 bytes = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
192 tprintf("ifr_hwaddr=%02x:%02x:%02x:%02x:%02x:%02x",
193 bytes[0], bytes[1], bytes[2],
194 bytes[3], bytes[4], bytes[5]);
195 break;
196 case SIOCGIFFLAGS:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000197 case SIOCSIFFLAGS:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200198 tprints("ifr_flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000199 printflags(iffflags, ifr.ifr_flags, "IFF_???");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000200 break;
201 case SIOCGIFMETRIC:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000202 case SIOCSIFMETRIC:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000203 tprintf("ifr_metric=%d", ifr.ifr_metric);
204 break;
205 case SIOCGIFMTU:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000206 case SIOCSIFMTU:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000207 tprintf("ifr_mtu=%d", ifr.ifr_mtu);
208 break;
209 case SIOCGIFSLAVE:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000210 case SIOCSIFSLAVE:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000211 tprintf("ifr_slave=\"%s\"", ifr.ifr_slave);
212 break;
Dmitry V. Levin40284242007-03-21 13:52:14 +0000213 case SIOCGIFTXQLEN:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000214 case SIOCSIFTXQLEN:
Dmitry V. Levin40284242007-03-21 13:52:14 +0000215 tprintf("ifr_qlen=%d", ifr.ifr_qlen);
216 break;
Dmitry V. Levinecdd0bb2007-03-21 13:57:50 +0000217 case SIOCGIFMAP:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000218 case SIOCSIFMAP:
Dmitry V. Levinecdd0bb2007-03-21 13:57:50 +0000219 tprintf("ifr_map={mem_start=%#lx, "
220 "mem_end=%#lx, base_addr=%#x, "
221 "irq=%u, dma=%u, port=%u}",
222 ifr.ifr_map.mem_start,
223 ifr.ifr_map.mem_end,
224 (unsigned) ifr.ifr_map.base_addr,
225 (unsigned) ifr.ifr_map.irq,
226 (unsigned) ifr.ifr_map.dma,
227 (unsigned) ifr.ifr_map.port);
228 break;
Roland McGrathe6a432d2005-02-02 20:25:17 +0000229 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200230 tprints("}");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000231 }
Roland McGrath5687ff12004-07-12 07:13:06 +0000232 return 1;
233 case SIOCGIFCONF:
Dmitry V. Levin652e4482007-03-21 14:18:17 +0000234 if (umove(tcp, tcp->u_arg[2], &ifc) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200235 tprints("???}");
Dmitry V. Levin652e4482007-03-21 14:18:17 +0000236 return 1;
237 }
Roland McGrath5687ff12004-07-12 07:13:06 +0000238 tprintf("%d, ", ifc.ifc_len);
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000239 if (syserror(tcp)) {
Roland McGrath5687ff12004-07-12 07:13:06 +0000240 tprintf("%lx", (unsigned long) ifc.ifc_buf);
241 } else if (ifc.ifc_buf == NULL) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200242 tprints("NULL");
Roland McGrath5687ff12004-07-12 07:13:06 +0000243 } else {
244 int i;
245 unsigned nifra = ifc.ifc_len / sizeof(struct ifreq);
246 struct ifreq ifra[nifra];
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000247
248 if (umoven(tcp, (unsigned long) ifc.ifc_buf,
249 sizeof(ifra), (char *) ifra) < 0) {
250 tprintf("%lx}", (unsigned long) ifc.ifc_buf);
251 return 1;
252 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200253 tprints("{");
Roland McGrath5687ff12004-07-12 07:13:06 +0000254 for (i = 0; i < nifra; ++i ) {
255 if (i > 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200256 tprints(", ");
Roland McGrath5687ff12004-07-12 07:13:06 +0000257 tprintf("{\"%s\", {",
258 ifra[i].ifr_name);
259 if (verbose(tcp)) {
260 printxval(addrfams,
261 ifra[i].ifr_addr.sa_family,
262 "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200263 tprints(", ");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000264 print_addr(tcp, ((long) tcp->u_arg[2]
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200265 + offsetof(struct ifreq,
Roland McGrathe6a432d2005-02-02 20:25:17 +0000266 ifr_addr.sa_data)
267 + ((char *) &ifra[i]
268 - (char *) &ifra[0])),
269 &ifra[i]);
Roland McGrath5687ff12004-07-12 07:13:06 +0000270 } else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200271 tprints("...");
272 tprints("}}");
Roland McGrath5687ff12004-07-12 07:13:06 +0000273 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200274 tprints("}");
Roland McGrath5687ff12004-07-12 07:13:06 +0000275 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200276 tprints("}");
Roland McGrath5687ff12004-07-12 07:13:06 +0000277 return 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000278 default:
279 return 0;
280 }
281}
Dmitry V. Levinb5e88d42012-02-20 17:02:38 +0000282
283int
284sys_socketcall(struct tcb *tcp)
285{
286 return printargs(tcp);
287}