home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / net / raw_usrreq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-06  |  6.9 KB  |  309 lines

  1. /*
  2.  * Copyright (c) 1980, 1986 Regents of the University of California.
  3.  * 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    7.9 (Berkeley) 6/28/90
  34.  */
  35.  
  36. #include "param.h"
  37. #include "mbuf.h"
  38. #include "domain.h"
  39. #include "protosw.h"
  40. #include "socket.h"
  41. #include "socketvar.h"
  42. #include "errno.h"
  43.  
  44. #include "if.h"
  45. #include "route.h"
  46. #include "netisr.h"
  47. #include "raw_cb.h"
  48.  
  49. #include "machine/mtpr.h"
  50.  
  51. /*
  52.  * Initialize raw connection block q.
  53.  */
  54. raw_init()
  55. {
  56.  
  57.     rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
  58.     rawintrq.ifq_maxlen = IFQ_MAXLEN;
  59. }
  60.  
  61.  
  62. /*
  63.  * Raw protocol input routine.  Find the socket
  64.  * associated with the packet(s) and move them over.  If
  65.  * nothing exists for this packet, drop it.
  66.  */
  67. /*
  68.  * Raw protocol interface.
  69.  */
  70. raw_input(m0, proto, src, dst)
  71.     struct mbuf *m0;
  72.     register struct sockproto *proto;
  73.     struct sockaddr *src, *dst;
  74. {
  75.     register struct rawcb *rp;
  76.     register struct mbuf *m = m0;
  77.     register int sockets = 0;
  78.     struct socket *last;
  79.  
  80.     last = 0;
  81.     for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
  82.         if (rp->rcb_proto.sp_family != proto->sp_family)
  83.             continue;
  84.         if (rp->rcb_proto.sp_protocol  &&
  85.             rp->rcb_proto.sp_protocol != proto->sp_protocol)
  86.             continue;
  87.         /*
  88.          * We assume the lower level routines have
  89.          * placed the address in a canonical format
  90.          * suitable for a structure comparison.
  91.          *
  92.          * Note that if the lengths are not the same
  93.          * the comparison will fail at the first byte.
  94.          */
  95. #define    equal(a1, a2) \
  96.   (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
  97.         if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
  98.             continue;
  99.         if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
  100.             continue;
  101.         if (last) {
  102.             struct mbuf *n;
  103.             if (n = m_copy(m, 0, (int)M_COPYALL)) {
  104.                 if (sbappendaddr(&last->so_rcv, src,
  105.                     n, (struct mbuf *)0) == 0)
  106.                     /* should notify about lost packet */
  107.                     m_freem(n);
  108.                 else {
  109.                     sorwakeup(last);
  110.                     sockets++;
  111.                 }
  112.             }
  113.         }
  114.         last = rp->rcb_socket;
  115.     }
  116.     if (last) {
  117.         if (sbappendaddr(&last->so_rcv, src,
  118.             m, (struct mbuf *)0) == 0)
  119.             m_freem(m);
  120.         else {
  121.             sorwakeup(last);
  122.             sockets++;
  123.         }
  124.     } else
  125.         m_freem(m);
  126.     return (sockets);
  127. }
  128.  
  129. /*ARGSUSED*/
  130. raw_ctlinput(cmd, arg)
  131.     int cmd;
  132.     struct sockaddr *arg;
  133. {
  134.  
  135.     if (cmd < 0 || cmd > PRC_NCMDS)
  136.         return;
  137.     /* INCOMPLETE */
  138. }
  139.  
  140. /*ARGSUSED*/
  141. raw_usrreq(so, req, m, nam, control)
  142.     struct socket *so;
  143.     int req;
  144.     struct mbuf *m, *nam, *control;
  145. {
  146.     register struct rawcb *rp = sotorawcb(so);
  147.     register int error = 0;
  148.     int len;
  149.  
  150.     if (req == PRU_CONTROL)
  151.         return (EOPNOTSUPP);
  152.     if (control && control->m_len) {
  153.         error = EOPNOTSUPP;
  154.         goto release;
  155.     }
  156.     if (rp == 0) {
  157.         error = EINVAL;
  158.         goto release;
  159.     }
  160.     switch (req) {
  161.  
  162.     /*
  163.      * Allocate a raw control block and fill in the
  164.      * necessary info to allow packets to be routed to
  165.      * the appropriate raw interface routine.
  166.      */
  167.     case PRU_ATTACH:
  168.         if ((so->so_state & SS_PRIV) == 0) {
  169.             error = EACCES;
  170.             break;
  171.         }
  172.         error = raw_attach(so, (int)nam);
  173.         break;
  174.  
  175.     /*
  176.      * Destroy state just before socket deallocation.
  177.      * Flush data or not depending on the options.
  178.      */
  179.     case PRU_DETACH:
  180.         if (rp == 0) {
  181.             error = ENOTCONN;
  182.             break;
  183.         }
  184.         raw_detach(rp);
  185.         break;
  186.  
  187. #ifdef notdef
  188.     /*
  189.      * If a socket isn't bound to a single address,
  190.      * the raw input routine will hand it anything
  191.      * within that protocol family (assuming there's
  192.      * nothing else around it should go to). 
  193.      */
  194.     case PRU_CONNECT:
  195.         if (rp->rcb_faddr) {
  196.             error = EISCONN;
  197.             break;
  198.         }
  199.         nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
  200.         rp->rcb_faddr = mtod(nam, struct sockaddr *);
  201.         soisconnected(so);
  202.         break;
  203.  
  204.     case PRU_BIND:
  205.         if (rp->rcb_laddr) {
  206.             error = EINVAL;            /* XXX */
  207.             break;
  208.         }
  209.         error = raw_bind(so, nam);
  210.         break;
  211. #endif
  212.  
  213.     case PRU_CONNECT2:
  214.         error = EOPNOTSUPP;
  215.         goto release;
  216.  
  217.     case PRU_DISCONNECT:
  218.         if (rp->rcb_faddr == 0) {
  219.             error = ENOTCONN;
  220.             break;
  221.         }
  222.         raw_disconnect(rp);
  223.         soisdisconnected(so);
  224.         break;
  225.  
  226.     /*
  227.      * Mark the connection as being incapable of further input.
  228.      */
  229.     case PRU_SHUTDOWN:
  230.         socantsendmore(so);
  231.         break;
  232.  
  233.     /*
  234.      * Ship a packet out.  The appropriate raw output
  235.      * routine handles any massaging necessary.
  236.      */
  237.     case PRU_SEND:
  238.         if (nam) {
  239.             if (rp->rcb_faddr) {
  240.                 error = EISCONN;
  241.                 break;
  242.             }
  243.             rp->rcb_faddr = mtod(nam, struct sockaddr *);
  244.         } else if (rp->rcb_faddr == 0) {
  245.             error = ENOTCONN;
  246.             break;
  247.         }
  248.         error = (*so->so_proto->pr_output)(m, so);
  249.         m = NULL;
  250.         if (nam)
  251.             rp->rcb_faddr = 0;
  252.         break;
  253.  
  254.     case PRU_ABORT:
  255.         raw_disconnect(rp);
  256.         sofree(so);
  257.         soisdisconnected(so);
  258.         break;
  259.  
  260.     case PRU_SENSE:
  261.         /*
  262.          * stat: don't bother with a blocksize.
  263.          */
  264.         return (0);
  265.  
  266.     /*
  267.      * Not supported.
  268.      */
  269.     case PRU_RCVOOB:
  270.     case PRU_RCVD:
  271.         return(EOPNOTSUPP);
  272.  
  273.     case PRU_LISTEN:
  274.     case PRU_ACCEPT:
  275.     case PRU_SENDOOB:
  276.         error = EOPNOTSUPP;
  277.         break;
  278.  
  279.     case PRU_SOCKADDR:
  280.         if (rp->rcb_laddr == 0) {
  281.             error = EINVAL;
  282.             break;
  283.         }
  284.         len = rp->rcb_laddr->sa_len;
  285.         bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
  286.         nam->m_len = len;
  287.         break;
  288.  
  289.     case PRU_PEERADDR:
  290.         if (rp->rcb_faddr == 0) {
  291.             error = ENOTCONN;
  292.             break;
  293.         }
  294.         len = rp->rcb_faddr->sa_len;
  295.         bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
  296.         nam->m_len = len;
  297.         break;
  298.  
  299.     default:
  300.         panic("raw_usrreq");
  301.     }
  302. release:
  303.     if (m != NULL)
  304.         m_freem(m);
  305.     return (error);
  306. }
  307.  
  308. rawintr() {} /* XXX - referenced by locore.  will soon go away */
  309.