• 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: 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
print_addr(tcp,addr,ifr)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
sock_ioctl(tcp,code,arg)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