xref: /netbsd-src/sys/compat/common/if_43.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: if_43.c,v 1.2 2009/03/17 00:08:10 dyoung Exp $	*/
2 
3 /*
4  * Copyright (c) 1982, 1986, 1989, 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *	@(#)uipc_syscalls.c	8.4 (Berkeley) 2/21/94
32  */
33 
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: if_43.c,v 1.2 2009/03/17 00:08:10 dyoung Exp $");
36 
37 #if defined(_KERNEL_OPT)
38 #include "opt_compat_netbsd.h"
39 #endif
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/filedesc.h>
44 #include <sys/kernel.h>
45 #include <sys/proc.h>
46 #include <sys/file.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/stat.h>
50 #include <sys/ioctl.h>
51 #include <sys/fcntl.h>
52 #include <sys/malloc.h>
53 #include <sys/syslog.h>
54 #include <sys/unistd.h>
55 #include <sys/resourcevar.h>
56 #include <sys/mbuf.h>		/* for MLEN */
57 #include <sys/protosw.h>
58 
59 #include <sys/mount.h>
60 #include <sys/syscallargs.h>
61 
62 #include <net/if.h>
63 #include <net/bpf.h>
64 #include <net/route.h>
65 #include <netinet/in.h>
66 #include <netinet/in_systm.h>
67 #include <netinet/ip.h>
68 #include <net/if_gre.h>
69 #include <net/if_atm.h>
70 #include <net/if_tap.h>
71 #include <net80211/ieee80211_ioctl.h>
72 #include <netinet6/in6_var.h>
73 #include <netinet6/nd6.h>
74 #include <compat/sys/socket.h>
75 #include <compat/sys/sockio.h>
76 
77 #include <compat/common/compat_util.h>
78 
79 #include <uvm/uvm_extern.h>
80 
81 u_long
82 compat_cvtcmd(u_long cmd)
83 {
84 	u_long ncmd;
85 
86 	if (IOCPARM_LEN(cmd) != sizeof(struct oifreq))
87 		return cmd;
88 
89 	ncmd = ((cmd) & ~(IOCPARM_MASK << IOCPARM_SHIFT)) |
90 		(sizeof(struct ifreq) << IOCPARM_SHIFT);
91 
92 	switch (ncmd) {
93 	case BIOCGETIF:
94 	case BIOCSETIF:
95 	case GREDSOCK:
96 	case GREGADDRD:
97 	case GREGADDRS:
98 	case GREGPROTO:
99 	case GRESADDRD:
100 	case GRESADDRS:
101 	case GRESPROTO:
102 	case GRESSOCK:
103 #ifdef COMPAT_20
104 	case OSIOCG80211STATS:
105 	case OSIOCG80211ZSTATS:
106 #endif /* COMPAT_20 */
107 	case SIOCADDMULTI:
108 	case SIOCDELMULTI:
109 	case SIOCDIFADDR:
110 	case SIOCDIFADDR_IN6:
111 	case SIOCDIFPHYADDR:
112 	case SIOCGDEFIFACE_IN6:
113 	case SIOCG80211NWID:
114 	case SIOCG80211STATS:
115 	case SIOCG80211ZSTATS:
116 	case SIOCGIFADDR:
117 	case SIOCGIFADDR_IN6:
118 	case SIOCGIFAFLAG_IN6:
119 	case SIOCGIFALIFETIME_IN6:
120 	case SIOCGIFBRDADDR:
121 	case SIOCGIFDLT:
122 	case SIOCGIFDSTADDR:
123 	case SIOCGIFDSTADDR_IN6:
124 	case SIOCGIFFLAGS:
125 	case SIOCGIFGENERIC:
126 	case SIOCGIFMETRIC:
127 	case SIOCGIFMTU:
128 	case SIOCGIFNETMASK:
129 	case SIOCGIFNETMASK_IN6:
130 	case SIOCGIFPDSTADDR:
131 	case SIOCGIFPDSTADDR_IN6:
132 	case SIOCGIFPSRCADDR:
133 	case SIOCGIFPSRCADDR_IN6:
134 	case SIOCGIFSTAT_ICMP6:
135 	case SIOCGIFSTAT_IN6:
136 	case SIOCGPVCSIF:
137 	case SIOCGVH:
138 	case SIOCIFCREATE:
139 	case SIOCIFDESTROY:
140 	case SIOCS80211NWID:
141 	case SIOCSDEFIFACE_IN6:
142 	case SIOCSIFADDR:
143 	case SIOCSIFADDR_IN6:
144 	case SIOCSIFBRDADDR:
145 	case SIOCSIFDSTADDR:
146 	case SIOCSIFDSTADDR_IN6:
147 	case SIOCSIFFLAGS:
148 	case SIOCSIFGENERIC:
149 	case SIOCSIFMEDIA:
150 	case SIOCSIFMETRIC:
151 	case SIOCSIFMTU:
152 	case SIOCSIFNETMASK:
153 	case SIOCSIFNETMASK_IN6:
154 	case SIOCSNDFLUSH_IN6:
155 	case SIOCSPFXFLUSH_IN6:
156 	case SIOCSPVCSIF:
157 	case SIOCSRTRFLUSH_IN6:
158 	case SIOCSVH:
159 	case TAPGIFNAME:
160 		return ncmd;
161 	}
162 	return cmd;
163 }
164 
165 int
166 compat_ifioctl(struct socket *so, u_long ocmd, u_long cmd, void *data,
167     struct lwp *l)
168 {
169 	int error;
170 	struct ifreq *ifr = data;
171 	struct ifnet *ifp = ifunit(ifr->ifr_name);
172 	struct sockaddr *sa;
173 
174 	if (ifp == NULL)
175 		return ENXIO;
176 
177 	switch (ocmd) {
178 	case OSIOCSIFADDR:
179 	case OSIOCSIFDSTADDR:
180 	case OSIOCSIFBRDADDR:
181 	case OSIOCSIFNETMASK:
182 		sa = &ifr->ifr_addr;
183 #if BYTE_ORDER != BIG_ENDIAN
184 		if (sa->sa_family == 0 && sa->sa_len < 16) {
185 			sa->sa_family = sa->sa_len;
186 			sa->sa_len = 16;
187 		}
188 #else
189 		if (sa->sa_len == 0)
190 			sa->sa_len = 16;
191 #endif
192 		break;
193 
194 	case OOSIOCGIFADDR:
195 		cmd = SIOCGIFADDR;
196 		break;
197 
198 	case OOSIOCGIFDSTADDR:
199 		cmd = SIOCGIFDSTADDR;
200 		break;
201 
202 	case OOSIOCGIFBRDADDR:
203 		cmd = SIOCGIFBRDADDR;
204 		break;
205 
206 	case OOSIOCGIFNETMASK:
207 		cmd = SIOCGIFNETMASK;
208 	}
209 
210 	error = (*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
211 	    (struct mbuf *)cmd, (struct mbuf *)ifr, (struct mbuf *)ifp, l);
212 
213 	switch (ocmd) {
214 	case OOSIOCGIFADDR:
215 	case OOSIOCGIFDSTADDR:
216 	case OOSIOCGIFBRDADDR:
217 	case OOSIOCGIFNETMASK:
218 		*(u_int16_t *)&ifr->ifr_addr =
219 		    ((struct sockaddr *)&ifr->ifr_addr)->sa_family;
220 	}
221 	return error;
222 }
223