xref: /netbsd-src/sys/compat/common/if_43.c (revision 466a16a118933bd295a8a104f095714fadf9cf68)
1 /*	$NetBSD: if_43.c,v 1.1 2008/11/14 23:10:57 ad 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.1 2008/11/14 23:10:57 ad Exp $");
36 
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/filedesc.h>
40 #include <sys/kernel.h>
41 #include <sys/proc.h>
42 #include <sys/file.h>
43 #include <sys/socket.h>
44 #include <sys/socketvar.h>
45 #include <sys/stat.h>
46 #include <sys/ioctl.h>
47 #include <sys/fcntl.h>
48 #include <sys/malloc.h>
49 #include <sys/syslog.h>
50 #include <sys/unistd.h>
51 #include <sys/resourcevar.h>
52 #include <sys/mbuf.h>		/* for MLEN */
53 #include <sys/protosw.h>
54 
55 #include <sys/mount.h>
56 #include <sys/syscallargs.h>
57 
58 #include <net/if.h>
59 #include <net/bpf.h>
60 #include <net/route.h>
61 #include <netinet/in.h>
62 #include <netinet/in_systm.h>
63 #include <netinet/ip.h>
64 #include <net/if_gre.h>
65 #include <net/if_atm.h>
66 #include <net/if_tap.h>
67 #include <net80211/ieee80211_ioctl.h>
68 #include <netinet6/in6_var.h>
69 #include <netinet6/nd6.h>
70 #include <compat/sys/socket.h>
71 #include <compat/sys/sockio.h>
72 
73 #include <compat/common/compat_util.h>
74 
75 #include <uvm/uvm_extern.h>
76 
77 u_long
78 compat_cvtcmd(u_long cmd)
79 {
80 	u_long ncmd;
81 
82 	if (IOCPARM_LEN(cmd) != sizeof(struct oifreq))
83 		return cmd;
84 
85 	ncmd = ((cmd) & ~(IOCPARM_MASK << IOCPARM_SHIFT)) |
86 		(sizeof(struct ifreq) << IOCPARM_SHIFT);
87 
88 	switch (ncmd) {
89 	case BIOCGETIF:
90 	case BIOCSETIF:
91 	case GREDSOCK:
92 	case GREGADDRD:
93 	case GREGADDRS:
94 	case GREGPROTO:
95 	case GRESADDRD:
96 	case GRESADDRS:
97 	case GRESPROTO:
98 	case GRESSOCK:
99 #ifdef COMPAT_20
100 	case OSIOCG80211STATS:
101 	case OSIOCG80211ZSTATS:
102 #endif /* COMPAT_20 */
103 	case SIOCADDMULTI:
104 	case SIOCDELMULTI:
105 	case SIOCDIFADDR:
106 	case SIOCDIFADDR_IN6:
107 	case SIOCDIFPHYADDR:
108 	case SIOCGDEFIFACE_IN6:
109 	case SIOCG80211NWID:
110 	case SIOCG80211STATS:
111 	case SIOCG80211ZSTATS:
112 	case SIOCGIFADDR:
113 	case SIOCGIFADDR_IN6:
114 	case SIOCGIFAFLAG_IN6:
115 	case SIOCGIFALIFETIME_IN6:
116 	case SIOCGIFBRDADDR:
117 	case SIOCGIFDLT:
118 	case SIOCGIFDSTADDR:
119 	case SIOCGIFDSTADDR_IN6:
120 	case SIOCGIFFLAGS:
121 	case SIOCGIFGENERIC:
122 	case SIOCGIFMETRIC:
123 	case SIOCGIFMTU:
124 	case SIOCGIFNETMASK:
125 	case SIOCGIFNETMASK_IN6:
126 	case SIOCGIFPDSTADDR:
127 	case SIOCGIFPDSTADDR_IN6:
128 	case SIOCGIFPSRCADDR:
129 	case SIOCGIFPSRCADDR_IN6:
130 	case SIOCGIFSTAT_ICMP6:
131 	case SIOCGIFSTAT_IN6:
132 	case SIOCGPVCSIF:
133 	case SIOCGVH:
134 	case SIOCIFCREATE:
135 	case SIOCIFDESTROY:
136 	case SIOCS80211NWID:
137 	case SIOCSDEFIFACE_IN6:
138 	case SIOCSIFADDR:
139 	case SIOCSIFADDR_IN6:
140 	case SIOCSIFBRDADDR:
141 	case SIOCSIFDSTADDR:
142 	case SIOCSIFDSTADDR_IN6:
143 	case SIOCSIFFLAGS:
144 	case SIOCSIFGENERIC:
145 	case SIOCSIFMEDIA:
146 	case SIOCSIFMETRIC:
147 	case SIOCSIFMTU:
148 	case SIOCSIFNETMASK:
149 	case SIOCSIFNETMASK_IN6:
150 	case SIOCSNDFLUSH_IN6:
151 	case SIOCSPFXFLUSH_IN6:
152 	case SIOCSPVCSIF:
153 	case SIOCSRTRFLUSH_IN6:
154 	case SIOCSVH:
155 	case TAPGIFNAME:
156 		return ncmd;
157 	}
158 	return cmd;
159 }
160 
161 int
162 compat_ifioctl(struct socket *so, u_long ocmd, u_long cmd, void *data,
163     struct lwp *l)
164 {
165 	int error;
166 	struct ifreq *ifr = data;
167 	struct ifnet *ifp = ifunit(ifr->ifr_name);
168 	struct sockaddr *sa;
169 
170 	if (ifp == NULL)
171 		return ENXIO;
172 
173 	switch (ocmd) {
174 	case OSIOCSIFADDR:
175 	case OSIOCSIFDSTADDR:
176 	case OSIOCSIFBRDADDR:
177 	case OSIOCSIFNETMASK:
178 		sa = &ifr->ifr_addr;
179 #if BYTE_ORDER != BIG_ENDIAN
180 		if (sa->sa_family == 0 && sa->sa_len < 16) {
181 			sa->sa_family = sa->sa_len;
182 			sa->sa_len = 16;
183 		}
184 #else
185 		if (sa->sa_len == 0)
186 			sa->sa_len = 16;
187 #endif
188 		break;
189 
190 	case OOSIOCGIFADDR:
191 		cmd = SIOCGIFADDR;
192 		break;
193 
194 	case OOSIOCGIFDSTADDR:
195 		cmd = SIOCGIFDSTADDR;
196 		break;
197 
198 	case OOSIOCGIFBRDADDR:
199 		cmd = SIOCGIFBRDADDR;
200 		break;
201 
202 	case OOSIOCGIFNETMASK:
203 		cmd = SIOCGIFNETMASK;
204 	}
205 
206 	error = (*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
207 	    (struct mbuf *)cmd, (struct mbuf *)ifr, (struct mbuf *)ifp, l);
208 
209 	switch (ocmd) {
210 	case OOSIOCGIFADDR:
211 	case OOSIOCGIFDSTADDR:
212 	case OOSIOCGIFBRDADDR:
213 	case OOSIOCGIFNETMASK:
214 		*(u_int16_t *)&ifr->ifr_addr =
215 		    ((struct sockaddr *)&ifr->ifr_addr)->sa_family;
216 	}
217 	return error;
218 }
219