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

Cache object: ad3ebd32573cb846044c8abbcf656d65


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