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

Cache object: d2dd84fffd27d37e01107489cedafd0e


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