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/netiso/clnp_raw.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: clnp_raw.c,v 1.23 2005/12/11 12:25:12 christos Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 1991, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  *      @(#)clnp_raw.c  8.1 (Berkeley) 6/10/93
   32  */
   33 
   34 /***********************************************************
   35                                 Copyright IBM Corporation 1987
   36 
   37                       All Rights Reserved
   38 
   39 Permission to use, copy, modify, and distribute this software and its
   40 documentation for any purpose and without fee is hereby granted,
   41 provided that the above copyright notice appear in all copies and that
   42 both that copyright notice and this permission notice appear in
   43 supporting documentation, and that the name of IBM not be
   44 used in advertising or publicity pertaining to distribution of the
   45 software without specific, written prior permission.
   46 
   47 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
   48 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
   49 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
   50 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   51 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
   52 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   53 SOFTWARE.
   54 
   55 ******************************************************************/
   56 
   57 /*
   58  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
   59  */
   60 
   61 #include <sys/cdefs.h>
   62 __KERNEL_RCSID(0, "$NetBSD: clnp_raw.c,v 1.23 2005/12/11 12:25:12 christos Exp $");
   63 
   64 #include <sys/param.h>
   65 #include <sys/mbuf.h>
   66 #include <sys/domain.h>
   67 #include <sys/protosw.h>
   68 #include <sys/socket.h>
   69 #include <sys/socketvar.h>
   70 #include <sys/errno.h>
   71 #include <sys/time.h>
   72 #include <sys/systm.h>
   73 #include <sys/proc.h>
   74 
   75 #include <net/if.h>
   76 #include <net/route.h>
   77 #include <net/raw_cb.h>
   78 
   79 #include <netiso/iso.h>
   80 #include <netiso/iso_pcb.h>
   81 #include <netiso/clnp.h>
   82 #include <netiso/clnp_stat.h>
   83 #include <netiso/argo_debug.h>
   84 
   85 #include <netiso/tp_user.h>     /* XXX -- defines SOL_NETWORK */
   86 
   87 #include <machine/stdarg.h>
   88 
   89 struct sockproto rclnp_proto = {PF_ISO, 0};
   90 
   91 /*
   92  * FUNCTION:            rclnp_input
   93  *
   94  * PURPOSE:             Setup generic address an protocol structures for
   95  *                      raw input routine, then pass them along with the
   96  *                      mbuf chain.
   97  *
   98  * RETURNS:             none
   99  *
  100  * SIDE EFFECTS:
  101  *
  102  * NOTES:               The protocol field of rclnp_proto is set to zero
  103  *                      indicating no protocol.
  104  */
  105 void
  106 rclnp_input(struct mbuf *m, ...)
  107 {
  108         struct sockaddr_iso *src;       /* ptr to src address */
  109         struct sockaddr_iso *dst;       /* ptr to dest address */
  110         int             hdrlen; /* length (in bytes) of clnp header */
  111         va_list ap;
  112 
  113         va_start(ap, m);
  114         src = va_arg(ap, struct sockaddr_iso *);
  115         dst = va_arg(ap, struct sockaddr_iso *);
  116         hdrlen = va_arg(ap, int);
  117         va_end(ap);
  118 #ifdef  TROLL
  119         if (trollctl.tr_ops & TR_CHUCK) {
  120                 m_freem(m);
  121                 return;
  122         }
  123 #endif                          /* TROLL */
  124 
  125         raw_input(m, &rclnp_proto, sisotosa(src), sisotosa(dst));
  126 }
  127 
  128 /*
  129  * FUNCTION:            rclnp_output
  130  *
  131  * PURPOSE:                     Prepare to send a raw clnp packet. Setup src and dest
  132  *                                      addresses, count the number of bytes to send, and
  133  *                                      call clnp_output.
  134  *
  135  * RETURNS:                     success - 0
  136  *                                      failure - an appropriate error code
  137  *
  138  * SIDE EFFECTS:
  139  *
  140  * NOTES:
  141  */
  142 int
  143 rclnp_output(struct mbuf *m0, ...)
  144 {
  145         struct socket  *so;     /* socket to send from */
  146         struct rawisopcb *rp;   /* ptr to raw cb */
  147         int             error;  /* return value of function */
  148         int             flags;  /* flags for clnp_output */
  149         va_list ap;
  150 
  151         va_start(ap, m0);
  152         so = va_arg(ap, struct socket *);
  153         va_end(ap);
  154         rp = sotorawisopcb(so);
  155 
  156         if ((m0->m_flags & M_PKTHDR) == 0)
  157                 return (EINVAL);
  158         /*
  159          * Set up src address. If user has bound socket to an address, use it.
  160          * Otherwise, do not specify src (clnp_output will fill it in).
  161          */
  162         if (rp->risop_rcb.rcb_laddr) {
  163                 if (rp->risop_isop.isop_sladdr.siso_family != AF_ISO) {
  164         bad:
  165                         m_freem(m0);
  166                         return (EAFNOSUPPORT);
  167                 }
  168         }
  169         /* set up dest address */
  170         if (rp->risop_rcb.rcb_faddr == 0)
  171                 goto bad;
  172         rp->risop_isop.isop_sfaddr = *satosiso(rp->risop_rcb.rcb_faddr);
  173         rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr;
  174 
  175         /* get flags and ship it off */
  176         flags = rp->risop_flags & CLNP_VFLAGS;
  177 
  178         error = clnp_output(m0, &rp->risop_isop, m0->m_pkthdr.len,
  179                             flags | CLNP_NOCACHE);
  180 
  181         return (error);
  182 }
  183 
  184 /*
  185  * FUNCTION:            rclnp_ctloutput
  186  *
  187  * PURPOSE:                     Raw clnp socket option processing
  188  *                                      All options are stored inside an mbuf.
  189  *
  190  * RETURNS:                     success - 0
  191  *                                      failure - unix error code
  192  *
  193  * SIDE EFFECTS:        If the options mbuf does not exist, it the mbuf passed
  194  *                                      is used.
  195  *
  196  * NOTES:
  197  */
  198 int
  199 rclnp_ctloutput(
  200         int             op,     /* type of operation */
  201         struct socket  *so,     /* ptr to socket */
  202         int             level,  /* level of option */
  203         int             optname,/* name of option */
  204         struct mbuf   **m)      /* ptr to ptr to option data */
  205 {
  206         int             error = 0;
  207         struct rawisopcb *rp = sotorawisopcb(so);       /* raw cb ptr */
  208 
  209 #ifdef ARGO_DEBUG
  210         if (argo_debug[D_CTLOUTPUT]) {
  211                 printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n",
  212                     op, level, optname);
  213                 if (*m != NULL) {
  214                         printf("rclnp_ctloutput: %d bytes of mbuf data\n", (*m)->m_len);
  215                         dump_buf(mtod((*m), caddr_t), (*m)->m_len);
  216                 }
  217         }
  218 #endif
  219 
  220 #ifdef SOL_NETWORK
  221         if (level != SOL_NETWORK)
  222                 error = EINVAL;
  223         else
  224                 switch (op) {
  225 #else
  226         switch (op) {
  227 #endif                          /* SOL_NETWORK */
  228         case PRCO_SETOPT:
  229                 switch (optname) {
  230                 case CLNPOPT_FLAGS:{
  231                                 u_short         usr_flags;
  232                                 /*
  233                                  * Insure that the data passed has exactly
  234                                  * one short in it
  235                                  */
  236                                 if ((*m == NULL) || ((*m)->m_len != sizeof(short))) {
  237                                         error = EINVAL;
  238                                         break;
  239                                 }
  240                                 /*
  241                                  *      Don't allow invalid flags to be set
  242                                  */
  243                                 usr_flags = (*mtod((*m), short *));
  244 
  245                                 if ((usr_flags & (CLNP_VFLAGS)) != usr_flags) {
  246                                         error = EINVAL;
  247                                 } else
  248                                         rp->risop_flags |= usr_flags;
  249 
  250                         } break;
  251 
  252                 case CLNPOPT_OPTS:
  253                         error = clnp_set_opts(&rp->risop_isop.isop_options, m);
  254                         if (error)
  255                                 break;
  256                         rp->risop_isop.isop_optindex = m_get(M_WAIT, MT_SOOPTS);
  257                         (void) clnp_opt_sanity(rp->risop_isop.isop_options,
  258                                  mtod(rp->risop_isop.isop_options, caddr_t),
  259                                          rp->risop_isop.isop_options->m_len,
  260                                           mtod(rp->risop_isop.isop_optindex,
  261                                                struct clnp_optidx *));
  262                         break;
  263                 }
  264                 break;
  265 
  266         case PRCO_GETOPT:
  267 #ifdef notdef
  268                 /* commented out to keep hi C quiet */
  269                 switch (optname) {
  270                 default:
  271                         error = EINVAL;
  272                         break;
  273                 }
  274 #endif                          /* notdef */
  275                 break;
  276         default:
  277                 error = EINVAL;
  278                 break;
  279         }
  280         if (op == PRCO_SETOPT) {
  281                 /* note: m_freem does not barf is *m is NULL */
  282                 m_freem(*m);
  283                 *m = NULL;
  284         }
  285         return error;
  286 }
  287 
  288 /* ARGSUSED */
  289 int
  290 clnp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
  291         struct mbuf *control, struct lwp *l)
  292 {
  293         int    error = 0;
  294         struct rawisopcb *rp = sotorawisopcb(so);
  295         struct proc *p;
  296 
  297         p = l ? l->l_proc : NULL;
  298         rp = sotorawisopcb(so);
  299         switch (req) {
  300 
  301         case PRU_ATTACH:
  302                 if (rp != 0) {
  303                         error = EISCONN;
  304                         break;
  305                 }
  306                 MALLOC(rp, struct rawisopcb *, sizeof *rp, M_PCB,
  307                     M_WAITOK|M_ZERO);
  308                 if (rp == 0)
  309                         return (ENOBUFS);
  310                 so->so_pcb = rp;
  311                 break;
  312 
  313         case PRU_DETACH:
  314                 if (rp->risop_isop.isop_options)
  315                         m_freem(rp->risop_isop.isop_options);
  316                 if (rp->risop_isop.isop_route.ro_rt)
  317                         RTFREE(rp->risop_isop.isop_route.ro_rt);
  318                 if (rp->risop_rcb.rcb_laddr)
  319                         rp->risop_rcb.rcb_laddr = 0;
  320                 /* free clnp cached hdr if necessary */
  321                 if (rp->risop_isop.isop_clnpcache != NULL) {
  322                         struct clnp_cache *clcp =
  323                         mtod(rp->risop_isop.isop_clnpcache, struct clnp_cache *);
  324                         if (clcp->clc_hdr != NULL) {
  325                                 m_free(clcp->clc_hdr);
  326                         }
  327                         m_free(rp->risop_isop.isop_clnpcache);
  328                 }
  329                 if (rp->risop_isop.isop_optindex != NULL)
  330                         m_free(rp->risop_isop.isop_optindex);
  331 
  332                 break;
  333 
  334         case PRU_BIND:
  335                 {
  336                         struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
  337 
  338                         if (nam->m_len != sizeof(*addr))
  339                                 return (EINVAL);
  340                         if ((ifnet.tqh_first == 0) ||
  341                             (addr->siso_family != AF_ISO) ||
  342                             (addr->siso_addr.isoa_len &&
  343                              ifa_ifwithaddr(sisotosa(addr)) == 0))
  344                                 return (EADDRNOTAVAIL);
  345                         rp->risop_isop.isop_sladdr = *addr;
  346                         rp->risop_rcb.rcb_laddr = sisotosa(
  347                                                            (rp->risop_isop.isop_laddr = &rp->risop_isop.isop_sladdr));
  348                         return (0);
  349                 }
  350         case PRU_CONNECT:
  351                 {
  352                         struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
  353 
  354                         if ((nam->m_len > sizeof(*addr)) || (addr->siso_len > sizeof(*addr)))
  355                                 return (EINVAL);
  356                         if (ifnet.tqh_first == 0)
  357                                 return (EADDRNOTAVAIL);
  358 
  359                         /* copy the address */
  360                         if (addr->siso_family != AF_ISO)
  361                                 rp->risop_isop.isop_sfaddr = *addr;
  362 
  363                         /* initialize address pointers */
  364                         rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr;
  365                         rp->risop_rcb.rcb_faddr = sisotosa(
  366                                 rp->risop_isop.isop_faddr);
  367 
  368                         /* address setup, mark socket connected */
  369                         soisconnected(so);
  370 
  371                         return (0);
  372                 }
  373         }
  374         error = raw_usrreq(so, req, m, nam, control, l);
  375 
  376         if (error && req == PRU_ATTACH && so->so_pcb)
  377                 free((caddr_t) rp, M_PCB);
  378         return (error);
  379 }

Cache object: 9df64a4339fe8f8f4dc9dd7af8bf31b1


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