date and time created 88/12/14 15:29:27 by sklower
authorKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Thu, 15 Dec 1988 07:29:27 +0000 (23:29 -0800)
committerKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Thu, 15 Dec 1988 07:29:27 +0000 (23:29 -0800)
SCCS-vsn: sys/netiso/clnp_raw.c 7.1

usr/src/sys/netiso/clnp_raw.c [new file with mode: 0644]

diff --git a/usr/src/sys/netiso/clnp_raw.c b/usr/src/sys/netiso/clnp_raw.c
new file mode 100644 (file)
index 0000000..44e92e4
--- /dev/null
@@ -0,0 +1,313 @@
+/***********************************************************
+               Copyright IBM Corporation 1987
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
+ */
+/* $Header: clnp_raw.c,v 4.2 88/06/29 14:58:56 hagens Exp $ */
+/* $Source: /usr/argo/sys/netiso/RCS/clnp_raw.c,v $ */
+#ifndef lint
+static char *rcsid = "$Header: clnp_raw.c,v 4.2 88/06/29 14:58:56 hagens Exp $";
+#endif lint
+
+#ifdef ISO
+
+#include "../h/types.h"
+#include "../h/param.h"
+#include "../h/mbuf.h"
+#include "../h/domain.h"
+#include "../h/protosw.h"
+#include "../h/socket.h"
+#include "../h/socketvar.h"
+#include "../h/errno.h"
+#include "../h/time.h"
+
+#include "../net/if.h"
+#include "../net/route.h"
+#include "../net/raw_cb.h"
+
+#include "../netiso/iso.h"
+#include "../netiso/iso_pcb.h"
+#include "../netiso/clnp.h"
+#include "../netiso/clnp_stat.h"
+#include "../netiso/argo_debug.h"
+
+struct sockaddr_iso    rclnp_src       = { AF_ISO };
+struct sockaddr_iso    rclnp_dst       = { AF_ISO };
+struct sockproto       rclnp_proto     = { PF_ISO, 0 };
+/*
+ * FUNCTION:           rclnp_input
+ *
+ * PURPOSE:                    Setup generic address an protocol structures for
+ *                                     raw input routine, then pass them along with the
+ *                                     mbuf chain.
+ *
+ * RETURNS:                    none
+ *
+ * SIDE EFFECTS:       
+ *
+ * NOTES:                      The protocol field of rclnp_proto is set to zero indicating
+ *                                     no protocol.
+ */
+rclnp_input(m, src, dst, hdrlen)
+struct mbuf            *m;             /* ptr to packet */
+struct iso_addr                *src;   /* ptr to src address */
+struct iso_addr                *dst;   /* ptr to dest address */
+int                                    hdrlen; /* length (in bytes) of clnp header */
+{
+#ifdef TROLL
+       if (trollctl.tr_ops & TR_CHUCK) {
+               m_freem(m);
+               return;
+       }
+#endif TROLL
+
+       rclnp_src.siso_addr = *src;
+       rclnp_dst.siso_addr = *dst;
+       raw_input(m, &rclnp_proto, (struct sockaddr *)&rclnp_src,
+               (struct sockaddr *)&rclnp_dst);
+}
+
+/*
+ * FUNCTION:           rclnp_output
+ *
+ * PURPOSE:                    Prepare to send a raw clnp packet. Setup src and dest
+ *                                     addresses, count the number of bytes to send, and
+ *                                     call clnp_output.
+ *
+ * RETURNS:                    success - 0
+ *                                     failure - an appropriate error code
+ *
+ * SIDE EFFECTS:       
+ *
+ * NOTES:                      
+ */
+rclnp_output(m0, so)
+struct mbuf            *m0;            /* packet to send */
+struct socket  *so;    /* socket to send from */
+{
+       register struct mbuf    *m;                     /* used to scan a chain */
+       int                                             len = 0;        /* store length of chain here */
+       struct rawcb                    *rp = sotorawcb(so); /* ptr to raw cb */
+       int                                             error;          /* return value of function */
+       u_int                                   flags;          /* flags for clnp_output */
+       struct isopcb                   isopcb;         /* isopcb used to interface w/clnp */
+
+       /* Calculate length of data */
+       for (m = m0; m; m = m->m_next)
+               len += m->m_len;
+       
+       bzero((caddr_t)&isopcb, sizeof(isopcb));
+
+       /*
+        *      Set up src address. If user has bound socket to an address, use it.
+        *      Otherwise, do not specify src (clnp_output will fill it in).
+        */
+       if (rp->rcb_flags & RAW_LADDR) {
+               if (rp->rcb_laddr.sa_family != AF_ISO) {
+                       m_freem(m0);
+                       return(EAFNOSUPPORT);
+               }
+               bcopy((caddr_t)&rp->rcb_laddr, &isopcb.isop_laddr,
+                       sizeof(struct sockaddr_iso));
+       }
+
+       /* set up route structure, if route is present */
+       if (rp->rcb_route.ro_rt != NULL)
+               bcopy((caddr_t)&rp->rcb_route, (caddr_t)&isopcb.isop_route,
+                       sizeof(struct route));
+
+       /* set up dest address */
+       bcopy((caddr_t)&rp->rcb_faddr, &isopcb.isop_faddr,
+               sizeof(struct sockaddr_iso));
+               
+       /* 
+        *      setup option index - this was done when option was set, but raw
+        *      cb has no place to put it.
+        */
+       if (rp->rcb_options != NULL) {
+               isopcb.isop_options = rp->rcb_options;
+               isopcb.isop_optindex = m_get(M_WAIT, MT_SOOPTS);
+               (void) clnp_opt_sanity(isopcb.isop_options, 
+                       mtod(isopcb.isop_options, caddr_t), isopcb.isop_options->m_len, 
+                       mtod(isopcb.isop_optindex, struct clnp_optidx *));
+       }
+
+       /* get flags and ship it off */
+       flags = rp->rcb_flags & CLNP_VFLAGS;
+
+#ifdef TROLL
+       if (trollctl.tr_ops & TR_BLAST) {
+               register int i;
+               struct timeval start, stop;
+               extern struct timeval   time;
+               struct mbuf *mbuf_orig;
+
+               mbuf_orig = m0;
+               start = time;
+               for (i=0; i<trollctl.tr_blast_cnt; i++) {
+                       m0 = m_copy(mbuf_orig, 0, M_COPYALL);
+                       if (m0 == NULL) {
+                               error = ENOBUFS;
+                       } else {
+                               error = clnp_output(m0, &isopcb, len, flags);
+                       }
+                       if (error)
+                               break;
+               }
+               stop = time;
+               printf("rclnp_output: %d pkts in %d sec\n", i,
+                       stop.tv_sec - start.tv_sec);
+               m_freem(mbuf_orig);
+       } else {
+               /*
+                *      Don't bother creating the cache since this is raw; probably
+                *      a one shot send
+                */
+               error = clnp_output(m0, &isopcb, len, flags|CLNP_NOCACHE);
+       }
+#else
+               error = clnp_output(m0, &isopcb, len, flags|CLNP_NOCACHE);
+#endif TROLL
+
+       if (isopcb.isop_route.ro_rt)
+               RTFREE(isopcb.isop_route.ro_rt);
+
+       /* free clnp cached hdr if necessary */
+       if (isopcb.isop_clnpcache != NULL) {
+               struct clnp_cache *clcp = 
+                       mtod(isopcb.isop_clnpcache, struct clnp_cache *);
+               if (clcp->clc_hdr != NULL) {
+                       m_free(clcp->clc_hdr);
+               }
+               m_free(isopcb.isop_clnpcache);
+       }
+
+       if (isopcb.isop_optindex != NULL)
+               m_free(isopcb.isop_optindex);
+
+       return (error);
+}
+
+/*
+ * FUNCTION:           rclnp_ctloutput
+ *
+ * PURPOSE:                    Raw clnp socket option processing
+ *                                     All options are stored inside an mbuf. 
+ *
+ * RETURNS:                    success - 0
+ *                                     failure - unix error code
+ *
+ * SIDE EFFECTS:       If the options mbuf does not exist, it the mbuf passed
+ *                                     is used.
+ *
+ * NOTES:                      
+ */
+rclnp_ctloutput(op, so, level, optname, m)
+int                            op;                             /* type of operation */
+struct socket  *so;                    /* ptr to socket */
+int                    level;                  /* level of option */
+int                            optname;                /* name of option */
+struct mbuf            **m;                    /* ptr to ptr to option data */
+{
+       int                                             error = 0;
+       register struct rawcb   *rp = sotorawcb(so);/* raw cb ptr */
+
+       IFDEBUG(D_CTLOUTPUT)
+               printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n",
+                       op, level, optname);
+               if (*m != NULL) {
+                       printf("rclnp_ctloutput: %d bytes of mbuf data\n", (*m)->m_len);
+                       dump_buf(mtod((*m), caddr_t), (*m)->m_len);
+               }
+       ENDDEBUG
+
+#ifdef SOL_NETWORK
+       if (level != SOL_NETWORK)
+               error = EINVAL;
+       else switch (op) {
+#else
+       switch (op) {
+#endif SOL_NETWORK
+               case PRCO_SETOPT:
+                       switch (optname) {
+                               case CLNPOPT_FLAGS: {
+                                       u_short usr_flags;
+                                       /* 
+                                        *      Insure that the data passed has exactly one short in it 
+                                        */
+                                       if ((*m == NULL) || ((*m)->m_len != sizeof(short))) {
+                                               error = EINVAL;
+                                               break;
+                                       }
+                                        
+                                       /*
+                                        *      Don't allow invalid flags to be set
+                                        */
+                                       usr_flags = (*mtod((*m), short *));
+
+                                       if ((usr_flags & (CLNP_VFLAGS)) != usr_flags) {
+                                               error = EINVAL;
+                                       } else
+                                               rp->rcb_flags |= usr_flags;
+
+                                       } break;
+                       
+                               case CLNPOPT_OPTS:
+                                       error = clnp_set_opts(&rp->rcb_options, m);
+                                       break;
+                       } 
+                       break;
+
+               case PRCO_GETOPT:
+#ifdef notdef
+                       /* commented out to keep hi C quiet */
+                       switch (optname) {
+                               default:
+                                       error = EINVAL;
+                                       break;
+                       }
+#endif notdef
+                       break;
+               default:
+                       error = EINVAL;
+                       break;
+       }
+       if (op == PRCO_SETOPT) {
+               /* note: m_freem does not barf is *m is NULL */
+               m_freem(*m);
+               *m = NULL;
+       }
+       
+       return error;
+}
+
+/*ARGSUSED*/
+clnp_usrreq(so, req, m, nam, rights)
+       struct socket *so;
+       int req;
+       struct mbuf *m, *nam, *rights;
+{
+       return EPROTOTYPE;
+}
+#endif ISO