Home | History | Annotate | Download | only in strace
      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