root/compat/linux/linux_socket.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. linux_to_bsd_domain
  2. bsd_to_linux_domain
  3. linux_socket
  4. linux_bind
  5. linux_connect
  6. linux_listen
  7. linux_accept
  8. linux_getsockname
  9. linux_getpeername
  10. linux_socketpair
  11. linux_send
  12. linux_recv
  13. linux_check_hdrincl
  14. linux_sendto_hdrincl
  15. linux_sendto
  16. linux_recvfrom
  17. linux_shutdown
  18. linux_to_bsd_sopt_level
  19. linux_to_bsd_so_sockopt
  20. linux_to_bsd_ip_sockopt
  21. linux_to_bsd_tcp_sockopt
  22. linux_to_bsd_udp_sockopt
  23. linux_setsockopt
  24. linux_getsockopt
  25. linux_recvmsg
  26. linux_sendmsg
  27. linux_sa_get
  28. linux_sa_put
  29. linux_sys_socketcall
  30. linux_ioctl_socket

    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 }

/* [<][>][^][v][top][bottom][index][help] */