Home | History | Annotate | Line # | Download | only in common
linux_socketcall.c revision 1.2
      1  1.2  mycroft /*	$NetBSD: linux_socketcall.c,v 1.2 1995/05/28 08:09:51 mycroft Exp $	*/
      2  1.1     fvdl 
      3  1.1     fvdl /*
      4  1.1     fvdl  * Copyright (c) 1995 Frank van der Linden
      5  1.1     fvdl  * All rights reserved.
      6  1.1     fvdl  *
      7  1.1     fvdl  * Redistribution and use in source and binary forms, with or without
      8  1.1     fvdl  * modification, are permitted provided that the following conditions
      9  1.1     fvdl  * are met:
     10  1.1     fvdl  * 1. Redistributions of source code must retain the above copyright
     11  1.1     fvdl  *    notice, this list of conditions and the following disclaimer.
     12  1.1     fvdl  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1     fvdl  *    notice, this list of conditions and the following disclaimer in the
     14  1.1     fvdl  *    documentation and/or other materials provided with the distribution.
     15  1.1     fvdl  * 3. All advertising materials mentioning features or use of this software
     16  1.1     fvdl  *    must display the following acknowledgement:
     17  1.1     fvdl  *      This product includes software developed for the NetBSD Project
     18  1.1     fvdl  *      by Frank van der Linden
     19  1.1     fvdl  * 4. The name of the author may not be used to endorse or promote products
     20  1.1     fvdl  *    derived from this software without specific prior written permission
     21  1.1     fvdl  *
     22  1.1     fvdl  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23  1.1     fvdl  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  1.1     fvdl  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  1.1     fvdl  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26  1.1     fvdl  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27  1.1     fvdl  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  1.1     fvdl  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  1.1     fvdl  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  1.1     fvdl  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31  1.1     fvdl  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  1.1     fvdl  */
     33  1.1     fvdl 
     34  1.1     fvdl #include <sys/param.h>
     35  1.1     fvdl #include <sys/kernel.h>
     36  1.1     fvdl #include <sys/systm.h>
     37  1.1     fvdl #include <sys/buf.h>
     38  1.1     fvdl #include <sys/malloc.h>
     39  1.1     fvdl #include <sys/ioctl.h>
     40  1.1     fvdl #include <sys/tty.h>
     41  1.1     fvdl #include <sys/file.h>
     42  1.1     fvdl #include <sys/filedesc.h>
     43  1.1     fvdl #include <sys/select.h>
     44  1.1     fvdl #include <sys/socket.h>
     45  1.1     fvdl #include <sys/socketvar.h>
     46  1.1     fvdl #include <net/if.h>
     47  1.1     fvdl #include <netinet/in.h>
     48  1.1     fvdl #include <sys/mount.h>
     49  1.1     fvdl #include <sys/proc.h>
     50  1.1     fvdl #include <sys/vnode.h>
     51  1.1     fvdl #include <sys/device.h>
     52  1.1     fvdl 
     53  1.1     fvdl #include <sys/syscallargs.h>
     54  1.1     fvdl 
     55  1.1     fvdl #include <compat/linux/linux_types.h>
     56  1.1     fvdl #include <compat/linux/linux_util.h>
     57  1.1     fvdl #include <compat/linux/linux_syscallargs.h>
     58  1.1     fvdl #include <compat/linux/linux_ioctl.h>
     59  1.1     fvdl #include <compat/linux/linux_socket.h>
     60  1.1     fvdl #include <compat/linux/linux_socketcall.h>
     61  1.1     fvdl #include <compat/linux/linux_sockio.h>
     62  1.1     fvdl 
     63  1.1     fvdl /*
     64  1.1     fvdl  * All the calls in this file are entered via one common system
     65  1.1     fvdl  * call in Linux, represented here by linux_socketcall()
     66  1.1     fvdl  * Arguments for the various calls are on the user stack. A pointer
     67  1.1     fvdl  * to them is the only thing that is passed. It is up to the various
     68  1.1     fvdl  * calls to copy them in themselves. To make it look better, they
     69  1.1     fvdl  * are copied to structures.
     70  1.1     fvdl  */
     71  1.1     fvdl 
     72  1.1     fvdl /*
     73  1.1     fvdl  * Convert between Linux and BSD socket domain values
     74  1.1     fvdl  */
     75  1.2  mycroft int
     76  1.1     fvdl linux_to_bsd_domain(ldom)
     77  1.1     fvdl 	int ldom;
     78  1.1     fvdl {
     79  1.1     fvdl 	switch (ldom) {
     80  1.1     fvdl 	case LINUX_AF_UNSPEC:
     81  1.1     fvdl 		return AF_UNSPEC;
     82  1.1     fvdl 	case LINUX_AF_UNIX:
     83  1.1     fvdl 		return AF_LOCAL;
     84  1.1     fvdl 	case LINUX_AF_INET:
     85  1.1     fvdl 		return AF_INET;
     86  1.1     fvdl 	case LINUX_AF_AX25:
     87  1.1     fvdl 		return AF_CCITT;
     88  1.1     fvdl 	case LINUX_AF_IPX:
     89  1.1     fvdl 		return AF_IPX;
     90  1.1     fvdl 	case LINUX_AF_APPLETALK:
     91  1.1     fvdl 		return AF_APPLETALK;
     92  1.1     fvdl 	default:
     93  1.1     fvdl 		return -1;
     94  1.1     fvdl 	}
     95  1.1     fvdl }
     96  1.1     fvdl 
     97  1.2  mycroft int
     98  1.1     fvdl linux_socket(p, args, retval)
     99  1.1     fvdl 	struct proc *p;
    100  1.1     fvdl 	struct linux_socket_args /* {
    101  1.1     fvdl 		syscallarg(int)	domain;
    102  1.1     fvdl 		syscallarg(int)	type;
    103  1.1     fvdl 		syscallarg(int) protocol;
    104  1.1     fvdl 	} */ *args;
    105  1.1     fvdl 	register_t *retval;
    106  1.1     fvdl {
    107  1.1     fvdl 	struct linux_socket_args lsa;
    108  1.1     fvdl 	struct socket_args bsa;
    109  1.1     fvdl 	int error;
    110  1.1     fvdl 
    111  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lsa, sizeof lsa)))
    112  1.1     fvdl 		return error;
    113  1.1     fvdl 
    114  1.1     fvdl 	SCARG(&bsa, protocol) = lsa.protocol;
    115  1.1     fvdl 	SCARG(&bsa, type) = lsa.type;
    116  1.1     fvdl 	SCARG(&bsa, domain) = linux_to_bsd_domain(lsa.domain);
    117  1.1     fvdl 	if (SCARG(&bsa, domain) == -1)
    118  1.1     fvdl 		return EINVAL;
    119  1.1     fvdl 	return socket(p, &bsa, retval);
    120  1.1     fvdl }
    121  1.1     fvdl 
    122  1.2  mycroft int
    123  1.1     fvdl linux_bind(p, args, retval)
    124  1.1     fvdl 	struct proc *p;
    125  1.1     fvdl 	struct linux_bind_args /* {
    126  1.1     fvdl 		syscallarg(int)	s;
    127  1.1     fvdl 		syscallarg(struct sockaddr *) name;
    128  1.1     fvdl 		syscallarg(int)	namelen;
    129  1.1     fvdl 	} */ *args;
    130  1.1     fvdl 	register_t *retval;
    131  1.1     fvdl {
    132  1.1     fvdl 	struct linux_bind_args lba;
    133  1.1     fvdl 	struct bind_args bba;
    134  1.1     fvdl 	int error;
    135  1.1     fvdl 
    136  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lba, sizeof lba)))
    137  1.1     fvdl 		return error;
    138  1.1     fvdl 
    139  1.1     fvdl 	SCARG(&bba, s) = lba.s;
    140  1.1     fvdl 	SCARG(&bba, name) = (caddr_t) lba.name;
    141  1.1     fvdl 	SCARG(&bba, namelen) = lba.namelen;
    142  1.1     fvdl 
    143  1.1     fvdl 	return bind(p, &bba, retval);
    144  1.1     fvdl }
    145  1.1     fvdl 
    146  1.2  mycroft int
    147  1.1     fvdl linux_connect(p, args, retval)
    148  1.1     fvdl 	struct proc *p;
    149  1.1     fvdl 	struct linux_connect_args /* {
    150  1.1     fvdl 		syscallarg(int)	s;
    151  1.1     fvdl 		syscallarg(struct sockaddr *) name;
    152  1.1     fvdl 		syscallarg(int)	namelen;
    153  1.1     fvdl 	} */ *args;
    154  1.1     fvdl 	register_t *retval;
    155  1.1     fvdl {
    156  1.1     fvdl 	struct linux_connect_args lca;
    157  1.1     fvdl 	struct connect_args bca;
    158  1.1     fvdl 	int error;
    159  1.1     fvdl 
    160  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lca, sizeof lca)))
    161  1.1     fvdl 		return error;
    162  1.1     fvdl 
    163  1.1     fvdl 	SCARG(&bca, s) = lca.s;
    164  1.1     fvdl 	SCARG(&bca, name) = (caddr_t) lca.name;
    165  1.1     fvdl 	SCARG(&bca, namelen) = lca.namelen;
    166  1.1     fvdl 
    167  1.1     fvdl 	return connect(p, &bca, retval);
    168  1.1     fvdl }
    169  1.1     fvdl 
    170  1.2  mycroft int
    171  1.1     fvdl linux_listen(p, args, retval)
    172  1.1     fvdl 	struct proc *p;
    173  1.1     fvdl 	struct linux_listen_args /* {
    174  1.1     fvdl 		syscallarg(int) s;
    175  1.1     fvdl 		syscallarg(int) backlog;
    176  1.1     fvdl 	} */ *args;
    177  1.1     fvdl 	register *retval;
    178  1.1     fvdl {
    179  1.1     fvdl 	struct linux_listen_args lla;
    180  1.1     fvdl 	struct listen_args bla;
    181  1.1     fvdl 	int error;
    182  1.1     fvdl 
    183  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lla, sizeof lla)))
    184  1.1     fvdl 		return error;
    185  1.1     fvdl 
    186  1.1     fvdl 	SCARG(&bla, s) = lla.s;
    187  1.1     fvdl 	SCARG(&bla, backlog) = lla.backlog;
    188  1.1     fvdl 
    189  1.1     fvdl 	return listen(p, &bla, retval);
    190  1.1     fvdl }
    191  1.1     fvdl 
    192  1.2  mycroft int
    193  1.1     fvdl linux_accept(p, args, retval)
    194  1.1     fvdl 	struct proc *p;
    195  1.1     fvdl 	struct linux_accept_args /* {
    196  1.1     fvdl 		syscallarg(int) s;
    197  1.1     fvdl 		syscallarg(struct sockaddr *) addr;
    198  1.1     fvdl 		syscallarg(int *) namelen;
    199  1.1     fvdl 	} */ *args;
    200  1.1     fvdl 	register_t *retval;
    201  1.1     fvdl {
    202  1.1     fvdl 	struct linux_accept_args laa;
    203  1.1     fvdl 	struct compat_43_accept_args baa;
    204  1.1     fvdl 	int error;
    205  1.1     fvdl 
    206  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &laa, sizeof laa)))
    207  1.1     fvdl 		return error;
    208  1.1     fvdl 
    209  1.1     fvdl 	SCARG(&baa, s) = laa.s;
    210  1.1     fvdl 	SCARG(&baa, name) = (caddr_t) laa.addr;
    211  1.1     fvdl 	SCARG(&baa, anamelen) = laa.namelen;
    212  1.1     fvdl 
    213  1.1     fvdl 	return compat_43_accept(p, &baa, retval);
    214  1.1     fvdl }
    215  1.1     fvdl 
    216  1.2  mycroft int
    217  1.1     fvdl linux_getsockname(p, args, retval)
    218  1.1     fvdl 	struct proc *p;
    219  1.1     fvdl 	struct linux_getsockname_args /* {
    220  1.1     fvdl 		syscallarg(int) s;
    221  1.1     fvdl 		syscallarg(struct sockaddr *) addr;
    222  1.1     fvdl 		syscallarg(int *) namelen;
    223  1.1     fvdl 	} */ *args;
    224  1.1     fvdl 	register_t *retval;
    225  1.1     fvdl {
    226  1.1     fvdl 	struct linux_getsockname_args lga;
    227  1.1     fvdl 	struct compat_43_getsockname_args bga;
    228  1.1     fvdl 	int error;
    229  1.1     fvdl 
    230  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lga, sizeof lga)))
    231  1.1     fvdl 		return error;
    232  1.1     fvdl 
    233  1.1     fvdl 	SCARG(&bga, fdec) = lga.s;
    234  1.1     fvdl 	SCARG(&bga, asa) = (caddr_t) lga.addr;
    235  1.1     fvdl 	SCARG(&bga, alen) = lga.namelen;
    236  1.1     fvdl 
    237  1.1     fvdl 	return compat_43_getsockname(p, &bga, retval);
    238  1.1     fvdl }
    239  1.1     fvdl 
    240  1.2  mycroft int
    241  1.1     fvdl linux_getpeername(p, args, retval)
    242  1.1     fvdl 	struct proc *p;
    243  1.1     fvdl 	struct linux_getpeername_args /* {
    244  1.1     fvdl 		syscallarg(int) s;
    245  1.1     fvdl 		syscallarg(struct sockaddr *) addr;
    246  1.1     fvdl 		syscallarg(int *) namelen;
    247  1.1     fvdl 	} */ *args;
    248  1.1     fvdl 	register_t *retval;
    249  1.1     fvdl {
    250  1.1     fvdl 	struct linux_getpeername_args lga;
    251  1.1     fvdl 	struct compat_43_getpeername_args bga;
    252  1.1     fvdl 	int error;
    253  1.1     fvdl 
    254  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lga, sizeof lga)))
    255  1.1     fvdl 		return error;
    256  1.1     fvdl 
    257  1.1     fvdl 	SCARG(&bga, fdes) = lga.s;
    258  1.1     fvdl 	SCARG(&bga, asa) = (caddr_t) lga.addr;
    259  1.1     fvdl 	SCARG(&bga, alen) = lga.namelen;
    260  1.1     fvdl 
    261  1.1     fvdl 	return compat_43_getpeername(p, &bga, retval);
    262  1.1     fvdl }
    263  1.1     fvdl 
    264  1.2  mycroft int
    265  1.1     fvdl linux_socketpair(p, args, retval)
    266  1.1     fvdl 	struct proc *p;
    267  1.1     fvdl 	struct linux_socketpair_args /* {
    268  1.1     fvdl 		syscallarg(int) domain;
    269  1.1     fvdl 		syscallarg(int) type;
    270  1.1     fvdl 		syscallarg(int) protocol;
    271  1.1     fvdl 		syscallarg(int *) rsv;
    272  1.1     fvdl 	} */ *args;
    273  1.1     fvdl 	register_t *retval;
    274  1.1     fvdl {
    275  1.1     fvdl 	struct linux_socketpair_args lsa;
    276  1.1     fvdl 	struct socketpair_args bsa;
    277  1.1     fvdl 	int error;
    278  1.1     fvdl 
    279  1.1     fvdl 	if ((error = copyin((caddr_t) args, &lsa, sizeof lsa)))
    280  1.1     fvdl 		return error;
    281  1.1     fvdl 
    282  1.1     fvdl 	SCARG(&bsa, domain) = linux_to_bsd_domain(lsa.domain);
    283  1.1     fvdl 	if (SCARG(&bsa, domain) == -1)
    284  1.1     fvdl 		return EINVAL;
    285  1.1     fvdl 	SCARG(&bsa, type) = lsa.type;
    286  1.1     fvdl 	SCARG(&bsa, protocol) = lsa.protocol;
    287  1.1     fvdl 	SCARG(&bsa, rsv) = lsa.rsv;
    288  1.1     fvdl 
    289  1.1     fvdl 	return socketpair(p, &bsa, retval);
    290  1.1     fvdl }
    291  1.1     fvdl 
    292  1.2  mycroft int
    293  1.1     fvdl linux_send(p, args, retval)
    294  1.1     fvdl 	struct proc *p;
    295  1.1     fvdl 	struct linux_send_args /* {
    296  1.1     fvdl 		syscallarg(int) s;
    297  1.1     fvdl 		syscallarg(void *) msg;
    298  1.1     fvdl 		syscallarg(int) len;
    299  1.1     fvdl 		syscallarg(int) flags;
    300  1.1     fvdl 	} */ *args;
    301  1.1     fvdl 	register_t *retval;
    302  1.1     fvdl {
    303  1.1     fvdl 	struct linux_send_args lsa;
    304  1.1     fvdl 	struct compat_43_send_args bsa;
    305  1.1     fvdl 	int error;
    306  1.1     fvdl 
    307  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lsa, sizeof lsa)))
    308  1.1     fvdl 		return error;
    309  1.1     fvdl 
    310  1.1     fvdl 	SCARG(&bsa, s) = lsa.s;
    311  1.1     fvdl 	SCARG(&bsa, buf) = lsa.msg;
    312  1.1     fvdl 	SCARG(&bsa, len) = lsa.len;
    313  1.1     fvdl 	SCARG(&bsa, flags) = lsa.flags;
    314  1.1     fvdl 
    315  1.1     fvdl 	return compat_43_send(p, &bsa, retval);
    316  1.1     fvdl }
    317  1.1     fvdl 
    318  1.2  mycroft int
    319  1.1     fvdl linux_recv(p, args, retval)
    320  1.1     fvdl 	struct proc *p;
    321  1.1     fvdl 	struct linux_recv_args *args;
    322  1.1     fvdl 	register_t *retval;
    323  1.1     fvdl {
    324  1.1     fvdl 	struct linux_recv_args lra;
    325  1.1     fvdl 	struct compat_43_recv_args bra;
    326  1.1     fvdl 	int error;
    327  1.1     fvdl 
    328  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lra, sizeof lra)))
    329  1.1     fvdl 		return error;
    330  1.1     fvdl 
    331  1.1     fvdl 	SCARG(&bra, s) = lra.s;
    332  1.1     fvdl 	SCARG(&bra, buf) = lra.msg;
    333  1.1     fvdl 	SCARG(&bra, len) = lra.len;
    334  1.1     fvdl 	SCARG(&bra, flags) = lra.flags;
    335  1.1     fvdl 
    336  1.1     fvdl 	return compat_43_recv(p, &bra, retval);
    337  1.1     fvdl }
    338  1.1     fvdl 
    339  1.2  mycroft int
    340  1.1     fvdl linux_sendto(p, args, retval)
    341  1.1     fvdl 	struct proc *p;
    342  1.1     fvdl 	struct linux_sendto_args /* {
    343  1.1     fvdl 		syscallarg(int) s;
    344  1.1     fvdl 		syscallarg(void *) msg;
    345  1.1     fvdl 		syscallarg(int) len;
    346  1.1     fvdl 		syscallarg(int) flags;
    347  1.1     fvdl 		syscallarg(sockaddr *) to;
    348  1.1     fvdl 		syscallarg(int) tolen;
    349  1.1     fvdl 	} */ *args;
    350  1.1     fvdl 	register_t *retval;
    351  1.1     fvdl {
    352  1.1     fvdl 	struct linux_sendto_args lsa;
    353  1.1     fvdl 	struct sendto_args bsa;
    354  1.1     fvdl 	int error;
    355  1.1     fvdl 
    356  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lsa, sizeof lsa)))
    357  1.1     fvdl 		return error;
    358  1.1     fvdl 
    359  1.1     fvdl 	SCARG(&bsa, s) = lsa.s;
    360  1.1     fvdl 	SCARG(&bsa, buf) = lsa.msg;
    361  1.1     fvdl 	SCARG(&bsa, len) = lsa.len;
    362  1.1     fvdl 	SCARG(&bsa, flags) = lsa.flags;
    363  1.1     fvdl 	SCARG(&bsa, to) = (caddr_t) lsa.to;
    364  1.1     fvdl 	SCARG(&bsa, tolen) = lsa.tolen;
    365  1.1     fvdl 
    366  1.1     fvdl 	return sendto(p, &bsa, retval);
    367  1.1     fvdl }
    368  1.1     fvdl 
    369  1.2  mycroft int
    370  1.1     fvdl linux_recvfrom(p, args, retval)
    371  1.1     fvdl 	struct proc *p;
    372  1.1     fvdl 	struct linux_recvfrom_args /* {
    373  1.1     fvdl 		syscallarg(int) s;
    374  1.1     fvdl 		syscallarg(void *) buf;
    375  1.1     fvdl 		syscallarg(int) len;
    376  1.1     fvdl 		syscallarg(int) flags;
    377  1.1     fvdl 		syscallarg(struct sockaddr *) from;
    378  1.1     fvdl 		syscallarg(int *) fromlen;
    379  1.1     fvdl 	} */ *args;
    380  1.1     fvdl {
    381  1.1     fvdl 	struct linux_recvfrom_args lra;
    382  1.1     fvdl 	struct compat_43_recvfrom_args bra;
    383  1.1     fvdl 	int error;
    384  1.1     fvdl 
    385  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lra, sizeof lra)))
    386  1.1     fvdl 		return error;
    387  1.1     fvdl 
    388  1.1     fvdl 	SCARG(&bra, s) = lra.s;
    389  1.1     fvdl 	SCARG(&bra, buf) = lra.buf;
    390  1.1     fvdl 	SCARG(&bra, len) = lra.len;
    391  1.1     fvdl 	SCARG(&bra, flags) = lra.flags;
    392  1.1     fvdl 	SCARG(&bra, from) = (caddr_t) lra.from;
    393  1.1     fvdl 	SCARG(&bra, fromlenaddr) = lra.fromlen;
    394  1.1     fvdl 
    395  1.1     fvdl 	return compat_43_recvfrom(p, &bra, retval);
    396  1.1     fvdl }
    397  1.1     fvdl 
    398  1.2  mycroft int
    399  1.1     fvdl linux_shutdown(p, args, retval)
    400  1.1     fvdl 	struct proc *p;
    401  1.1     fvdl 	struct linux_shutdown_args /* {
    402  1.1     fvdl 		syscallarg(int) s;
    403  1.1     fvdl 		syscallarg(int) how;
    404  1.1     fvdl 	} */ *args;
    405  1.1     fvdl 	register_t *retval;
    406  1.1     fvdl {
    407  1.1     fvdl 	struct linux_shutdown_args lsa;
    408  1.1     fvdl 	struct shutdown_args bsa;
    409  1.1     fvdl 	int error;
    410  1.1     fvdl 
    411  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lsa, sizeof lsa)))
    412  1.1     fvdl 		return error;
    413  1.1     fvdl 
    414  1.1     fvdl 	SCARG(&bsa, s) = lsa.s;
    415  1.1     fvdl 	SCARG(&bsa, how) = lsa.how;
    416  1.1     fvdl 
    417  1.1     fvdl 	return shutdown(p, &bsa, retval);
    418  1.1     fvdl }
    419  1.1     fvdl 
    420  1.1     fvdl /*
    421  1.1     fvdl  * Convert socket option level from Linux to NetBSD value. Only SOL_SOCKET
    422  1.1     fvdl  * is different, the rest matches IPPROTO_* on both systems.
    423  1.1     fvdl  */
    424  1.2  mycroft int
    425  1.1     fvdl linux_to_bsd_sopt_level(llevel)
    426  1.1     fvdl 	int llevel;
    427  1.1     fvdl {
    428  1.1     fvdl 	switch (llevel) {
    429  1.1     fvdl 	case LINUX_SOL_SOCKET:
    430  1.1     fvdl 		return SOL_SOCKET;
    431  1.1     fvdl 	default:
    432  1.1     fvdl 		return llevel;
    433  1.1     fvdl 	}
    434  1.1     fvdl }
    435  1.1     fvdl 
    436  1.1     fvdl /*
    437  1.1     fvdl  * Convert Linux IP level socket option number to NetBSD values.
    438  1.1     fvdl  * Linux only implements IP_TOS and IP_TTL
    439  1.1     fvdl  */
    440  1.2  mycroft int
    441  1.2  mycroft linux_to_bsd_ip_sockopt(lopt)
    442  1.1     fvdl 	int lopt;
    443  1.1     fvdl {
    444  1.1     fvdl 	switch (lopt) {
    445  1.1     fvdl 	case LINUX_IP_TOS:
    446  1.1     fvdl 		return IP_TOS;
    447  1.1     fvdl 	case LINUX_IP_TTL:
    448  1.1     fvdl 		return IP_TTL;
    449  1.1     fvdl 	default:
    450  1.1     fvdl 		return -1;
    451  1.1     fvdl 	}
    452  1.1     fvdl }
    453  1.1     fvdl 
    454  1.1     fvdl /*
    455  1.1     fvdl  * Convert Linux socket level socket option numbers to NetBSD values.
    456  1.1     fvdl  */
    457  1.2  mycroft int
    458  1.1     fvdl linux_to_bsd_so_sockopt(lopt)
    459  1.1     fvdl 	int lopt;
    460  1.1     fvdl {
    461  1.1     fvdl 	switch (lopt) {
    462  1.1     fvdl 	case LINUX_SO_DEBUG:
    463  1.1     fvdl 		return SO_DEBUG;
    464  1.1     fvdl 	case LINUX_SO_REUSEADDR:
    465  1.1     fvdl 		return SO_REUSEADDR;
    466  1.1     fvdl 	case LINUX_SO_TYPE:
    467  1.1     fvdl 		return SO_TYPE;
    468  1.1     fvdl 	case LINUX_SO_ERROR:
    469  1.1     fvdl 		return SO_ERROR;
    470  1.1     fvdl 	case LINUX_SO_DONTROUTE:
    471  1.1     fvdl 		return SO_DONTROUTE;
    472  1.1     fvdl 	case LINUX_SO_BROADCAST:
    473  1.1     fvdl 		return SO_BROADCAST;
    474  1.1     fvdl 	case LINUX_SO_SNDBUF:
    475  1.1     fvdl 		return SO_SNDBUF;
    476  1.1     fvdl 	case LINUX_SO_RCVBUF:
    477  1.1     fvdl 		return SO_RCVBUF;
    478  1.1     fvdl 	case LINUX_SO_KEEPALIVE:
    479  1.1     fvdl 		return SO_KEEPALIVE;
    480  1.1     fvdl 	case LINUX_SO_OOBINLINE:
    481  1.1     fvdl 		return SO_OOBINLINE;
    482  1.1     fvdl 	case LINUX_SO_LINGER:
    483  1.1     fvdl 		return SO_LINGER;
    484  1.1     fvdl 	case LINUX_SO_PRIORITY:
    485  1.1     fvdl 	case LINUX_SO_NO_CHECK:
    486  1.1     fvdl 	default:
    487  1.1     fvdl 		return -1;
    488  1.1     fvdl 	}
    489  1.1     fvdl }
    490  1.1     fvdl 
    491  1.1     fvdl /*
    492  1.1     fvdl  * Another reasonably straightforward function: setsockopt(2). Only
    493  1.1     fvdl  * the SOL_SOCKET and IPPROTO_IP levels are implemented here.
    494  1.1     fvdl  * The level and option numbers are converted; the values passed
    495  1.1     fvdl  * are not (yet) converted, the ones currently implemented don't
    496  1.1     fvdl  * need conversion, as they are the same on both systems.
    497  1.1     fvdl  */
    498  1.2  mycroft int
    499  1.1     fvdl linux_setsockopt(p, args, retval)
    500  1.1     fvdl 	struct proc *p;
    501  1.1     fvdl 	struct linux_setsockopt_args /* {
    502  1.1     fvdl 		syscallarg(int) s;
    503  1.1     fvdl 		syscallarg(int) level;
    504  1.1     fvdl 		syscallarg(int) optname;
    505  1.1     fvdl 		syscallarg(void *) optval;
    506  1.1     fvdl 		syscallarg(int) optlen;
    507  1.1     fvdl 	} */ *args;
    508  1.1     fvdl 	register_t *retval;
    509  1.1     fvdl {
    510  1.1     fvdl 	struct linux_setsockopt_args lsa;
    511  1.1     fvdl 	struct setsockopt_args bsa;
    512  1.1     fvdl 	int error, name;
    513  1.1     fvdl 
    514  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lsa, sizeof lsa)))
    515  1.1     fvdl 		return error;
    516  1.1     fvdl 
    517  1.1     fvdl 	SCARG(&bsa, s) = lsa.s;
    518  1.1     fvdl 
    519  1.1     fvdl 	SCARG(&bsa, level) = linux_to_bsd_sopt_level(lsa.level);
    520  1.1     fvdl 
    521  1.1     fvdl 	switch (SCARG(&bsa, level)) {
    522  1.1     fvdl 		case SOL_SOCKET:
    523  1.1     fvdl 			name = linux_to_bsd_so_sockopt(lsa.optname);
    524  1.1     fvdl 			break;
    525  1.1     fvdl 		case IPPROTO_IP:
    526  1.1     fvdl 			name = linux_to_bsd_ip_sockopt(lsa.optname);
    527  1.1     fvdl 			break;
    528  1.1     fvdl 		default:
    529  1.1     fvdl 			return EINVAL;
    530  1.1     fvdl 	}
    531  1.1     fvdl 
    532  1.1     fvdl 	if (name == -1)
    533  1.1     fvdl 		return EINVAL;
    534  1.1     fvdl 	SCARG(&bsa, name) = name;
    535  1.1     fvdl 	SCARG(&bsa, val) = lsa.optval;
    536  1.1     fvdl 	SCARG(&bsa, valsize) = lsa.optlen;
    537  1.1     fvdl 
    538  1.1     fvdl 	return setsockopt(p, &bsa, retval);
    539  1.1     fvdl }
    540  1.1     fvdl 
    541  1.1     fvdl /*
    542  1.1     fvdl  * getsockopt(2) is very much the same as setsockopt(2) (see above)
    543  1.1     fvdl  */
    544  1.2  mycroft int
    545  1.1     fvdl linux_getsockopt(p, args, retval)
    546  1.1     fvdl 	struct proc *p;
    547  1.1     fvdl 	struct linux_getsockopt_args /* {
    548  1.1     fvdl 		syscallarg(int) s;
    549  1.1     fvdl 		syscallarg(int) level;
    550  1.1     fvdl 		syscallarg(int) optname;
    551  1.1     fvdl 		syscallarg(void *) optval;
    552  1.1     fvdl 		syscallarg(int) *optlen;
    553  1.1     fvdl 	} */ *args;
    554  1.1     fvdl 	register_t *retval;
    555  1.1     fvdl {
    556  1.1     fvdl 	struct linux_getsockopt_args lga;
    557  1.1     fvdl 	struct getsockopt_args bga;
    558  1.1     fvdl 	int error, name;
    559  1.1     fvdl 
    560  1.1     fvdl 	if ((error = copyin((caddr_t) args, (caddr_t) &lga, sizeof lga)))
    561  1.1     fvdl 		return error;
    562  1.1     fvdl 
    563  1.1     fvdl 	SCARG(&bga, s) = lga.s;
    564  1.1     fvdl 
    565  1.1     fvdl 	SCARG(&bga, level) = linux_to_bsd_sopt_level(lga.level);
    566  1.1     fvdl 
    567  1.1     fvdl 	switch (SCARG(&bga, level)) {
    568  1.1     fvdl 		case SOL_SOCKET:
    569  1.1     fvdl 			name = linux_to_bsd_so_sockopt(lga.optname);
    570  1.1     fvdl 			break;
    571  1.1     fvdl 		case IPPROTO_IP:
    572  1.1     fvdl 			name = linux_to_bsd_ip_sockopt(lga.optname);
    573  1.1     fvdl 			break;
    574  1.1     fvdl 		default:
    575  1.1     fvdl 			return EINVAL;
    576  1.1     fvdl 	}
    577  1.1     fvdl 
    578  1.1     fvdl 	if (name == -1)
    579  1.1     fvdl 		return EINVAL;
    580  1.1     fvdl 	SCARG(&bga, val) = lga.optval;
    581  1.1     fvdl 	SCARG(&bga, avalsize) = lga.optlen;
    582  1.1     fvdl 
    583  1.1     fvdl 	return getsockopt(p, &bga, retval);
    584  1.1     fvdl }
    585  1.1     fvdl 
    586  1.1     fvdl /*
    587  1.1     fvdl  * Entry point to all Linux socket calls. Just check which call to
    588  1.1     fvdl  * make and take appropriate action.
    589  1.1     fvdl  */
    590  1.1     fvdl int
    591  1.1     fvdl linux_socketcall(p, uap, retval)
    592  1.1     fvdl 	struct proc *p;
    593  1.1     fvdl 	struct linux_socketcall_args /* {
    594  1.1     fvdl 		syscallarg(int) what;
    595  1.1     fvdl 		syscallarg(void *) args;
    596  1.1     fvdl 	} */ *uap;
    597  1.1     fvdl 	register_t *retval;
    598  1.1     fvdl {
    599  1.1     fvdl 	switch (SCARG(uap, what)) {
    600  1.1     fvdl 	case LINUX_SYS_socket:
    601  1.1     fvdl 		return linux_socket(p, SCARG(uap, args), retval);
    602  1.1     fvdl 	case LINUX_SYS_bind:
    603  1.1     fvdl 		return linux_bind(p, SCARG(uap, args), retval);
    604  1.1     fvdl 	case LINUX_SYS_connect:
    605  1.1     fvdl 		return linux_connect(p, SCARG(uap, args), retval);
    606  1.1     fvdl 	case LINUX_SYS_listen:
    607  1.1     fvdl 		return linux_listen(p, SCARG(uap, args), retval);
    608  1.1     fvdl 	case LINUX_SYS_accept:
    609  1.1     fvdl 		return linux_accept(p, SCARG(uap, args), retval);
    610  1.1     fvdl 	case LINUX_SYS_getsockname:
    611  1.1     fvdl 		return linux_getsockname(p, SCARG(uap, args), retval);
    612  1.1     fvdl 	case LINUX_SYS_getpeername:
    613  1.1     fvdl 		return linux_getpeername(p, SCARG(uap, args), retval);
    614  1.1     fvdl 	case LINUX_SYS_socketpair:
    615  1.1     fvdl 		return linux_socketpair(p, SCARG(uap, args), retval);
    616  1.1     fvdl 	case LINUX_SYS_send:
    617  1.1     fvdl 		return linux_send(p, SCARG(uap, args), retval);
    618  1.1     fvdl 	case LINUX_SYS_recv:
    619  1.1     fvdl 		return linux_recv(p, SCARG(uap, args), retval);
    620  1.1     fvdl 	case LINUX_SYS_sendto:
    621  1.1     fvdl 		return linux_sendto(p, SCARG(uap, args), retval);
    622  1.1     fvdl 	case LINUX_SYS_recvfrom:
    623  1.1     fvdl 		return linux_recvfrom(p, SCARG(uap, args), retval);
    624  1.1     fvdl 	case LINUX_SYS_shutdown:
    625  1.1     fvdl 		return linux_shutdown(p, SCARG(uap, args), retval);
    626  1.1     fvdl 	case LINUX_SYS_setsockopt:
    627  1.1     fvdl 		return linux_setsockopt(p, SCARG(uap, args), retval);
    628  1.1     fvdl 	case LINUX_SYS_getsockopt:
    629  1.1     fvdl 		return linux_getsockopt(p, SCARG(uap, args), retval);
    630  1.1     fvdl 	default:
    631  1.1     fvdl 		return ENOSYS;
    632  1.1     fvdl 	}
    633  1.1     fvdl }
    634