[BACK]Return to linux_socket.c CVS log [TXT][DIR] Up to [local] / sys / compat / linux

Annotation of sys/compat/linux/linux_socket.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: linux_socket.c,v 1.36 2007/06/06 09:59:21 henning Exp $       */
                      2: /*     $NetBSD: linux_socket.c,v 1.14 1996/04/05 00:01:50 christos Exp $       */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Frank van der Linden
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *      This product includes software developed for the NetBSD Project
                     19:  *      by Frank van der Linden
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include <sys/param.h>
                     36: #include <sys/kernel.h>
                     37: #include <sys/systm.h>
                     38: #include <sys/buf.h>
                     39: #include <sys/malloc.h>
                     40: #include <sys/ioctl.h>
                     41: #include <sys/tty.h>
                     42: #include <sys/file.h>
                     43: #include <sys/filedesc.h>
                     44: #include <sys/selinfo.h>
                     45: #include <sys/socket.h>
                     46: #include <sys/socketvar.h>
                     47: #include <net/if.h>
                     48: #include <net/if_types.h>
                     49: #include <net/if_dl.h>
                     50: #include <netinet/in.h>
                     51: #include <netinet/in_systm.h>
                     52: #include <netinet/ip.h>
                     53: #include <netinet/tcp.h>
                     54: #include <sys/mount.h>
                     55: #include <sys/proc.h>
                     56: #include <sys/vnode.h>
                     57: #include <sys/device.h>
                     58:
                     59: #include <sys/syscallargs.h>
                     60:
                     61: #include <compat/linux/linux_types.h>
                     62: #include <compat/linux/linux_util.h>
                     63: #include <compat/linux/linux_signal.h>
                     64: #include <compat/linux/linux_syscallargs.h>
                     65: #include <compat/linux/linux_ioctl.h>
                     66: #include <compat/linux/linux_socket.h>
                     67: #include <compat/linux/linux_socketcall.h>
                     68: #include <compat/linux/linux_sockio.h>
                     69:
                     70: /*
                     71:  * All the calls in this file are entered via one common system
                     72:  * call in Linux, represented here by linux_socketcall()
                     73:  * Arguments for the various calls are on the user stack. A pointer
                     74:  * to them is the only thing that is passed. It is up to the various
                     75:  * calls to copy them in themselves. To make it look better, they
                     76:  * are copied to structures.
                     77:  */
                     78:
                     79: static int linux_to_bsd_domain (int);
                     80: static int bsd_to_linux_domain(int);
                     81:
                     82: int linux_socket(struct proc *, void *, register_t *);
                     83: int linux_bind(struct proc *, void *, register_t *);
                     84: int linux_connect(struct proc *, void *, register_t *);
                     85: int linux_listen(struct proc *, void *, register_t *);
                     86: int linux_accept(struct proc *, void *, register_t *);
                     87: int linux_getsockname(struct proc *, void *, register_t *);
                     88: int linux_getpeername(struct proc *, void *, register_t *);
                     89: int linux_socketpair(struct proc *, void *, register_t *);
                     90: int linux_send(struct proc *, void *, register_t *);
                     91: int linux_recv(struct proc *, void *, register_t *);
                     92: int linux_sendto(struct proc *, void *, register_t *);
                     93: int linux_recvfrom(struct proc *, void *, register_t *);
                     94: int linux_shutdown(struct proc *, void *, register_t *);
                     95: int linux_to_bsd_sopt_level(int);
                     96: int linux_to_bsd_so_sockopt(int);
                     97: int linux_to_bsd_ip_sockopt(int);
                     98: int linux_to_bsd_tcp_sockopt(int);
                     99: int linux_to_bsd_udp_sockopt(int);
                    100: int linux_setsockopt(struct proc *, void *, register_t *);
                    101: int linux_getsockopt(struct proc *, void *, register_t *);
                    102: int linux_recvmsg(struct proc *, void *, register_t *);
                    103: int linux_sendmsg(struct proc *, void *, register_t *);
                    104:
                    105: int linux_check_hdrincl(struct proc *, int, register_t *, caddr_t *);
                    106: int linux_sendto_hdrincl(struct proc *, struct sys_sendto_args *,
                    107:     register_t *, caddr_t *);
                    108:
                    109: int linux_sa_get(struct proc *, caddr_t *, struct sockaddr **,
                    110:     const struct osockaddr *, int *);
                    111: int linux_sa_put(struct osockaddr *);
                    112:
                    113: static const int linux_to_bsd_domain_[LINUX_AF_MAX] = {
                    114:        AF_UNSPEC,
                    115:        AF_UNIX,
                    116:        AF_INET,
                    117:        -1,             /* LINUX_AF_AX25 */
                    118:        -1,             /* IPX */
                    119:        AF_APPLETALK,
                    120:        -1,             /* LINUX_AF_NETROM */
                    121:        -1,             /* LINUX_AF_BRIDGE */
                    122:        -1,             /* LINUX_AF_ATMPVC */
                    123:        -1,             /* LINUX_AF_X25 */
                    124:        AF_INET6,
                    125:        -1,             /* LINUX_AF_ROSE */
                    126:        AF_DECnet,
                    127:        -1,             /* LINUX_AF_NETBEUI */
                    128:        -1,             /* LINUX_AF_SECURITY */
                    129:        -1,             /* pseudo_AF_KEY */
                    130:        AF_ROUTE,       /* LINUX_AF_NETLINK */
                    131:        -1,             /* LINUX_AF_PACKET */
                    132:        -1,             /* LINUX_AF_ASH */
                    133:        -1,             /* LINUX_AF_ECONET */
                    134:        -1,             /* LINUX_AF_ATMSVC */
                    135:        AF_SNA,
                    136:        /* rest up to LINUX_AF_MAX-1 is not allocated */
                    137:        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    138: };
                    139:
                    140: static const int bsd_to_linux_domain_[AF_MAX] = {
                    141:        LINUX_AF_UNSPEC,
                    142:        LINUX_AF_UNIX,
                    143:        LINUX_AF_INET,
                    144:        -1,             /* AF_IMPLINK */
                    145:        -1,             /* AF_PUP */
                    146:        -1,             /* AF_CHAOS */
                    147:        -1,             /* AF_NS */
                    148:        -1,             /* AF_ISO */
                    149:        -1,             /* AF_ECMA */
                    150:        -1,             /* AF_DATAKIT */
                    151:        -1,             /* AF_CCITT */
                    152:        -1,             /* LINUX_AF_SNA */
                    153:        -1,             /* LINUX_AF_DECnet */
                    154:        -1,             /* AF_DLI */
                    155:        -1,             /* AF_LAT */
                    156:        -1,             /* AF_HYLINK */
                    157:        LINUX_AF_APPLETALK,
                    158:        -1,             /* LINUX_AF_NETLINK */
                    159:        -1,             /* AF_LINK */
                    160:        -1,             /* AF_XTP */
                    161:        -1,             /* AF_COIP */
                    162:        -1,             /* AF_CNT */
                    163:        -1,             /* pseudo_AF_RTIP */
                    164:        LINUX_AF_IPX,
                    165:        LINUX_AF_INET6,
                    166:        -1,             /* pseudo_AF_PIP */
                    167:        -1,             /* AF_ISDN */
                    168:        -1,             /* AF_NATM */
                    169:        -1,             /* AF_ARP */
                    170:        -1,             /* LINUX_pseudo_AF_KEY */
                    171:        -1,             /* pseudo_AF_HDRCMPLT */
                    172: };
                    173:
                    174: /*
                    175:  * Convert between Linux and BSD socket domain values
                    176:  */
                    177: static int
                    178: linux_to_bsd_domain(ldom)
                    179:        int ldom;
                    180: {
                    181:        if (ldom < 0 || ldom >= LINUX_AF_MAX)
                    182:                return (-1);
                    183:
                    184:        return linux_to_bsd_domain_[ldom];
                    185: }
                    186:
                    187: /*
                    188:  * Convert between BSD and Linux socket domain values
                    189:  */
                    190: static int
                    191: bsd_to_linux_domain(bdom)
                    192:        int bdom;
                    193: {
                    194:        if (bdom < 0 || bdom >= AF_MAX)
                    195:                return (-1);
                    196:
                    197:        return bsd_to_linux_domain_[bdom];
                    198: }
                    199:
                    200: int
                    201: linux_socket(p, v, retval)
                    202:        struct proc *p;
                    203:        void *v;
                    204:        register_t *retval;
                    205: {
                    206:        struct linux_socket_args /* {
                    207:                syscallarg(int) domain;
                    208:                syscallarg(int) type;
                    209:                syscallarg(int) protocol;
                    210:        } */ *uap = v;
                    211:        struct linux_socket_args lsa;
                    212:        struct sys_socket_args bsa;
                    213:        int error;
                    214:
                    215:        if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa)))
                    216:                return error;
                    217:
                    218:        SCARG(&bsa, protocol) = lsa.protocol;
                    219:        SCARG(&bsa, type) = lsa.type;
                    220:        SCARG(&bsa, domain) = linux_to_bsd_domain(lsa.domain);
                    221:        if (SCARG(&bsa, domain) == -1)
                    222:                return EINVAL;
                    223:        return sys_socket(p, &bsa, retval);
                    224: }
                    225:
                    226: int
                    227: linux_bind(p, v, retval)
                    228:        struct proc *p;
                    229:        void *v;
                    230:        register_t *retval;
                    231: {
                    232:        struct linux_bind_args /* {
                    233:                syscallarg(int) s;
                    234:                syscallarg(struct sockaddr *) name;
                    235:                syscallarg(int) namelen;
                    236:        } */ *uap = v;
                    237:        struct linux_bind_args lba;
                    238:        struct sys_bind_args bba;
                    239:        int error;
                    240:        int namlen;
                    241:
                    242:        if ((error = copyin((caddr_t) uap, (caddr_t) &lba, sizeof lba)))
                    243:                return error;
                    244:
                    245:        SCARG(&bba, s) = lba.s;
                    246:        namlen = lba.namelen;
                    247:        if (lba.name) {
                    248:                struct sockaddr *sa;
                    249:                caddr_t sg = stackgap_init(p->p_emul);
                    250:
                    251:                error = linux_sa_get(p, &sg, &sa, lba.name, &namlen);
                    252:                if (error)
                    253:                        return (error);
                    254:                SCARG(&bba, name) = sa;
                    255:        } else
                    256:                SCARG(&bba, name) = NULL;
                    257:        SCARG(&bba, namelen) = namlen;
                    258:
                    259:        return sys_bind(p, &bba, retval);
                    260: }
                    261:
                    262: int
                    263: linux_connect(p, v, retval)
                    264:        struct proc *p;
                    265:        void *v;
                    266:        register_t *retval;
                    267: {
                    268:        struct linux_connect_args /* {
                    269:                syscallarg(int) s;
                    270:                syscallarg(struct osockaddr *) name;
                    271:                syscallarg(int) namelen;
                    272:        } */ *uap = v;
                    273:        struct linux_connect_args lca;
                    274:        struct sys_connect_args bca;
                    275:        struct sockaddr *sa;
                    276:        caddr_t sg = stackgap_init(p->p_emul);
                    277:        int namlen;
                    278:        int error;
                    279:
                    280:        if ((error = copyin((caddr_t) uap, (caddr_t) &lca, sizeof lca)))
                    281:                return error;
                    282:
                    283:        namlen = lca.namelen;
                    284:        error = linux_sa_get(p, &sg, &sa, lca.name, &namlen);
                    285:        if (error)
                    286:                return (error);
                    287:
                    288:        SCARG(&bca, s) = lca.s;
                    289:        SCARG(&bca, name) = sa;
                    290:        SCARG(&bca, namelen) = (unsigned int)namlen;
                    291:
                    292:        error = sys_connect(p, &bca, retval);
                    293:
                    294:        if (error == EISCONN) {
                    295:                struct sys_getsockopt_args bga;
                    296: #if 0
                    297:                struct sys_fcntl_args fca;
                    298: #endif
                    299:                void *status, *statusl;
                    300:                int stat, statl = sizeof stat;
                    301:
                    302: #if 0
                    303:                SCARG(&fca, fd) = lca.s;
                    304:                SCARG(&fca, cmd) = F_GETFL;
                    305:                SCARG(&fca, arg) = 0;
                    306:                if (sys_fcntl(p, &fca, retval) == -1 ||
                    307:                    (*retval & O_NONBLOCK) == 0)
                    308:                        return error;
                    309: #endif
                    310:
                    311:                status = stackgap_alloc(&sg, sizeof stat);
                    312:                statusl = stackgap_alloc(&sg, sizeof statusl);
                    313:
                    314:                if ((error = copyout(&statl, statusl, sizeof statl)))
                    315:                        return error;
                    316:
                    317:                SCARG(&bga, s) = lca.s;
                    318:                SCARG(&bga, level) = SOL_SOCKET;
                    319:                SCARG(&bga, name) = SO_ERROR;
                    320:                SCARG(&bga, val) = status;
                    321:                SCARG(&bga, avalsize) = statusl;
                    322:
                    323:                error = sys_getsockopt(p, &bga, retval);
                    324:                if (error)
                    325:                        return error;
                    326:                if ((error = copyin(status, &stat, sizeof stat)))
                    327:                        return error;
                    328:                return stat;
                    329:        }
                    330:        return error;
                    331: }
                    332:
                    333: int
                    334: linux_listen(p, v, retval)
                    335:        struct proc *p;
                    336:        void *v;
                    337:        register_t *retval;
                    338: {
                    339:        struct linux_listen_args /* {
                    340:                syscallarg(int) s;
                    341:                syscallarg(int) backlog;
                    342:        } */ *uap = v;
                    343:        struct linux_listen_args lla;
                    344:        struct sys_listen_args bla;
                    345:        int error;
                    346:
                    347:        if ((error = copyin((caddr_t) uap, (caddr_t) &lla, sizeof lla)))
                    348:                return error;
                    349:
                    350:        SCARG(&bla, s) = lla.s;
                    351:        SCARG(&bla, backlog) = lla.backlog;
                    352:
                    353:        return sys_listen(p, &bla, retval);
                    354: }
                    355:
                    356: int
                    357: linux_accept(p, v, retval)
                    358:        struct proc *p;
                    359:        void *v;
                    360:        register_t *retval;
                    361: {
                    362:        struct linux_accept_args /* {
                    363:                syscallarg(int) s;
                    364:                syscallarg(struct sockaddr *) addr;
                    365:                syscallarg(int *) namelen;
                    366:        } */ *uap = v;
                    367:        struct linux_accept_args laa;
                    368:        struct compat_43_sys_accept_args baa;
                    369:        struct sys_fcntl_args fca;
                    370:        int error;
                    371:
                    372:        if ((error = copyin((caddr_t) uap, (caddr_t) &laa, sizeof laa)))
                    373:                return error;
                    374:
                    375:        SCARG(&baa, s) = laa.s;
                    376:        SCARG(&baa, name) = (caddr_t) laa.addr;
                    377:        SCARG(&baa, anamelen) = laa.namelen;
                    378:
                    379:        error = compat_43_sys_accept(p, &baa, retval);
                    380:        if (error)
                    381:                return (error);
                    382:
                    383:        /*
                    384:         * linux appears not to copy flags from the parent socket to the
                    385:         * accepted one, so we must clear the flags in the new descriptor.
                    386:         * Ignore any errors, because we already have an open fd.
                    387:         */
                    388:        SCARG(&fca, fd) = *retval;
                    389:        SCARG(&fca, cmd) = F_SETFL;
                    390:        SCARG(&fca, arg) = 0;
                    391:        (void)sys_fcntl(p, &fca, retval);
                    392:        *retval = SCARG(&fca, fd);
                    393:        return (0);
                    394: }
                    395:
                    396: int
                    397: linux_getsockname(p, v, retval)
                    398:        struct proc *p;
                    399:        void *v;
                    400:        register_t *retval;
                    401: {
                    402:        struct linux_getsockname_args /* {
                    403:                syscallarg(int) s;
                    404:                syscallarg(caddr_t) addr;
                    405:                syscallarg(int *) namelen;
                    406:        } */ *uap = v;
                    407:        struct linux_getsockname_args lga;
                    408:        struct sys_getsockname_args bga;
                    409:        int error;
                    410:
                    411:        if ((error = copyin((caddr_t) uap, (caddr_t) &lga, sizeof lga)))
                    412:                return error;
                    413:
                    414:        SCARG(&bga, fdes) = lga.s;
                    415:        SCARG(&bga, asa) = (struct sockaddr *) lga.addr;
                    416:        SCARG(&bga, alen) = lga.namelen;
                    417:
                    418:        error = sys_getsockname(p, &bga, retval);
                    419:        if (error)
                    420:                return (error);
                    421:
                    422:        if ((error = linux_sa_put((struct osockaddr *)lga.addr)))
                    423:                return (error);
                    424:
                    425:        return (0);
                    426: }
                    427:
                    428: int
                    429: linux_getpeername(p, v, retval)
                    430:        struct proc *p;
                    431:        void *v;
                    432:        register_t *retval;
                    433: {
                    434:        struct linux_getpeername_args /* {
                    435:                syscallarg(int) s;
                    436:                syscallarg(struct sockaddr *) addr;
                    437:                syscallarg(int *) namelen;
                    438:        } */ *uap = v;
                    439:        struct linux_getpeername_args lga;
                    440:        struct sys_getpeername_args bga;
                    441:        int error;
                    442:
                    443:        if ((error = copyin((caddr_t) uap, (caddr_t) &lga, sizeof lga)))
                    444:                return error;
                    445:
                    446:        SCARG(&bga, fdes) = lga.s;
                    447:        SCARG(&bga, asa) = (struct sockaddr *) lga.addr;
                    448:        SCARG(&bga, alen) = lga.namelen;
                    449:
                    450:        error = sys_getpeername(p, &bga, retval);
                    451:        if (error)
                    452:                return (error);
                    453:
                    454:        if ((error = linux_sa_put((struct osockaddr *)lga.addr)))
                    455:                return (error);
                    456:
                    457:        return (0);
                    458: }
                    459:
                    460: int
                    461: linux_socketpair(p, v, retval)
                    462:        struct proc *p;
                    463:        void *v;
                    464:        register_t *retval;
                    465: {
                    466:        struct linux_socketpair_args /* {
                    467:                syscallarg(int) domain;
                    468:                syscallarg(int) type;
                    469:                syscallarg(int) protocol;
                    470:                syscallarg(int *) rsv;
                    471:        } */ *uap = v;
                    472:        struct linux_socketpair_args lsa;
                    473:        struct sys_socketpair_args bsa;
                    474:        int error;
                    475:
                    476:        if ((error = copyin((caddr_t) uap, &lsa, sizeof lsa)))
                    477:                return error;
                    478:
                    479:        SCARG(&bsa, domain) = linux_to_bsd_domain(lsa.domain);
                    480:        if (SCARG(&bsa, domain) == -1)
                    481:                return EINVAL;
                    482:        SCARG(&bsa, type) = lsa.type;
                    483:        SCARG(&bsa, protocol) = lsa.protocol;
                    484:        SCARG(&bsa, rsv) = lsa.rsv;
                    485:
                    486:        return sys_socketpair(p, &bsa, retval);
                    487: }
                    488:
                    489: int
                    490: linux_send(p, v, retval)
                    491:        struct proc *p;
                    492:        void *v;
                    493:        register_t *retval;
                    494: {
                    495:        struct linux_send_args /* {
                    496:                syscallarg(int) s;
                    497:                syscallarg(void *) msg;
                    498:                syscallarg(int) len;
                    499:                syscallarg(int) flags;
                    500:        } */ *uap = v;
                    501:        struct linux_send_args lsa;
                    502:        struct compat_43_sys_send_args bsa;
                    503:        int error;
                    504:
                    505:        if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa)))
                    506:                return error;
                    507:
                    508:        SCARG(&bsa, s) = lsa.s;
                    509:        SCARG(&bsa, buf) = lsa.msg;
                    510:        SCARG(&bsa, len) = lsa.len;
                    511:        SCARG(&bsa, flags) = lsa.flags;
                    512:
                    513:        return compat_43_sys_send(p, &bsa, retval);
                    514: }
                    515:
                    516: int
                    517: linux_recv(p, v, retval)
                    518:        struct proc *p;
                    519:        void *v;
                    520:        register_t *retval;
                    521: {
                    522:        struct linux_recv_args /* {
                    523:                syscallarg(int) s;
                    524:                syscallarg(void *) msg;
                    525:                syscallarg(int) len;
                    526:                syscallarg(int) flags;
                    527:        } */ *uap = v;
                    528:        struct linux_recv_args lra;
                    529:        struct compat_43_sys_recv_args bra;
                    530:        int error;
                    531:
                    532:        if ((error = copyin((caddr_t) uap, (caddr_t) &lra, sizeof lra)))
                    533:                return error;
                    534:
                    535:        SCARG(&bra, s) = lra.s;
                    536:        SCARG(&bra, buf) = lra.msg;
                    537:        SCARG(&bra, len) = lra.len;
                    538:        SCARG(&bra, flags) = lra.flags;
                    539:
                    540:        return compat_43_sys_recv(p, &bra, retval);
                    541: }
                    542:
                    543: int
                    544: linux_check_hdrincl(p, fd, retval, sgp)
                    545:        struct proc *p;
                    546:        int fd;
                    547:        register_t *retval;
                    548:        caddr_t *sgp;
                    549: {
                    550:        struct sys_getsockopt_args /* {
                    551:                int s;
                    552:                int level;
                    553:                int name;
                    554:                caddr_t val;
                    555:                int *avalsize;
                    556:        } */ gsa;
                    557:        int error;
                    558:        caddr_t val;
                    559:        int *valsize;
                    560:        int size_val = sizeof val;
                    561:        int optval;
                    562:
                    563:        val = stackgap_alloc(sgp, sizeof(optval));
                    564:        valsize = stackgap_alloc(sgp, sizeof(size_val));
                    565:
                    566:        if ((error = copyout(&size_val, valsize, sizeof(size_val))))
                    567:                return (error);
                    568:        SCARG(&gsa, s) = fd;
                    569:        SCARG(&gsa, level) = IPPROTO_IP;
                    570:        SCARG(&gsa, name) = IP_HDRINCL;
                    571:        SCARG(&gsa, val) = val;
                    572:        SCARG(&gsa, avalsize) = valsize;
                    573:
                    574:        if ((error = sys_getsockopt(p, &gsa, retval)))
                    575:                return (error);
                    576:        if ((error = copyin(val, &optval, sizeof(optval))))
                    577:                return (error);
                    578:        return (optval == 0);
                    579: }
                    580:
                    581: /*
                    582:  * linux_ip_copysize defines how many bytes we should copy
                    583:  * from the beginning of the IP packet before we customize it for BSD.
                    584:  * It should include all the fields we modify (ip_len and ip_off)
                    585:  * and be as small as possible to minimize copying overhead.
                    586:  */
                    587: #define linux_ip_copysize      8
                    588:
                    589: int
                    590: linux_sendto_hdrincl(p, bsa, retval, sgp)
                    591:        struct proc *p;
                    592:        struct sys_sendto_args *bsa;
                    593:        register_t *retval;
                    594:        caddr_t *sgp;
                    595: {
                    596:        struct sys_sendmsg_args ssa;
                    597:        struct ip *packet, rpacket;
                    598:        struct msghdr *msg, rmsg;
                    599:        struct iovec *iov, riov[2];
                    600:        int error;
                    601:
                    602:        /* Check the packet isn't too small before we mess with it */
                    603:        if (SCARG(bsa, len) < linux_ip_copysize)
                    604:                return EINVAL;
                    605:
                    606:        /*
                    607:         * Tweaking the user buffer in place would be bad manners.
                    608:         * We create a corrected IP header with just the needed length,
                    609:         * then use an iovec to glue it to the rest of the user packet
                    610:         * when calling sendmsg().
                    611:         */
                    612:        packet = (struct ip *)stackgap_alloc(sgp, linux_ip_copysize);
                    613:        msg = (struct msghdr *)stackgap_alloc(sgp, sizeof(*msg));
                    614:        iov = (struct iovec *)stackgap_alloc(sgp, sizeof(*iov)*2);
                    615:
                    616:        /* Make a copy of the beginning of the packet to be sent */
                    617:        if ((error = copyin(SCARG(bsa, buf), (caddr_t)&rpacket,
                    618:            linux_ip_copysize)))
                    619:                return error;
                    620:
                    621:        /* Convert fields from Linux to BSD raw IP socket format */
                    622:        rpacket.ip_len = SCARG(bsa, len);
                    623:        error = copyout(&rpacket, packet, linux_ip_copysize);
                    624:        if (error)
                    625:                return (error);
                    626:
                    627:        riov[0].iov_base = (char *)packet;
                    628:        riov[0].iov_len = linux_ip_copysize;
                    629:        riov[1].iov_base = (caddr_t)SCARG(bsa, buf) + linux_ip_copysize;
                    630:        riov[1].iov_len = SCARG(bsa, len) - linux_ip_copysize;
                    631:
                    632:        error = copyout(&riov[0], iov, sizeof(riov));
                    633:        if (error)
                    634:                return (error);
                    635:
                    636:        /* Prepare the msghdr and iovec structures describing the new packet */
                    637:        rmsg.msg_name = (void *)SCARG(bsa, to);
                    638:        rmsg.msg_namelen = SCARG(bsa, tolen);
                    639:        rmsg.msg_iov = iov;
                    640:        rmsg.msg_iovlen = 2;
                    641:        rmsg.msg_control = NULL;
                    642:        rmsg.msg_controllen = 0;
                    643:        rmsg.msg_flags = 0;
                    644:
                    645:        error = copyout(&riov[0], iov, sizeof(riov));
                    646:        if (error)
                    647:                return (error);
                    648:
                    649:        SCARG(&ssa, s) = SCARG(bsa, s);
                    650:        SCARG(&ssa, msg) = msg;
                    651:        SCARG(&ssa, flags) = SCARG(bsa, flags);
                    652:        return sys_sendmsg(p, &ssa, retval);
                    653: }
                    654:
                    655: int
                    656: linux_sendto(p, v, retval)
                    657:        struct proc *p;
                    658:        void *v;
                    659:        register_t *retval;
                    660: {
                    661:        struct linux_sendto_args /* {
                    662:                syscallarg(int) s;
                    663:                syscallarg(void *) msg;
                    664:                syscallarg(int) len;
                    665:                syscallarg(int) flags;
                    666:                syscallarg(osockaddr *) to;
                    667:                syscallarg(int) tolen;
                    668:        } */ *uap = v;
                    669:        struct linux_sendto_args lsa;
                    670:        struct sys_sendto_args bsa;
                    671:        int error;
                    672:        int tolen;
                    673:        caddr_t sg = stackgap_init(p->p_emul);
                    674:
                    675:        if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa)))
                    676:                return error;
                    677:
                    678:        SCARG(&bsa, s) = lsa.s;
                    679:        SCARG(&bsa, buf) = lsa.msg;
                    680:        SCARG(&bsa, len) = lsa.len;
                    681:        SCARG(&bsa, flags) = lsa.flags;
                    682:        tolen = lsa.tolen;
                    683:        if (lsa.to) {
                    684:                struct sockaddr *sa;
                    685:
                    686:                if ((error = linux_sa_get(p, &sg, &sa, lsa.to, &tolen)))
                    687:                        return (error);
                    688:                SCARG(&bsa, to) = sa;
                    689:        } else
                    690:                SCARG(&bsa, to) = NULL;
                    691:        SCARG(&bsa, tolen) = tolen;
                    692:
                    693:        if (linux_check_hdrincl(p, lsa.s, retval, &sg) == 0)
                    694:                return linux_sendto_hdrincl(p, &bsa, retval, &sg);
                    695:        return sys_sendto(p, &bsa, retval);
                    696: }
                    697:
                    698: int
                    699: linux_recvfrom(p, v, retval)
                    700:        struct proc *p;
                    701:        void *v;
                    702:        register_t *retval;
                    703: {
                    704:        struct linux_recvfrom_args /* {
                    705:                syscallarg(int) s;
                    706:                syscallarg(void *) buf;
                    707:                syscallarg(int) len;
                    708:                syscallarg(int) flags;
                    709:                syscallarg(struct osockaddr *) from;
                    710:                syscallarg(int *) fromlen;
                    711:        } */ *uap = v;
                    712:        struct linux_recvfrom_args lra;
                    713:        struct sys_recvfrom_args bra;
                    714:        int error;
                    715:
                    716:        if ((error = copyin((caddr_t) uap, (caddr_t) &lra, sizeof lra)))
                    717:                return error;
                    718:
                    719:        SCARG(&bra, s) = lra.s;
                    720:        SCARG(&bra, buf) = lra.buf;
                    721:        SCARG(&bra, len) = lra.len;
                    722:        SCARG(&bra, flags) = lra.flags;
                    723:        SCARG(&bra, from) = (struct sockaddr *) lra.from;
                    724:        SCARG(&bra, fromlenaddr) = lra.fromlen;
                    725:
                    726:        if ((error = sys_recvfrom(p, &bra, retval)))
                    727:                return (error);
                    728:
                    729:        if (lra.from && (error = linux_sa_put(lra.from)))
                    730:                return (error);
                    731:
                    732:        return (0);
                    733: }
                    734:
                    735: int
                    736: linux_shutdown(p, v, retval)
                    737:        struct proc *p;
                    738:        void *v;
                    739:        register_t *retval;
                    740: {
                    741:        struct linux_shutdown_args /* {
                    742:                syscallarg(int) s;
                    743:                syscallarg(int) how;
                    744:        } */ *uap = v;
                    745:        struct linux_shutdown_args lsa;
                    746:        struct sys_shutdown_args bsa;
                    747:        int error;
                    748:
                    749:        if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa)))
                    750:                return error;
                    751:
                    752:        SCARG(&bsa, s) = lsa.s;
                    753:        SCARG(&bsa, how) = lsa.how;
                    754:
                    755:        return sys_shutdown(p, &bsa, retval);
                    756: }
                    757:
                    758: /*
                    759:  * Convert socket option level from Linux to OpenBSD value. Only SOL_SOCKET
                    760:  * is different, the rest matches IPPROTO_* on both systems.
                    761:  */
                    762: int
                    763: linux_to_bsd_sopt_level(llevel)
                    764:        int llevel;
                    765: {
                    766:
                    767:        switch (llevel) {
                    768:        case LINUX_SOL_SOCKET:
                    769:                return SOL_SOCKET;
                    770:        case LINUX_SOL_IP:
                    771:                return IPPROTO_IP;
                    772:        case LINUX_SOL_TCP:
                    773:                return IPPROTO_TCP;
                    774:        case LINUX_SOL_UDP:
                    775:                return IPPROTO_UDP;
                    776:        default:
                    777:                return -1;
                    778:        }
                    779: }
                    780:
                    781: /*
                    782:  * Convert Linux socket level socket option numbers to OpenBSD values.
                    783:  */
                    784: int
                    785: linux_to_bsd_so_sockopt(lopt)
                    786:        int lopt;
                    787: {
                    788:
                    789:        switch (lopt) {
                    790:        case LINUX_SO_DEBUG:
                    791:                return SO_DEBUG;
                    792:        case LINUX_SO_REUSEADDR:
                    793:                /*
                    794:                 * Linux does not implement SO_REUSEPORT, but allows reuse
                    795:                 * of a host:port pair through SO_REUSEADDR even if the
                    796:                 * address is not a multicast-address.  Effectively, this
                    797:                 * means that we should use SO_REUSEPORT to allow Linux
                    798:                 * applications to not exit with EADDRINUSE.
                    799:                 */
                    800:                return SO_REUSEPORT;
                    801:        case LINUX_SO_TYPE:
                    802:                return SO_TYPE;
                    803:        case LINUX_SO_ERROR:
                    804:                return SO_ERROR;
                    805:        case LINUX_SO_DONTROUTE:
                    806:                return SO_DONTROUTE;
                    807:        case LINUX_SO_BROADCAST:
                    808:                return SO_BROADCAST;
                    809:        case LINUX_SO_SNDBUF:
                    810:                return SO_SNDBUF;
                    811:        case LINUX_SO_RCVBUF:
                    812:                return SO_RCVBUF;
                    813:        case LINUX_SO_KEEPALIVE:
                    814:                return SO_KEEPALIVE;
                    815:        case LINUX_SO_OOBINLINE:
                    816:                return SO_OOBINLINE;
                    817:        case LINUX_SO_LINGER:
                    818:                return SO_LINGER;
                    819:        case LINUX_SO_PRIORITY:
                    820:        case LINUX_SO_NO_CHECK:
                    821:        default:
                    822:                return -1;
                    823:        }
                    824: }
                    825:
                    826: /*
                    827:  * Convert Linux IP level socket option number to OpenBSD values.
                    828:  */
                    829: int
                    830: linux_to_bsd_ip_sockopt(lopt)
                    831:        int lopt;
                    832: {
                    833:
                    834:        switch (lopt) {
                    835:        case LINUX_IP_TOS:
                    836:                return IP_TOS;
                    837:        case LINUX_IP_TTL:
                    838:                return IP_TTL;
                    839:        case LINUX_IP_MULTICAST_TTL:
                    840:                return IP_MULTICAST_TTL;
                    841:        case LINUX_IP_MULTICAST_LOOP:
                    842:                return IP_MULTICAST_LOOP;
                    843:        case LINUX_IP_MULTICAST_IF:
                    844:                return IP_MULTICAST_IF;
                    845:        case LINUX_IP_ADD_MEMBERSHIP:
                    846:                return IP_ADD_MEMBERSHIP;
                    847:        case LINUX_IP_DROP_MEMBERSHIP:
                    848:                return IP_DROP_MEMBERSHIP;
                    849:        case LINUX_IP_HDRINCL:
                    850:                return IP_HDRINCL;
                    851:        default:
                    852:                return -1;
                    853:        }
                    854: }
                    855:
                    856: /*
                    857:  * Convert Linux TCP level socket option number to OpenBSD values.
                    858:  */
                    859: int
                    860: linux_to_bsd_tcp_sockopt(lopt)
                    861:        int lopt;
                    862: {
                    863:
                    864:        switch (lopt) {
                    865:        case LINUX_TCP_NODELAY:
                    866:                return TCP_NODELAY;
                    867:        case LINUX_TCP_MAXSEG:
                    868:                return TCP_MAXSEG;
                    869:        default:
                    870:                return -1;
                    871:        }
                    872: }
                    873:
                    874: /*
                    875:  * Convert Linux UDP level socket option number to OpenBSD values.
                    876:  */
                    877: int
                    878: linux_to_bsd_udp_sockopt(lopt)
                    879:        int lopt;
                    880: {
                    881:
                    882:        switch (lopt) {
                    883:        default:
                    884:                return -1;
                    885:        }
                    886: }
                    887:
                    888: /*
                    889:  * Another reasonably straightforward function: setsockopt(2).
                    890:  * The level and option numbers are converted; the values passed
                    891:  * are not (yet) converted, the ones currently implemented don't
                    892:  * need conversion, as they are the same on both systems.
                    893:  */
                    894: int
                    895: linux_setsockopt(p, v, retval)
                    896:        struct proc *p;
                    897:        void *v;
                    898:        register_t *retval;
                    899: {
                    900:        struct linux_setsockopt_args /* {
                    901:                syscallarg(int) s;
                    902:                syscallarg(int) level;
                    903:                syscallarg(int) optname;
                    904:                syscallarg(void *) optval;
                    905:                syscallarg(int) optlen;
                    906:        } */ *uap = v;
                    907:        struct linux_setsockopt_args lsa;
                    908:        struct sys_setsockopt_args bsa;
                    909:        int error, name;
                    910:
                    911:        if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa)))
                    912:                return error;
                    913:
                    914:        SCARG(&bsa, s) = lsa.s;
                    915:        SCARG(&bsa, level) = linux_to_bsd_sopt_level(lsa.level);
                    916:        SCARG(&bsa, val) = lsa.optval;
                    917:        SCARG(&bsa, valsize) = lsa.optlen;
                    918:
                    919:        switch (SCARG(&bsa, level)) {
                    920:        case SOL_SOCKET:
                    921:                name = linux_to_bsd_so_sockopt(lsa.optname);
                    922:                break;
                    923:        case IPPROTO_IP:
                    924:                name = linux_to_bsd_ip_sockopt(lsa.optname);
                    925:                break;
                    926:        case IPPROTO_TCP:
                    927:                name = linux_to_bsd_tcp_sockopt(lsa.optname);
                    928:                break;
                    929:        case IPPROTO_UDP:
                    930:                name = linux_to_bsd_udp_sockopt(lsa.optname);
                    931:                break;
                    932:        default:
                    933:                return EINVAL;
                    934:        }
                    935:
                    936:        if (name == -1)
                    937:                return EINVAL;
                    938:        SCARG(&bsa, name) = name;
                    939:
                    940:        return sys_setsockopt(p, &bsa, retval);
                    941: }
                    942:
                    943: /*
                    944:  * getsockopt(2) is very much the same as setsockopt(2) (see above)
                    945:  */
                    946: int
                    947: linux_getsockopt(p, v, retval)
                    948:        struct proc *p;
                    949:        void *v;
                    950:        register_t *retval;
                    951: {
                    952:        struct linux_getsockopt_args /* {
                    953:                syscallarg(int) s;
                    954:                syscallarg(int) level;
                    955:                syscallarg(int) optname;
                    956:                syscallarg(void *) optval;
                    957:                syscallarg(int) *optlen;
                    958:        } */ *uap = v;
                    959:        struct linux_getsockopt_args lga;
                    960:        struct sys_getsockopt_args bga;
                    961:        int error, name;
                    962:
                    963:        if ((error = copyin((caddr_t) uap, (caddr_t) &lga, sizeof lga)))
                    964:                return error;
                    965:
                    966:        SCARG(&bga, s) = lga.s;
                    967:        SCARG(&bga, level) = linux_to_bsd_sopt_level(lga.level);
                    968:        SCARG(&bga, val) = lga.optval;
                    969:        SCARG(&bga, avalsize) = lga.optlen;
                    970:
                    971:        switch (SCARG(&bga, level)) {
                    972:        case SOL_SOCKET:
                    973:                name = linux_to_bsd_so_sockopt(lga.optname);
                    974:                break;
                    975:        case IPPROTO_IP:
                    976:                name = linux_to_bsd_ip_sockopt(lga.optname);
                    977:                break;
                    978:        case IPPROTO_TCP:
                    979:                name = linux_to_bsd_tcp_sockopt(lga.optname);
                    980:                break;
                    981:        case IPPROTO_UDP:
                    982:                name = linux_to_bsd_udp_sockopt(lga.optname);
                    983:                break;
                    984:        default:
                    985:                return EINVAL;
                    986:        }
                    987:
                    988:        if (name == -1)
                    989:                return EINVAL;
                    990:        SCARG(&bga, name) = name;
                    991:
                    992:        return sys_getsockopt(p, &bga, retval);
                    993: }
                    994:
                    995: int
                    996: linux_recvmsg(p, v, retval)
                    997:        struct proc *p;
                    998:        void *v;
                    999:        register_t *retval;
                   1000: {
                   1001:        struct linux_recvmsg_args /* {
                   1002:                syscallarg(int) s;
                   1003:                syscallarg(caddr_t) msg;
                   1004:                syscallarg(int) flags;
                   1005:        } */ *uap = v;
                   1006:        struct linux_recvmsg_args lla;
                   1007:        struct sys_recvmsg_args bla;
                   1008:        struct msghdr msg;
                   1009:        int error;
                   1010:
                   1011:        if ((error = copyin((caddr_t) uap, (caddr_t) &lla, sizeof lla)))
                   1012:                return error;
                   1013:
                   1014:        SCARG(&bla, s) = lla.s;
                   1015:        SCARG(&bla, msg) = (struct msghdr *)lla.msg;
                   1016:        SCARG(&bla, flags) = lla.flags;
                   1017:
                   1018:        error = sys_recvmsg(p, &bla, retval);
                   1019:        if (error)
                   1020:                return (error);
                   1021:
                   1022:        error = copyin(lla.msg, (caddr_t)&msg, sizeof(msg));
                   1023:
                   1024:        if (!error && msg.msg_name && msg.msg_namelen > 2)
                   1025:                error = linux_sa_put(msg.msg_name);
                   1026:
                   1027:        return (error);
                   1028: }
                   1029:
                   1030: int
                   1031: linux_sendmsg(p, v, retval)
                   1032:        struct proc *p;
                   1033:        void *v;
                   1034:        register_t *retval;
                   1035: {
                   1036:        struct linux_sendmsg_args /* {
                   1037:                syscallarg(int) s;
                   1038:                syscallarg(struct msghdr *) msg;
                   1039:                syscallarg(int) flags;
                   1040:        } */ *uap = v;
                   1041:        struct linux_sendmsg_args lla;
                   1042:        struct sys_sendmsg_args bla;
                   1043:        struct msghdr msg, *nmsg = NULL;
                   1044:        int error;
                   1045:        caddr_t control;
                   1046:        int level;
                   1047:
                   1048:        if ((error = copyin((caddr_t) uap, (caddr_t) &lla, sizeof lla)))
                   1049:                return error;
                   1050:
                   1051:        if ((error = copyin(lla.msg, (caddr_t) &msg, sizeof(msg))))
                   1052:                return (error);
                   1053:
                   1054:        if (msg.msg_name) {
                   1055:                struct sockaddr *sa;
                   1056:                caddr_t sg = stackgap_init(p->p_emul);
                   1057:
                   1058:                nmsg = (struct msghdr *)stackgap_alloc(&sg,
                   1059:                    sizeof(struct msghdr));
                   1060:                if (!nmsg)
                   1061:                        return (ENOMEM);
                   1062:
                   1063:                error = linux_sa_get(p, &sg, &sa,
                   1064:                    (struct osockaddr *)msg.msg_name, &msg.msg_namelen);
                   1065:                if (error)
                   1066:                        return (error);
                   1067:
                   1068:                msg.msg_name = (struct sockaddr *)sa;
                   1069:                if ((error = copyout(&msg, nmsg, sizeof(struct msghdr))))
                   1070:                        return (error);
                   1071:                lla.msg = nmsg;
                   1072:        }
                   1073:
                   1074:        SCARG(&bla, s) = lla.s;
                   1075:        SCARG(&bla, msg) = lla.msg;
                   1076:        SCARG(&bla, flags) = lla.flags;
                   1077:
                   1078:        error = copyin(lla.msg->msg_control, &control, sizeof(caddr_t));
                   1079:        if (error)
                   1080:                return error;
                   1081:        if (control == NULL)
                   1082:                goto done;
                   1083:        error = copyin(&((struct cmsghdr *)control)->cmsg_level,
                   1084:            &level, sizeof(int));
                   1085:        if (error)
                   1086:                return error;
                   1087:        if (level == 1) {
                   1088:                /*
                   1089:                 * Linux thinks that SOL_SOCKET is 1; we know that it's really
                   1090:                 * 0xffff, of course.
                   1091:                 */
                   1092:                level = SOL_SOCKET;
                   1093:                /*
                   1094:                 * XXX should use stack gap!
                   1095:                 * We don't because the control header is variable length
                   1096:                 * up to 2048 bytes, and there's only 512 bytes of gap.
                   1097:                 */
                   1098:                error = copyout(&level, &((struct cmsghdr *)control)->
                   1099:                    cmsg_level, sizeof(int));
                   1100:                if (error)
                   1101:                        return error;
                   1102:        }
                   1103: done:
                   1104:        error = sys_sendmsg(p, &bla, retval);
                   1105:        /* replace level, just in case somebody cares. */
                   1106:        if (level == SOL_SOCKET) {
                   1107:                level = 1;
                   1108:                /* don't worry about the error */
                   1109:                copyout(&level, &((struct cmsghdr *)control)->cmsg_level,
                   1110:                    sizeof(int));
                   1111:        }
                   1112:        return (error);
                   1113: }
                   1114:
                   1115: /*
                   1116:  * Copy the osockaddr structure pointed to by osa to kernel, adjust
                   1117:  * family and convert to sockaddr, allocate stackgap and put the
                   1118:  * the converted structure there, address on stackgap returned in sap.
                   1119:  */
                   1120: int
                   1121: linux_sa_get(p, sgp, sap, osa, osalen)
                   1122:        struct proc *p;
                   1123:        caddr_t *sgp;
                   1124:        struct sockaddr **sap;
                   1125:        const struct osockaddr *osa;
                   1126:        int *osalen;
                   1127: {
                   1128:        int error=0, bdom;
                   1129:        struct sockaddr *sa, *usa;
                   1130:        struct osockaddr *kosa;
                   1131:        int alloclen;
                   1132: #ifdef INET6
                   1133:        int oldv6size;
                   1134:        struct sockaddr_in6 *sin6;
                   1135: #endif
                   1136:
                   1137:        if (*osalen < 2 || *osalen > UCHAR_MAX || !osa) {
                   1138:                return (EINVAL);
                   1139:        }
                   1140:
                   1141:        alloclen = *osalen;
                   1142: #ifdef INET6
                   1143:        oldv6size = 0;
                   1144:        /*
                   1145:         * Check for old (pre-RFC2553) sockaddr_in6. We may accept it
                   1146:         * if it's a v4-mapped address, so reserve the proper space
                   1147:         * for it.
                   1148:         */
                   1149:        if (alloclen == sizeof (struct sockaddr_in6) - sizeof (u_int32_t)) {
                   1150:                alloclen = sizeof (struct sockaddr_in6);
                   1151:                oldv6size = 1;
                   1152:        }
                   1153: #endif
                   1154:
                   1155:        kosa = (struct osockaddr *) malloc(alloclen, M_TEMP, M_WAITOK);
                   1156:
                   1157:        if ((error = copyin(osa, (caddr_t) kosa, *osalen))) {
                   1158:                goto out;
                   1159:        }
                   1160:
                   1161:        bdom = linux_to_bsd_domain(kosa->sa_family);
                   1162:        if (bdom == -1) {
                   1163:                error = EINVAL;
                   1164:                goto out;
                   1165:        }
                   1166:
                   1167: #ifdef INET6
                   1168:        /*
                   1169:         * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6,
                   1170:         * which lacks the scope id compared with RFC2553 one. If we detect
                   1171:         * the situation, reject the address.
                   1172:         *
                   1173:         * Still accept addresses for which the scope id is not used.
                   1174:         */
                   1175:        if (oldv6size && bdom == AF_INET6) {
                   1176:                sin6 = (struct sockaddr_in6 *)kosa;
                   1177:                if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ||
                   1178:                    (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
                   1179:                     !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
                   1180:                     !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) &&
                   1181:                     !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
                   1182:                     !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) {
                   1183:                        sin6->sin6_scope_id = 0;
                   1184:                } else {
                   1185:                        error = EINVAL;
                   1186:                        goto out;
                   1187:                }
                   1188:        } else
                   1189: #endif
                   1190:        if (bdom == AF_INET) {
                   1191:                alloclen = sizeof(struct sockaddr_in);
                   1192:        }
                   1193:
                   1194:        sa = (struct sockaddr *) kosa;
                   1195:        sa->sa_family = bdom;
                   1196:        sa->sa_len = alloclen;
                   1197:
                   1198:        usa = (struct sockaddr *) stackgap_alloc(sgp, alloclen);
                   1199:        if (!usa) {
                   1200:                error = ENOMEM;
                   1201:                goto out;
                   1202:        }
                   1203:
                   1204:        if ((error = copyout(sa, usa, alloclen))) {
                   1205:                goto out;
                   1206:        }
                   1207:
                   1208:        *sap = usa;
                   1209:
                   1210:     out:
                   1211:        *osalen = alloclen;
                   1212:        free(kosa, M_TEMP);
                   1213:        return (error);
                   1214: }
                   1215:
                   1216: int
                   1217: linux_sa_put(osa)
                   1218:        struct osockaddr *osa;
                   1219: {
                   1220:        struct sockaddr sa;
                   1221:        struct osockaddr *kosa;
                   1222:        int error, bdom, len;
                   1223:
                   1224:        /*
                   1225:         * Only read/write the sockaddr family and length part, the rest is
                   1226:         * not changed.
                   1227:         */
                   1228:        len = sizeof(sa.sa_len) + sizeof(sa.sa_family);
                   1229:
                   1230:        error = copyin((caddr_t) osa, (caddr_t) &sa, len);
                   1231:        if (error)
                   1232:                return (error);
                   1233:
                   1234:        bdom = bsd_to_linux_domain(sa.sa_family);
                   1235:        if (bdom == -1)
                   1236:                return (EINVAL);
                   1237:
                   1238:        /* Note: we convert from sockaddr to osockaddr here, too */
                   1239:        kosa = (struct osockaddr *) &sa;
                   1240:        kosa->sa_family = bdom;
                   1241:        error = copyout(kosa, osa, len);
                   1242:        if (error)
                   1243:                return (error);
                   1244:
                   1245:        return (0);
                   1246: }
                   1247:
                   1248: /*
                   1249:  * Entry point to all Linux socket calls. Just check which call to
                   1250:  * make and take appropriate action.
                   1251:  */
                   1252: int
                   1253: linux_sys_socketcall(p, v, retval)
                   1254:        struct proc *p;
                   1255:        void *v;
                   1256:        register_t *retval;
                   1257: {
                   1258:        struct linux_sys_socketcall_args /* {
                   1259:                syscallarg(int) what;
                   1260:                syscallarg(void *) args;
                   1261:        } */ *uap = v;
                   1262:
                   1263:        switch (SCARG(uap, what)) {
                   1264:        case LINUX_SYS_socket:
                   1265:                return linux_socket(p, SCARG(uap, args), retval);
                   1266:        case LINUX_SYS_bind:
                   1267:                return linux_bind(p, SCARG(uap, args), retval);
                   1268:        case LINUX_SYS_connect:
                   1269:                return linux_connect(p, SCARG(uap, args), retval);
                   1270:        case LINUX_SYS_listen:
                   1271:                return linux_listen(p, SCARG(uap, args), retval);
                   1272:        case LINUX_SYS_accept:
                   1273:                return linux_accept(p, SCARG(uap, args), retval);
                   1274:        case LINUX_SYS_getsockname:
                   1275:                return linux_getsockname(p, SCARG(uap, args), retval);
                   1276:        case LINUX_SYS_getpeername:
                   1277:                return linux_getpeername(p, SCARG(uap, args), retval);
                   1278:        case LINUX_SYS_socketpair:
                   1279:                return linux_socketpair(p, SCARG(uap, args), retval);
                   1280:        case LINUX_SYS_send:
                   1281:                return linux_send(p, SCARG(uap, args), retval);
                   1282:        case LINUX_SYS_recv:
                   1283:                return linux_recv(p, SCARG(uap, args), retval);
                   1284:        case LINUX_SYS_sendto:
                   1285:                return linux_sendto(p, SCARG(uap, args), retval);
                   1286:        case LINUX_SYS_recvfrom:
                   1287:                return linux_recvfrom(p, SCARG(uap, args), retval);
                   1288:        case LINUX_SYS_shutdown:
                   1289:                return linux_shutdown(p, SCARG(uap, args), retval);
                   1290:        case LINUX_SYS_setsockopt:
                   1291:                return linux_setsockopt(p, SCARG(uap, args), retval);
                   1292:        case LINUX_SYS_getsockopt:
                   1293:                return linux_getsockopt(p, SCARG(uap, args), retval);
                   1294:        case LINUX_SYS_sendmsg:
                   1295:                return linux_sendmsg(p, SCARG(uap, args), retval);
                   1296:        case LINUX_SYS_recvmsg:
                   1297:                return linux_recvmsg(p, SCARG(uap, args), retval);
                   1298:        default:
                   1299:                return ENOSYS;
                   1300:        }
                   1301: }
                   1302:
                   1303: int
                   1304: linux_ioctl_socket(p, v, retval)
                   1305:        register struct proc *p;
                   1306:        void *v;
                   1307:        register_t *retval;
                   1308: {
                   1309:        struct linux_sys_ioctl_args /* {
                   1310:                syscallarg(int) fd;
                   1311:                syscallarg(u_long) com;
                   1312:                syscallarg(caddr_t) data;
                   1313:        } */ *uap = v;
                   1314:        u_long com;
                   1315:        struct sys_ioctl_args ia;
                   1316:        struct file *fp;
                   1317:        struct filedesc *fdp;
                   1318:        struct vnode *vp;
                   1319:        int (*ioctlf)(struct file *, u_long, caddr_t, struct proc *);
                   1320:        struct ioctl_pt pt;
                   1321:        int error = 0, isdev = 0, dosys = 1;
                   1322:
                   1323:        fdp = p->p_fd;
                   1324:        if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
                   1325:                return (EBADF);
                   1326:        FREF(fp);
                   1327:
                   1328:        if (fp->f_type == DTYPE_VNODE) {
                   1329:                vp = (struct vnode *)fp->f_data;
                   1330:                isdev = vp->v_type == VCHR;
                   1331:        }
                   1332:
                   1333:        /*
                   1334:         * Don't try to interpret socket ioctl calls that are done
                   1335:         * on a device filedescriptor, just pass them through, to
                   1336:         * emulate Linux behaviour. Use PTIOCLINUX so that the
                   1337:         * device will only handle these if it's prepared to do
                   1338:         * so, to avoid unexpected things from happening.
                   1339:         */
                   1340:        if (isdev) {
                   1341:                dosys = 0;
                   1342:                ioctlf = fp->f_ops->fo_ioctl;
                   1343:                pt.com = SCARG(uap, com);
                   1344:                pt.data = SCARG(uap, data);
                   1345:                error = ioctlf(fp, PTIOCLINUX, (caddr_t)&pt, p);
                   1346:                /*
                   1347:                 * XXX hack: if the function returns EJUSTRETURN,
                   1348:                 * it has stuffed a sysctl return value in pt.data.
                   1349:                 */
                   1350:                if (error == EJUSTRETURN) {
                   1351:                        retval[0] = (register_t)pt.data;
                   1352:                        error = 0;
                   1353:                }
                   1354:                goto out;
                   1355:        }
                   1356:
                   1357:        com = SCARG(uap, com);
                   1358:        retval[0] = 0;
                   1359:
                   1360:        switch (com) {
                   1361:        case LINUX_FIOSETOWN:
                   1362:                SCARG(&ia, com) = FIOSETOWN;
                   1363:                break;
                   1364:        case LINUX_SIOCSPGRP:
                   1365:                SCARG(&ia, com) = SIOCSPGRP;
                   1366:                break;
                   1367:        case LINUX_FIOGETOWN:
                   1368:                SCARG(&ia, com) = FIOGETOWN;
                   1369:                break;
                   1370:        case LINUX_SIOCGPGRP:
                   1371:                SCARG(&ia, com) = SIOCGPGRP;
                   1372:                break;
                   1373:        case LINUX_SIOCATMARK:
                   1374:                SCARG(&ia, com) = SIOCATMARK;
                   1375:                break;
                   1376: #if 0
                   1377:        case LINUX_SIOCGSTAMP:
                   1378:                SCARG(&ia, com) = SIOCGSTAMP;
                   1379:                break;
                   1380: #endif
                   1381:        case LINUX_SIOCGIFCONF:
                   1382:                SCARG(&ia, com) = OSIOCGIFCONF;
                   1383:                break;
                   1384:        case LINUX_SIOCGIFFLAGS:
                   1385:                SCARG(&ia, com) = SIOCGIFFLAGS;
                   1386:                break;
                   1387:        case LINUX_SIOCGIFADDR:
                   1388:                SCARG(&ia, com) = OSIOCGIFADDR;
                   1389:                break;
                   1390:        case LINUX_SIOCGIFDSTADDR:
                   1391:                SCARG(&ia, com) = OSIOCGIFDSTADDR;
                   1392:                break;
                   1393:        case LINUX_SIOCGIFBRDADDR:
                   1394:                SCARG(&ia, com) = OSIOCGIFBRDADDR;
                   1395:                break;
                   1396:        case LINUX_SIOCGIFNETMASK:
                   1397:                SCARG(&ia, com) = OSIOCGIFNETMASK;
                   1398:                break;
                   1399:        case LINUX_SIOCGIFMETRIC:
                   1400:                SCARG(&ia, com) = SIOCGIFMETRIC;
                   1401:                break;
                   1402:        case LINUX_SIOCGIFMTU:
                   1403:                SCARG(&ia, com) = SIOCGIFMTU;
                   1404:                break;
                   1405:        case LINUX_SIOCADDMULTI:
                   1406:                SCARG(&ia, com) = SIOCADDMULTI;
                   1407:                break;
                   1408:        case LINUX_SIOCDELMULTI:
                   1409:                SCARG(&ia, com) = SIOCDELMULTI;
                   1410:                break;
                   1411:        case LINUX_SIOCGIFHWADDR: {
                   1412:                struct linux_ifreq *ifr = (struct linux_ifreq *)SCARG(uap, data);
                   1413:                struct sockaddr_dl *sdl;
                   1414:                struct ifnet *ifp;
                   1415:                struct ifaddr *ifa;
                   1416:
                   1417:                /*
                   1418:                 * Note that we don't actually respect the name in the ifreq
                   1419:                 * structure, as Linux interface names are all different.
                   1420:                 */
                   1421:                TAILQ_FOREACH(ifp, &ifnet, if_list) {
                   1422:                        if (ifp->if_type != IFT_ETHER)
                   1423:                                continue;
                   1424:                        TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
                   1425:                                if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
                   1426:                                    (sdl->sdl_family == AF_LINK) &&
                   1427:                                    (sdl->sdl_type == IFT_ETHER)) {
                   1428:                                        error = copyout(LLADDR(sdl),
                   1429:                                            (caddr_t)&ifr->ifr_hwaddr.sa_data,
                   1430:                                            LINUX_IFHWADDRLEN);
                   1431:                                        dosys = 0;
                   1432:                                        goto out;
                   1433:                                }
                   1434:                        }
                   1435:                }
                   1436:                error = ENOENT;
                   1437:                break;
                   1438:            }
                   1439:        default:
                   1440:                error = EINVAL;
                   1441:        }
                   1442:
                   1443: out:
                   1444:        if (error == 0 && dosys) {
                   1445:                SCARG(&ia, fd) = SCARG(uap, fd);
                   1446:                SCARG(&ia, data) = SCARG(uap, data);
                   1447:                error = sys_ioctl(p, &ia, retval);
                   1448:        }
                   1449:
                   1450:        FRELE(fp);
                   1451:        return (error);
                   1452: }

CVSweb