Home | History | Annotate | Line # | Download | only in common
if_43.c revision 1.9.2.3
      1  1.9.2.3     skrll /*	$NetBSD: if_43.c,v 1.9.2.3 2016/10/05 20:55:37 skrll Exp $	*/
      2      1.1        ad 
      3      1.1        ad /*
      4      1.1        ad  * Copyright (c) 1982, 1986, 1989, 1990, 1993
      5      1.1        ad  *	The Regents of the University of California.  All rights reserved.
      6      1.1        ad  *
      7      1.1        ad  * Redistribution and use in source and binary forms, with or without
      8      1.1        ad  * modification, are permitted provided that the following conditions
      9      1.1        ad  * are met:
     10      1.1        ad  * 1. Redistributions of source code must retain the above copyright
     11      1.1        ad  *    notice, this list of conditions and the following disclaimer.
     12      1.1        ad  * 2. Redistributions in binary form must reproduce the above copyright
     13      1.1        ad  *    notice, this list of conditions and the following disclaimer in the
     14      1.1        ad  *    documentation and/or other materials provided with the distribution.
     15      1.1        ad  * 3. Neither the name of the University nor the names of its contributors
     16      1.1        ad  *    may be used to endorse or promote products derived from this software
     17      1.1        ad  *    without specific prior written permission.
     18      1.1        ad  *
     19      1.1        ad  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20      1.1        ad  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21      1.1        ad  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22      1.1        ad  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23      1.1        ad  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24      1.1        ad  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25      1.1        ad  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26      1.1        ad  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27      1.1        ad  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28      1.1        ad  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29      1.1        ad  * SUCH DAMAGE.
     30      1.1        ad  *
     31      1.1        ad  *	@(#)uipc_syscalls.c	8.4 (Berkeley) 2/21/94
     32      1.1        ad  */
     33      1.1        ad 
     34      1.1        ad #include <sys/cdefs.h>
     35  1.9.2.3     skrll __KERNEL_RCSID(0, "$NetBSD: if_43.c,v 1.9.2.3 2016/10/05 20:55:37 skrll Exp $");
     36      1.2    dyoung 
     37      1.2    dyoung #if defined(_KERNEL_OPT)
     38      1.2    dyoung #include "opt_compat_netbsd.h"
     39      1.2    dyoung #endif
     40      1.1        ad 
     41      1.1        ad #include <sys/param.h>
     42      1.1        ad #include <sys/systm.h>
     43      1.1        ad #include <sys/filedesc.h>
     44      1.1        ad #include <sys/kernel.h>
     45      1.1        ad #include <sys/proc.h>
     46      1.1        ad #include <sys/file.h>
     47      1.1        ad #include <sys/socket.h>
     48      1.1        ad #include <sys/socketvar.h>
     49      1.1        ad #include <sys/stat.h>
     50      1.1        ad #include <sys/ioctl.h>
     51      1.1        ad #include <sys/fcntl.h>
     52      1.1        ad #include <sys/syslog.h>
     53      1.1        ad #include <sys/unistd.h>
     54      1.1        ad #include <sys/resourcevar.h>
     55      1.1        ad #include <sys/mbuf.h>		/* for MLEN */
     56      1.1        ad #include <sys/protosw.h>
     57      1.1        ad 
     58      1.1        ad #include <sys/syscallargs.h>
     59      1.1        ad 
     60      1.1        ad #include <net/if.h>
     61      1.1        ad #include <net/bpf.h>
     62      1.1        ad #include <net/route.h>
     63      1.1        ad #include <netinet/in.h>
     64      1.1        ad #include <netinet/in_systm.h>
     65      1.1        ad #include <netinet/ip.h>
     66      1.1        ad #include <net/if_gre.h>
     67      1.1        ad #include <net/if_atm.h>
     68      1.1        ad #include <net/if_tap.h>
     69      1.1        ad #include <net80211/ieee80211_ioctl.h>
     70      1.1        ad #include <netinet6/in6_var.h>
     71      1.1        ad #include <netinet6/nd6.h>
     72      1.1        ad #include <compat/sys/socket.h>
     73      1.1        ad #include <compat/sys/sockio.h>
     74      1.1        ad 
     75      1.1        ad #include <compat/common/compat_util.h>
     76      1.1        ad 
     77      1.1        ad #include <uvm/uvm_extern.h>
     78      1.1        ad 
     79  1.9.2.2     skrll u_long
     80      1.1        ad compat_cvtcmd(u_long cmd)
     81  1.9.2.2     skrll {
     82      1.1        ad 	u_long ncmd;
     83      1.1        ad 
     84      1.1        ad 	if (IOCPARM_LEN(cmd) != sizeof(struct oifreq))
     85      1.1        ad 		return cmd;
     86      1.1        ad 
     87      1.3  christos 	switch (cmd) {
     88      1.3  christos 	case OSIOCSIFADDR:
     89      1.3  christos 		return SIOCSIFADDR;
     90      1.3  christos 	case OOSIOCGIFADDR:
     91      1.3  christos 		return SIOCGIFADDR;
     92      1.3  christos 	case OSIOCSIFDSTADDR:
     93      1.3  christos 		return SIOCSIFDSTADDR;
     94      1.3  christos 	case OOSIOCGIFDSTADDR:
     95      1.3  christos 		return SIOCGIFDSTADDR;
     96      1.3  christos 	case OSIOCSIFFLAGS:
     97      1.3  christos 		return SIOCSIFFLAGS;
     98      1.3  christos 	case OSIOCGIFFLAGS:
     99      1.3  christos 		return SIOCGIFFLAGS;
    100      1.3  christos 	case OOSIOCGIFBRDADDR:
    101      1.3  christos 		return SIOCGIFBRDADDR;
    102      1.3  christos 	case OSIOCSIFBRDADDR:
    103      1.3  christos 		return SIOCSIFBRDADDR;
    104      1.3  christos 	case OOSIOCGIFCONF:
    105      1.3  christos 		return SIOCGIFCONF;
    106      1.3  christos 	case OOSIOCGIFNETMASK:
    107      1.3  christos 		return SIOCGIFNETMASK;
    108      1.3  christos 	case OSIOCSIFNETMASK:
    109      1.3  christos 		return SIOCSIFNETMASK;
    110      1.3  christos 	case OSIOCGIFCONF:
    111      1.3  christos 		return SIOCGIFCONF;
    112      1.3  christos 	case OSIOCADDMULTI:
    113      1.3  christos 		return SIOCADDMULTI;
    114      1.3  christos 	case OSIOCDELMULTI:
    115      1.3  christos 		return SIOCDELMULTI;
    116      1.3  christos 	case OSIOCSIFMEDIA:
    117      1.3  christos 		return SIOCSIFMEDIA;
    118      1.3  christos 	case OSIOCGIFMTU:
    119      1.3  christos 		return SIOCGIFMTU;
    120      1.3  christos 	case OSIOCGIFDATA:
    121      1.3  christos 		return SIOCGIFDATA;
    122      1.3  christos 	case OSIOCZIFDATA:
    123      1.3  christos 		return SIOCZIFDATA;
    124      1.3  christos 	case OBIOCGETIF:
    125      1.3  christos 		return BIOCGETIF;
    126      1.3  christos 	case OBIOCSETIF:
    127      1.3  christos 		return BIOCSETIF;
    128      1.3  christos 	case OTAPGIFNAME:
    129      1.3  christos 		return TAPGIFNAME;
    130      1.3  christos 	default:
    131      1.3  christos 		/*
    132      1.3  christos 		 * XXX: the following code should be removed and the
    133      1.3  christos 		 * needing treatment ioctls should move to the switch
    134      1.3  christos 		 * above.
    135      1.3  christos 		 */
    136  1.9.2.2     skrll 		ncmd = ((cmd) & ~(IOCPARM_MASK << IOCPARM_SHIFT)) |
    137      1.3  christos 		    (sizeof(struct ifreq) << IOCPARM_SHIFT);
    138      1.3  christos 		switch (ncmd) {
    139      1.3  christos 		case BIOCGETIF:
    140      1.3  christos 		case BIOCSETIF:
    141      1.3  christos 		case GREDSOCK:
    142      1.3  christos 		case GREGADDRD:
    143      1.3  christos 		case GREGADDRS:
    144      1.3  christos 		case GREGPROTO:
    145      1.3  christos 		case GRESADDRD:
    146      1.3  christos 		case GRESADDRS:
    147      1.3  christos 		case GRESPROTO:
    148      1.3  christos 		case GRESSOCK:
    149      1.1        ad #ifdef COMPAT_20
    150      1.3  christos 		case OSIOCG80211STATS:
    151      1.3  christos 		case OSIOCG80211ZSTATS:
    152      1.1        ad #endif /* COMPAT_20 */
    153      1.3  christos 		case SIOCADDMULTI:
    154      1.3  christos 		case SIOCDELMULTI:
    155      1.3  christos 		case SIOCDIFADDR:
    156      1.3  christos 		case SIOCDIFADDR_IN6:
    157      1.3  christos 		case SIOCDIFPHYADDR:
    158      1.3  christos 		case SIOCGDEFIFACE_IN6:
    159      1.3  christos 		case SIOCG80211NWID:
    160      1.3  christos 		case SIOCG80211STATS:
    161      1.3  christos 		case SIOCG80211ZSTATS:
    162      1.3  christos 		case SIOCGIFADDR:
    163      1.3  christos 		case SIOCGIFADDR_IN6:
    164      1.3  christos 		case SIOCGIFAFLAG_IN6:
    165      1.3  christos 		case SIOCGIFALIFETIME_IN6:
    166      1.3  christos 		case SIOCGIFBRDADDR:
    167      1.3  christos 		case SIOCGIFDLT:
    168      1.3  christos 		case SIOCGIFDSTADDR:
    169      1.3  christos 		case SIOCGIFDSTADDR_IN6:
    170      1.3  christos 		case SIOCGIFFLAGS:
    171      1.3  christos 		case SIOCGIFGENERIC:
    172      1.3  christos 		case SIOCGIFMETRIC:
    173      1.3  christos 		case SIOCGIFMTU:
    174      1.3  christos 		case SIOCGIFNETMASK:
    175      1.3  christos 		case SIOCGIFNETMASK_IN6:
    176      1.3  christos 		case SIOCGIFPDSTADDR:
    177      1.3  christos 		case SIOCGIFPDSTADDR_IN6:
    178      1.3  christos 		case SIOCGIFPSRCADDR:
    179      1.3  christos 		case SIOCGIFPSRCADDR_IN6:
    180      1.3  christos 		case SIOCGIFSTAT_ICMP6:
    181      1.3  christos 		case SIOCGIFSTAT_IN6:
    182      1.3  christos 		case SIOCGPVCSIF:
    183      1.3  christos 		case SIOCGVH:
    184      1.3  christos 		case SIOCIFCREATE:
    185      1.3  christos 		case SIOCIFDESTROY:
    186      1.3  christos 		case SIOCS80211NWID:
    187      1.3  christos 		case SIOCSDEFIFACE_IN6:
    188      1.3  christos 		case SIOCSIFADDR:
    189      1.3  christos 		case SIOCSIFADDR_IN6:
    190      1.3  christos 		case SIOCSIFBRDADDR:
    191      1.3  christos 		case SIOCSIFDSTADDR:
    192      1.3  christos 		case SIOCSIFDSTADDR_IN6:
    193      1.3  christos 		case SIOCSIFFLAGS:
    194      1.3  christos 		case SIOCSIFGENERIC:
    195      1.3  christos 		case SIOCSIFMEDIA:
    196      1.3  christos 		case SIOCSIFMETRIC:
    197      1.3  christos 		case SIOCSIFMTU:
    198      1.3  christos 		case SIOCSIFNETMASK:
    199      1.3  christos 		case SIOCSIFNETMASK_IN6:
    200      1.3  christos 		case SIOCSNDFLUSH_IN6:
    201      1.3  christos 		case SIOCSPFXFLUSH_IN6:
    202      1.3  christos 		case SIOCSPVCSIF:
    203      1.3  christos 		case SIOCSRTRFLUSH_IN6:
    204      1.3  christos 		case SIOCSVH:
    205      1.3  christos 		case TAPGIFNAME:
    206      1.3  christos 			return ncmd;
    207      1.3  christos 		default:
    208      1.3  christos 			return cmd;
    209      1.3  christos 		}
    210      1.1        ad 	}
    211      1.1        ad }
    212      1.1        ad 
    213      1.1        ad int
    214      1.1        ad compat_ifioctl(struct socket *so, u_long ocmd, u_long cmd, void *data,
    215      1.1        ad     struct lwp *l)
    216      1.1        ad {
    217      1.1        ad 	int error;
    218      1.8      matt 	struct ifreq *ifr = (struct ifreq *)data;
    219  1.9.2.1     skrll 	struct ifreq ifrb;
    220  1.9.2.1     skrll 	struct oifreq *oifr = NULL;
    221  1.9.2.3     skrll 	struct ifnet *ifp;
    222      1.1        ad 	struct sockaddr *sa;
    223  1.9.2.3     skrll 	struct psref psref;
    224  1.9.2.3     skrll 	int bound = curlwp_bind();
    225      1.1        ad 
    226  1.9.2.3     skrll 	ifp = if_get(ifr->ifr_name, &psref);
    227  1.9.2.3     skrll 	if (ifp == NULL) {
    228  1.9.2.3     skrll 		curlwp_bindx(bound);
    229      1.1        ad 		return ENXIO;
    230  1.9.2.3     skrll 	}
    231      1.1        ad 
    232  1.9.2.1     skrll 	/*
    233  1.9.2.1     skrll 	 * If we have not been converted, make sure that we are.
    234  1.9.2.1     skrll 	 * (because the upper layer handles old socket calls, but
    235  1.9.2.1     skrll 	 * not oifreq calls.
    236  1.9.2.1     skrll 	 */
    237  1.9.2.1     skrll 	if (cmd == ocmd) {
    238  1.9.2.1     skrll 		cmd = compat_cvtcmd(ocmd);
    239  1.9.2.2     skrll 	}
    240  1.9.2.2     skrll 	if (cmd != ocmd) {
    241  1.9.2.2     skrll 		oifr = data;
    242  1.9.2.2     skrll 		data = ifr = &ifrb;
    243  1.9.2.2     skrll 		ifreqo2n(oifr, ifr);
    244  1.9.2.1     skrll 	}
    245  1.9.2.1     skrll 
    246      1.1        ad 	switch (ocmd) {
    247      1.1        ad 	case OSIOCSIFADDR:
    248      1.1        ad 	case OSIOCSIFDSTADDR:
    249      1.1        ad 	case OSIOCSIFBRDADDR:
    250      1.1        ad 	case OSIOCSIFNETMASK:
    251      1.1        ad 		sa = &ifr->ifr_addr;
    252      1.1        ad #if BYTE_ORDER != BIG_ENDIAN
    253      1.1        ad 		if (sa->sa_family == 0 && sa->sa_len < 16) {
    254      1.1        ad 			sa->sa_family = sa->sa_len;
    255      1.1        ad 			sa->sa_len = 16;
    256      1.1        ad 		}
    257      1.1        ad #else
    258      1.1        ad 		if (sa->sa_len == 0)
    259      1.1        ad 			sa->sa_len = 16;
    260      1.1        ad #endif
    261      1.1        ad 		break;
    262      1.1        ad 	}
    263      1.1        ad 
    264      1.7       rtr 	error = (*so->so_proto->pr_usrreqs->pr_ioctl)(so, cmd, ifr, ifp);
    265  1.9.2.3     skrll 	if_put(ifp, &psref);
    266  1.9.2.3     skrll 	curlwp_bindx(bound);
    267      1.1        ad 
    268      1.1        ad 	switch (ocmd) {
    269      1.1        ad 	case OOSIOCGIFADDR:
    270      1.1        ad 	case OOSIOCGIFDSTADDR:
    271      1.1        ad 	case OOSIOCGIFBRDADDR:
    272      1.1        ad 	case OOSIOCGIFNETMASK:
    273  1.9.2.2     skrll 		*(u_int16_t *)&ifr->ifr_addr =
    274      1.1        ad 		    ((struct sockaddr *)&ifr->ifr_addr)->sa_family;
    275  1.9.2.1     skrll 		break;
    276      1.1        ad 	}
    277  1.9.2.1     skrll 
    278  1.9.2.1     skrll 	if (cmd != ocmd)
    279  1.9.2.1     skrll 		ifreqn2o(oifr, ifr);
    280  1.9.2.1     skrll 
    281      1.1        ad 	return error;
    282      1.1        ad }
    283