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  *	$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