1 /* $NetBSD: if_43.c,v 1.4 2011/01/19 10:21:16 tsutsui 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.4 2011/01/19 10:21:16 tsutsui 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/syscallargs.h> 60 61 #include <net/if.h> 62 #include <net/bpf.h> 63 #include <net/route.h> 64 #include <netinet/in.h> 65 #include <netinet/in_systm.h> 66 #include <netinet/ip.h> 67 #include <net/if_gre.h> 68 #include <net/if_atm.h> 69 #include <net/if_tap.h> 70 #include <net80211/ieee80211_ioctl.h> 71 #include <netinet6/in6_var.h> 72 #include <netinet6/nd6.h> 73 #include <compat/sys/socket.h> 74 #include <compat/sys/sockio.h> 75 76 #include <compat/common/compat_util.h> 77 78 #include <uvm/uvm_extern.h> 79 80 u_long 81 compat_cvtcmd(u_long cmd) 82 { 83 u_long ncmd; 84 85 if (IOCPARM_LEN(cmd) != sizeof(struct oifreq)) 86 return cmd; 87 88 switch (cmd) { 89 case OSIOCSIFADDR: 90 return SIOCSIFADDR; 91 case OOSIOCGIFADDR: 92 return SIOCGIFADDR; 93 case OSIOCSIFDSTADDR: 94 return SIOCSIFDSTADDR; 95 case OOSIOCGIFDSTADDR: 96 return SIOCGIFDSTADDR; 97 case OSIOCSIFFLAGS: 98 return SIOCSIFFLAGS; 99 case OSIOCGIFFLAGS: 100 return SIOCGIFFLAGS; 101 case OOSIOCGIFBRDADDR: 102 return SIOCGIFBRDADDR; 103 case OSIOCSIFBRDADDR: 104 return SIOCSIFBRDADDR; 105 case OOSIOCGIFCONF: 106 return SIOCGIFCONF; 107 case OOSIOCGIFNETMASK: 108 return SIOCGIFNETMASK; 109 case OSIOCSIFNETMASK: 110 return SIOCSIFNETMASK; 111 case OSIOCGIFCONF: 112 return SIOCGIFCONF; 113 case OSIOCADDMULTI: 114 return SIOCADDMULTI; 115 case OSIOCDELMULTI: 116 return SIOCDELMULTI; 117 case OSIOCSIFMEDIA: 118 return SIOCSIFMEDIA; 119 case OSIOCGIFMTU: 120 return SIOCGIFMTU; 121 case OSIOCGIFDATA: 122 return SIOCGIFDATA; 123 case OSIOCZIFDATA: 124 return SIOCZIFDATA; 125 case OBIOCGETIF: 126 return BIOCGETIF; 127 case OBIOCSETIF: 128 return BIOCSETIF; 129 case OTAPGIFNAME: 130 return TAPGIFNAME; 131 default: 132 /* 133 * XXX: the following code should be removed and the 134 * needing treatment ioctls should move to the switch 135 * above. 136 */ 137 ncmd = ((cmd) & ~(IOCPARM_MASK << IOCPARM_SHIFT)) | 138 (sizeof(struct ifreq) << IOCPARM_SHIFT); 139 switch (ncmd) { 140 case BIOCGETIF: 141 case BIOCSETIF: 142 case GREDSOCK: 143 case GREGADDRD: 144 case GREGADDRS: 145 case GREGPROTO: 146 case GRESADDRD: 147 case GRESADDRS: 148 case GRESPROTO: 149 case GRESSOCK: 150 #ifdef COMPAT_20 151 case OSIOCG80211STATS: 152 case OSIOCG80211ZSTATS: 153 #endif /* COMPAT_20 */ 154 case SIOCADDMULTI: 155 case SIOCDELMULTI: 156 case SIOCDIFADDR: 157 case SIOCDIFADDR_IN6: 158 case SIOCDIFPHYADDR: 159 case SIOCGDEFIFACE_IN6: 160 case SIOCG80211NWID: 161 case SIOCG80211STATS: 162 case SIOCG80211ZSTATS: 163 case SIOCGIFADDR: 164 case SIOCGIFADDR_IN6: 165 case SIOCGIFAFLAG_IN6: 166 case SIOCGIFALIFETIME_IN6: 167 case SIOCGIFBRDADDR: 168 case SIOCGIFDLT: 169 case SIOCGIFDSTADDR: 170 case SIOCGIFDSTADDR_IN6: 171 case SIOCGIFFLAGS: 172 case SIOCGIFGENERIC: 173 case SIOCGIFMETRIC: 174 case SIOCGIFMTU: 175 case SIOCGIFNETMASK: 176 case SIOCGIFNETMASK_IN6: 177 case SIOCGIFPDSTADDR: 178 case SIOCGIFPDSTADDR_IN6: 179 case SIOCGIFPSRCADDR: 180 case SIOCGIFPSRCADDR_IN6: 181 case SIOCGIFSTAT_ICMP6: 182 case SIOCGIFSTAT_IN6: 183 case SIOCGPVCSIF: 184 case SIOCGVH: 185 case SIOCIFCREATE: 186 case SIOCIFDESTROY: 187 case SIOCS80211NWID: 188 case SIOCSDEFIFACE_IN6: 189 case SIOCSIFADDR: 190 case SIOCSIFADDR_IN6: 191 case SIOCSIFBRDADDR: 192 case SIOCSIFDSTADDR: 193 case SIOCSIFDSTADDR_IN6: 194 case SIOCSIFFLAGS: 195 case SIOCSIFGENERIC: 196 case SIOCSIFMEDIA: 197 case SIOCSIFMETRIC: 198 case SIOCSIFMTU: 199 case SIOCSIFNETMASK: 200 case SIOCSIFNETMASK_IN6: 201 case SIOCSNDFLUSH_IN6: 202 case SIOCSPFXFLUSH_IN6: 203 case SIOCSPVCSIF: 204 case SIOCSRTRFLUSH_IN6: 205 case SIOCSVH: 206 case TAPGIFNAME: 207 return ncmd; 208 default: 209 return cmd; 210 } 211 } 212 } 213 214 int 215 compat_ifioctl(struct socket *so, u_long ocmd, u_long cmd, void *data, 216 struct lwp *l) 217 { 218 int error; 219 struct ifreq *ifr = data; 220 struct ifnet *ifp = ifunit(ifr->ifr_name); 221 struct sockaddr *sa; 222 223 if (ifp == NULL) 224 return ENXIO; 225 226 switch (ocmd) { 227 case OSIOCSIFADDR: 228 case OSIOCSIFDSTADDR: 229 case OSIOCSIFBRDADDR: 230 case OSIOCSIFNETMASK: 231 sa = &ifr->ifr_addr; 232 #if BYTE_ORDER != BIG_ENDIAN 233 if (sa->sa_family == 0 && sa->sa_len < 16) { 234 sa->sa_family = sa->sa_len; 235 sa->sa_len = 16; 236 } 237 #else 238 if (sa->sa_len == 0) 239 sa->sa_len = 16; 240 #endif 241 break; 242 243 case OOSIOCGIFADDR: 244 cmd = SIOCGIFADDR; 245 break; 246 247 case OOSIOCGIFDSTADDR: 248 cmd = SIOCGIFDSTADDR; 249 break; 250 251 case OOSIOCGIFBRDADDR: 252 cmd = SIOCGIFBRDADDR; 253 break; 254 255 case OOSIOCGIFNETMASK: 256 cmd = SIOCGIFNETMASK; 257 } 258 259 error = (*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 260 (struct mbuf *)cmd, (struct mbuf *)ifr, (struct mbuf *)ifp, l); 261 262 switch (ocmd) { 263 case OOSIOCGIFADDR: 264 case OOSIOCGIFDSTADDR: 265 case OOSIOCGIFBRDADDR: 266 case OOSIOCGIFNETMASK: 267 *(u_int16_t *)&ifr->ifr_addr = 268 ((struct sockaddr *)&ifr->ifr_addr)->sa_family; 269 } 270 return error; 271 } 272