1 /* 2 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) 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 28 #include "defs.h" 29 #include <sys/socket.h> 30 #include <linux/sockios.h> 31 #include <arpa/inet.h> 32 #if defined(ALPHA) || defined(SH) || defined(SH64) 33 # if defined(HAVE_SYS_IOCTL_H) 34 # include <sys/ioctl.h> 35 # elif defined(HAVE_IOCTLS_H) 36 # include <ioctls.h> 37 # endif 38 #endif 39 #include <net/if.h> 40 41 #include "xlat/iffflags.h" 42 43 static void 44 print_addr(struct tcb *tcp, long addr, struct ifreq *ifr) 45 { 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 54 int 55 sock_ioctl(struct tcb *tcp, long code, long arg) 56 { 57 struct ifreq ifr; 58 struct ifconf ifc; 59 const char *str = NULL; 60 unsigned char *bytes; 61 62 if (entering(tcp)) { 63 if (code == SIOCGIFCONF) { 64 if (umove(tcp, tcp->u_arg[2], &ifc) >= 0 65 && ifc.ifc_buf == NULL) 66 tprintf(", {%d -> ", ifc.ifc_len); 67 else 68 tprints(", {"); 69 } 70 return 0; 71 } 72 73 switch (code) { 74 #ifdef SIOCSHIWAT 75 case SIOCSHIWAT: 76 #endif 77 #ifdef SIOCGHIWAT 78 case SIOCGHIWAT: 79 #endif 80 #ifdef SIOCSLOWAT 81 case SIOCSLOWAT: 82 #endif 83 #ifdef SIOCGLOWAT 84 case SIOCGLOWAT: 85 #endif 86 #ifdef FIOSETOWN 87 case FIOSETOWN: 88 #endif 89 #ifdef FIOGETOWN 90 case FIOGETOWN: 91 #endif 92 #ifdef SIOCSPGRP 93 case SIOCSPGRP: 94 #endif 95 #ifdef SIOCGPGRP 96 case SIOCGPGRP: 97 #endif 98 #ifdef SIOCATMARK 99 case SIOCATMARK: 100 #endif 101 printnum(tcp, arg, ", %#d"); 102 return 1; 103 case SIOCGIFNAME: 104 case SIOCSIFNAME: 105 case SIOCGIFINDEX: 106 case SIOCGIFADDR: 107 case SIOCSIFADDR: 108 case SIOCGIFDSTADDR: 109 case SIOCSIFDSTADDR: 110 case SIOCGIFBRDADDR: 111 case SIOCSIFBRDADDR: 112 case SIOCGIFNETMASK: 113 case SIOCSIFNETMASK: 114 case SIOCGIFFLAGS: 115 case SIOCSIFFLAGS: 116 case SIOCGIFMETRIC: 117 case SIOCSIFMETRIC: 118 case SIOCGIFMTU: 119 case SIOCSIFMTU: 120 case SIOCGIFSLAVE: 121 case SIOCSIFSLAVE: 122 case SIOCGIFHWADDR: 123 case SIOCSIFHWADDR: 124 case SIOCGIFTXQLEN: 125 case SIOCSIFTXQLEN: 126 case SIOCGIFMAP: 127 case SIOCSIFMAP: 128 if (umove(tcp, tcp->u_arg[2], &ifr) < 0) 129 tprintf(", %#lx", tcp->u_arg[2]); 130 else if (syserror(tcp)) { 131 if (code == SIOCGIFNAME || code == SIOCSIFNAME) 132 tprintf(", {ifr_index=%d, ifr_name=???}", ifr.ifr_ifindex); 133 else 134 tprintf(", {ifr_name=\"%s\", ???}", ifr.ifr_name); 135 } else if (code == SIOCGIFNAME || code == SIOCSIFNAME) 136 tprintf(", {ifr_index=%d, ifr_name=\"%s\"}", 137 ifr.ifr_ifindex, ifr.ifr_name); 138 else { 139 tprintf(", {ifr_name=\"%s\", ", ifr.ifr_name); 140 switch (code) { 141 case SIOCGIFINDEX: 142 tprintf("ifr_index=%d", ifr.ifr_ifindex); 143 break; 144 case SIOCGIFADDR: 145 case SIOCSIFADDR: 146 str = "ifr_addr"; 147 case SIOCGIFDSTADDR: 148 case SIOCSIFDSTADDR: 149 if (!str) 150 str = "ifr_dstaddr"; 151 case SIOCGIFBRDADDR: 152 case SIOCSIFBRDADDR: 153 if (!str) 154 str = "ifr_broadaddr"; 155 case SIOCGIFNETMASK: 156 case SIOCSIFNETMASK: 157 if (!str) 158 str = "ifr_netmask"; 159 tprintf("%s={", str); 160 printxval(addrfams, 161 ifr.ifr_addr.sa_family, 162 "AF_???"); 163 tprints(", "); 164 print_addr(tcp, ((long) tcp->u_arg[2] 165 + offsetof(struct ifreq, 166 ifr_addr.sa_data)), 167 &ifr); 168 tprints("}"); 169 break; 170 case SIOCGIFHWADDR: 171 case SIOCSIFHWADDR: 172 /* XXX Are there other hardware addresses 173 than 6-byte MACs? */ 174 bytes = (unsigned char *) &ifr.ifr_hwaddr.sa_data; 175 tprintf("ifr_hwaddr=%02x:%02x:%02x:%02x:%02x:%02x", 176 bytes[0], bytes[1], bytes[2], 177 bytes[3], bytes[4], bytes[5]); 178 break; 179 case SIOCGIFFLAGS: 180 case SIOCSIFFLAGS: 181 tprints("ifr_flags="); 182 printflags(iffflags, ifr.ifr_flags, "IFF_???"); 183 break; 184 case SIOCGIFMETRIC: 185 case SIOCSIFMETRIC: 186 tprintf("ifr_metric=%d", ifr.ifr_metric); 187 break; 188 case SIOCGIFMTU: 189 case SIOCSIFMTU: 190 tprintf("ifr_mtu=%d", ifr.ifr_mtu); 191 break; 192 case SIOCGIFSLAVE: 193 case SIOCSIFSLAVE: 194 tprintf("ifr_slave=\"%s\"", ifr.ifr_slave); 195 break; 196 case SIOCGIFTXQLEN: 197 case SIOCSIFTXQLEN: 198 tprintf("ifr_qlen=%d", ifr.ifr_qlen); 199 break; 200 case SIOCGIFMAP: 201 case SIOCSIFMAP: 202 tprintf("ifr_map={mem_start=%#lx, " 203 "mem_end=%#lx, base_addr=%#x, " 204 "irq=%u, dma=%u, port=%u}", 205 ifr.ifr_map.mem_start, 206 ifr.ifr_map.mem_end, 207 (unsigned) ifr.ifr_map.base_addr, 208 (unsigned) ifr.ifr_map.irq, 209 (unsigned) ifr.ifr_map.dma, 210 (unsigned) ifr.ifr_map.port); 211 break; 212 } 213 tprints("}"); 214 } 215 return 1; 216 case SIOCGIFCONF: 217 if (umove(tcp, tcp->u_arg[2], &ifc) < 0) { 218 tprints("???}"); 219 return 1; 220 } 221 tprintf("%d, ", ifc.ifc_len); 222 if (syserror(tcp)) { 223 tprintf("%lx", (unsigned long) ifc.ifc_buf); 224 } else if (ifc.ifc_buf == NULL) { 225 tprints("NULL"); 226 } else { 227 int i; 228 unsigned nifra = ifc.ifc_len / sizeof(struct ifreq); 229 struct ifreq ifra[nifra]; 230 231 if (umoven(tcp, (unsigned long) ifc.ifc_buf, 232 sizeof(ifra), (char *) ifra) < 0) { 233 tprintf("%lx}", (unsigned long) ifc.ifc_buf); 234 return 1; 235 } 236 tprints("{"); 237 for (i = 0; i < nifra; ++i ) { 238 if (i > 0) 239 tprints(", "); 240 tprintf("{\"%s\", {", 241 ifra[i].ifr_name); 242 if (verbose(tcp)) { 243 printxval(addrfams, 244 ifra[i].ifr_addr.sa_family, 245 "AF_???"); 246 tprints(", "); 247 print_addr(tcp, ((long) tcp->u_arg[2] 248 + offsetof(struct ifreq, 249 ifr_addr.sa_data) 250 + ((char *) &ifra[i] 251 - (char *) &ifra[0])), 252 &ifra[i]); 253 } else 254 tprints("..."); 255 tprints("}}"); 256 } 257 tprints("}"); 258 } 259 tprints("}"); 260 return 1; 261 default: 262 return 0; 263 } 264 } 265 266 int 267 sys_socketcall(struct tcb *tcp) 268 { 269 return printargs(tcp); 270 } 271