The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/darwin/darwin_socket.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: darwin_socket.c,v 1.20 2008/04/28 20:23:41 martin Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Emmanuel Dreyfus
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: darwin_socket.c,v 1.20 2008/04/28 20:23:41 martin Exp $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/socket.h>
   38 #include <sys/signal.h>
   39 #include <sys/lwp.h>
   40 #include <sys/socketvar.h>
   41 #include <sys/un.h>
   42 #include <sys/mbuf.h>
   43 #include <sys/filedesc.h>
   44 #include <sys/protosw.h>
   45 #include <sys/syscallargs.h>
   46 
   47 #include <compat/sys/signal.h>
   48 
   49 #include <compat/common/compat_util.h>
   50 
   51 #include <compat/mach/mach_vm.h>
   52 
   53 #include <compat/darwin/darwin_audit.h>
   54 #include <compat/darwin/darwin_socket.h>
   55 #include <compat/darwin/darwin_syscallargs.h>
   56 
   57 unsigned char native_to_darwin_af[] = {
   58         0,
   59         DARWIN_AF_LOCAL,
   60         DARWIN_AF_INET,
   61         DARWIN_AF_IMPLINK,
   62         DARWIN_AF_PUP,
   63         DARWIN_AF_CHAOS,        /* 5 */
   64         DARWIN_AF_NS,
   65         DARWIN_AF_ISO,
   66         DARWIN_AF_ECMA,
   67         DARWIN_AF_DATAKIT,
   68         DARWIN_AF_CCITT,        /* 10 */
   69         DARWIN_AF_SNA,
   70         DARWIN_AF_DECnet,
   71         DARWIN_AF_DLI,
   72         DARWIN_AF_LAT,
   73         DARWIN_AF_HYLINK,       /* 15 */
   74         DARWIN_AF_APPLETALK,
   75         DARWIN_AF_ROUTE,
   76         DARWIN_AF_LINK,
   77         DARWIN_AF_XTP,
   78         DARWIN_AF_COIP,         /* 20 */
   79         DARWIN_AF_CNT,
   80         DARWIN_AF_RTIP,
   81         DARWIN_AF_IPX,
   82         DARWIN_AF_INET6,
   83         DARWIN_AF_PIP,          /* 25 */
   84         DARWIN_AF_ISDN,
   85         DARWIN_AF_NATM,
   86         0,
   87         DARWIN_AF_KEY,
   88         DARWIN_AF_HDRCMPLT,     /* 30 */
   89         0,
   90         0,
   91         0,
   92         0,
   93         0,                      /* 35 */
   94         0,
   95 };
   96 
   97 unsigned char darwin_to_native_af[] = {
   98         0,
   99         AF_LOCAL,
  100         AF_INET,
  101         AF_IMPLINK,
  102         AF_PUP,
  103         AF_CHAOS,       /* 5 */
  104         AF_NS,
  105         AF_ISO,
  106         AF_ECMA,
  107         AF_DATAKIT,
  108         AF_CCITT,       /* 10 */
  109         AF_SNA,
  110         AF_DECnet,
  111         AF_DLI,
  112         AF_LAT,
  113         AF_HYLINK,      /* 15 */
  114         AF_APPLETALK,
  115         AF_ROUTE,
  116         AF_LINK,
  117         0,
  118         AF_COIP,        /* 20 */
  119         AF_CNT,
  120         0,
  121         AF_IPX,
  122         0,
  123         0,              /* 25 */
  124         0,
  125         0,
  126         AF_ISDN,
  127         pseudo_AF_KEY,
  128         AF_INET6,       /* 30 */
  129         AF_NATM,
  130         0,
  131         0,
  132         0,
  133         pseudo_AF_HDRCMPLT,     /* 35 */
  134         0,
  135 };
  136 
  137 static int
  138 native_to_darwin_sockaddr(struct mbuf *nam)
  139 {
  140         struct sockaddr *sa = mtod(nam, void *);
  141 
  142         /* We only need to translate the address family */
  143         if ((unsigned)sa->sa_family >= __arraycount(native_to_darwin_af))
  144                 return EPROTONOSUPPORT;
  145 
  146         sa->sa_family = native_to_darwin_af[sa->sa_family];
  147         return 0;
  148 }
  149 
  150 static int
  151 darwin_to_native_sockaddr(struct mbuf *nam)
  152 {
  153         struct sockaddr *sa = mtod(nam, void *);
  154 
  155         if ((unsigned)sa->sa_family >= __arraycount(darwin_to_native_af)) {
  156                 m_free(nam);
  157                 return EPROTONOSUPPORT;
  158         }
  159         sa->sa_family = darwin_to_native_af[sa->sa_family];
  160 
  161         /*
  162          * sa_len is zero for AF_LOCAL sockets, believe size we copied in!
  163          * The code used to strlen the filename, but that way lies madness!
  164          */
  165 
  166         if (sa->sa_len > nam->m_len || sa->sa_len == 0)
  167                 sa->sa_len = nam->m_len;
  168         else
  169                 nam->m_len = sa->sa_len;
  170 
  171         return 0;
  172 }
  173 
  174 int
  175 darwin_sys_socket(struct lwp *l, const struct darwin_sys_socket_args *uap, register_t *retval)
  176 {
  177         /* {
  178                 syscallarg(int) domain;
  179                 syscallarg(int) type;
  180                 syscallarg(int) protocol;
  181         } */
  182         struct compat_30_sys_socket_args cup;
  183 
  184         if ((unsigned)SCARG(uap, domain) >= __arraycount(darwin_to_native_af))
  185                 return (EPROTONOSUPPORT);
  186 
  187         SCARG(&cup, domain) = darwin_to_native_af[SCARG(uap, domain)];
  188         SCARG(&cup, type) = SCARG(uap, type);
  189         SCARG(&cup, protocol) = SCARG(uap, protocol);
  190 
  191         return compat_30_sys_socket(l, &cup, retval);
  192 }
  193 
  194 int
  195 darwin_sys_recvfrom(struct lwp *l, const struct darwin_sys_recvfrom_args *uap, register_t *retval)
  196 {
  197         /* {
  198                 syscallarg(int) s;
  199                 syscallarg(void *) buf;
  200                 syscallarg(size_t) len;
  201                 syscallarg(int) flags;
  202                 syscallarg(struct sockaddr *) from;
  203                 syscallarg(unsigned int *) fromlenaddr;
  204         } */
  205         struct msghdr   msg;
  206         struct iovec    aiov;
  207         int             error;
  208         struct mbuf     *from;
  209 
  210         msg.msg_name = NULL;;
  211         msg.msg_iov = &aiov;
  212         msg.msg_iovlen = 1;
  213         aiov.iov_base = SCARG(uap, buf);
  214         aiov.iov_len = SCARG(uap, len);
  215         msg.msg_control = NULL;
  216         msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
  217 
  218         error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval);
  219         if (error != 0)
  220                 return error;
  221 
  222         error = native_to_darwin_sockaddr(from);
  223         if (error == 0)
  224                 error = copyout_sockname(SCARG(uap, from),
  225                     SCARG(uap, fromlenaddr), MSG_LENUSRSPACE, from);
  226         if (from != NULL)
  227                 m_free(from);
  228         return error;
  229 }
  230 
  231 int
  232 darwin_sys_accept(struct lwp *l, const struct darwin_sys_accept_args *uap, register_t *retval)
  233 {
  234         /* {
  235                 syscallarg(int) s;
  236                 syscallarg(struct sockaddr *) name;
  237                 syscallarg(unsigned int *) anamelen;
  238         } */
  239         int error, fd;
  240         struct mbuf *name;
  241 
  242         error = do_sys_accept(l, SCARG(uap, s), &name, retval);
  243         if (error != 0)
  244                 return error;
  245 
  246         error = native_to_darwin_sockaddr(name);
  247         if (error == 0)
  248                 error = copyout_sockname(SCARG(uap, name), SCARG(uap, anamelen),
  249                     MSG_LENUSRSPACE, name);
  250         if (name != NULL)
  251                 m_free(name);
  252         if (error != 0) {
  253                 fd = (int)*retval;
  254                 if (fd_getfile(fd) != NULL)
  255                         fd_close(fd);
  256         }
  257         return error;
  258 }
  259 
  260 int
  261 darwin_sys_getpeername(struct lwp *l, const struct darwin_sys_getpeername_args *uap, register_t *retval)
  262 {
  263         /* {
  264                 syscallarg(int) fdes;
  265                 syscallarg(struct sockaddr *) asa;
  266                 syscallarg(unsigned int *) alen;
  267         } */
  268         struct mbuf     *m;
  269         int             error;
  270 
  271         error = do_sys_getsockname(l, SCARG(uap, fdes), PRU_PEERADDR, &m);
  272         if (error != 0)
  273                 return error;
  274 
  275         error = native_to_darwin_sockaddr(m);
  276         if (error != 0)
  277                 error = copyout_sockname(SCARG(uap, asa), SCARG(uap, alen),
  278                     MSG_LENUSRSPACE, m);
  279         if (m != NULL)
  280                 m_free(m);
  281         return error;
  282 }
  283 
  284 int
  285 darwin_sys_getsockname(struct lwp *l, const struct darwin_sys_getsockname_args *uap, register_t *retval)
  286 {
  287         /* {
  288                 syscallarg(int) fdes;
  289                 syscallarg(struct sockaddr *) asa;
  290                 syscallarg(unsigned int *) alen;
  291         } */
  292         struct mbuf     *m;
  293         int             error;
  294 
  295         error = do_sys_getsockname(l, SCARG(uap, fdes), PRU_SOCKADDR, &m);
  296         if (error != 0)
  297                 return error;
  298 
  299         error = native_to_darwin_sockaddr(m);
  300         if (error != 0)
  301                 error = copyout_sockname(SCARG(uap, asa), SCARG(uap, alen),
  302                     MSG_LENUSRSPACE, m);
  303         if (m != NULL)
  304                 m_free(m);
  305         return error;
  306 }
  307 
  308 int
  309 darwin_sys_connect(struct lwp *l, const struct darwin_sys_connect_args *uap, register_t *retval)
  310 {
  311         /* {
  312                 syscallarg(int) s;
  313                 syscallarg(struct sockaddr *) name;
  314                 syscallarg(unsigned int *) namelen;
  315         } */
  316         struct mbuf *nam;
  317         int error;
  318 
  319         error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
  320             MT_SONAME);
  321         if (error == 0)
  322                 error = darwin_to_native_sockaddr(nam);
  323         if (error == 0)
  324                 error = do_sys_connect(l, SCARG(uap, s), nam);
  325 
  326         return error;
  327 }
  328 
  329 int
  330 darwin_sys_bind(struct lwp *l, const struct darwin_sys_bind_args *uap, register_t *retval)
  331 {
  332         /* {
  333                 syscallarg(int) s;
  334                 syscallarg(struct sockaddr *) name;
  335                 syscallarg(unsigned int *) namelen;
  336         } */
  337         struct mbuf *nam;
  338         int error;
  339 
  340         error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
  341             MT_SONAME);
  342         if (error == 0)
  343                 error = darwin_to_native_sockaddr(nam);
  344         if (error == 0)
  345                 error = do_sys_bind(l, SCARG(uap, s), nam);
  346 
  347         return error;
  348 }
  349 
  350 int
  351 darwin_sys_sendto(struct lwp *l, const struct darwin_sys_sendto_args *uap, register_t *retval)
  352 {
  353         /* {
  354                 syscallarg(int) s;
  355                 syscallarg(const void *) buf;
  356                 syscallarg(size_t) len;
  357                 syscallarg(int) flags;
  358                 syscallarg(struct sockaddr *) to;
  359                 syscallarg(unsigned int) tolen;
  360         } */
  361 
  362         struct msghdr   msg;
  363         struct iovec    aiov;
  364         struct mbuf *nam;
  365         int error;
  366 
  367         error = sockargs(&nam, SCARG(uap, to), SCARG(uap, tolen), MT_SONAME);
  368         if (error != 0)
  369                 return error;
  370         error = darwin_to_native_sockaddr(nam);
  371         if (error != 0)
  372                 return error;
  373 
  374         msg.msg_name = nam;
  375         msg.msg_namelen = 0;
  376         msg.msg_iov = &aiov;
  377         msg.msg_iovlen = 1;
  378         msg.msg_control = 0;
  379         msg.msg_flags = MSG_NAMEMBUF;
  380         aiov.iov_base = __UNCONST(SCARG(uap, buf)); /* XXXUNCONST kills const */
  381         aiov.iov_len = SCARG(uap, len);
  382         return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
  383 }

Cache object: 187979ce51eda07abd829a556f957be9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.