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

Cache object: 450f331ef9a88fb443ef43379f8b94e9


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