|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1984, 1985, 1986, 1987 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution is only permitted until one year after the first shipment ! 6: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and ! 7: * binary forms are permitted provided that: (1) source distributions retain ! 8: * this entire copyright notice and comment, and (2) distributions including ! 9: * binaries display the following acknowledgement: This product includes ! 10: * software developed by the University of California, Berkeley and its ! 11: * contributors'' in the documentation or other materials provided with the ! 12: * distribution and in all advertising materials mentioning features or use ! 13: * of this software. Neither the name of the University nor the names of ! 14: * its contributors may be used to endorse or promote products derived from ! 15: * this software without specific prior written permission. ! 16: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 19: * ! 20: * @(#)ns_output.c 7.7 (Berkeley) 6/28/90 ! 21: */ ! 22: ! 23: #include "param.h" ! 24: #include "malloc.h" ! 25: #include "mbuf.h" ! 26: #include "errno.h" ! 27: #include "socket.h" ! 28: #include "socketvar.h" ! 29: ! 30: #include "../net/if.h" ! 31: #include "../net/route.h" ! 32: ! 33: #include "ns.h" ! 34: #include "ns_if.h" ! 35: #include "idp.h" ! 36: #include "idp_var.h" ! 37: ! 38: #ifdef vax ! 39: #include "../vax/mtpr.h" ! 40: #endif ! 41: int ns_hold_output = 0; ! 42: int ns_copy_output = 0; ! 43: int ns_output_cnt = 0; ! 44: struct mbuf *ns_lastout; ! 45: ! 46: ns_output(m0, ro, flags) ! 47: struct mbuf *m0; ! 48: struct route *ro; ! 49: int flags; ! 50: { ! 51: register struct idp *idp = mtod(m0, struct idp *); ! 52: register struct ifnet *ifp = 0; ! 53: int error = 0; ! 54: struct route idproute; ! 55: struct sockaddr_ns *dst; ! 56: extern int idpcksum; ! 57: ! 58: if (ns_hold_output) { ! 59: if (ns_lastout) { ! 60: (void)m_free(ns_lastout); ! 61: } ! 62: ns_lastout = m_copy(m0, 0, (int)M_COPYALL); ! 63: } ! 64: /* ! 65: * Route packet. ! 66: */ ! 67: if (ro == 0) { ! 68: ro = &idproute; ! 69: bzero((caddr_t)ro, sizeof (*ro)); ! 70: } ! 71: dst = (struct sockaddr_ns *)&ro->ro_dst; ! 72: if (ro->ro_rt == 0) { ! 73: dst->sns_family = AF_NS; ! 74: dst->sns_len = sizeof (*dst); ! 75: dst->sns_addr = idp->idp_dna; ! 76: dst->sns_addr.x_port = 0; ! 77: /* ! 78: * If routing to interface only, ! 79: * short circuit routing lookup. ! 80: */ ! 81: if (flags & NS_ROUTETOIF) { ! 82: struct ns_ifaddr *ia = ns_iaonnetof(&idp->idp_dna); ! 83: ! 84: if (ia == 0) { ! 85: error = ENETUNREACH; ! 86: goto bad; ! 87: } ! 88: ifp = ia->ia_ifp; ! 89: goto gotif; ! 90: } ! 91: rtalloc(ro); ! 92: } else if ((ro->ro_rt->rt_flags & RTF_UP) == 0) { ! 93: /* ! 94: * The old route has gone away; try for a new one. ! 95: */ ! 96: rtfree(ro->ro_rt); ! 97: ro->ro_rt = NULL; ! 98: rtalloc(ro); ! 99: } ! 100: if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) { ! 101: error = ENETUNREACH; ! 102: goto bad; ! 103: } ! 104: ro->ro_rt->rt_use++; ! 105: if (ro->ro_rt->rt_flags & (RTF_GATEWAY|RTF_HOST)) ! 106: dst = (struct sockaddr_ns *)ro->ro_rt->rt_gateway; ! 107: gotif: ! 108: ! 109: /* ! 110: * Look for multicast addresses and ! 111: * and verify user is allowed to send ! 112: * such a packet. ! 113: */ ! 114: if (dst->sns_addr.x_host.c_host[0]&1) { ! 115: if ((ifp->if_flags & IFF_BROADCAST) == 0) { ! 116: error = EADDRNOTAVAIL; ! 117: goto bad; ! 118: } ! 119: if ((flags & NS_ALLOWBROADCAST) == 0) { ! 120: error = EACCES; ! 121: goto bad; ! 122: } ! 123: } ! 124: ! 125: if (htons(idp->idp_len) <= ifp->if_mtu) { ! 126: ns_output_cnt++; ! 127: if (ns_copy_output) { ! 128: ns_watch_output(m0, ifp); ! 129: } ! 130: error = (*ifp->if_output)(ifp, m0, ! 131: (struct sockaddr *)dst, ro->ro_rt); ! 132: goto done; ! 133: } else error = EMSGSIZE; ! 134: ! 135: ! 136: bad: ! 137: if (ns_copy_output) { ! 138: ns_watch_output(m0, ifp); ! 139: } ! 140: m_freem(m0); ! 141: done: ! 142: if (ro == &idproute && (flags & NS_ROUTETOIF) == 0 && ro->ro_rt) { ! 143: RTFREE(ro->ro_rt); ! 144: ro->ro_rt = 0; ! 145: } ! 146: return (error); ! 147: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.