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_net.c

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

    1 /*      $NetBSD: svr4_net.c,v 1.45 2006/11/16 01:32:44 christos Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 1994 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Christos Zoulas.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * Emulate /dev/{udp,tcp,...}
   41  */
   42 
   43 #include <sys/cdefs.h>
   44 __KERNEL_RCSID(0, "$NetBSD: svr4_net.c,v 1.45 2006/11/16 01:32:44 christos Exp $");
   45 
   46 #define COMPAT_SVR4 1
   47 
   48 #include <sys/param.h>
   49 #include <sys/kernel.h>
   50 #include <sys/systm.h>
   51 #include <sys/buf.h>
   52 #include <sys/malloc.h>
   53 #include <sys/ioctl.h>
   54 #include <sys/tty.h>
   55 #include <sys/file.h>
   56 #include <sys/filedesc.h>
   57 #include <sys/fcntl.h>
   58 #include <sys/select.h>
   59 #include <sys/socket.h>
   60 #include <sys/socketvar.h>
   61 #include <sys/protosw.h>
   62 #include <sys/domain.h>
   63 #include <net/if.h>
   64 #include <netinet/in.h>
   65 #include <sys/proc.h>
   66 #include <sys/vnode.h>
   67 #include <sys/device.h>
   68 #include <sys/conf.h>
   69 #include <sys/mount.h>
   70 
   71 #include <sys/sa.h>
   72 #include <sys/syscallargs.h>
   73 
   74 #include <compat/svr4/svr4_types.h>
   75 #include <compat/svr4/svr4_util.h>
   76 #include <compat/svr4/svr4_signal.h>
   77 #include <compat/svr4/svr4_lwp.h>
   78 #include <compat/svr4/svr4_ucontext.h>
   79 #include <compat/svr4/svr4_syscallargs.h>
   80 #include <compat/svr4/svr4_ioctl.h>
   81 #include <compat/svr4/svr4_stropts.h>
   82 #include <compat/svr4/svr4_socket.h>
   83 
   84 dev_type_open(svr4_netopen);
   85 
   86 const struct cdevsw svr4_net_cdevsw = {
   87         svr4_netopen, noclose, noread, nowrite, noioctl,
   88         nostop, notty, nopoll, nommap, nokqfilter, D_OTHER,
   89 };
   90 
   91 /*
   92  * Device minor numbers
   93  */
   94 enum {
   95         dev_ptm                 = 10,
   96         dev_arp                 = 26,
   97         dev_icmp                = 27,
   98         dev_ip                  = 28,
   99         dev_tcp                 = 35,
  100         dev_udp                 = 36,
  101         dev_rawip               = 37,
  102         dev_unix_dgram          = 38,
  103         dev_unix_stream         = 39,
  104         dev_unix_ord_stream     = 40
  105 };
  106 
  107 int svr4_netattach __P((int));
  108 
  109 int svr4_soo_close __P((struct file *, struct lwp *));
  110 int svr4_ptm_alloc __P((struct proc *));
  111 
  112 static const struct fileops svr4_netops = {
  113         soo_read, soo_write, soo_ioctl, soo_fcntl, soo_poll,
  114         soo_stat, svr4_soo_close, soo_kqfilter
  115 };
  116 
  117 
  118 /*
  119  * Used by new config, but we don't need it.
  120  */
  121 int
  122 svr4_netattach(int n)
  123 {
  124         return 0;
  125 }
  126 
  127 
  128 int
  129 svr4_netopen(dev_t dev, int flag, int mode, struct lwp *l)
  130 {
  131         struct proc *p = l->l_proc;
  132         int type, protocol;
  133         int fd;
  134         struct file *fp;
  135         struct socket *so;
  136         int error;
  137         int family;
  138 
  139         DPRINTF(("netopen("));
  140 
  141         if (curlwp->l_dupfd >= 0)       /* XXX */
  142                 return ENODEV;
  143 
  144         switch (minor(dev)) {
  145         case dev_udp:
  146                 family = AF_INET;
  147                 type = SOCK_DGRAM;
  148                 protocol = IPPROTO_UDP;
  149                 DPRINTF(("udp, "));
  150                 break;
  151 
  152         case dev_tcp:
  153                 family = AF_INET;
  154                 type = SOCK_STREAM;
  155                 protocol = IPPROTO_TCP;
  156                 DPRINTF(("tcp, "));
  157                 break;
  158 
  159         case dev_ip:
  160         case dev_rawip:
  161                 family = AF_INET;
  162                 type = SOCK_RAW;
  163                 protocol = IPPROTO_IP;
  164                 DPRINTF(("ip, "));
  165                 break;
  166 
  167         case dev_icmp:
  168                 family = AF_INET;
  169                 type = SOCK_RAW;
  170                 protocol = IPPROTO_ICMP;
  171                 DPRINTF(("icmp, "));
  172                 break;
  173 
  174         case dev_unix_dgram:
  175                 family = AF_LOCAL;
  176                 type = SOCK_DGRAM;
  177                 protocol = 0;
  178                 DPRINTF(("unix-dgram, "));
  179                 break;
  180 
  181         case dev_unix_stream:
  182         case dev_unix_ord_stream:
  183                 family = AF_LOCAL;
  184                 type = SOCK_STREAM;
  185                 protocol = 0;
  186                 DPRINTF(("unix-stream, "));
  187                 break;
  188 
  189         case dev_ptm:
  190                 DPRINTF(("ptm);\n"));
  191                 return svr4_ptm_alloc(p);
  192 
  193         default:
  194                 DPRINTF(("%d);\n", minor(dev)));
  195                 return EOPNOTSUPP;
  196         }
  197 
  198         /* falloc() will use the descriptor for us */
  199         if ((error = falloc(l, &fp, &fd)) != 0)
  200                 return error;
  201 
  202         if ((error = socreate(family, &so, type, protocol, l)) != 0) {
  203                 DPRINTF(("socreate error %d\n", error));
  204                 fdremove(p->p_fd, fd);
  205                 FILE_UNUSE(fp, NULL);
  206                 ffree(fp);
  207                 return error;
  208         }
  209 
  210         error = fdclone(l, fp, fd, flag, &svr4_netops, so);
  211         fp->f_type = DTYPE_SOCKET;
  212         (void)svr4_stream_get(fp);
  213 
  214         DPRINTF(("ok);\n"));
  215         return error;
  216 }
  217 
  218 
  219 int
  220 svr4_soo_close(fp, l)
  221         struct file *fp;
  222         struct lwp *l;
  223 {
  224         struct socket *so = (struct socket *) fp->f_data;
  225 
  226         svr4_delete_socket(l->l_proc, fp);
  227         free(so->so_internal, M_NETADDR);
  228         return soo_close(fp, l);
  229 }
  230 
  231 
  232 int
  233 svr4_ptm_alloc(p)
  234         struct proc *p;
  235 {
  236         /*
  237          * XXX this is very, very ugly.  But I can't find a better
  238          * way that won't duplicate a big amount of code from
  239          * sys_open().  Ho hum...
  240          *
  241          * Fortunately for us, Solaris (at least 2.5.1) makes the
  242          * /dev/ptmx open automatically just open a pty, that (after
  243          * STREAMS I_PUSHes), is just a plain pty.  fstat() is used
  244          * to get the minor device number to map to a tty.
  245          *
  246          * Cycle through the names. If sys_open() returns ENOENT (or
  247          * ENXIO), short circuit the cycle and exit.
  248          */
  249         char ptyname[] = "/dev/ptyXX";
  250         static const char ttyletters[] = "pqrstuvwxyzPQRST";
  251         caddr_t sg = stackgap_init(p, 0);
  252         char *path = stackgap_alloc(p, &sg, sizeof(ptyname));
  253         struct sys_open_args oa;
  254         int l = 0, n = 0;
  255         register_t fd = -1;
  256         int error;
  257 
  258         SCARG(&oa, path) = path;
  259         SCARG(&oa, flags) = O_RDWR;
  260         SCARG(&oa, mode) = 0;
  261 
  262         while (fd == -1) {
  263                 ptyname[8] = ttyletters[l];
  264                 ptyname[9] = hexdigits[n];
  265 
  266                 if ((error = copyout(ptyname, path, sizeof(ptyname))) != 0)
  267                         return error;
  268 
  269                 switch (error = sys_open(curlwp, &oa, &fd)) { /* XXX NJWLWP */
  270                 case ENOENT:
  271                 case ENXIO:
  272                         return error;
  273                 case 0:
  274                         curlwp->l_dupfd = fd;
  275                         return EMOVEFD;
  276                 default:
  277                         if (hexdigits[++n] == '\0') {
  278                                 if (ttyletters[++l] == '\0')
  279                                         break;
  280                                 n = 0;
  281                         }
  282                 }
  283         }
  284         return ENOENT;
  285 }
  286 
  287 
  288 struct svr4_strm *
  289 svr4_stream_get(fp)
  290         struct file *fp;
  291 {
  292         struct socket *so;
  293         struct svr4_strm *st;
  294 
  295         if (fp == NULL || fp->f_type != DTYPE_SOCKET)
  296                 return NULL;
  297 
  298         so = (struct socket *) fp->f_data;
  299 
  300         if (so->so_internal)
  301                 return so->so_internal;
  302 
  303         /* Allocate a new one. */
  304         fp->f_ops = &svr4_netops;
  305         st = malloc(sizeof(struct svr4_strm), M_NETADDR, M_WAITOK);
  306         st->s_family = so->so_proto->pr_domain->dom_family;
  307         st->s_cmd = ~0;
  308         st->s_afd = -1;
  309         st->s_eventmask = 0;
  310         so->so_internal = st;
  311 
  312         return st;
  313 }

Cache object: b8ed20c9aa363bb442f13f6270e15003


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