• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  *	$Id$
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 static const struct xlat iffflags[] = {
51 	{ IFF_UP,		"IFF_UP"		},
52 	{ IFF_BROADCAST,	"IFF_BROADCAST"		},
53 	{ IFF_DEBUG,		"IFF_DEBUG"		},
54 	{ IFF_LOOPBACK,		"IFF_LOOPBACK"		},
55 	{ IFF_POINTOPOINT,	"IFF_POINTOPOINT"	},
56 	{ IFF_NOTRAILERS,	"IFF_NOTRAILERS"	},
57 	{ IFF_RUNNING,		"IFF_RUNNING"		},
58 	{ IFF_NOARP,		"IFF_NOARP"		},
59 	{ IFF_PROMISC,		"IFF_PROMISC"		},
60 	{ IFF_ALLMULTI,		"IFF_ALLMULTI"		},
61 	{ IFF_MASTER,		"IFF_MASTER"		},
62 	{ IFF_SLAVE,		"IFF_SLAVE"		},
63 	{ IFF_MULTICAST,	"IFF_MULTICAST"		},
64 	{ IFF_PORTSEL,		"IFF_PORTSEL"		},
65 	{ IFF_AUTOMEDIA,	"IFF_AUTOMEDIA"		},
66 	{ 0,			NULL			}
67 };
68 
69 
70 static void
print_addr(tcp,addr,ifr)71 print_addr(tcp, addr, ifr)
72 struct tcb *tcp;
73 long addr;
74 struct ifreq *ifr;
75 {
76 	if (ifr->ifr_addr.sa_family == AF_INET) {
77 		struct sockaddr_in *sinp;
78 		sinp = (struct sockaddr_in *) &ifr->ifr_addr;
79 		tprintf("inet_addr(\"%s\")", inet_ntoa(sinp->sin_addr));
80 	} else
81 		printstr(tcp, addr, sizeof(ifr->ifr_addr.sa_data));
82 }
83 
84 int
sock_ioctl(struct tcb * tcp,long code,long arg)85 sock_ioctl(struct tcb *tcp, long code, long arg)
86 {
87 	struct ifreq ifr;
88 	struct ifconf ifc;
89 	const char *str = NULL;
90 	unsigned char *bytes;
91 
92 	if (entering(tcp)) {
93 		if (code == SIOCGIFCONF) {
94 			if (umove(tcp, tcp->u_arg[2], &ifc) >= 0
95 			    && ifc.ifc_buf == NULL)
96 				tprintf(", {%d -> ", ifc.ifc_len);
97 			else
98 				tprintf(", {");
99 		}
100 		return 0;
101 	}
102 
103 	switch (code) {
104 #ifdef SIOCSHIWAT
105 	case SIOCSHIWAT:
106 #endif
107 #ifdef SIOCGHIWAT
108 	case SIOCGHIWAT:
109 #endif
110 #ifdef SIOCSLOWAT
111 	case SIOCSLOWAT:
112 #endif
113 #ifdef SIOCGLOWAT
114 	case SIOCGLOWAT:
115 #endif
116 #ifdef FIOSETOWN
117 	case FIOSETOWN:
118 #endif
119 #ifdef FIOGETOWN
120 	case FIOGETOWN:
121 #endif
122 #ifdef SIOCSPGRP
123 	case SIOCSPGRP:
124 #endif
125 #ifdef SIOCGPGRP
126 	case SIOCGPGRP:
127 #endif
128 #ifdef SIOCATMARK
129 	case SIOCATMARK:
130 #endif
131 		printnum(tcp, arg, ", %#d");
132 		return 1;
133 #ifdef LINUX
134 	case SIOCGIFNAME:
135 	case SIOCSIFNAME:
136 	case SIOCGIFINDEX:
137 	case SIOCGIFADDR:
138 	case SIOCSIFADDR:
139 	case SIOCGIFDSTADDR:
140 	case SIOCSIFDSTADDR:
141 	case SIOCGIFBRDADDR:
142 	case SIOCSIFBRDADDR:
143 	case SIOCGIFNETMASK:
144 	case SIOCSIFNETMASK:
145 	case SIOCGIFFLAGS:
146 	case SIOCSIFFLAGS:
147 	case SIOCGIFMETRIC:
148 	case SIOCSIFMETRIC:
149 	case SIOCGIFMTU:
150 	case SIOCSIFMTU:
151 	case SIOCGIFSLAVE:
152 	case SIOCSIFSLAVE:
153 	case SIOCGIFHWADDR:
154 	case SIOCSIFHWADDR:
155 	case SIOCGIFTXQLEN:
156 	case SIOCSIFTXQLEN:
157 	case SIOCGIFMAP:
158 	case SIOCSIFMAP:
159 		if (umove(tcp, tcp->u_arg[2], &ifr) < 0)
160 			tprintf(", %#lx", tcp->u_arg[2]);
161 		else if (syserror(tcp)) {
162 			if (code == SIOCGIFNAME || code == SIOCSIFNAME)
163 				tprintf(", {ifr_index=%d, ifr_name=???}", ifr.ifr_ifindex);
164 			else
165 				tprintf(", {ifr_name=\"%s\", ???}", ifr.ifr_name);
166 		} else if (code == SIOCGIFNAME || code == SIOCSIFNAME)
167 			tprintf(", {ifr_index=%d, ifr_name=\"%s\"}",
168 				ifr.ifr_ifindex, ifr.ifr_name);
169 		else {
170 			tprintf(", {ifr_name=\"%s\", ", ifr.ifr_name);
171 			switch (code) {
172 			case SIOCGIFINDEX:
173 				tprintf("ifr_index=%d", ifr.ifr_ifindex);
174 				break;
175 			case SIOCGIFADDR:
176 			case SIOCSIFADDR:
177 				str = "ifr_addr";
178 			case SIOCGIFDSTADDR:
179 			case SIOCSIFDSTADDR:
180 				if (!str)
181 					str = "ifr_dstaddr";
182 			case SIOCGIFBRDADDR:
183 			case SIOCSIFBRDADDR:
184 				if (!str)
185 					str = "ifr_broadaddr";
186 			case SIOCGIFNETMASK:
187 			case SIOCSIFNETMASK:
188 				if (!str)
189 					str = "ifr_netmask";
190 				tprintf("%s={", str);
191 				printxval(addrfams,
192 					  ifr.ifr_addr.sa_family,
193 					  "AF_???");
194 				tprintf(", ");
195 				print_addr(tcp, ((long) tcp->u_arg[2]
196 						 + offsetof (struct ifreq,
197 							     ifr_addr.sa_data)),
198 					   &ifr);
199 				tprintf("}");
200 				break;
201 			case SIOCGIFHWADDR:
202 			case SIOCSIFHWADDR:
203 				/* XXX Are there other hardware addresses
204 				   than 6-byte MACs?  */
205 				bytes = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
206 				tprintf("ifr_hwaddr=%02x:%02x:%02x:%02x:%02x:%02x",
207 					bytes[0], bytes[1], bytes[2],
208 					bytes[3], bytes[4], bytes[5]);
209 				break;
210 			case SIOCGIFFLAGS:
211 			case SIOCSIFFLAGS:
212 				tprintf("ifr_flags=");
213 				printflags(iffflags, ifr.ifr_flags, "IFF_???");
214 				break;
215 			case SIOCGIFMETRIC:
216 			case SIOCSIFMETRIC:
217 				tprintf("ifr_metric=%d", ifr.ifr_metric);
218 				break;
219 			case SIOCGIFMTU:
220 			case SIOCSIFMTU:
221 				tprintf("ifr_mtu=%d", ifr.ifr_mtu);
222 				break;
223 			case SIOCGIFSLAVE:
224 			case SIOCSIFSLAVE:
225 				tprintf("ifr_slave=\"%s\"", ifr.ifr_slave);
226 				break;
227 			case SIOCGIFTXQLEN:
228 			case SIOCSIFTXQLEN:
229 				tprintf("ifr_qlen=%d", ifr.ifr_qlen);
230 				break;
231 			case SIOCGIFMAP:
232 			case SIOCSIFMAP:
233 				tprintf("ifr_map={mem_start=%#lx, "
234 					"mem_end=%#lx, base_addr=%#x, "
235 					"irq=%u, dma=%u, port=%u}",
236 					ifr.ifr_map.mem_start,
237 					ifr.ifr_map.mem_end,
238 					(unsigned) ifr.ifr_map.base_addr,
239 					(unsigned) ifr.ifr_map.irq,
240 					(unsigned) ifr.ifr_map.dma,
241 					(unsigned) ifr.ifr_map.port);
242 				break;
243 			}
244 			tprintf("}");
245 		}
246 		return 1;
247 	case SIOCGIFCONF:
248 		if (umove(tcp, tcp->u_arg[2], &ifc) < 0) {
249 			tprintf("???}");
250 			return 1;
251 		}
252 		tprintf("%d, ", ifc.ifc_len);
253 		if (syserror(tcp)) {
254 			tprintf("%lx", (unsigned long) ifc.ifc_buf);
255 		} else if (ifc.ifc_buf == NULL) {
256 			tprintf("NULL");
257 		} else {
258 			int i;
259 			unsigned nifra = ifc.ifc_len / sizeof(struct ifreq);
260 			struct ifreq ifra[nifra];
261 
262 			if (umoven(tcp, (unsigned long) ifc.ifc_buf,
263 				sizeof(ifra), (char *) ifra) < 0) {
264 				tprintf("%lx}", (unsigned long) ifc.ifc_buf);
265 				return 1;
266 			}
267 			tprintf("{");
268 			for (i = 0; i < nifra; ++i ) {
269 				if (i > 0)
270 					tprintf(", ");
271 				tprintf("{\"%s\", {",
272 					ifra[i].ifr_name);
273 				if (verbose(tcp)) {
274 					printxval(addrfams,
275 						  ifra[i].ifr_addr.sa_family,
276 						  "AF_???");
277 					tprintf(", ");
278 					print_addr(tcp, ((long) tcp->u_arg[2]
279 							 + offsetof (struct ifreq,
280 								     ifr_addr.sa_data)
281 							 + ((char *) &ifra[i]
282 							    - (char *) &ifra[0])),
283 						   &ifra[i]);
284 				} else
285 					tprintf("...");
286 				tprintf("}}");
287 			}
288 			tprintf("}");
289 		}
290 		tprintf("}");
291 		return 1;
292 #endif
293 	default:
294 		return 0;
295 	}
296 }
297