|
|
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.