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/net/raw_usrreq.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) 1980, 1986, 1993
    3  *      The Regents of the University of California.  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 the University of
   16  *      California, Berkeley and its contributors.
   17  * 4. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  *
   33  *      @(#)raw_usrreq.c        8.1 (Berkeley) 6/10/93
   34  * $FreeBSD: src/sys/net/raw_usrreq.c,v 1.8.4.1 1999/09/05 08:17:59 peter Exp $
   35  */
   36 
   37 #include <sys/param.h>
   38 #include <sys/queue.h>
   39 #include <sys/systm.h>
   40 #include <sys/mbuf.h>
   41 #include <sys/domain.h>
   42 #include <sys/protosw.h>
   43 #include <sys/socket.h>
   44 #include <sys/socketvar.h>
   45 #include <sys/errno.h>
   46 
   47 #include <net/if.h>
   48 #include <net/route.h>
   49 #include <net/netisr.h>
   50 #include <net/raw_cb.h>
   51 
   52 /*
   53  * Initialize raw connection block q.
   54  */
   55 void
   56 raw_init()
   57 {
   58 
   59         rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
   60 }
   61 
   62 
   63 /*
   64  * Raw protocol input routine.  Find the socket
   65  * associated with the packet(s) and move them over.  If
   66  * nothing exists for this packet, drop it.
   67  */
   68 /*
   69  * Raw protocol interface.
   70  */
   71 void
   72 raw_input(m0, proto, src, dst)
   73         struct mbuf *m0;
   74         register struct sockproto *proto;
   75         struct sockaddr *src, *dst;
   76 {
   77         register struct rawcb *rp;
   78         register struct mbuf *m = m0;
   79         register int sockets = 0;
   80         struct socket *last;
   81 
   82         last = 0;
   83         for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
   84                 if (rp->rcb_proto.sp_family != proto->sp_family)
   85                         continue;
   86                 if (rp->rcb_proto.sp_protocol  &&
   87                     rp->rcb_proto.sp_protocol != proto->sp_protocol)
   88                         continue;
   89                 /*
   90                  * We assume the lower level routines have
   91                  * placed the address in a canonical format
   92                  * suitable for a structure comparison.
   93                  *
   94                  * Note that if the lengths are not the same
   95                  * the comparison will fail at the first byte.
   96                  */
   97 #define equal(a1, a2) \
   98   (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
   99                 if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
  100                         continue;
  101                 if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
  102                         continue;
  103                 if (last) {
  104                         struct mbuf *n;
  105                         n = m_copy(m, 0, (int)M_COPYALL);
  106                         if (n) {
  107                                 if (sbappendaddr(&last->so_rcv, src,
  108                                     n, (struct mbuf *)0) == 0)
  109                                         /* should notify about lost packet */
  110                                         m_freem(n);
  111                                 else {
  112                                         sorwakeup(last);
  113                                         sockets++;
  114                                 }
  115                         }
  116                 }
  117                 last = rp->rcb_socket;
  118         }
  119         if (last) {
  120                 if (sbappendaddr(&last->so_rcv, src,
  121                     m, (struct mbuf *)0) == 0)
  122                         m_freem(m);
  123                 else {
  124                         sorwakeup(last);
  125                         sockets++;
  126                 }
  127         } else
  128                 m_freem(m);
  129 }
  130 
  131 /*ARGSUSED*/
  132 void
  133 raw_ctlinput(cmd, arg, dummy)
  134         int cmd;
  135         struct sockaddr *arg;
  136         void *dummy;
  137 {
  138 
  139         if (cmd < 0 || cmd > PRC_NCMDS)
  140                 return;
  141         /* INCOMPLETE */
  142 }
  143 
  144 /*ARGSUSED*/
  145 int
  146 raw_usrreq(so, req, m, nam, control)
  147         struct socket *so;
  148         int req;
  149         struct mbuf *m, *nam, *control;
  150 {
  151         register struct rawcb *rp = sotorawcb(so);
  152         register int error = 0;
  153         int len;
  154 
  155         if (req == PRU_CONTROL)
  156                 return (EOPNOTSUPP);
  157         if (control && control->m_len) {
  158                 error = EOPNOTSUPP;
  159                 goto release;
  160         }
  161         if (rp == 0) {
  162                 error = EINVAL;
  163                 goto release;
  164         }
  165         switch (req) {
  166 
  167         /*
  168          * Allocate a raw control block and fill in the
  169          * necessary info to allow packets to be routed to
  170          * the appropriate raw interface routine.
  171          */
  172         case PRU_ATTACH:
  173                 if ((so->so_state & SS_PRIV) == 0) {
  174                         error = EACCES;
  175                         break;
  176                 }
  177                 error = raw_attach(so, (int)nam);
  178                 break;
  179 
  180         /*
  181          * Destroy state just before socket deallocation.
  182          * Flush data or not depending on the options.
  183          */
  184         case PRU_DETACH:
  185                 if (rp == 0) {
  186                         error = ENOTCONN;
  187                         break;
  188                 }
  189                 raw_detach(rp);
  190                 break;
  191 
  192         /*
  193          * If a socket isn't bound to a single address,
  194          * the raw input routine will hand it anything
  195          * within that protocol family (assuming there's
  196          * nothing else around it should go to).
  197          */
  198         case PRU_CONNECT:
  199                 error = EINVAL;
  200 #if 0
  201                 if (rp->rcb_faddr) {
  202                         error = EISCONN;
  203                         break;
  204                 }
  205                 nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
  206                 rp->rcb_faddr = mtod(nam, struct sockaddr *);
  207                 soisconnected(so);
  208 #endif
  209                 break;
  210 
  211         case PRU_BIND:
  212                 error = EINVAL;
  213 #if 0
  214                 if (rp->rcb_laddr) {
  215                         error = EINVAL;                 /* XXX */
  216                         break;
  217                 }
  218                 error = raw_bind(so, nam);
  219 #endif
  220                 break;
  221 
  222         case PRU_CONNECT2:
  223                 error = EOPNOTSUPP;
  224                 goto release;
  225 
  226         case PRU_DISCONNECT:
  227                 if (rp->rcb_faddr == 0) {
  228                         error = ENOTCONN;
  229                         break;
  230                 }
  231                 raw_disconnect(rp);
  232                 soisdisconnected(so);
  233                 break;
  234 
  235         /*
  236          * Mark the connection as being incapable of further input.
  237          */
  238         case PRU_SHUTDOWN:
  239                 socantsendmore(so);
  240                 break;
  241 
  242         /*
  243          * Ship a packet out.  The appropriate raw output
  244          * routine handles any massaging necessary.
  245          */
  246         case PRU_SEND:
  247                 if (nam) {
  248                         if (rp->rcb_faddr) {
  249                                 error = EISCONN;
  250                                 break;
  251                         }
  252                         rp->rcb_faddr = mtod(nam, struct sockaddr *);
  253                 } else if (rp->rcb_faddr == 0) {
  254                         error = ENOTCONN;
  255                         break;
  256                 }
  257                 error = (*so->so_proto->pr_output)(m, so);
  258                 m = NULL;
  259                 if (nam)
  260                         rp->rcb_faddr = 0;
  261                 break;
  262 
  263         case PRU_ABORT:
  264                 raw_disconnect(rp);
  265                 sofree(so);
  266                 soisdisconnected(so);
  267                 break;
  268 
  269         case PRU_SENSE:
  270                 /*
  271                  * stat: don't bother with a blocksize.
  272                  */
  273                 return (0);
  274 
  275         /*
  276          * Not supported.
  277          */
  278         case PRU_RCVOOB:
  279         case PRU_RCVD:
  280                 return(EOPNOTSUPP);
  281 
  282         case PRU_LISTEN:
  283         case PRU_ACCEPT:
  284         case PRU_SENDOOB:
  285                 error = EOPNOTSUPP;
  286                 break;
  287 
  288         case PRU_SOCKADDR:
  289                 if (rp->rcb_laddr == 0) {
  290                         error = EINVAL;
  291                         break;
  292                 }
  293                 len = rp->rcb_laddr->sa_len;
  294                 bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
  295                 nam->m_len = len;
  296                 break;
  297 
  298         case PRU_PEERADDR:
  299                 if (rp->rcb_faddr == 0) {
  300                         error = ENOTCONN;
  301                         break;
  302                 }
  303                 len = rp->rcb_faddr->sa_len;
  304                 bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
  305                 nam->m_len = len;
  306                 break;
  307 
  308         default:
  309                 panic("raw_usrreq");
  310         }
  311 release:
  312         if (m != NULL)
  313                 m_freem(m);
  314         return (error);
  315 }

Cache object: db1fd30c8c6a5a6390c2d24991020467


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