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 * $Id: sock.c,v 1.11 2005/06/01 19:02:37 roland Exp $ 28 */ 29 30 #include "defs.h" 31 32 #ifdef LINUX 33 #include <sys/socket.h> 34 #include <linux/sockios.h> 35 #else 36 #include <sys/socket.h> 37 #include <sys/sockio.h> 38 #endif 39 #include <arpa/inet.h> 40 41 #if defined (ALPHA) || defined(SH) || defined(SH64) 42 #ifdef HAVE_SYS_IOCTL_H 43 #include <sys/ioctl.h> 44 #elif defined(HAVE_IOCTLS_H) 45 #include <ioctls.h> 46 #endif 47 #endif 48 #include <net/if.h> 49 50 extern const struct xlat addrfams[]; 51 52 static const struct xlat iffflags[] = { 53 { IFF_UP, "IFF_UP" }, 54 { IFF_BROADCAST, "IFF_BROADCAST" }, 55 { IFF_DEBUG, "IFF_DEBUG" }, 56 { IFF_LOOPBACK, "IFF_LOOPBACK" }, 57 { IFF_POINTOPOINT, "IFF_POINTOPOINT" }, 58 { IFF_NOTRAILERS, "IFF_NOTRAILERS" }, 59 { IFF_RUNNING, "IFF_RUNNING" }, 60 { IFF_NOARP, "IFF_NOARP" }, 61 { IFF_PROMISC, "IFF_PROMISC" }, 62 { IFF_ALLMULTI, "IFF_ALLMULTI" }, 63 { IFF_MASTER, "IFF_MASTER" }, 64 { IFF_SLAVE, "IFF_SLAVE" }, 65 { IFF_MULTICAST, "IFF_MULTICAST" }, 66 { IFF_PORTSEL, "IFF_PORTSEL" }, 67 { IFF_AUTOMEDIA, "IFF_AUTOMEDIA" }, 68 { 0, NULL } 69 }; 70 71 72 static void 73 print_addr(tcp, addr, ifr) 74 struct tcb *tcp; 75 long addr; 76 struct ifreq *ifr; 77 { 78 if (ifr->ifr_addr.sa_family == AF_INET) { 79 struct sockaddr_in *sinp; 80 sinp = (struct sockaddr_in *) &ifr->ifr_addr; 81 tprintf("inet_addr(\"%s\")", inet_ntoa(sinp->sin_addr)); 82 } else 83 printstr(tcp, addr, sizeof(ifr->ifr_addr.sa_data)); 84 } 85 86 int 87 sock_ioctl(tcp, code, arg) 88 struct tcb *tcp; 89 long code, arg; 90 { 91 struct ifreq ifr; 92 struct ifconf ifc; 93 const char *str = NULL; 94 unsigned char *bytes; 95 96 if (entering(tcp)) { 97 if (code == SIOCGIFCONF) { 98 umove(tcp, tcp->u_arg[2], &ifc); 99 if (ifc.ifc_buf == NULL) 100 tprintf(", {%d -> ", ifc.ifc_len); 101 else 102 tprintf(", {"); 103 } 104 return 0; 105 } 106 107 switch (code) { 108 #ifdef SIOCSHIWAT 109 case SIOCSHIWAT: 110 #endif 111 #ifdef SIOCGHIWAT 112 case SIOCGHIWAT: 113 #endif 114 #ifdef SIOCSLOWAT 115 case SIOCSLOWAT: 116 #endif 117 #ifdef SIOCGLOWAT 118 case SIOCGLOWAT: 119 #endif 120 #ifdef FIOSETOWN 121 case FIOSETOWN: 122 #endif 123 #ifdef FIOGETOWN 124 case FIOGETOWN: 125 #endif 126 #ifdef SIOCSPGRP 127 case SIOCSPGRP: 128 #endif 129 #ifdef SIOCGPGRP 130 case SIOCGPGRP: 131 #endif 132 #ifdef SIOCATMARK 133 case SIOCATMARK: 134 #endif 135 printnum(tcp, arg, ", %#d"); 136 return 1; 137 #ifdef LINUX 138 case SIOCGIFNAME: 139 case SIOCGIFINDEX: 140 case SIOCGIFADDR: 141 case SIOCGIFDSTADDR: 142 case SIOCGIFBRDADDR: 143 case SIOCGIFNETMASK: 144 case SIOCGIFFLAGS: 145 case SIOCGIFMETRIC: 146 case SIOCGIFMTU: 147 case SIOCGIFSLAVE: 148 case SIOCGIFHWADDR: 149 umove(tcp, tcp->u_arg[2], &ifr); 150 if (syserror(tcp)) { 151 if (code == SIOCGIFNAME) 152 tprintf(", {ifr_index=%d, ifr_name=???}", ifr.ifr_ifindex); 153 else 154 tprintf(", {ifr_name=\"%s\", ???}", ifr.ifr_name); 155 } else if (code == SIOCGIFNAME) 156 tprintf(", {ifr_index=%d, ifr_name=\"%s\"}", 157 ifr.ifr_ifindex, ifr.ifr_name); 158 else { 159 tprintf(", {ifr_name=\"%s\", ", ifr.ifr_name); 160 switch (code) { 161 case SIOCGIFINDEX: 162 tprintf("ifr_index=%d", ifr.ifr_ifindex); 163 break; 164 case SIOCGIFADDR: 165 str = "ifr_addr"; 166 case SIOCGIFDSTADDR: 167 if (str == NULL) 168 str = "ifr_dstaddr"; 169 case SIOCGIFBRDADDR: 170 if (str == NULL) 171 str = "ifr_broadaddr"; 172 case SIOCGIFNETMASK: 173 if (str == NULL) 174 str = "ifr_netmask"; 175 tprintf("%s={", str); 176 printxval(addrfams, 177 ifr.ifr_addr.sa_family, 178 "AF_???"); 179 tprintf(", "); 180 print_addr(tcp, ((long) tcp->u_arg[2] 181 + offsetof (struct ifreq, 182 ifr_addr.sa_data)), 183 &ifr); 184 tprintf("}"); 185 break; 186 case SIOCGIFHWADDR: 187 /* XXX Are there other hardware addresses 188 than 6-byte MACs? */ 189 bytes = (unsigned char *) &ifr.ifr_hwaddr.sa_data; 190 tprintf("ifr_hwaddr=%02x:%02x:%02x:%02x:%02x:%02x", 191 bytes[0], bytes[1], bytes[2], 192 bytes[3], bytes[4], bytes[5]); 193 break; 194 case SIOCGIFFLAGS: 195 tprintf("ifr_flags="); 196 printflags(iffflags, ifr.ifr_flags, "IFF_???"); 197 break; 198 case SIOCGIFMETRIC: 199 tprintf("ifr_metric=%d", ifr.ifr_metric); 200 break; 201 case SIOCGIFMTU: 202 tprintf("ifr_mtu=%d", ifr.ifr_mtu); 203 break; 204 case SIOCGIFSLAVE: 205 tprintf("ifr_slave=\"%s\"", ifr.ifr_slave); 206 break; 207 } 208 tprintf("}"); 209 } 210 return 1; 211 case SIOCGIFCONF: 212 umove(tcp, tcp->u_arg[2], &ifc); 213 tprintf("%d, ", ifc.ifc_len); 214 if (syserror(tcp)) { 215 tprintf("%lx", (unsigned long) ifc.ifc_buf); 216 } else if (ifc.ifc_buf == NULL) { 217 tprintf("NULL"); 218 } else { 219 int i; 220 unsigned nifra = ifc.ifc_len / sizeof(struct ifreq); 221 struct ifreq ifra[nifra]; 222 umoven(tcp, (unsigned long) ifc.ifc_buf, sizeof(ifra), 223 (char *) ifra); 224 tprintf("{"); 225 for (i = 0; i < nifra; ++i ) { 226 if (i > 0) 227 tprintf(", "); 228 tprintf("{\"%s\", {", 229 ifra[i].ifr_name); 230 if (verbose(tcp)) { 231 printxval(addrfams, 232 ifra[i].ifr_addr.sa_family, 233 "AF_???"); 234 tprintf(", "); 235 print_addr(tcp, ((long) tcp->u_arg[2] 236 + offsetof (struct ifreq, 237 ifr_addr.sa_data) 238 + ((char *) &ifra[i] 239 - (char *) &ifra[0])), 240 &ifra[i]); 241 } else 242 tprintf("..."); 243 tprintf("}}"); 244 } 245 tprintf("}"); 246 } 247 tprintf("}"); 248 return 1; 249 #endif 250 default: 251 return 0; 252 } 253 } 254