1*21745Ssklower /* ns_output.c 6.2 85/06/01 */ 221488Ssklower 321488Ssklower #include "param.h" 421488Ssklower #include "mbuf.h" 521488Ssklower #include "errno.h" 621488Ssklower #include "socket.h" 721488Ssklower #include "socketvar.h" 821488Ssklower 921488Ssklower #include "../net/if.h" 1021488Ssklower #include "../net/route.h" 1121488Ssklower 1221488Ssklower #include "ns.h" 1321488Ssklower #include "ns_if.h" 1421488Ssklower #include "idp.h" 1521488Ssklower #include "idp_var.h" 1621488Ssklower 1721488Ssklower #ifdef vax 1821488Ssklower #include "../vax/mtpr.h" 1921488Ssklower #endif 20*21745Ssklower int ns_hold_output = 0; 21*21745Ssklower int ns_copy_output = 0; 22*21745Ssklower int ns_output_cnt = 0; 2321488Ssklower struct mbuf *ns_lastout; 2421488Ssklower 2521488Ssklower ns_output(m0, ro, flags) 2621488Ssklower struct mbuf *m0; 2721488Ssklower struct route *ro; 2821488Ssklower int flags; 2921488Ssklower { 3021488Ssklower register struct idp *idp = mtod(m0, struct idp *); 3121488Ssklower register struct ifnet *ifp; 3221488Ssklower register struct mbuf *m; 3321488Ssklower int len, rlen, off, error = 0; 3421488Ssklower struct route idproute; 3521488Ssklower struct sockaddr_ns *dst; 3621488Ssklower extern int idpcksum; 3721488Ssklower 3821488Ssklower if(ns_hold_output) { 3921488Ssklower if(ns_lastout) { 4021488Ssklower m_free(ns_lastout); 4121488Ssklower } 4221488Ssklower ns_lastout = m_copy(m0, 0, M_COPYALL); 4321488Ssklower } 4421488Ssklower if(ns_copy_output) { 4521488Ssklower ns_watch_output(m0); 4621488Ssklower } 4721488Ssklower 4821488Ssklower /* 4921488Ssklower * Route packet. 5021488Ssklower */ 5121488Ssklower if (ro == 0) { 5221488Ssklower ro = &idproute; 5321488Ssklower bzero((caddr_t)ro, sizeof (*ro)); 5421488Ssklower } 5521488Ssklower dst = (struct sockaddr_ns *)&ro->ro_dst; 5621488Ssklower if (ro->ro_rt == 0) { 5721488Ssklower dst->sns_family = AF_NS; 5821488Ssklower dst->sns_addr = idp->idp_dna; 5921488Ssklower /* 6021488Ssklower * If routing to interface only, 6121488Ssklower * short circuit routing lookup. 6221488Ssklower */ 6321488Ssklower if (flags & NS_ROUTETOIF) { 6421488Ssklower struct ns_ifaddr *ia; 6521488Ssklower ia = ns_iaonnetof(idp->idp_dna.x_net); 6621488Ssklower if (ia == 0) { 6721488Ssklower error = ENETUNREACH; 6821488Ssklower goto bad; 6921488Ssklower } 7021488Ssklower ifp = ia->ia_ifp; 7121488Ssklower goto gotif; 7221488Ssklower } 7321488Ssklower rtalloc(ro); 7421488Ssklower } else if ((ro->ro_rt->rt_flags & RTF_UP) == 0) { 7521488Ssklower /* 7621488Ssklower * The old route has gone away; try for a new one. 7721488Ssklower */ 7821488Ssklower rtfree(ro->ro_rt); 7921488Ssklower rtalloc(ro); 8021488Ssklower } 8121488Ssklower if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) { 8221488Ssklower error = ENETUNREACH; 8321488Ssklower goto bad; 8421488Ssklower } 8521488Ssklower ro->ro_rt->rt_use++; 8621488Ssklower if (ro->ro_rt->rt_flags & (RTF_GATEWAY|RTF_HOST)) 8721488Ssklower dst = (struct sockaddr_ns *)&ro->ro_rt->rt_gateway; 8821488Ssklower gotif: 8921488Ssklower 9021488Ssklower /* 9121488Ssklower * Look for multicast addresses and 9221488Ssklower * and verify user is allowed to send 9321488Ssklower * such a packet. 9421488Ssklower */ 9521488Ssklower if (dst->sns_addr.x_host.c_host[0]&1) { 9621488Ssklower if ((ifp->if_flags & IFF_BROADCAST) == 0) { 9721488Ssklower error = EADDRNOTAVAIL; 9821488Ssklower goto bad; 9921488Ssklower } 10021488Ssklower if ((flags & NS_ALLOWBROADCAST) == 0) { 10121488Ssklower error = EACCES; 10221488Ssklower goto bad; 10321488Ssklower } 10421488Ssklower } 10521488Ssklower 10621488Ssklower if (htons(idp->idp_len) <= ifp->if_mtu) { 10721488Ssklower ns_output_cnt++; 10821488Ssklower error = (*ifp->if_output)(ifp, m0, (struct sockaddr *)dst); 10921488Ssklower goto done; 11021488Ssklower } else error = EMSGSIZE; 11121488Ssklower 11221488Ssklower 11321488Ssklower bad: 11421488Ssklower m_freem(m0); 11521488Ssklower done: 11621488Ssklower if (ro == &idproute && (flags & NS_ROUTETOIF) == 0 && ro->ro_rt) 11721488Ssklower RTFREE(ro->ro_rt); 11821488Ssklower return (error); 11921488Ssklower } 120