home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / netns / ns_output.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  4.3 KB  |  161 lines

  1. /*
  2.  * Copyright (c) 1984, 1985, 1986, 1987 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *    @(#)ns_output.c    7.8 (Berkeley) 12/16/90
  34.  */
  35.  
  36. #include "param.h"
  37. #include "malloc.h"
  38. #include "mbuf.h"
  39. #include "errno.h"
  40. #include "socket.h"
  41. #include "socketvar.h"
  42.  
  43. #include "../net/if.h"
  44. #include "../net/route.h"
  45.  
  46. #include "ns.h"
  47. #include "ns_if.h"
  48. #include "idp.h"
  49. #include "idp_var.h"
  50.  
  51. #ifdef vax
  52. #include "vax/include/mtpr.h"
  53. #endif
  54. int ns_hold_output = 0;
  55. int ns_copy_output = 0;
  56. int ns_output_cnt = 0;
  57. struct mbuf *ns_lastout;
  58.  
  59. ns_output(m0, ro, flags)
  60.     struct mbuf *m0;
  61.     struct route *ro;
  62.     int flags;
  63. {
  64.     register struct idp *idp = mtod(m0, struct idp *);
  65.     register struct ifnet *ifp = 0;
  66.     int error = 0;
  67.     struct route idproute;
  68.     struct sockaddr_ns *dst;
  69.     extern int idpcksum;
  70.  
  71.     if (ns_hold_output) {
  72.         if (ns_lastout) {
  73.             (void)m_free(ns_lastout);
  74.         }
  75.         ns_lastout = m_copy(m0, 0, (int)M_COPYALL);
  76.     }
  77.     /*
  78.      * Route packet.
  79.      */
  80.     if (ro == 0) {
  81.         ro = &idproute;
  82.         bzero((caddr_t)ro, sizeof (*ro));
  83.     }
  84.     dst = (struct sockaddr_ns *)&ro->ro_dst;
  85.     if (ro->ro_rt == 0) {
  86.         dst->sns_family = AF_NS;
  87.         dst->sns_len = sizeof (*dst);
  88.         dst->sns_addr = idp->idp_dna;
  89.         dst->sns_addr.x_port = 0;
  90.         /*
  91.          * If routing to interface only,
  92.          * short circuit routing lookup.
  93.          */
  94.         if (flags & NS_ROUTETOIF) {
  95.             struct ns_ifaddr *ia = ns_iaonnetof(&idp->idp_dna);
  96.  
  97.             if (ia == 0) {
  98.                 error = ENETUNREACH;
  99.                 goto bad;
  100.             }
  101.             ifp = ia->ia_ifp;
  102.             goto gotif;
  103.         }
  104.         rtalloc(ro);
  105.     } else if ((ro->ro_rt->rt_flags & RTF_UP) == 0) {
  106.         /*
  107.          * The old route has gone away; try for a new one.
  108.          */
  109.         rtfree(ro->ro_rt);
  110.         ro->ro_rt = NULL;
  111.         rtalloc(ro);
  112.     }
  113.     if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
  114.         error = ENETUNREACH;
  115.         goto bad;
  116.     }
  117.     ro->ro_rt->rt_use++;
  118.     if (ro->ro_rt->rt_flags & (RTF_GATEWAY|RTF_HOST))
  119.         dst = (struct sockaddr_ns *)ro->ro_rt->rt_gateway;
  120. gotif:
  121.  
  122.     /*
  123.      * Look for multicast addresses and
  124.      * and verify user is allowed to send
  125.      * such a packet.
  126.      */
  127.     if (dst->sns_addr.x_host.c_host[0]&1) {
  128.         if ((ifp->if_flags & IFF_BROADCAST) == 0) {
  129.             error = EADDRNOTAVAIL;
  130.             goto bad;
  131.         }
  132.         if ((flags & NS_ALLOWBROADCAST) == 0) {
  133.             error = EACCES;
  134.             goto bad;
  135.         }
  136.     }
  137.  
  138.     if (htons(idp->idp_len) <= ifp->if_mtu) {
  139.         ns_output_cnt++;
  140.         if (ns_copy_output) {
  141.             ns_watch_output(m0, ifp);
  142.         }
  143.         error = (*ifp->if_output)(ifp, m0,
  144.                     (struct sockaddr *)dst, ro->ro_rt);
  145.         goto done;
  146.     } else error = EMSGSIZE;
  147.  
  148.  
  149. bad:
  150.     if (ns_copy_output) {
  151.         ns_watch_output(m0, ifp);
  152.     }
  153.     m_freem(m0);
  154. done:
  155.     if (ro == &idproute && (flags & NS_ROUTETOIF) == 0 && ro->ro_rt) {
  156.         RTFREE(ro->ro_rt);
  157.         ro->ro_rt = 0;
  158.     }
  159.     return (error);
  160. }
  161.