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.22 2004/04/25 21:13:13 matt 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.22 2004/04/25 21:13:13 matt 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 
   74 #include <net/if.h>
   75 #include <net/route.h>
   76 #include <net/raw_cb.h>
   77 
   78 #include <netiso/iso.h>
   79 #include <netiso/iso_pcb.h>
   80 #include <netiso/clnp.h>
   81 #include <netiso/clnp_stat.h>
   82 #include <netiso/argo_debug.h>
   83 
   84 #include <netiso/tp_user.h>     /* XXX -- defines SOL_NETWORK */
   85 
   86 #include <machine/stdarg.h>
   87 
   88 struct sockproto rclnp_proto = {PF_ISO, 0};
   89 
   90 /*
   91  * FUNCTION:            rclnp_input
   92  *
   93  * PURPOSE:             Setup generic address an protocol structures for
   94  *                      raw input routine, then pass them along with the
   95  *                      mbuf chain.
   96  *
   97  * RETURNS:             none
   98  *
   99  * SIDE EFFECTS:
  100  *
  101  * NOTES:               The protocol field of rclnp_proto is set to zero
  102  *                      indicating no protocol.
  103  */
  104 void
  105 rclnp_input(struct mbuf *m, ...)
  106 {
  107         struct sockaddr_iso *src;       /* ptr to src address */
  108         struct sockaddr_iso *dst;       /* ptr to dest address */
  109         int             hdrlen; /* length (in bytes) of clnp header */
  110         va_list ap;
  111 
  112         va_start(ap, m);
  113         src = va_arg(ap, struct sockaddr_iso *);
  114         dst = va_arg(ap, struct sockaddr_iso *);
  115         hdrlen = va_arg(ap, int);
  116         va_end(ap);
  117 #ifdef  TROLL
  118         if (trollctl.tr_ops & TR_CHUCK) {
  119                 m_freem(m);
  120                 return;
  121         }
  122 #endif                          /* TROLL */
  123 
  124         raw_input(m, &rclnp_proto, sisotosa(src), sisotosa(dst));
  125 }
  126 
  127 /*
  128  * FUNCTION:            rclnp_output
  129  *
  130  * PURPOSE:                     Prepare to send a raw clnp packet. Setup src and dest
  131  *                                      addresses, count the number of bytes to send, and
  132  *                                      call clnp_output.
  133  *
  134  * RETURNS:                     success - 0
  135  *                                      failure - an appropriate error code
  136  *
  137  * SIDE EFFECTS:
  138  *
  139  * NOTES:
  140  */
  141 int
  142 rclnp_output(struct mbuf *m0, ...)
  143 {
  144         struct socket  *so;     /* socket to send from */
  145         struct rawisopcb *rp;   /* ptr to raw cb */
  146         int             error;  /* return value of function */
  147         int             flags;  /* flags for clnp_output */
  148         va_list ap;
  149 
  150         va_start(ap, m0);
  151         so = va_arg(ap, struct socket *);
  152         va_end(ap);
  153         rp = sotorawisopcb(so);
  154 
  155         if ((m0->m_flags & M_PKTHDR) == 0)
  156                 return (EINVAL);
  157         /*
  158          * Set up src address. If user has bound socket to an address, use it.
  159          * Otherwise, do not specify src (clnp_output will fill it in).
  160          */
  161         if (rp->risop_rcb.rcb_laddr) {
  162                 if (rp->risop_isop.isop_sladdr.siso_family != AF_ISO) {
  163         bad:
  164                         m_freem(m0);
  165                         return (EAFNOSUPPORT);
  166                 }
  167         }
  168         /* set up dest address */
  169         if (rp->risop_rcb.rcb_faddr == 0)
  170                 goto bad;
  171         rp->risop_isop.isop_sfaddr = *satosiso(rp->risop_rcb.rcb_faddr);
  172         rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr;
  173 
  174         /* get flags and ship it off */
  175         flags = rp->risop_flags & CLNP_VFLAGS;
  176 
  177         error = clnp_output(m0, &rp->risop_isop, m0->m_pkthdr.len,
  178                             flags | CLNP_NOCACHE);
  179 
  180         return (error);
  181 }
  182 
  183 /*
  184  * FUNCTION:            rclnp_ctloutput
  185  *
  186  * PURPOSE:                     Raw clnp socket option processing
  187  *                                      All options are stored inside an mbuf.
  188  *
  189  * RETURNS:                     success - 0
  190  *                                      failure - unix error code
  191  *
  192  * SIDE EFFECTS:        If the options mbuf does not exist, it the mbuf passed
  193  *                                      is used.
  194  *
  195  * NOTES:
  196  */
  197 int
  198 rclnp_ctloutput(
  199         int             op,     /* type of operation */
  200         struct socket  *so,     /* ptr to socket */
  201         int             level,  /* level of option */
  202         int             optname,/* name of option */
  203         struct mbuf   **m)      /* ptr to ptr to option data */
  204 {
  205         int             error = 0;
  206         struct rawisopcb *rp = sotorawisopcb(so);       /* raw cb ptr */
  207 
  208 #ifdef ARGO_DEBUG
  209         if (argo_debug[D_CTLOUTPUT]) {
  210                 printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n",
  211                     op, level, optname);
  212                 if (*m != NULL) {
  213                         printf("rclnp_ctloutput: %d bytes of mbuf data\n", (*m)->m_len);
  214                         dump_buf(mtod((*m), caddr_t), (*m)->m_len);
  215                 }
  216         }
  217 #endif
  218 
  219 #ifdef SOL_NETWORK
  220         if (level != SOL_NETWORK)
  221                 error = EINVAL;
  222         else
  223                 switch (op) {
  224 #else
  225         switch (op) {
  226 #endif                          /* SOL_NETWORK */
  227         case PRCO_SETOPT:
  228                 switch (optname) {
  229                 case CLNPOPT_FLAGS:{
  230                                 u_short         usr_flags;
  231                                 /*
  232                                  * Insure that the data passed has exactly
  233                                  * one short in it
  234                                  */
  235                                 if ((*m == NULL) || ((*m)->m_len != sizeof(short))) {
  236                                         error = EINVAL;
  237                                         break;
  238                                 }
  239                                 /*
  240                                  *      Don't allow invalid flags to be set
  241                                  */
  242                                 usr_flags = (*mtod((*m), short *));
  243 
  244                                 if ((usr_flags & (CLNP_VFLAGS)) != usr_flags) {
  245                                         error = EINVAL;
  246                                 } else
  247                                         rp->risop_flags |= usr_flags;
  248 
  249                         } break;
  250 
  251                 case CLNPOPT_OPTS:
  252                         error = clnp_set_opts(&rp->risop_isop.isop_options, m);
  253                         if (error)
  254                                 break;
  255                         rp->risop_isop.isop_optindex = m_get(M_WAIT, MT_SOOPTS);
  256                         (void) clnp_opt_sanity(rp->risop_isop.isop_options,
  257                                  mtod(rp->risop_isop.isop_options, caddr_t),
  258                                          rp->risop_isop.isop_options->m_len,
  259                                           mtod(rp->risop_isop.isop_optindex,
  260                                                struct clnp_optidx *));
  261                         break;
  262                 }
  263                 break;
  264 
  265         case PRCO_GETOPT:
  266 #ifdef notdef
  267                 /* commented out to keep hi C quiet */
  268                 switch (optname) {
  269                 default:
  270                         error = EINVAL;
  271                         break;
  272                 }
  273 #endif                          /* notdef */
  274                 break;
  275         default:
  276                 error = EINVAL;
  277                 break;
  278         }
  279         if (op == PRCO_SETOPT) {
  280                 /* note: m_freem does not barf is *m is NULL */
  281                 m_freem(*m);
  282                 *m = NULL;
  283         }
  284         return error;
  285 }
  286 
  287 /* ARGSUSED */
  288 int
  289 clnp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
  290         struct mbuf *control, struct proc *p)
  291 {
  292         int    error = 0;
  293         struct rawisopcb *rp = sotorawisopcb(so);
  294 
  295         rp = sotorawisopcb(so);
  296         switch (req) {
  297 
  298         case PRU_ATTACH:
  299                 if (rp != 0) {
  300                         error = EISCONN;
  301                         break;
  302                 }
  303                 MALLOC(rp, struct rawisopcb *, sizeof *rp, M_PCB,
  304                     M_WAITOK|M_ZERO);
  305                 if (rp == 0)
  306                         return (ENOBUFS);
  307                 so->so_pcb = rp;
  308                 break;
  309 
  310         case PRU_DETACH:
  311                 if (rp->risop_isop.isop_options)
  312                         m_freem(rp->risop_isop.isop_options);
  313                 if (rp->risop_isop.isop_route.ro_rt)
  314                         RTFREE(rp->risop_isop.isop_route.ro_rt);
  315                 if (rp->risop_rcb.rcb_laddr)
  316                         rp->risop_rcb.rcb_laddr = 0;
  317                 /* free clnp cached hdr if necessary */
  318                 if (rp->risop_isop.isop_clnpcache != NULL) {
  319                         struct clnp_cache *clcp =
  320                         mtod(rp->risop_isop.isop_clnpcache, struct clnp_cache *);
  321                         if (clcp->clc_hdr != NULL) {
  322                                 m_free(clcp->clc_hdr);
  323                         }
  324                         m_free(rp->risop_isop.isop_clnpcache);
  325                 }
  326                 if (rp->risop_isop.isop_optindex != NULL)
  327                         m_free(rp->risop_isop.isop_optindex);
  328 
  329                 break;
  330 
  331         case PRU_BIND:
  332                 {
  333                         struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
  334 
  335                         if (nam->m_len != sizeof(*addr))
  336                                 return (EINVAL);
  337                         if ((ifnet.tqh_first == 0) ||
  338                             (addr->siso_family != AF_ISO) ||
  339                             (addr->siso_addr.isoa_len &&
  340                              ifa_ifwithaddr(sisotosa(addr)) == 0))
  341                                 return (EADDRNOTAVAIL);
  342                         rp->risop_isop.isop_sladdr = *addr;
  343                         rp->risop_rcb.rcb_laddr = sisotosa(
  344                                                            (rp->risop_isop.isop_laddr = &rp->risop_isop.isop_sladdr));
  345                         return (0);
  346                 }
  347         case PRU_CONNECT:
  348                 {
  349                         struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
  350 
  351                         if ((nam->m_len > sizeof(*addr)) || (addr->siso_len > sizeof(*addr)))
  352                                 return (EINVAL);
  353                         if (ifnet.tqh_first == 0)
  354                                 return (EADDRNOTAVAIL);
  355 
  356                         /* copy the address */
  357                         if (addr->siso_family != AF_ISO)
  358                                 rp->risop_isop.isop_sfaddr = *addr;
  359 
  360                         /* initialize address pointers */
  361                         rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr;
  362                         rp->risop_rcb.rcb_faddr = sisotosa(
  363                                 rp->risop_isop.isop_faddr);
  364 
  365                         /* address setup, mark socket connected */
  366                         soisconnected(so);
  367 
  368                         return (0);
  369                 }
  370         }
  371         error = raw_usrreq(so, req, m, nam, control, p);
  372 
  373         if (error && req == PRU_ATTACH && so->so_pcb)
  374                 free((caddr_t) rp, M_PCB);
  375         return (error);
  376 }

Cache object: c68df8494d7132b4e1a7b85db9a941aa


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