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/svr4/svr4_stream.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: svr4_stream.c,v 1.77 2008/04/28 20:23:45 martin Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 1994, 2008 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Christos Zoulas.
    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 /*
   33  * Pretend that we have streams...
   34  * Yes, this is gross.
   35  *
   36  * ToDo: The state machine for getmsg needs re-thinking
   37  *
   38  * The svr4_32 version is built from this file as well.
   39  */
   40 
   41 #include <sys/cdefs.h>
   42 __KERNEL_RCSID(0, "$NetBSD: svr4_stream.c,v 1.77 2008/04/28 20:23:45 martin Exp $");
   43 
   44 #include <sys/param.h>
   45 #include <sys/kernel.h>
   46 #include <sys/systm.h>
   47 #include <sys/buf.h>
   48 #include <sys/malloc.h>
   49 #include <sys/ioctl.h>
   50 #include <sys/tty.h>
   51 #include <sys/file.h>
   52 #include <sys/filedesc.h>
   53 #include <sys/namei.h>
   54 #include <sys/select.h>
   55 #include <sys/socket.h>
   56 #include <sys/socketvar.h>
   57 #include <sys/protosw.h>
   58 #include <sys/un.h>
   59 #include <net/if.h>
   60 #include <netinet/in.h>
   61 #include <sys/mbuf.h>
   62 #include <sys/mount.h>
   63 #include <sys/proc.h>
   64 #include <sys/vfs_syscalls.h>
   65 #include <sys/vnode.h>
   66 #include <sys/device.h>
   67 #include <sys/stat.h>
   68 
   69 #include <sys/syscallargs.h>
   70 
   71 #ifndef SVR4_32
   72 #define compat(name) <compat/svr4/svr4_##name>
   73 #else
   74 #define compat(name) <compat/svr4_32/svr4_32_##name>
   75 #endif
   76 
   77 #include compat(types.h)
   78 #include compat(util.h)
   79 #include compat(signal.h)
   80 #include compat(lwp.h)
   81 #include compat(ucontext.h)
   82 #include compat(syscallargs.h)
   83 #include compat(stropts.h)
   84 #include compat(timod.h)
   85 #include <compat/svr4/svr4_sockmod.h>
   86 #include compat(ioctl.h)
   87 #include compat(socket.h)
   88 
   89 #undef compat
   90 
   91 #ifndef SVR4_32
   92 
   93 #define SCARG_PTR(uap, arg)     SCARG(uap, arg)
   94 #define NETBSD32PTR(ptr)        (ptr)
   95 
   96 #else
   97 
   98 #define SCARG_PTR(uap, arg)     SCARG_P32(uap, arg)
   99 #define NETBSD32PTR(ptr)        NETBSD32PTR64(ptr)
  100 
  101 /* Rename stuff that is different for the svr4_32 build */
  102 #define svr4_infocmd            svr4_32_infocmd
  103 #define svr4_ino_t              svr4_32_ino_t
  104 #define svr4_netaddr_in         svr4_32_netaddr_in
  105 #define svr4_netaddr_un         svr4_32_netaddr_un
  106 #define svr4_strbuf             svr4_32_strbuf
  107 #define svr4_stream_get         svr4_32_stream_get
  108 #define svr4_stream_ioctl       svr4_32_stream_ioctl
  109 #define svr4_stream_ti_ioctl    svr4_32_stream_ti_ioctl
  110 #define svr4_strfdinsert        svr4_32_strfdinsert
  111 #define svr4_strioctl           svr4_32_strioctl
  112 #define svr4_strmcmd            svr4_32_strmcmd
  113 #define svr4_sys_getmsg         svr4_32_sys_getmsg
  114 #define svr4_sys_getmsg_args    svr4_32_sys_getmsg_args
  115 #define svr4_sys_putmsg         svr4_32_sys_putmsg
  116 #define svr4_sys_putmsg_args    svr4_32_sys_putmsg_args
  117 
  118 #endif /* SVR4_32 */
  119 
  120 /* Utils */
  121 static int clean_pipe(struct lwp *, const char *);
  122 static void getparm(file_t *, struct svr4_si_sockparms *);
  123 
  124 /* Address Conversions */
  125 static void sockaddr_to_netaddr_in(struct svr4_strmcmd *,
  126                                         const struct sockaddr_in *);
  127 static void sockaddr_to_netaddr_un(struct svr4_strmcmd *,
  128                                         const struct sockaddr_un *);
  129 static void netaddr_to_sockaddr_in(struct sockaddr_in *,
  130                                         const struct svr4_strmcmd *);
  131 static void netaddr_to_sockaddr_un(struct sockaddr_un *,
  132                                         const struct svr4_strmcmd *);
  133 
  134 /* stream ioctls */
  135 static int i_nread(file_t *, struct lwp *, register_t *, int,
  136     u_long, void *);
  137 static int i_fdinsert(file_t *, struct lwp *, register_t *, int,
  138     u_long, void *);
  139 static int i_str(file_t *, struct lwp *, register_t *, int,
  140     u_long, void *);
  141 static int i_setsig(file_t *, struct lwp *, register_t *, int,
  142     u_long, void *);
  143 static int i_getsig(file_t *, struct lwp *, register_t *, int,
  144     u_long, void *);
  145 static int _i_bind_rsvd(file_t *, struct lwp *, register_t *, int,
  146     u_long, void *);
  147 static int _i_rele_rsvd(file_t *, struct lwp *, register_t *, int,
  148     u_long, void *);
  149 
  150 /* i_str sockmod calls */
  151 static int sockmod(file_t *, int, struct svr4_strioctl *,
  152                               struct lwp *);
  153 static int si_listen(file_t *, int, struct svr4_strioctl *,
  154                               struct lwp *);
  155 static int si_ogetudata(file_t *, int, struct svr4_strioctl *,
  156                               struct lwp *);
  157 static int si_sockparams(file_t *, int, struct svr4_strioctl *,
  158                               struct lwp *);
  159 static int si_shutdown(file_t *, int, struct svr4_strioctl *,
  160                               struct lwp *);
  161 static int si_getudata(file_t *, int, struct svr4_strioctl *,
  162                               struct lwp *);
  163 
  164 /* i_str timod calls */
  165 static int timod(file_t *, int, struct svr4_strioctl *,
  166                               struct lwp *);
  167 static int ti_getinfo(file_t *, int, struct svr4_strioctl *,
  168                               struct lwp *);
  169 static int ti_bind(file_t *, int, struct svr4_strioctl *,
  170                               struct lwp *);
  171 
  172 #ifdef DEBUG_SVR4
  173 static void bufprint(u_char *, size_t);
  174 static int show_ioc(const char *, struct svr4_strioctl *);
  175 static int show_strbuf(struct svr4_strbuf *);
  176 static void show_msg(const char *, int, struct svr4_strbuf *,
  177                           struct svr4_strbuf *, int);
  178 
  179 static void
  180 bufprint(u_char *buf, size_t len)
  181 {
  182         size_t i;
  183 
  184         uprintf("\n\t");
  185         for (i = 0; i < len; i++) {
  186                 uprintf("%x ", buf[i]);
  187                 if (i && (i % 16) == 0)
  188                         uprintf("\n\t");
  189         }
  190 }
  191 
  192 static int
  193 show_ioc(const char *str, struct svr4_strioctl *ioc)
  194 {
  195         u_char *ptr;
  196         int error, len;
  197 
  198         len = ioc->len;
  199         if (len > 1024)
  200                 len = 1024;
  201 
  202         ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK);
  203         uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ",
  204             str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf);
  205 
  206         if ((error = copyin(ioc->buf, ptr, len)) != 0) {
  207                 free((char *) ptr, M_TEMP);
  208                 return error;
  209         }
  210 
  211         bufprint(ptr, len);
  212 
  213         uprintf("}\n");
  214 
  215         free((char *) ptr, M_TEMP);
  216         return 0;
  217 }
  218 
  219 
  220 static int
  221 show_strbuf(struct svr4_strbuf *str)
  222 {
  223         int error;
  224         u_char *ptr = NULL;
  225         int maxlen = str->maxlen;
  226         int len = str->len;
  227 
  228         if (maxlen > 8192)
  229                 maxlen = 8192;
  230 
  231         if (maxlen < 0)
  232                 maxlen = 0;
  233 
  234         if (len >= maxlen)
  235                 len = maxlen;
  236 
  237         if (len > 0) {
  238             ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK);
  239 
  240             if ((error = copyin(str->buf, ptr, len)) != 0) {
  241                     free((char *) ptr, M_TEMP);
  242                     return error;
  243             }
  244         }
  245 
  246         uprintf(", { %d, %d, %p=[ ", str->maxlen, str->len, str->buf);
  247 
  248         if (ptr)
  249                 bufprint(ptr, len);
  250 
  251         uprintf("]}");
  252 
  253         if (ptr)
  254                 free((char *) ptr, M_TEMP);
  255 
  256         return 0;
  257 }
  258 
  259 
  260 static void
  261 show_msg(const char *str, int fd, struct svr4_strbuf *ctl, struct svr4_strbuf *dat, int flags)
  262 {
  263         struct svr4_strbuf      buf;
  264         int error;
  265 
  266         uprintf("%s(%d", str, fd);
  267         if (ctl != NULL) {
  268                 if ((error = copyin(ctl, &buf, sizeof(buf))) != 0)
  269                         return;
  270                 show_strbuf(&buf);
  271         }
  272         else
  273                 uprintf(", NULL");
  274 
  275         if (dat != NULL) {
  276                 if ((error = copyin(dat, &buf, sizeof(buf))) != 0)
  277                         return;
  278                 show_strbuf(&buf);
  279         }
  280         else
  281                 uprintf(", NULL");
  282 
  283         uprintf(", %x);\n", flags);
  284 }
  285 
  286 #endif /* DEBUG_SVR4 */
  287 
  288 
  289 /*
  290  * We are faced with an interesting situation. On svr4 unix sockets
  291  * are really pipes. But we really have sockets, and we might as
  292  * well use them. At the point where svr4 calls TI_BIND, it has
  293  * already created a named pipe for the socket using mknod(2).
  294  * We need to create a socket with the same name when we bind,
  295  * so we need to remove the pipe before, otherwise we'll get address
  296  * already in use. So we *carefully* remove the pipe, to avoid
  297  * using this as a random file removal tool.
  298  */
  299 static int
  300 clean_pipe(struct lwp *l, const char *path)
  301 {
  302         struct nameidata nd;
  303         struct vattr va;
  304         int error;
  305 
  306         NDINIT(&nd, DELETE, NOFOLLOW | LOCKPARENT | LOCKLEAF | TRYEMULROOT,
  307             UIO_SYSSPACE, path);
  308 
  309         error = namei(&nd);
  310         if (error != 0)
  311                 return error;
  312 
  313         /*
  314          * Make sure we are dealing with a mode 0 named pipe.
  315          */
  316         if (nd.ni_vp->v_type != VFIFO)
  317                 goto bad;
  318         error = VOP_GETATTR(nd.ni_vp, &va, l->l_cred);
  319         if (error != 0)
  320                 goto bad;
  321         if ((va.va_mode & ALLPERMS) != 0)
  322                 goto bad;
  323 
  324         return VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
  325 
  326     bad:
  327         if (nd.ni_dvp == nd.ni_vp)
  328                 vrele(nd.ni_dvp);
  329         else
  330                 vput(nd.ni_dvp);
  331         vput(nd.ni_vp);
  332         return error;
  333 }
  334 
  335 
  336 static void
  337 sockaddr_to_netaddr_in(struct svr4_strmcmd *sc, const struct sockaddr_in *sain)
  338 {
  339         struct svr4_netaddr_in *na;
  340         na = SVR4_ADDROF(sc);
  341 
  342         na->family = sain->sin_family;
  343         na->port = sain->sin_port;
  344         na->addr = sain->sin_addr.s_addr;
  345         DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na->family, na->port,
  346                  na->addr));
  347 }
  348 
  349 
  350 static void
  351 sockaddr_to_netaddr_un(struct svr4_strmcmd *sc, const struct sockaddr_un *saun)
  352 {
  353         struct svr4_netaddr_un *na;
  354         char *dst, *edst = ((char *) sc) + sc->offs + sizeof(na->family) + 1  -
  355             sizeof(*sc);
  356         const char *src;
  357 
  358         na = SVR4_ADDROF(sc);
  359         na->family = saun->sun_family;
  360         for (src = saun->sun_path, dst = na->path; (*dst++ = *src++) != '\0'; )
  361                 if (dst == edst)
  362                         break;
  363         DPRINTF(("sockaddr_un -> netaddr %d %s\n", na->family, na->path));
  364 }
  365 
  366 
  367 static void
  368 netaddr_to_sockaddr_in(struct sockaddr_in *sain, const struct svr4_strmcmd *sc)
  369 {
  370         const struct svr4_netaddr_in *na;
  371 
  372 
  373         na = SVR4_C_ADDROF(sc);
  374         memset(sain, 0, sizeof(*sain));
  375         sain->sin_len = sizeof(*sain);
  376         sain->sin_family = na->family;
  377         sain->sin_port = na->port;
  378         sain->sin_addr.s_addr = na->addr;
  379         DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain->sin_family,
  380                  sain->sin_port, sain->sin_addr.s_addr));
  381 }
  382 
  383 
  384 static void
  385 netaddr_to_sockaddr_un(struct sockaddr_un *saun, const struct svr4_strmcmd *sc)
  386 {
  387         const struct svr4_netaddr_un *na;
  388         char *dst, *edst = &saun->sun_path[sizeof(saun->sun_path) - 1];
  389         const char *src;
  390 
  391         na = SVR4_C_ADDROF(sc);
  392         memset(saun, 0, sizeof(*saun));
  393         saun->sun_family = na->family;
  394         for (src = na->path, dst = saun->sun_path; (*dst++ = *src++) != '\0'; )
  395                 if (dst == edst)
  396                         break;
  397         saun->sun_len = dst - saun->sun_path;
  398         DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun->sun_family,
  399                  saun->sun_path));
  400 }
  401 
  402 
  403 static void
  404 getparm(file_t *fp, struct svr4_si_sockparms *pa)
  405 {
  406         struct svr4_strm *st = svr4_stream_get(fp);
  407         struct socket *so = (struct socket *) fp->f_data;
  408 
  409         if (st == NULL)
  410                 return;
  411 
  412         pa->family = st->s_family;
  413 
  414         switch (so->so_type) {
  415         case SOCK_DGRAM:
  416                 pa->type = SVR4_T_CLTS;
  417                 pa->protocol = IPPROTO_UDP;
  418                 DPRINTF(("getparm(dgram)\n"));
  419                 return;
  420 
  421         case SOCK_STREAM:
  422                 pa->type = SVR4_T_COTS;  /* What about T_COTS_ORD? XXX */
  423                 pa->protocol = IPPROTO_IP;
  424                 DPRINTF(("getparm(stream)\n"));
  425                 return;
  426 
  427         case SOCK_RAW:
  428                 pa->type = SVR4_T_CLTS;
  429                 pa->protocol = IPPROTO_RAW;
  430                 DPRINTF(("getparm(raw)\n"));
  431                 return;
  432 
  433         default:
  434                 pa->type = 0;
  435                 pa->protocol = 0;
  436                 DPRINTF(("getparm(type %d?)\n", so->so_type));
  437                 return;
  438         }
  439 }
  440 
  441 
  442 static int
  443 si_ogetudata(file_t *fp, int fd, struct svr4_strioctl *ioc,
  444     struct lwp *l)
  445 {
  446         int error;
  447         struct svr4_si_oudata ud;
  448         struct svr4_si_sockparms pa;
  449         (void)memset(&pa, 0, sizeof(pa));       /* XXX: GCC */
  450 
  451         if (ioc->len != sizeof(ud) && ioc->len != sizeof(ud) - sizeof(int)) {
  452                 DPRINTF(("SI_OGETUDATA: Wrong size %ld != %d\n",
  453                     (unsigned long)sizeof(ud), ioc->len));
  454                 return EINVAL;
  455         }
  456 
  457         if ((error = copyin(NETBSD32PTR(ioc->buf), &ud, sizeof(ud))) != 0)
  458                 return error;
  459 
  460         getparm(fp, &pa);
  461 
  462         switch (pa.family) {
  463         case AF_INET:
  464             ud.tidusize = 16384;
  465             ud.addrsize = sizeof(struct sockaddr_in);
  466             if (pa.type == SVR4_SOCK_STREAM)
  467                     ud.etsdusize = 1;
  468             else
  469                     ud.etsdusize = 0;
  470             break;
  471 
  472         case AF_LOCAL:
  473             ud.tidusize = 65536;
  474             ud.addrsize = 128;
  475             ud.etsdusize = 128;
  476             break;
  477 
  478         default:
  479             DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n",
  480                      pa.family));
  481             return ENOSYS;
  482         }
  483 
  484         /* I have no idea what these should be! */
  485         ud.optsize = 128;
  486         ud.tsdusize = 128;
  487 
  488         ud.servtype = pa.type;
  489 
  490         /* XXX: Fixme */
  491         ud.so_state = 0;
  492         ud.so_options = 0;
  493         return copyout(&ud, NETBSD32PTR(ioc->buf), ioc->len);
  494 }
  495 
  496 
  497 static int
  498 si_sockparams(file_t *fp, int fd, struct svr4_strioctl *ioc,
  499     struct lwp *l)
  500 {
  501         struct svr4_si_sockparms pa;
  502 
  503         getparm(fp, &pa);
  504         return copyout(&pa, NETBSD32PTR(ioc->buf), sizeof(pa));
  505 }
  506 
  507 
  508 static int
  509 si_listen(file_t *fp, int fd, struct svr4_strioctl *ioc, struct lwp *l)
  510 {
  511         int error;
  512         struct svr4_strm *st = svr4_stream_get(fp);
  513         register_t retval;
  514         struct svr4_strmcmd lst;
  515         struct sys_listen_args la;
  516 
  517         if (st == NULL)
  518                 return EINVAL;
  519 
  520         if (ioc->len > sizeof(lst))
  521                 return EINVAL;
  522 
  523         if ((error = copyin(NETBSD32PTR(ioc->buf), &lst, ioc->len)) != 0)
  524                 return error;
  525 
  526         if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) {
  527                 DPRINTF(("si_listen: bad request %ld\n", lst.cmd));
  528                 return EINVAL;
  529         }
  530 
  531         /*
  532          * We are making assumptions again...
  533          */
  534         SCARG(&la, s) = fd;
  535         DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd, 5));
  536         SCARG(&la, backlog) = 5;
  537 
  538         if ((error = sys_listen(l, &la, &retval)) != 0) {
  539                 DPRINTF(("SI_LISTEN: listen failed %d\n", error));
  540                 return error;
  541         }
  542 
  543         st->s_cmd = SVR4_TI__ACCEPT_WAIT;
  544         lst.cmd = SVR4_TI_BIND_REPLY;
  545 
  546         switch (st->s_family) {
  547         case AF_INET:
  548                 /* XXX: Fill the length here */
  549                 break;
  550 
  551         case AF_LOCAL:
  552                 lst.len = 140;
  553                 lst.pad[28] = 0x00000000;       /* magic again */
  554                 lst.pad[29] = 0x00000800;       /* magic again */
  555                 lst.pad[30] = 0x80001400;       /* magic again */
  556                 break;
  557 
  558         default:
  559                 DPRINTF(("SI_LISTEN: Unsupported address family %d\n",
  560                     st->s_family));
  561                 return ENOSYS;
  562         }
  563 
  564 
  565         if ((error = copyout(&lst, NETBSD32PTR(ioc->buf), ioc->len)) != 0)
  566                 return error;
  567 
  568         return 0;
  569 }
  570 
  571 
  572 static int
  573 si_getudata(file_t *fp, int fd, struct svr4_strioctl *ioc,
  574     struct lwp *l)
  575 {
  576         int error;
  577         struct svr4_si_udata ud;
  578 
  579         if (sizeof(ud) != ioc->len) {
  580                 DPRINTF(("SI_GETUDATA: Wrong size %ld != %d\n",
  581                     (unsigned long)sizeof(ud), ioc->len));
  582                 return EINVAL;
  583         }
  584 
  585         if ((error = copyin(NETBSD32PTR(ioc->buf), &ud, sizeof(ud))) != 0)
  586                 return error;
  587 
  588         getparm(fp, &ud.sockparms);
  589 
  590         switch (ud.sockparms.family) {
  591         case AF_INET:
  592             ud.tidusize = 16384;
  593             ud.tsdusize = 16384;
  594             ud.addrsize = sizeof(struct sockaddr_in);
  595             if (ud.sockparms.type == SVR4_SOCK_STREAM)
  596                     ud.etsdusize = 1;
  597             else
  598                     ud.etsdusize = 0;
  599             ud.optsize = 0;
  600             break;
  601 
  602         case AF_LOCAL:
  603             ud.tidusize = 65536;
  604             ud.tsdusize = 128;
  605             ud.addrsize = 128;
  606             ud.etsdusize = 128;
  607             ud.optsize = 128;
  608             break;
  609 
  610         default:
  611             DPRINTF(("SI_GETUDATA: Unsupported address family %d\n",
  612                      ud.sockparms.family));
  613             return ENOSYS;
  614         }
  615 
  616 
  617         ud.servtype = ud.sockparms.type;
  618 
  619         /* XXX: Fixme */
  620         ud.so_state = 0;
  621         ud.so_options = 0;
  622         return copyout(&ud, NETBSD32PTR(ioc->buf), sizeof(ud));
  623 }
  624 
  625 
  626 static int
  627 si_shutdown(file_t *fp, int fd, struct svr4_strioctl *ioc,
  628     struct lwp *l)
  629 {
  630         int error;
  631         struct sys_shutdown_args ap;
  632         register_t retval;
  633 
  634         if (ioc->len != sizeof(SCARG(&ap, how))) {
  635                 DPRINTF(("SI_SHUTDOWN: Wrong size %ld != %d\n",
  636                     (unsigned long)sizeof(SCARG(&ap, how)), ioc->len));
  637                 return EINVAL;
  638         }
  639 
  640         if ((error = copyin(NETBSD32PTR(ioc->buf), &SCARG(&ap, how), ioc->len)) != 0)
  641                 return error;
  642 
  643         SCARG(&ap, s) = fd;
  644 
  645         return sys_shutdown(l, &ap, &retval);
  646 }
  647 
  648 
  649 static int
  650 sockmod(file_t *fp, int fd, struct svr4_strioctl *ioc, struct lwp *l)
  651 {
  652         switch (ioc->cmd) {
  653         case SVR4_SI_OGETUDATA:
  654                 DPRINTF(("SI_OGETUDATA\n"));
  655                 return si_ogetudata(fp, fd, ioc, l);
  656 
  657         case SVR4_SI_SHUTDOWN:
  658                 DPRINTF(("SI_SHUTDOWN\n"));
  659                 return si_shutdown(fp, fd, ioc, l);
  660 
  661         case SVR4_SI_LISTEN:
  662                 DPRINTF(("SI_LISTEN\n"));
  663                 return si_listen(fp, fd, ioc, l);
  664 
  665         case SVR4_SI_SETMYNAME:
  666                 DPRINTF(("SI_SETMYNAME\n"));
  667                 return 0;
  668 
  669         case SVR4_SI_SETPEERNAME:
  670                 DPRINTF(("SI_SETPEERNAME\n"));
  671                 return 0;
  672 
  673         case SVR4_SI_GETINTRANSIT:
  674                 DPRINTF(("SI_GETINTRANSIT\n"));
  675                 return 0;
  676 
  677         case SVR4_SI_TCL_LINK:
  678                 DPRINTF(("SI_TCL_LINK\n"));
  679                 return 0;
  680 
  681         case SVR4_SI_TCL_UNLINK:
  682                 DPRINTF(("SI_TCL_UNLINK\n"));
  683                 return 0;
  684 
  685         case SVR4_SI_SOCKPARAMS:
  686                 DPRINTF(("SI_SOCKPARAMS\n"));
  687                 return si_sockparams(fp, fd, ioc, l);
  688 
  689         case SVR4_SI_GETUDATA:
  690                 DPRINTF(("SI_GETUDATA\n"));
  691                 return si_getudata(fp, fd, ioc, l);
  692 
  693         default:
  694                 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc->cmd));
  695                 return 0;
  696 
  697         }
  698 }
  699 
  700 
  701 static int
  702 ti_getinfo(file_t *fp, int fd, struct svr4_strioctl *ioc,
  703     struct lwp *l)
  704 {
  705         int error;
  706         struct svr4_infocmd info;
  707 
  708         memset(&info, 0, sizeof(info));
  709 
  710         if (ioc->len > sizeof(info))
  711                 return EINVAL;
  712 
  713         if ((error = copyin(NETBSD32PTR(ioc->buf), &info, ioc->len)) != 0)
  714                 return error;
  715 
  716         if (info.cmd != SVR4_TI_INFO_REQUEST)
  717                 return EINVAL;
  718 
  719         info.cmd = SVR4_TI_INFO_REPLY;
  720         info.tsdu = 0;
  721         info.etsdu = 1;
  722         info.cdata = -2;
  723         info.ddata = -2;
  724         info.addr = 16;
  725         info.opt = -1;
  726         info.tidu = 16384;
  727         info.serv = 2;
  728         info.current = 0;
  729         info.provider = 2;
  730 
  731         ioc->len = sizeof(info);
  732         if ((error = copyout(&info, NETBSD32PTR(ioc->buf), ioc->len)) != 0)
  733                 return error;
  734 
  735         return 0;
  736 }
  737 
  738 
  739 static int
  740 ti_bind(file_t *fp, int fd, struct svr4_strioctl *ioc, struct lwp *l)
  741 {
  742         int error;
  743         struct svr4_strm *st = svr4_stream_get(fp);
  744         struct sockaddr_in sain;
  745         struct sockaddr_un saun;
  746         void *skp, *sup = NULL;
  747         int sasize;
  748         struct svr4_strmcmd bnd;
  749         struct mbuf *name;
  750 
  751         if (st == NULL) {
  752                 DPRINTF(("ti_bind: bad file descriptor\n"));
  753                 return EINVAL;
  754         }
  755 
  756         if (ioc->len > sizeof(bnd))
  757                 return EINVAL;
  758 
  759         if ((error = copyin(NETBSD32PTR(ioc->buf), &bnd, ioc->len)) != 0)
  760                 return error;
  761 
  762         if (bnd.cmd != SVR4_TI_OLD_BIND_REQUEST) {
  763                 DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd));
  764                 return EINVAL;
  765         }
  766 
  767         switch (st->s_family) {
  768         case AF_INET:
  769                 skp = &sain;
  770                 sasize = sizeof(sain);
  771 
  772                 if (bnd.offs == 0)
  773                         goto reply;
  774 
  775                 netaddr_to_sockaddr_in(&sain, &bnd);
  776 
  777                 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n",
  778                          sain.sin_family, sain.sin_port,
  779                          sain.sin_addr.s_addr));
  780                 break;
  781 
  782         case AF_LOCAL:
  783                 skp = &saun;
  784                 sasize = sizeof(saun);
  785                 if (bnd.offs == 0)
  786                         goto reply;
  787 
  788                 netaddr_to_sockaddr_un(&saun, &bnd);
  789 
  790                 if (saun.sun_path[0] == '\0')
  791                         goto reply;
  792 
  793                 DPRINTF(("TI_BIND: fam %d, path %s\n",
  794                          saun.sun_family, saun.sun_path));
  795 
  796                 if ((error = clean_pipe(l, saun.sun_path)) != 0)
  797                         return error;
  798 
  799                 bnd.pad[28] = 0x00001000;       /* magic again */
  800                 break;
  801 
  802         default:
  803                 DPRINTF(("TI_BIND: Unsupported address family %d\n",
  804                          st->s_family));
  805                 return ENOSYS;
  806         }
  807 
  808         name = m_get(M_WAIT, MT_SONAME);
  809         if (sasize > MLEN)
  810                 MEXTMALLOC(name, sasize, M_WAITOK);
  811 
  812         memcpy(mtod(name, void *), skp, sasize);
  813 
  814         DPRINTF(("TI_BIND: fileno %d\n", fd));
  815 
  816         error = do_sys_bind(l, fd, name);
  817         if (error != 0) {
  818                 DPRINTF(("TI_BIND: bind failed %d\n", error));
  819                 return error;
  820         }
  821 
  822 reply:
  823         if (sup == NULL) {
  824                 memset(&bnd, 0, sizeof(bnd));
  825                 bnd.len = sasize + 4;
  826                 bnd.offs = 0x10;        /* XXX */
  827         }
  828 
  829         bnd.cmd = SVR4_TI_BIND_REPLY;
  830 
  831         if ((error = copyout(&bnd, NETBSD32PTR(ioc->buf), ioc->len)) != 0)
  832                 return error;
  833 
  834         return 0;
  835 }
  836 
  837 
  838 static int
  839 timod(file_t *fp, int fd, struct svr4_strioctl *ioc, struct lwp *l)
  840 {
  841         switch (ioc->cmd) {
  842         case SVR4_TI_GETINFO:
  843                 DPRINTF(("TI_GETINFO\n"));
  844                 return ti_getinfo(fp, fd, ioc, l);
  845 
  846         case SVR4_TI_OPTMGMT:
  847                 DPRINTF(("TI_OPTMGMT\n"));
  848                 return 0;
  849 
  850         case SVR4_TI_BIND:
  851                 DPRINTF(("TI_BIND\n"));
  852                 return ti_bind(fp, fd, ioc, l);
  853 
  854         case SVR4_TI_UNBIND:
  855                 DPRINTF(("TI_UNBIND\n"));
  856                 return 0;
  857 
  858         default:
  859                 DPRINTF(("Unknown timod ioctl %lx\n", ioc->cmd));
  860                 return 0;
  861         }
  862 }
  863 
  864 
  865 int
  866 svr4_stream_ti_ioctl(file_t *fp, struct lwp *l, register_t *retval, int fd, u_long cmd, void *dat)
  867 {
  868         struct svr4_strbuf skb, *sub = (struct svr4_strbuf *) dat;
  869         struct svr4_strm *st = svr4_stream_get(fp);
  870         int error;
  871         struct svr4_strmcmd sc;
  872         struct mbuf *name;
  873 
  874         if (st == NULL)
  875                 return EINVAL;
  876 
  877         sc.offs = 0x10;
  878 
  879         if ((error = copyin(sub, &skb, sizeof(skb))) != 0) {
  880                 DPRINTF(("ti_ioctl: error copying in strbuf\n"));
  881                 return error;
  882         }
  883 
  884         switch (cmd) {
  885         case SVR4_TI_GETMYNAME:
  886                 DPRINTF(("TI_GETMYNAME\n"));
  887                 cmd = PRU_SOCKADDR;
  888                 break;
  889 
  890         case SVR4_TI_GETPEERNAME:
  891                 DPRINTF(("TI_GETPEERNAME\n"));
  892                 cmd = PRU_PEERADDR;
  893                 break;
  894 
  895         case SVR4_TI_SETMYNAME:
  896                 DPRINTF(("TI_SETMYNAME\n"));
  897                 return 0;
  898 
  899         case SVR4_TI_SETPEERNAME:
  900                 DPRINTF(("TI_SETPEERNAME\n"));
  901                 return 0;
  902         default:
  903                 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd));
  904                 return ENOSYS;
  905         }
  906 
  907         error = do_sys_getsockname(l, fd, cmd, &name);
  908         if (error != 0)
  909                 return error;
  910 
  911         switch (st->s_family) {
  912         case AF_INET:
  913                 sockaddr_to_netaddr_in(&sc, mtod(name, void *));
  914                 skb.len = sizeof (struct sockaddr_in);
  915                 break;
  916 
  917         case AF_LOCAL:
  918                 sockaddr_to_netaddr_un(&sc, mtod(name, void *));
  919                 /* XXX: the length gets adjusted but the copyout doesn't */
  920                 skb.len = sizeof (struct sockaddr_un) + 4;
  921                 break;
  922 
  923         default:
  924                 DPRINTF(("ti_ioctl: Unsupported address family %d\n",
  925                          st->s_family));
  926                 m_free(name);
  927                 return ENOSYS;
  928         }
  929 
  930         error = copyout(SVR4_ADDROF(&sc), NETBSD32PTR(skb.buf), name->m_len);
  931         m_free(name);
  932         if (error != 0) {
  933                 DPRINTF(("ti_ioctl: error copying out socket data\n"));
  934                 return error;
  935         }
  936 
  937 
  938         if ((error = copyout(&skb, sub, sizeof(skb))) != 0) {
  939                 DPRINTF(("ti_ioctl: error copying out strbuf\n"));
  940                 return error;
  941         }
  942 
  943         return error;
  944 }
  945 
  946 
  947 
  948 
  949 static int
  950 i_nread(file_t *fp, struct lwp *l, register_t *retval, int fd,
  951     u_long cmd, void *dat)
  952 {
  953         int error;
  954         int nread = 0;
  955 
  956         /*
  957          * We are supposed to return the message length in nread, and the
  958          * number of messages in retval. We don't have the notion of number
  959          * of stream messages, so we just find out if we have any bytes waiting
  960          * for us, and if we do, then we assume that we have at least one
  961          * message waiting for us.
  962          */
  963         if ((error = (*fp->f_ops->fo_ioctl)(fp, FIONREAD, &nread)) != 0)
  964                 return error;
  965 
  966         if (nread != 0)
  967                 *retval = 1;
  968         else
  969                 *retval = 0;
  970 
  971         return copyout(&nread, dat, sizeof(nread));
  972 }
  973 
  974 static int
  975 i_fdinsert(file_t *fp, struct lwp *l, register_t *retval, int fd,
  976     u_long cmd, void *dat)
  977 {
  978         /*
  979          * Major hack again here. We assume that we are using this to
  980          * implement accept(2). If that is the case, we have already
  981          * called accept, and we have stored the file descriptor in
  982          * afd. We find the file descriptor that the code wants to use
  983          * in fd insert, and then we dup2() our accepted file descriptor
  984          * to it.
  985          */
  986         int error;
  987         struct svr4_strm *st = svr4_stream_get(fp);
  988         struct svr4_strfdinsert fdi;
  989         struct sys_dup2_args d2p;
  990         struct sys_close_args clp;
  991 
  992         if (st == NULL) {
  993                 DPRINTF(("fdinsert: bad file type\n"));
  994                 return EINVAL;
  995         }
  996 
  997         if (st->s_afd == -1) {
  998                 DPRINTF(("fdinsert: accept fd not found\n"));
  999                 return ENOENT;
 1000         }
 1001 
 1002         if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) {
 1003                 DPRINTF(("fdinsert: copyin failed %d\n", error));
 1004                 return error;
 1005         }
 1006 
 1007         SCARG(&d2p, from) = st->s_afd;
 1008         SCARG(&d2p, to) = fdi.fd;
 1009 
 1010         if ((error = sys_dup2(l, &d2p, retval)) != 0) {
 1011                 DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n",
 1012                     st->s_afd, fdi.fd, error));
 1013                 return error;
 1014         }
 1015 
 1016         SCARG(&clp, fd) = st->s_afd;
 1017 
 1018         if ((error = sys_close(l, &clp, retval)) != 0) {
 1019                 DPRINTF(("fdinsert: close(%d) failed %d\n",
 1020                     st->s_afd, error));
 1021                 return error;
 1022         }
 1023 
 1024         st->s_afd = -1;
 1025 
 1026         *retval = 0;
 1027         return 0;
 1028 }
 1029 
 1030 
 1031 static int
 1032 _i_bind_rsvd(file_t *fp, struct lwp *l, register_t *retval,
 1033     int fd, u_long cmd, void *dat)
 1034 {
 1035         struct sys_mkfifo_args ap;
 1036 
 1037         /*
 1038          * This is a supposed to be a kernel and library only ioctl.
 1039          * It gets called before ti_bind, when we have a unix
 1040          * socket, to physically create the socket transport and
 1041          * ``reserve'' it. I don't know how this get reserved inside
 1042          * the kernel, but we are going to create it nevertheless.
 1043          */
 1044         SCARG(&ap, path) = dat;
 1045         SCARG(&ap, mode) = S_IFIFO;
 1046 
 1047         return sys_mkfifo(l, &ap, retval);
 1048 }
 1049 
 1050 static int
 1051 _i_rele_rsvd(file_t *fp, struct lwp *l, register_t *retval,
 1052     int fd, u_long cmd, void *dat)
 1053 {
 1054         struct sys_unlink_args ap;
 1055 
 1056         /*
 1057          * This is a supposed to be a kernel and library only ioctl.
 1058          * I guess it is supposed to release the socket.
 1059          */
 1060         SCARG(&ap, path) = dat;
 1061 
 1062         return sys_unlink(l, &ap, retval);
 1063 }
 1064 
 1065 static int
 1066 i_str(file_t *fp, struct lwp *l, register_t *retval, int fd,
 1067     u_long cmd, void *dat)
 1068 {
 1069         int                      error;
 1070         struct svr4_strioctl     ioc;
 1071 
 1072         /*
 1073          * Noop on non sockets
 1074          */
 1075         if (fp->f_type != DTYPE_SOCKET)
 1076                 return 0;
 1077 
 1078         if ((error = copyin(dat, &ioc, sizeof(ioc))) != 0)
 1079                 return error;
 1080 
 1081 #ifdef DEBUG_SVR4
 1082         if ((error = show_ioc(">", &ioc)) != 0)
 1083                 return error;
 1084 #endif /* DEBUG_SVR4 */
 1085 
 1086         switch (ioc.cmd & 0xff00) {
 1087         case SVR4_SIMOD:
 1088                 if ((error = sockmod(fp, fd, &ioc, l)) != 0)
 1089                         return error;
 1090                 break;
 1091 
 1092         case SVR4_TIMOD:
 1093                 if ((error = timod(fp, fd, &ioc, l)) != 0)
 1094                         return error;
 1095                 break;
 1096 
 1097         default:
 1098                 DPRINTF(("Unimplemented module %c %ld\n",
 1099                          (char) (cmd >> 8), cmd & 0xff));
 1100                 return 0;
 1101         }
 1102 
 1103 #ifdef DEBUG_SVR4
 1104         if ((error = show_ioc("<", &ioc)) != 0)
 1105                 return error;
 1106 #endif /* DEBUG_SVR4 */
 1107         return copyout(&ioc, dat, sizeof(ioc));
 1108 }
 1109 
 1110 static int
 1111 i_setsig(file_t *fp, struct lwp *l, register_t *retval, int fd,
 1112     u_long cmd, void *dat)
 1113 {
 1114         /*
 1115          * This is the best we can do for now; we cannot generate
 1116          * signals only for specific events so the signal mask gets
 1117          * ignored; we save it just to pass it to a possible I_GETSIG...
 1118          *
 1119          * We alse have to fix the O_ASYNC fcntl bit, so the
 1120          * process will get SIGPOLLs.
 1121          */
 1122         struct sys_fcntl_args fa;
 1123         int error;
 1124         register_t oflags, flags;
 1125         struct svr4_strm *st = svr4_stream_get(fp);
 1126 
 1127         if (st == NULL) {
 1128                 DPRINTF(("i_setsig: bad file descriptor\n"));
 1129                 return EINVAL;
 1130         }
 1131         /* get old status flags */
 1132         SCARG(&fa, fd) = fd;
 1133         SCARG(&fa, cmd) = F_GETFL;
 1134 
 1135         if ((error = sys_fcntl(l, &fa, &oflags)) != 0)
 1136                 return error;
 1137 
 1138         /* update the flags */
 1139         if (dat != NULL) {
 1140                 int mask;
 1141 
 1142                 flags = oflags | O_ASYNC;
 1143                 mask = (int)(u_long)dat;
 1144                 if (mask & ~SVR4_S_ALLMASK) {
 1145                         DPRINTF(("i_setsig: bad eventmask data %x\n", mask));
 1146                         return EINVAL;
 1147                 }
 1148                 st->s_eventmask = mask;
 1149         }
 1150         else {
 1151                 flags = oflags & ~O_ASYNC;
 1152                 st->s_eventmask = 0;
 1153         }
 1154 
 1155         /* set the new flags, if changed */
 1156         if (flags != oflags) {
 1157                 SCARG(&fa, cmd) = F_SETFL;
 1158                 SCARG(&fa, arg) = (void *) flags;
 1159                 if ((error = sys_fcntl(l, &fa, &flags)) != 0)
 1160                         return error;
 1161         }
 1162 
 1163         /* set up SIGIO receiver if needed */
 1164         if (dat != NULL) {
 1165                 SCARG(&fa, cmd) = F_SETOWN;
 1166                 SCARG(&fa, arg) = (void *)(u_long)l->l_proc->p_pid;
 1167                 return sys_fcntl(l, &fa, &flags);
 1168         }
 1169         return 0;
 1170 }
 1171 
 1172 static int
 1173 i_getsig(file_t *fp, struct lwp *l, register_t *retval,
 1174     int fd, u_long cmd, void *dat)
 1175 {
 1176         int error;
 1177 
 1178         if (dat != NULL) {
 1179                 struct svr4_strm *st = svr4_stream_get(fp);
 1180 
 1181                 if (st == NULL) {
 1182                         DPRINTF(("i_getsig: bad file descriptor\n"));
 1183                         return EINVAL;
 1184                 }
 1185                 if ((error = copyout(&st->s_eventmask, dat,
 1186                     sizeof(st->s_eventmask))) != 0) {
 1187                         DPRINTF(("i_getsig: bad eventmask pointer\n"));
 1188                         return error;
 1189                 }
 1190         }
 1191         return 0;
 1192 }
 1193 
 1194 int
 1195 svr4_stream_ioctl(file_t *fp, struct lwp *l, register_t *retval, int fd, u_long cmd, void *dat)
 1196 {
 1197         *retval = 0;
 1198 
 1199         /*
 1200          * All the following stuff assumes "sockmod" is pushed...
 1201          */
 1202         switch (cmd) {
 1203         case SVR4_I_NREAD:
 1204                 DPRINTF(("I_NREAD\n"));
 1205                 return i_nread(fp, l, retval, fd, cmd, dat);
 1206 
 1207         case SVR4_I_PUSH:
 1208                 DPRINTF(("I_PUSH\n"));
 1209                 return 0;
 1210 
 1211         case SVR4_I_POP:
 1212                 DPRINTF(("I_POP\n"));
 1213                 return 0;
 1214 
 1215         case SVR4_I_LOOK:
 1216                 DPRINTF(("I_LOOK\n"));
 1217                 return 0;
 1218 
 1219         case SVR4_I_FLUSH:
 1220                 DPRINTF(("I_FLUSH\n"));
 1221                 return 0;
 1222 
 1223         case SVR4_I_SRDOPT:
 1224                 DPRINTF(("I_SRDOPT\n"));
 1225                 return 0;
 1226 
 1227         case SVR4_I_GRDOPT:
 1228                 DPRINTF(("I_GRDOPT\n"));
 1229                 return 0;
 1230 
 1231         case SVR4_I_STR:
 1232                 DPRINTF(("I_STR\n"));
 1233                 return i_str(fp, l, retval, fd, cmd, dat);
 1234 
 1235         case SVR4_I_SETSIG:
 1236                 DPRINTF(("I_SETSIG\n"));
 1237                 return i_setsig(fp, l, retval, fd, cmd, dat);
 1238 
 1239         case SVR4_I_GETSIG:
 1240                 DPRINTF(("I_GETSIG\n"));
 1241                 return i_getsig(fp, l, retval, fd, cmd, dat);
 1242 
 1243         case SVR4_I_FIND:
 1244                 DPRINTF(("I_FIND\n"));
 1245                 /*
 1246                  * Here we are not pushing modules really, we just
 1247                  * pretend all are present
 1248                  */
 1249                 *retval = 1;
 1250                 return 0;
 1251 
 1252         case SVR4_I_LINK:
 1253                 DPRINTF(("I_LINK\n"));
 1254                 return 0;
 1255 
 1256         case SVR4_I_UNLINK:
 1257                 DPRINTF(("I_UNLINK\n"));
 1258                 return 0;
 1259 
 1260         case SVR4_I_ERECVFD:
 1261                 DPRINTF(("I_ERECVFD\n"));
 1262                 return 0;
 1263 
 1264         case SVR4_I_PEEK:
 1265                 DPRINTF(("I_PEEK\n"));
 1266                 return 0;
 1267 
 1268         case SVR4_I_FDINSERT:
 1269                 DPRINTF(("I_FDINSERT\n"));
 1270                 return i_fdinsert(fp, l, retval, fd, cmd, dat);
 1271 
 1272         case SVR4_I_SENDFD:
 1273                 DPRINTF(("I_SENDFD\n"));
 1274                 return 0;
 1275 
 1276         case SVR4_I_RECVFD:
 1277                 DPRINTF(("I_RECVFD\n"));
 1278                 return 0;
 1279 
 1280         case SVR4_I_SWROPT:
 1281                 DPRINTF(("I_SWROPT\n"));
 1282                 return 0;
 1283 
 1284         case SVR4_I_GWROPT:
 1285                 DPRINTF(("I_GWROPT\n"));
 1286                 return 0;
 1287 
 1288         case SVR4_I_LIST:
 1289                 DPRINTF(("I_LIST\n"));
 1290                 return 0;
 1291 
 1292         case SVR4_I_PLINK:
 1293                 DPRINTF(("I_PLINK\n"));
 1294                 return 0;
 1295 
 1296         case SVR4_I_PUNLINK:
 1297                 DPRINTF(("I_PUNLINK\n"));
 1298                 return 0;
 1299 
 1300         case SVR4_I_SETEV:
 1301                 DPRINTF(("I_SETEV\n"));
 1302                 return 0;
 1303 
 1304         case SVR4_I_GETEV:
 1305                 DPRINTF(("I_GETEV\n"));
 1306                 return 0;
 1307 
 1308         case SVR4_I_STREV:
 1309                 DPRINTF(("I_STREV\n"));
 1310                 return 0;
 1311 
 1312         case SVR4_I_UNSTREV:
 1313                 DPRINTF(("I_UNSTREV\n"));
 1314                 return 0;
 1315 
 1316         case SVR4_I_FLUSHBAND:
 1317                 DPRINTF(("I_FLUSHBAND\n"));
 1318                 return 0;
 1319 
 1320         case SVR4_I_CKBAND:
 1321                 DPRINTF(("I_CKBAND\n"));
 1322                 return 0;
 1323 
 1324         case SVR4_I_GETBAND:
 1325                 DPRINTF(("I_GETBANK\n"));
 1326                 return 0;
 1327 
 1328         case SVR4_I_ATMARK:
 1329                 DPRINTF(("I_ATMARK\n"));
 1330                 return 0;
 1331 
 1332         case SVR4_I_SETCLTIME:
 1333                 DPRINTF(("I_SETCLTIME\n"));
 1334                 return 0;
 1335 
 1336         case SVR4_I_GETCLTIME:
 1337                 DPRINTF(("I_GETCLTIME\n"));
 1338                 return 0;
 1339 
 1340         case SVR4_I_CANPUT:
 1341                 DPRINTF(("I_CANPUT\n"));
 1342                 return 0;
 1343 
 1344         case SVR4__I_BIND_RSVD:
 1345                 DPRINTF(("_I_BIND_RSVD\n"));
 1346                 return _i_bind_rsvd(fp, l, retval, fd, cmd, dat);
 1347 
 1348         case SVR4__I_RELE_RSVD:
 1349                 DPRINTF(("_I_RELE_RSVD\n"));
 1350                 return _i_rele_rsvd(fp, l, retval, fd, cmd, dat);
 1351 
 1352         default:
 1353                 DPRINTF(("unimpl cmd = %lx\n", cmd));
 1354                 break;
 1355         }
 1356 
 1357         return 0;
 1358 }
 1359 
 1360 
 1361 
 1362 
 1363 int
 1364 svr4_sys_putmsg(struct lwp *l, const struct svr4_sys_putmsg_args *uap, register_t *retval)
 1365 {
 1366         struct proc *p = l->l_proc;
 1367         file_t  *fp;
 1368         struct svr4_strbuf dat, ctl;
 1369         struct svr4_strmcmd sc;
 1370         struct sockaddr_in sain;
 1371         struct sockaddr_un saun;
 1372         void *skp;
 1373         int sasize;
 1374         struct svr4_strm *st;
 1375         int error;
 1376         struct mbuf *nam;
 1377         struct msghdr msg;
 1378         struct iovec aiov;
 1379 
 1380 
 1381 #ifdef DEBUG_SVR4
 1382         show_msg(">putmsg", SCARG(uap, fd), SCARG(uap, ctl),
 1383                  SCARG(uap, dat), SCARG(uap, flags));
 1384 #endif /* DEBUG_SVR4 */
 1385 
 1386         if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
 1387                 return EBADF;
 1388 
 1389         KERNEL_LOCK(1, NULL);   /* svr4_find_socket */
 1390 
 1391         if (SCARG_PTR(uap, ctl) != NULL) {
 1392                 if ((error = copyin(SCARG_PTR(uap, ctl),
 1393                                     &ctl, sizeof(ctl))) != 0)
 1394                         goto out;
 1395         } else
 1396                 ctl.len = -1;
 1397 
 1398         if (SCARG_PTR(uap, dat) != NULL) {
 1399                 if ((error = copyin(SCARG_PTR(uap, dat),
 1400                                     &dat, sizeof(dat))) != 0)
 1401                         goto out;
 1402         } else
 1403                 dat.len = -1;
 1404 
 1405         /*
 1406          * Only for sockets for now.
 1407          */
 1408         if ((st = svr4_stream_get(fp)) == NULL) {
 1409                 DPRINTF(("putmsg: bad file type\n"));
 1410                 error = EINVAL;
 1411                 goto out;
 1412         }
 1413 
 1414         if (ctl.len > sizeof(sc)) {
 1415                 DPRINTF(("putmsg: Bad control size %ld != %d\n",
 1416                     (unsigned long)sizeof(struct svr4_strmcmd), ctl.len));
 1417                 error = EINVAL;
 1418                 goto out;
 1419         }
 1420 
 1421         if ((error = copyin(NETBSD32PTR(ctl.buf), &sc, ctl.len)) != 0)
 1422                 goto out;
 1423 
 1424         switch (st->s_family) {
 1425         case AF_INET:
 1426                 if (sc.len != sizeof(sain)) {
 1427 #ifdef notyet
 1428                         if (sc.cmd == SVR4_TI_DATA_REQUEST) {
 1429                                 struct sys_write_args wa;
 1430 
 1431                                 /* Solaris seems to use sc.cmd = 3 to
 1432                                  * send "expedited" data.  telnet uses
 1433                                  * this for options processing, sending EOF,
 1434                                  * etc.  I'm sure other things use it too.
 1435                                  * I don't have any documentation
 1436                                  * on it, so I'm making a guess that this
 1437                                  * is how it works. newton@atdot.dotat.org XXX
 1438                                  *
 1439                                  * Hmm, expedited data seems to be sc.cmd = 4.
 1440                                  * I think 3 is normal data. (christos)
 1441                                  */
 1442                                 DPRINTF(("sending expedited data (?)\n"));
 1443                                 SCARG(&wa, fd) = SCARG(uap, fd);
 1444                                 SCARG(&wa, buf) = dat.buf;
 1445                                 SCARG(&wa, nbyte) = dat.len;
 1446                                 error = sys_write(l, &wa, retval);
 1447                                 goto out;
 1448                         }
 1449 #endif
 1450                         DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len));
 1451                         error = EINVAL;
 1452                         goto out;
 1453                 }
 1454                 netaddr_to_sockaddr_in(&sain, &sc);
 1455                 skp = &sain;
 1456                 sasize = sizeof(sain);
 1457                 error = sain.sin_family != st->s_family;
 1458                 break;
 1459 
 1460         case AF_LOCAL:
 1461                 if (ctl.len == 8) {
 1462                         /* We are doing an accept; succeed */
 1463                         DPRINTF(("putmsg: Do nothing\n"));
 1464                         *retval = 0;
 1465                         error = 0;
 1466                         goto out;
 1467                 }
 1468                 else {
 1469                         /* Maybe we've been given a device/inode pair */
 1470                         dev_t *dev = SVR4_ADDROF(&sc);
 1471                         svr4_ino_t *ino = (svr4_ino_t *) &dev[1];
 1472                         skp = svr4_find_socket(p, fp, *dev, *ino);
 1473                         if (skp == NULL) {
 1474                                 skp = &saun;
 1475                                 /* I guess we have it by name */
 1476                                 netaddr_to_sockaddr_un(skp, &sc);
 1477                         }
 1478                         sasize = sizeof(saun);
 1479                 }
 1480                 break;
 1481 
 1482         default:
 1483                 DPRINTF(("putmsg: Unsupported address family %d\n",
 1484                          st->s_family));
 1485                 error = ENOSYS;
 1486                 goto out;
 1487         }
 1488 
 1489         nam = m_get(M_WAIT, MT_SONAME);
 1490         nam->m_len = sasize;
 1491         memcpy(mtod(nam, void *), skp, sasize);
 1492 
 1493         switch (st->s_cmd = sc.cmd) {
 1494         case SVR4_TI_CONNECT_REQUEST:   /* connect      */
 1495                 KERNEL_UNLOCK_ONE(NULL);
 1496                 return do_sys_connect(l, SCARG(uap, fd), nam);
 1497 
 1498         case SVR4_TI_SENDTO_REQUEST:    /* sendto       */
 1499                 KERNEL_UNLOCK_ONE(NULL);
 1500                 msg.msg_name = nam;
 1501                 msg.msg_namelen = sasize;
 1502                 msg.msg_iov = &aiov;
 1503                 msg.msg_iovlen = 1;
 1504                 msg.msg_control = NULL;
 1505                 msg.msg_flags = MSG_NAMEMBUF;
 1506                 aiov.iov_base = NETBSD32PTR(dat.buf);
 1507                 aiov.iov_len = dat.len;
 1508                 error = do_sys_sendmsg(l, SCARG(uap, fd), &msg,
 1509                                SCARG(uap, flags), retval);
 1510 
 1511                 *retval = 0;
 1512                 return error;
 1513   
 1514         default:
 1515                 m_free(nam);
 1516                 DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd));
 1517                 error = ENOSYS;
 1518                 goto out;
 1519         }
 1520 
 1521  out:
 1522         KERNEL_UNLOCK_ONE(NULL);
 1523         fd_putfile(SCARG(uap, fd));
 1524         return error;
 1525 }
 1526 
 1527 
 1528 int
 1529 svr4_sys_getmsg(struct lwp *l, const struct svr4_sys_getmsg_args *uap, register_t *retval)
 1530 {
 1531         file_t *fp;
 1532         struct svr4_strbuf dat, ctl;
 1533         struct svr4_strmcmd sc;
 1534         int error = 0;
 1535         struct msghdr msg;
 1536         struct iovec aiov;
 1537         struct svr4_strm *st;
 1538         int fl;
 1539         struct mbuf *name;
 1540 
 1541         memset(&sc, 0, sizeof(sc));
 1542 
 1543 #ifdef DEBUG_SVR4
 1544         show_msg(">getmsg", SCARG(uap, fd), SCARG(uap, ctl),
 1545                  SCARG(uap, dat), 0);
 1546 #endif /* DEBUG_SVR4 */
 1547 
 1548         if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
 1549                 return EBADF;
 1550 
 1551         if (SCARG_PTR(uap, ctl) != NULL) {
 1552                 if ((error = copyin(SCARG_PTR(uap, ctl), &ctl,
 1553                                     sizeof(ctl))) != 0)
 1554                         goto out;
 1555         } else {
 1556                 ctl.len = -1;
 1557                 ctl.maxlen = 0;
 1558         }
 1559 
 1560         if (SCARG_PTR(uap, dat) != NULL) {
 1561                 if ((error = copyin(SCARG_PTR(uap, dat), &dat,
 1562                                     sizeof(dat))) != 0)
 1563                         goto out;
 1564         } else {
 1565                 dat.len = -1;
 1566                 dat.maxlen = 0;
 1567         }
 1568 
 1569         /*
 1570          * Only for sockets for now.
 1571          */
 1572         if ((st = svr4_stream_get(fp)) == NULL) {
 1573                 DPRINTF(("getmsg: bad file type\n"));
 1574                 error = EINVAL;
 1575                 goto out;
 1576         }
 1577 
 1578         if (ctl.maxlen == -1 || dat.maxlen == -1) {
 1579                 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n"));
 1580                 error = ENOSYS;
 1581                 goto out;
 1582         }
 1583 
 1584         switch (st->s_family) {
 1585         case AF_INET:
 1586         case AF_LOCAL:
 1587                 break;
 1588 
 1589         default:
 1590                 DPRINTF(("getmsg: Unsupported address family %d\n",
 1591                          st->s_family));
 1592                 goto out;
 1593         }
 1594 
 1595         switch (st->s_cmd) {
 1596         case SVR4_TI_CONNECT_REQUEST:
 1597                 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
 1598                 /*
 1599                  * We do the connect in one step, so the putmsg should
 1600                  * have gotten the error.
 1601                  */
 1602                 sc.cmd = SVR4_TI_OK_REPLY;
 1603                 sc.len = 0;
 1604 
 1605                 ctl.len = 8;
 1606                 dat.len = -1;
 1607                 fl = 1;
 1608                 st->s_cmd = sc.cmd;
 1609                 break;
 1610 
 1611         case SVR4_TI_OK_REPLY:
 1612                 DPRINTF(("getmsg: TI_OK_REPLY\n"));
 1613                 /*
 1614                  * We are immediately after a connect reply, so we send
 1615                  * a connect verification.
 1616                  */
 1617 
 1618                 error = do_sys_getsockname(l, SCARG(uap, fd), PRU_SOCKADDR,
 1619                     &name);
 1620                 if (error != 0) {
 1621                         DPRINTF(("getmsg: getpeername failed %d\n", error));
 1622                         goto out;
 1623                 }
 1624 
 1625                 sc.cmd = SVR4_TI_CONNECT_REPLY;
 1626                 sc.pad[0] = 0x4;
 1627                 sc.offs = 0x18;
 1628                 sc.pad[1] = 0x14;
 1629                 sc.pad[2] = 0x04000402;
 1630 
 1631                 switch (st->s_family) {
 1632                 case AF_INET:
 1633                         sc.len = sizeof (struct sockaddr_in) + 4;
 1634                         sockaddr_to_netaddr_in(&sc, mtod(name, void *));
 1635                         break;
 1636 
 1637                 case AF_LOCAL:
 1638                         sc.len = sizeof (struct sockaddr_un) + 4;
 1639                         sockaddr_to_netaddr_un(&sc, mtod(name, void *));
 1640                         break;
 1641 
 1642                 default:
 1643                         m_free(name);
 1644                         error = ENOSYS;
 1645                         goto out;
 1646                 }
 1647                 m_free(name);
 1648 
 1649                 ctl.len = 40;
 1650                 dat.len = -1;
 1651                 fl = 0;
 1652                 st->s_cmd = sc.cmd;
 1653                 break;
 1654 
 1655         case SVR4_TI__ACCEPT_OK:
 1656                 DPRINTF(("getmsg: TI__ACCEPT_OK\n"));
 1657                 /*
 1658                  * We do the connect in one step, so the putmsg should
 1659                  * have gotten the error.
 1660                  */
 1661                 sc.cmd = SVR4_TI_OK_REPLY;
 1662                 sc.len = 1;
 1663 
 1664                 ctl.len = 8;
 1665                 dat.len = -1;
 1666                 fl = 1;
 1667                 st->s_cmd = SVR4_TI__ACCEPT_WAIT;
 1668                 break;
 1669 
 1670         case SVR4_TI__ACCEPT_WAIT:
 1671                 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n"));
 1672                 /*
 1673                  * We are after a listen, so we try to accept...
 1674                  */
 1675 
 1676                 error = do_sys_accept(l, SCARG(uap, fd), &name, retval);
 1677                 if (error != 0) {
 1678                         DPRINTF(("getmsg: accept failed %d\n", error));
 1679                         goto out;
 1680                 }
 1681 
 1682                 st->s_afd = *retval;
 1683 
 1684                 DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd));
 1685 
 1686                 sc.cmd = SVR4_TI_ACCEPT_REPLY;
 1687                 sc.offs = 0x18;
 1688                 sc.pad[0] = 0x0;
 1689 
 1690                 switch (st->s_family) {
 1691                 case AF_INET:
 1692                         sc.pad[1] = 0x28;
 1693                         sockaddr_to_netaddr_in(&sc, mtod(name, void *));
 1694                         ctl.len = 40;
 1695                         sc.len = sizeof (struct sockaddr_in);
 1696                         break;
 1697 
 1698                 case AF_LOCAL:
 1699                         sc.pad[1] = 0x00010000;
 1700                         sc.pad[2] = 0xf6bcdaa0; /* I don't know what that is */
 1701                         sc.pad[3] = 0x00010000;
 1702                         ctl.len = 134;
 1703                         sc.len = sizeof (struct sockaddr_un) + 4;
 1704                         break;
 1705 
 1706                 default:
 1707                         m_free(name);
 1708                         error = ENOSYS;
 1709                         goto out;
 1710                 }
 1711                 m_free(name);
 1712 
 1713                 dat.len = -1;
 1714                 fl = 0;
 1715                 st->s_cmd = SVR4_TI__ACCEPT_OK;
 1716                 break;
 1717 
 1718         case SVR4_TI_SENDTO_REQUEST:
 1719                 /*
 1720                  * XXX: dsl - I think this means that because we last did a
 1721                  * 'sendto' we'd better do a recvfrom now.
 1722                  */
 1723                 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n"));
 1724                 if (ctl.maxlen > 36 && ctl.len < 36)
 1725                     ctl.len = 36;
 1726                 if (ctl.len > sizeof(sc))
 1727                         ctl.len = sizeof(sc);
 1728 
 1729                 if ((error = copyin(NETBSD32PTR(ctl.buf), &sc, ctl.len)) != 0)
 1730                         goto out;
 1731 
 1732                 msg.msg_name = NULL;
 1733                 msg.msg_namelen = 0;
 1734                 msg.msg_iov = &aiov;
 1735                 msg.msg_iovlen = 1;
 1736                 msg.msg_control = 0;
 1737                 aiov.iov_base = NETBSD32PTR(dat.buf);
 1738                 aiov.iov_len = dat.maxlen;
 1739                 msg.msg_flags = 0;
 1740 
 1741                 error = do_sys_recvmsg(l,  SCARG(uap, fd), &msg, &name, NULL,
 1742                     retval);
 1743 
 1744                 if (error) {
 1745                         DPRINTF(("getmsg: do_sys_recvmsg failed %d\n", error));
 1746                         goto out;
 1747                 }
 1748 
 1749                 sc.cmd = SVR4_TI_RECVFROM_IND;
 1750 
 1751                 switch (st->s_family) {
 1752                 case AF_INET:
 1753                         sc.len = sizeof (struct sockaddr_in);
 1754                         sockaddr_to_netaddr_in(&sc, mtod(name, void *));
 1755                         break;
 1756 
 1757                 case AF_LOCAL:
 1758                         sc.len = sizeof (struct sockaddr_un) + 4;
 1759                         sockaddr_to_netaddr_un(&sc, mtod(name, void *));
 1760                         break;
 1761 
 1762                 default:
 1763                         m_free(name);
 1764                         error = ENOSYS;
 1765                         goto out;
 1766                 }
 1767                 m_free(name);
 1768 
 1769                 dat.len = *retval;
 1770                 fl = 0;
 1771                 st->s_cmd = sc.cmd;
 1772                 break;
 1773 
 1774         default:
 1775                 st->s_cmd = sc.cmd;
 1776 #ifdef notyet
 1777                 if (st->s_cmd == SVR4_TI_CONNECT_REQUEST) {
 1778                         struct sys_read_args ra;
 1779 
 1780                         /* More weirdness:  Again, I can't find documentation
 1781                          * to back this up, but when a process does a generic
 1782                          * "getmsg()" call it seems that the command field is
 1783                          * zero and the length of the data area is zero.  I
 1784                          * think processes expect getmsg() to fill in dat.len
 1785                          * after reading at most dat.maxlen octets from the
 1786                          * stream.  Since we're using sockets I can let
 1787                          * read() look after it and frob return values
 1788                          * appropriately (or inappropriately :-)
 1789                          *   -- newton@atdot.dotat.org        XXX
 1790                          */
 1791                         SCARG(&ra, fd) = SCARG(uap, fd);
 1792                         SCARG(&ra, buf) = dat.buf;
 1793                         SCARG(&ra, nbyte) = dat.maxlen;
 1794                         if ((error = sys_read(p, &ra, retval)) != 0)
 1795                                 goto out;
 1796                         dat.len = *retval;
 1797                         *retval = 0;
 1798                         st->s_cmd = SVR4_TI_SENDTO_REQUEST;
 1799                         break;
 1800 
 1801                 }
 1802 #endif
 1803                 DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd));
 1804                 error = EINVAL;
 1805                 goto out;
 1806         }
 1807 
 1808         if (SCARG_PTR(uap, ctl)) {
 1809                 if (ctl.len != -1)
 1810                         if ((error = copyout(&sc, NETBSD32PTR(ctl.buf),
 1811                                              ctl.len)) != 0)
 1812                                 goto out;
 1813 
 1814                 if ((error = copyout(&ctl, SCARG_PTR(uap, ctl),
 1815                                      sizeof(ctl))) != 0)
 1816                         goto out;
 1817         }
 1818 
 1819         if (SCARG_PTR(uap, dat)) {
 1820                 if ((error = copyout(&dat, SCARG_PTR(uap, dat),
 1821                                      sizeof(dat))) != 0)
 1822                         goto out;
 1823         }
 1824 
 1825         if (SCARG_PTR(uap, flags)) { /* XXX: Need translation */
 1826                 if ((error = copyout(&fl, SCARG_PTR(uap, flags),
 1827                                      sizeof(fl))) != 0)
 1828                         goto out;
 1829         }
 1830 
 1831         *retval = 0;
 1832 
 1833 #ifdef DEBUG_SVR4
 1834         show_msg("<getmsg", SCARG(uap, fd), SCARG(uap, ctl),
 1835                  SCARG(uap, dat), fl);
 1836 #endif /* DEBUG_SVR4 */
 1837 
 1838  out:
 1839         fd_putfile(SCARG(uap, fd));
 1840         return error;
 1841 }

Cache object: 69bac9df1e52ac037742f310cc8cfe64


[ 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.