root/compat/svr4/svr4_stream.c

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

DEFINITIONS

This source file includes following definitions.
  1. bufprint
  2. show_ioc
  3. show_strbuf
  4. show_msg
  5. clean_pipe
  6. sockaddr_to_netaddr_in
  7. sockaddr_to_netaddr_un
  8. netaddr_to_sockaddr_in
  9. netaddr_to_sockaddr_un
  10. getparm
  11. si_ogetudata
  12. si_sockparams
  13. si_listen
  14. si_getudata
  15. si_shutdown
  16. sockmod
  17. ti_getinfo
  18. ti_bind
  19. timod
  20. svr4_stream_ti_ioctl
  21. i_nread
  22. i_fdinsert
  23. _i_bind_rsvd
  24. _i_rele_rsvd
  25. i_str
  26. svr4_stream_ioctl
  27. svr4_sys_putmsg
  28. svr4_sys_getmsg

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

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