]> git.saurik.com Git - apple/network_cmds.git/blob - routed.tproj/output.c
65463f61b5ad25858798d8231a99c2ac8852647f
[apple/network_cmds.git] / routed.tproj / output.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * Copyright (c) 1983, 1988, 1993
25 * The Regents of the University of California. All rights reserved.
26 *
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
29 * are met:
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgment:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
54 *
55 * @(#)defs.h 8.1 (Berkeley) 6/5/93
56 */
57
58
59 /*
60 * Routing Table Management Daemon
61 */
62 #include "defs.h"
63
64 /*
65 * Apply the function "f" to all non-passive
66 * interfaces. If the interface supports the
67 * use of broadcasting use it, otherwise address
68 * the output to the known router.
69 */
70 toall(f, rtstate, skipif)
71 int (*f)();
72 int rtstate;
73 struct interface *skipif;
74 {
75 register struct interface *ifp;
76 register struct sockaddr *dst;
77 register int flags;
78 extern struct interface *ifnet;
79
80 for (ifp = ifnet; ifp; ifp = ifp->int_next) {
81 if (ifp->int_flags & IFF_PASSIVE || ifp == skipif)
82 continue;
83 dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr :
84 ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr :
85 &ifp->int_addr;
86 flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0;
87 (*f)(dst, flags, ifp, rtstate);
88 }
89 }
90
91 /*
92 * Output a preformed packet.
93 */
94 /*ARGSUSED*/
95 sndmsg(dst, flags, ifp, rtstate)
96 struct sockaddr *dst;
97 int flags;
98 struct interface *ifp;
99 int rtstate;
100 {
101
102 (*afswitch[dst->sa_family].af_output)(s, flags,
103 dst, sizeof (struct rip));
104 TRACE_OUTPUT(ifp, dst, sizeof (struct rip));
105 }
106
107 /*
108 * Supply dst with the contents of the routing tables.
109 * If this won't fit in one packet, chop it up into several.
110 */
111 supply(dst, flags, ifp, rtstate)
112 struct sockaddr *dst;
113 int flags;
114 register struct interface *ifp;
115 int rtstate;
116 {
117 register struct rt_entry *rt;
118 register struct netinfo *n = msg->rip_nets;
119 register struct rthash *rh;
120 struct rthash *base = hosthash;
121 int doinghost = 1, size;
122 int (*output)() = afswitch[dst->sa_family].af_output;
123 int (*sendroute)() = afswitch[dst->sa_family].af_sendroute;
124 int npackets = 0;
125
126 msg->rip_cmd = RIPCMD_RESPONSE;
127 msg->rip_vers = RIPVERSION;
128 memset(msg->rip_res1, 0, sizeof(msg->rip_res1));
129 again:
130 for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++)
131 for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
132 /*
133 * Don't resend the information on the network
134 * from which it was received (unless sending
135 * in response to a query).
136 */
137 if (ifp && rt->rt_ifp == ifp &&
138 (rt->rt_state & RTS_INTERFACE) == 0)
139 continue;
140 if (rt->rt_state & RTS_EXTERNAL)
141 continue;
142 /*
143 * For dynamic updates, limit update to routes
144 * with the specified state.
145 */
146 if (rtstate && (rt->rt_state & rtstate) == 0)
147 continue;
148 /*
149 * Limit the spread of subnet information
150 * to those who are interested.
151 */
152 if (doinghost == 0 && rt->rt_state & RTS_SUBNET) {
153 if (rt->rt_dst.sa_family != dst->sa_family)
154 continue;
155 if ((*sendroute)(rt, dst) == 0)
156 continue;
157 }
158 size = (char *)n - packet;
159 if (size > MAXPACKETSIZE - sizeof (struct netinfo)) {
160 TRACE_OUTPUT(ifp, dst, size);
161 (*output)(s, flags, dst, size);
162 /*
163 * If only sending to ourselves,
164 * one packet is enough to monitor interface.
165 */
166 if (ifp && (ifp->int_flags &
167 (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0)
168 return;
169 n = msg->rip_nets;
170 npackets++;
171 }
172 n->rip_dst = rt->rt_dst;
173 #if BSD < 198810
174 if (sizeof(n->rip_dst.sa_family) > 1) /* XXX */
175 n->rip_dst.sa_family = htons(n->rip_dst.sa_family);
176 #else
177 #define osa(x) ((struct osockaddr *)(&(x)))
178 osa(n->rip_dst)->sa_family = htons(n->rip_dst.sa_family);
179 #endif
180 n->rip_metric = htonl(rt->rt_metric);
181 n++;
182 }
183 if (doinghost) {
184 doinghost = 0;
185 base = nethash;
186 goto again;
187 }
188 if (n != msg->rip_nets || (npackets == 0 && rtstate == 0)) {
189 size = (char *)n - packet;
190 TRACE_OUTPUT(ifp, dst, size);
191 (*output)(s, flags, dst, size);
192 }
193 }