sock.c revision 5dec78d0c2663930cd1bbcecbbcee47f68bc52f3
1/* 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 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 41static const struct xlat iffflags[] = { 42 XLAT(IFF_UP), 43 XLAT(IFF_BROADCAST), 44 XLAT(IFF_DEBUG), 45 XLAT(IFF_LOOPBACK), 46 XLAT(IFF_POINTOPOINT), 47 XLAT(IFF_NOTRAILERS), 48 XLAT(IFF_RUNNING), 49 XLAT(IFF_NOARP), 50 XLAT(IFF_PROMISC), 51 XLAT(IFF_ALLMULTI), 52 XLAT(IFF_MASTER), 53 XLAT(IFF_SLAVE), 54 XLAT(IFF_MULTICAST), 55 XLAT(IFF_PORTSEL), 56 XLAT(IFF_AUTOMEDIA), 57 XLAT_END 58}; 59 60static void 61print_addr(struct tcb *tcp, long addr, struct ifreq *ifr) 62{ 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 71int 72sock_ioctl(struct tcb *tcp, long code, long arg) 73{ 74 struct ifreq ifr; 75 struct ifconf ifc; 76 const char *str = NULL; 77 unsigned char *bytes; 78 79 if (entering(tcp)) { 80 if (code == SIOCGIFCONF) { 81 if (umove(tcp, tcp->u_arg[2], &ifc) >= 0 82 && ifc.ifc_buf == NULL) 83 tprintf(", {%d -> ", ifc.ifc_len); 84 else 85 tprints(", {"); 86 } 87 return 0; 88 } 89 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; 120 case SIOCGIFNAME: 121 case SIOCSIFNAME: 122 case SIOCGIFINDEX: 123 case SIOCGIFADDR: 124 case SIOCSIFADDR: 125 case SIOCGIFDSTADDR: 126 case SIOCSIFDSTADDR: 127 case SIOCGIFBRDADDR: 128 case SIOCSIFBRDADDR: 129 case SIOCGIFNETMASK: 130 case SIOCSIFNETMASK: 131 case SIOCGIFFLAGS: 132 case SIOCSIFFLAGS: 133 case SIOCGIFMETRIC: 134 case SIOCSIFMETRIC: 135 case SIOCGIFMTU: 136 case SIOCSIFMTU: 137 case SIOCGIFSLAVE: 138 case SIOCSIFSLAVE: 139 case SIOCGIFHWADDR: 140 case SIOCSIFHWADDR: 141 case SIOCGIFTXQLEN: 142 case SIOCSIFTXQLEN: 143 case SIOCGIFMAP: 144 case SIOCSIFMAP: 145 if (umove(tcp, tcp->u_arg[2], &ifr) < 0) 146 tprintf(", %#lx", tcp->u_arg[2]); 147 else if (syserror(tcp)) { 148 if (code == SIOCGIFNAME || code == SIOCSIFNAME) 149 tprintf(", {ifr_index=%d, ifr_name=???}", ifr.ifr_ifindex); 150 else 151 tprintf(", {ifr_name=\"%s\", ???}", ifr.ifr_name); 152 } else if (code == SIOCGIFNAME || code == SIOCSIFNAME) 153 tprintf(", {ifr_index=%d, ifr_name=\"%s\"}", 154 ifr.ifr_ifindex, ifr.ifr_name); 155 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: 162 case SIOCSIFADDR: 163 str = "ifr_addr"; 164 case SIOCGIFDSTADDR: 165 case SIOCSIFDSTADDR: 166 if (!str) 167 str = "ifr_dstaddr"; 168 case SIOCGIFBRDADDR: 169 case SIOCSIFBRDADDR: 170 if (!str) 171 str = "ifr_broadaddr"; 172 case SIOCGIFNETMASK: 173 case SIOCSIFNETMASK: 174 if (!str) 175 str = "ifr_netmask"; 176 tprintf("%s={", str); 177 printxval(addrfams, 178 ifr.ifr_addr.sa_family, 179 "AF_???"); 180 tprints(", "); 181 print_addr(tcp, ((long) tcp->u_arg[2] 182 + offsetof(struct ifreq, 183 ifr_addr.sa_data)), 184 &ifr); 185 tprints("}"); 186 break; 187 case SIOCGIFHWADDR: 188 case SIOCSIFHWADDR: 189 /* 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: 197 case SIOCSIFFLAGS: 198 tprints("ifr_flags="); 199 printflags(iffflags, ifr.ifr_flags, "IFF_???"); 200 break; 201 case SIOCGIFMETRIC: 202 case SIOCSIFMETRIC: 203 tprintf("ifr_metric=%d", ifr.ifr_metric); 204 break; 205 case SIOCGIFMTU: 206 case SIOCSIFMTU: 207 tprintf("ifr_mtu=%d", ifr.ifr_mtu); 208 break; 209 case SIOCGIFSLAVE: 210 case SIOCSIFSLAVE: 211 tprintf("ifr_slave=\"%s\"", ifr.ifr_slave); 212 break; 213 case SIOCGIFTXQLEN: 214 case SIOCSIFTXQLEN: 215 tprintf("ifr_qlen=%d", ifr.ifr_qlen); 216 break; 217 case SIOCGIFMAP: 218 case SIOCSIFMAP: 219 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; 229 } 230 tprints("}"); 231 } 232 return 1; 233 case SIOCGIFCONF: 234 if (umove(tcp, tcp->u_arg[2], &ifc) < 0) { 235 tprints("???}"); 236 return 1; 237 } 238 tprintf("%d, ", ifc.ifc_len); 239 if (syserror(tcp)) { 240 tprintf("%lx", (unsigned long) ifc.ifc_buf); 241 } else if (ifc.ifc_buf == NULL) { 242 tprints("NULL"); 243 } else { 244 int i; 245 unsigned nifra = ifc.ifc_len / sizeof(struct ifreq); 246 struct ifreq ifra[nifra]; 247 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 } 253 tprints("{"); 254 for (i = 0; i < nifra; ++i ) { 255 if (i > 0) 256 tprints(", "); 257 tprintf("{\"%s\", {", 258 ifra[i].ifr_name); 259 if (verbose(tcp)) { 260 printxval(addrfams, 261 ifra[i].ifr_addr.sa_family, 262 "AF_???"); 263 tprints(", "); 264 print_addr(tcp, ((long) tcp->u_arg[2] 265 + offsetof(struct ifreq, 266 ifr_addr.sa_data) 267 + ((char *) &ifra[i] 268 - (char *) &ifra[0])), 269 &ifra[i]); 270 } else 271 tprints("..."); 272 tprints("}}"); 273 } 274 tprints("}"); 275 } 276 tprints("}"); 277 return 1; 278 default: 279 return 0; 280 } 281} 282 283int 284sys_socketcall(struct tcb *tcp) 285{ 286 return printargs(tcp); 287} 288