blob: ec2022384658fe6771289fce4bff1e9e18c0509d [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.
26 *
27 * $Id$
28 */
29
30#include "defs.h"
31
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000032#include <sys/socket.h>
Roland McGrath5687ff12004-07-12 07:13:06 +000033#include <linux/sockios.h>
Roland McGrath5687ff12004-07-12 07:13:06 +000034#include <arpa/inet.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000035
Denys Vlasenkoc36c3522012-02-25 02:47:15 +010036#if defined(ALPHA) || defined(SH) || defined(SH64)
37# ifdef HAVE_SYS_IOCTL_H
38# include <sys/ioctl.h>
39# elif defined(HAVE_IOCTLS_H)
40# include <ioctls.h>
41# endif
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000042#endif
Roland McGrath5687ff12004-07-12 07:13:06 +000043#include <net/if.h>
44
Roland McGrathe6a432d2005-02-02 20:25:17 +000045static const struct xlat iffflags[] = {
46 { IFF_UP, "IFF_UP" },
47 { IFF_BROADCAST, "IFF_BROADCAST" },
48 { IFF_DEBUG, "IFF_DEBUG" },
49 { IFF_LOOPBACK, "IFF_LOOPBACK" },
50 { IFF_POINTOPOINT, "IFF_POINTOPOINT" },
51 { IFF_NOTRAILERS, "IFF_NOTRAILERS" },
52 { IFF_RUNNING, "IFF_RUNNING" },
53 { IFF_NOARP, "IFF_NOARP" },
54 { IFF_PROMISC, "IFF_PROMISC" },
55 { IFF_ALLMULTI, "IFF_ALLMULTI" },
56 { IFF_MASTER, "IFF_MASTER" },
57 { IFF_SLAVE, "IFF_SLAVE" },
58 { IFF_MULTICAST, "IFF_MULTICAST" },
59 { IFF_PORTSEL, "IFF_PORTSEL" },
60 { IFF_AUTOMEDIA, "IFF_AUTOMEDIA" },
61 { 0, NULL }
62};
63
Roland McGrathe6a432d2005-02-02 20:25:17 +000064static void
Denys Vlasenko12014262011-05-30 14:00:14 +020065print_addr(struct tcb *tcp, long addr, struct ifreq *ifr)
Roland McGrathe6a432d2005-02-02 20:25:17 +000066{
67 if (ifr->ifr_addr.sa_family == AF_INET) {
68 struct sockaddr_in *sinp;
69 sinp = (struct sockaddr_in *) &ifr->ifr_addr;
70 tprintf("inet_addr(\"%s\")", inet_ntoa(sinp->sin_addr));
71 } else
72 printstr(tcp, addr, sizeof(ifr->ifr_addr.sa_data));
73}
74
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000075int
Dmitry V. Levin40284242007-03-21 13:52:14 +000076sock_ioctl(struct tcb *tcp, long code, long arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000077{
Roland McGrath5687ff12004-07-12 07:13:06 +000078 struct ifreq ifr;
79 struct ifconf ifc;
Roland McGrathe6a432d2005-02-02 20:25:17 +000080 const char *str = NULL;
81 unsigned char *bytes;
Roland McGrath5687ff12004-07-12 07:13:06 +000082
83 if (entering(tcp)) {
84 if (code == SIOCGIFCONF) {
Dmitry V. Levin652e4482007-03-21 14:18:17 +000085 if (umove(tcp, tcp->u_arg[2], &ifc) >= 0
86 && ifc.ifc_buf == NULL)
Roland McGrath5687ff12004-07-12 07:13:06 +000087 tprintf(", {%d -> ", ifc.ifc_len);
88 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +020089 tprints(", {");
Roland McGrath5687ff12004-07-12 07:13:06 +000090 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000091 return 0;
Roland McGrath5687ff12004-07-12 07:13:06 +000092 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000093
94 switch (code) {
95#ifdef SIOCSHIWAT
96 case SIOCSHIWAT:
97#endif
98#ifdef SIOCGHIWAT
99 case SIOCGHIWAT:
100#endif
101#ifdef SIOCSLOWAT
102 case SIOCSLOWAT:
103#endif
104#ifdef SIOCGLOWAT
105 case SIOCGLOWAT:
106#endif
107#ifdef FIOSETOWN
108 case FIOSETOWN:
109#endif
110#ifdef FIOGETOWN
111 case FIOGETOWN:
112#endif
113#ifdef SIOCSPGRP
114 case SIOCSPGRP:
115#endif
116#ifdef SIOCGPGRP
117 case SIOCGPGRP:
118#endif
119#ifdef SIOCATMARK
120 case SIOCATMARK:
121#endif
122 printnum(tcp, arg, ", %#d");
123 return 1;
Roland McGrath5687ff12004-07-12 07:13:06 +0000124 case SIOCGIFNAME:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000125 case SIOCSIFNAME:
Roland McGrath5687ff12004-07-12 07:13:06 +0000126 case SIOCGIFINDEX:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000127 case SIOCGIFADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000128 case SIOCSIFADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000129 case SIOCGIFDSTADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000130 case SIOCSIFDSTADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000131 case SIOCGIFBRDADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000132 case SIOCSIFBRDADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000133 case SIOCGIFNETMASK:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000134 case SIOCSIFNETMASK:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000135 case SIOCGIFFLAGS:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000136 case SIOCSIFFLAGS:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000137 case SIOCGIFMETRIC:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000138 case SIOCSIFMETRIC:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000139 case SIOCGIFMTU:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000140 case SIOCSIFMTU:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000141 case SIOCGIFSLAVE:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000142 case SIOCSIFSLAVE:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000143 case SIOCGIFHWADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000144 case SIOCSIFHWADDR:
Dmitry V. Levin40284242007-03-21 13:52:14 +0000145 case SIOCGIFTXQLEN:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000146 case SIOCSIFTXQLEN:
Dmitry V. Levinecdd0bb2007-03-21 13:57:50 +0000147 case SIOCGIFMAP:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000148 case SIOCSIFMAP:
Dmitry V. Levin652e4482007-03-21 14:18:17 +0000149 if (umove(tcp, tcp->u_arg[2], &ifr) < 0)
150 tprintf(", %#lx", tcp->u_arg[2]);
151 else if (syserror(tcp)) {
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000152 if (code == SIOCGIFNAME || code == SIOCSIFNAME)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000153 tprintf(", {ifr_index=%d, ifr_name=???}", ifr.ifr_ifindex);
154 else
155 tprintf(", {ifr_name=\"%s\", ???}", ifr.ifr_name);
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000156 } else if (code == SIOCGIFNAME || code == SIOCSIFNAME)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000157 tprintf(", {ifr_index=%d, ifr_name=\"%s\"}",
Roland McGrath5687ff12004-07-12 07:13:06 +0000158 ifr.ifr_ifindex, ifr.ifr_name);
Roland McGrathe6a432d2005-02-02 20:25:17 +0000159 else {
160 tprintf(", {ifr_name=\"%s\", ", ifr.ifr_name);
161 switch (code) {
162 case SIOCGIFINDEX:
163 tprintf("ifr_index=%d", ifr.ifr_ifindex);
164 break;
165 case SIOCGIFADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000166 case SIOCSIFADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000167 str = "ifr_addr";
168 case SIOCGIFDSTADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000169 case SIOCSIFDSTADDR:
170 if (!str)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000171 str = "ifr_dstaddr";
172 case SIOCGIFBRDADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000173 case SIOCSIFBRDADDR:
174 if (!str)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000175 str = "ifr_broadaddr";
176 case SIOCGIFNETMASK:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000177 case SIOCSIFNETMASK:
178 if (!str)
Roland McGrathe6a432d2005-02-02 20:25:17 +0000179 str = "ifr_netmask";
180 tprintf("%s={", str);
181 printxval(addrfams,
182 ifr.ifr_addr.sa_family,
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000183 "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200184 tprints(", ");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000185 print_addr(tcp, ((long) tcp->u_arg[2]
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200186 + offsetof(struct ifreq,
Roland McGrathe6a432d2005-02-02 20:25:17 +0000187 ifr_addr.sa_data)),
188 &ifr);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200189 tprints("}");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000190 break;
191 case SIOCGIFHWADDR:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000192 case SIOCSIFHWADDR:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000193 /* XXX Are there other hardware addresses
194 than 6-byte MACs? */
195 bytes = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
196 tprintf("ifr_hwaddr=%02x:%02x:%02x:%02x:%02x:%02x",
197 bytes[0], bytes[1], bytes[2],
198 bytes[3], bytes[4], bytes[5]);
199 break;
200 case SIOCGIFFLAGS:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000201 case SIOCSIFFLAGS:
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200202 tprints("ifr_flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000203 printflags(iffflags, ifr.ifr_flags, "IFF_???");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000204 break;
205 case SIOCGIFMETRIC:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000206 case SIOCSIFMETRIC:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000207 tprintf("ifr_metric=%d", ifr.ifr_metric);
208 break;
209 case SIOCGIFMTU:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000210 case SIOCSIFMTU:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000211 tprintf("ifr_mtu=%d", ifr.ifr_mtu);
212 break;
213 case SIOCGIFSLAVE:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000214 case SIOCSIFSLAVE:
Roland McGrathe6a432d2005-02-02 20:25:17 +0000215 tprintf("ifr_slave=\"%s\"", ifr.ifr_slave);
216 break;
Dmitry V. Levin40284242007-03-21 13:52:14 +0000217 case SIOCGIFTXQLEN:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000218 case SIOCSIFTXQLEN:
Dmitry V. Levin40284242007-03-21 13:52:14 +0000219 tprintf("ifr_qlen=%d", ifr.ifr_qlen);
220 break;
Dmitry V. Levinecdd0bb2007-03-21 13:57:50 +0000221 case SIOCGIFMAP:
Dmitry V. Levin5414bf72008-12-10 13:51:40 +0000222 case SIOCSIFMAP:
Dmitry V. Levinecdd0bb2007-03-21 13:57:50 +0000223 tprintf("ifr_map={mem_start=%#lx, "
224 "mem_end=%#lx, base_addr=%#x, "
225 "irq=%u, dma=%u, port=%u}",
226 ifr.ifr_map.mem_start,
227 ifr.ifr_map.mem_end,
228 (unsigned) ifr.ifr_map.base_addr,
229 (unsigned) ifr.ifr_map.irq,
230 (unsigned) ifr.ifr_map.dma,
231 (unsigned) ifr.ifr_map.port);
232 break;
Roland McGrathe6a432d2005-02-02 20:25:17 +0000233 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200234 tprints("}");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000235 }
Roland McGrath5687ff12004-07-12 07:13:06 +0000236 return 1;
237 case SIOCGIFCONF:
Dmitry V. Levin652e4482007-03-21 14:18:17 +0000238 if (umove(tcp, tcp->u_arg[2], &ifc) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200239 tprints("???}");
Dmitry V. Levin652e4482007-03-21 14:18:17 +0000240 return 1;
241 }
Roland McGrath5687ff12004-07-12 07:13:06 +0000242 tprintf("%d, ", ifc.ifc_len);
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000243 if (syserror(tcp)) {
Roland McGrath5687ff12004-07-12 07:13:06 +0000244 tprintf("%lx", (unsigned long) ifc.ifc_buf);
245 } else if (ifc.ifc_buf == NULL) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200246 tprints("NULL");
Roland McGrath5687ff12004-07-12 07:13:06 +0000247 } else {
248 int i;
249 unsigned nifra = ifc.ifc_len / sizeof(struct ifreq);
250 struct ifreq ifra[nifra];
Dmitry V. Levin62e05962009-11-03 14:38:44 +0000251
252 if (umoven(tcp, (unsigned long) ifc.ifc_buf,
253 sizeof(ifra), (char *) ifra) < 0) {
254 tprintf("%lx}", (unsigned long) ifc.ifc_buf);
255 return 1;
256 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200257 tprints("{");
Roland McGrath5687ff12004-07-12 07:13:06 +0000258 for (i = 0; i < nifra; ++i ) {
259 if (i > 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200260 tprints(", ");
Roland McGrath5687ff12004-07-12 07:13:06 +0000261 tprintf("{\"%s\", {",
262 ifra[i].ifr_name);
263 if (verbose(tcp)) {
264 printxval(addrfams,
265 ifra[i].ifr_addr.sa_family,
266 "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200267 tprints(", ");
Roland McGrathe6a432d2005-02-02 20:25:17 +0000268 print_addr(tcp, ((long) tcp->u_arg[2]
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200269 + offsetof(struct ifreq,
Roland McGrathe6a432d2005-02-02 20:25:17 +0000270 ifr_addr.sa_data)
271 + ((char *) &ifra[i]
272 - (char *) &ifra[0])),
273 &ifra[i]);
Roland McGrath5687ff12004-07-12 07:13:06 +0000274 } else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200275 tprints("...");
276 tprints("}}");
Roland McGrath5687ff12004-07-12 07:13:06 +0000277 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200278 tprints("}");
Roland McGrath5687ff12004-07-12 07:13:06 +0000279 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200280 tprints("}");
Roland McGrath5687ff12004-07-12 07:13:06 +0000281 return 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000282 default:
283 return 0;
284 }
285}
Dmitry V. Levinb5e88d42012-02-20 17:02:38 +0000286
287int
288sys_socketcall(struct tcb *tcp)
289{
290 return printargs(tcp);
291}