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