|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.