root/net/raw_usrreq.c

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

DEFINITIONS

This source file includes following definitions.
  1. raw_init
  2. raw_input
  3. raw_ctlinput
  4. raw_usrreq

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

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