if_43.c revision 1.1.8.2 1 /* $NetBSD: if_43.c,v 1.1.8.2 2009/01/19 13:17:17 skrll 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.8.2 2009/01/19 13:17:17 skrll 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