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.32 2008/08/09 13:52:05 dogcow 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.32 2008/08/09 13:52:05 dogcow 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 and 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 a sockopt.
  189  *
  190  * RETURNS:                     success - 0
  191  *                                      failure - unix error code
  192  *
  193  * SIDE EFFECTS:
  194  *
  195  * NOTES:
  196  */
  197 int
  198 rclnp_ctloutput(
  199         int             op,     /* type of operation */
  200         struct socket  *so,     /* ptr to socket */
  201         struct sockopt *sopt)   /* socket options */
  202 {
  203         int             error = 0;
  204         struct rawisopcb *rp = sotorawisopcb(so);       /* raw cb ptr */
  205 
  206 #ifdef ARGO_DEBUG
  207         if (argo_debug[D_CTLOUTPUT]) {
  208                 printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n",
  209                     op, sopt->sopt_level, sopt->sopt_name);
  210                 printf("rclnp_ctloutput: %zu bytes of data\n", sopt->sopt_size);
  211                 dump_buf(sopt->sopt_data, sopt->sopt_size);
  212         }
  213 #endif
  214 
  215 #ifdef SOL_NETWORK
  216         if (sopt->sopt_level != SOL_NETWORK)
  217                 return (EINVAL);
  218 #endif
  219 
  220         switch (op) {
  221         case PRCO_SETOPT:
  222                 switch (sopt->sopt_name) {
  223                 case CLNPOPT_FLAGS:{
  224                         u_short flags;
  225 
  226                         error = sockopt_get(sopt, &flags, sizeof(flags));
  227                         if (error)
  228                                 break;
  229 
  230                         /*
  231                          *      Don't allow invalid flags to be set
  232                          */
  233                         if ((flags & (CLNP_VFLAGS)) != flags)
  234                                 error = EINVAL;
  235                         else
  236                                 rp->risop_flags |= flags;
  237 
  238                         break;
  239                         }
  240 
  241                 case CLNPOPT_OPTS: {
  242                         struct mbuf *m;
  243 
  244                         m = sockopt_getmbuf(sopt);
  245                         if (m == NULL) {
  246                                 error = ENOBUFS;
  247                                 break;
  248                         }
  249 
  250                         error = clnp_set_opts(&rp->risop_isop.isop_options, &m);
  251                         m_freem(m);
  252                         if (error)
  253                                 break;
  254                         rp->risop_isop.isop_optindex = m_get(M_WAIT, MT_SOOPTS);
  255                         (void) clnp_opt_sanity(rp->risop_isop.isop_options,
  256                                  mtod(rp->risop_isop.isop_options, void *),
  257                                          rp->risop_isop.isop_options->m_len,
  258                                           mtod(rp->risop_isop.isop_optindex,
  259                                                struct clnp_optidx *));
  260                         break;
  261                         }
  262                 }
  263                 break;
  264 
  265         case PRCO_GETOPT:
  266 #ifdef notdef
  267                 /* commented out to keep hi C quiet */
  268                 switch (sopt->sopt_name) {
  269                 default:
  270                         error = EINVAL;
  271                         break;
  272                 }
  273 #endif                          /* notdef */
  274                 break;
  275         default:
  276                 error = EINVAL;
  277                 break;
  278         }
  279         return error;
  280 }
  281 
  282 /* ARGSUSED */
  283 int
  284 clnp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
  285         struct mbuf *control, struct lwp *l)
  286 {
  287         int    error = 0;
  288         struct rawisopcb *rp = sotorawisopcb(so);
  289         struct proc *p;
  290 
  291         p = l ? l->l_proc : NULL;
  292         rp = sotorawisopcb(so);
  293         switch (req) {
  294 
  295         case PRU_ATTACH:
  296                 sosetlock(so);
  297                 if (rp != 0) {
  298                         error = EISCONN;
  299                         break;
  300                 }
  301                 MALLOC(rp, struct rawisopcb *, sizeof *rp, M_PCB,
  302                     M_WAITOK|M_ZERO);
  303                 if (rp == 0)
  304                         return (ENOBUFS);
  305                 so->so_pcb = rp;
  306                 break;
  307 
  308         case PRU_DETACH:
  309                 if (rp->risop_isop.isop_options)
  310                         m_freem(rp->risop_isop.isop_options);
  311                 rtcache_free(&rp->risop_isop.isop_route);
  312                 if (rp->risop_rcb.rcb_laddr)
  313                         rp->risop_rcb.rcb_laddr = 0;
  314                 /* free clnp cached hdr if necessary */
  315                 if (rp->risop_isop.isop_clnpcache != NULL) {
  316                         struct clnp_cache *clcp =
  317                         mtod(rp->risop_isop.isop_clnpcache, struct clnp_cache *);
  318                         if (clcp->clc_hdr != NULL) {
  319                                 m_free(clcp->clc_hdr);
  320                         }
  321                         m_free(rp->risop_isop.isop_clnpcache);
  322                 }
  323                 if (rp->risop_isop.isop_optindex != NULL)
  324                         m_free(rp->risop_isop.isop_optindex);
  325 
  326                 break;
  327 
  328         case PRU_BIND:
  329                 {
  330                         struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
  331 
  332                         if (nam->m_len != sizeof(*addr))
  333                                 return (EINVAL);
  334                         if ((ifnet.tqh_first == 0) ||
  335                             (addr->siso_family != AF_ISO) ||
  336                             (addr->siso_addr.isoa_len &&
  337                              ifa_ifwithaddr(sisotosa(addr)) == 0))
  338                                 return (EADDRNOTAVAIL);
  339                         rp->risop_isop.isop_sladdr = *addr;
  340                         rp->risop_rcb.rcb_laddr = sisotosa(
  341                                                            (rp->risop_isop.isop_laddr = &rp->risop_isop.isop_sladdr));
  342                         return (0);
  343                 }
  344         case PRU_CONNECT:
  345                 {
  346                         struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
  347 
  348                         if ((nam->m_len > sizeof(*addr)) || (addr->siso_len > sizeof(*addr)))
  349                                 return (EINVAL);
  350                         if (ifnet.tqh_first == 0)
  351                                 return (EADDRNOTAVAIL);
  352 
  353                         /* copy the address */
  354                         if (addr->siso_family != AF_ISO)
  355                                 rp->risop_isop.isop_sfaddr = *addr;
  356 
  357                         /* initialize address pointers */
  358                         rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr;
  359                         rp->risop_rcb.rcb_faddr = sisotosa(
  360                                 rp->risop_isop.isop_faddr);
  361 
  362                         /* address setup, mark socket connected */
  363                         soisconnected(so);
  364 
  365                         return (0);
  366                 }
  367         }
  368         error = raw_usrreq(so, req, m, nam, control, l);
  369 
  370         if (error && req == PRU_ATTACH && so->so_pcb)
  371                 free((void *) rp, M_PCB);
  372         return (error);
  373 }

Cache object: 8531a996bb4f56f2b4167f17b9b136ec


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