2 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1995 John Hay. All rights reserved.
7 * This file includes significant work done at Cornell University by
8 * Bill Nesheim. That work included by permission.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * $FreeBSD: src/usr.sbin/IPXrouted/output.c,v 1.8 1999/08/28 01:15:03 peter Exp $
39 * $DragonFly: src/usr.sbin/IPXrouted/output.c,v 1.3 2004/03/11 09:38:59 hmp Exp $
41 * @(#)output.c 8.1 (Berkeley) 6/5/93
45 * Routing Table Management Daemon
51 * Apply the function "f" to all non-passive
52 * interfaces. If the interface supports the
53 * use of broadcasting use it, otherwise address
54 * the output to the known router.
57 toall(void (*f
)(struct sockaddr
*, int, struct interface
*, int),
58 struct rt_entry
*except
, int changesonly
)
60 struct interface
*ifp
;
65 extern struct interface
*ifnet
;
67 for (ifp
= ifnet
; ifp
; ifp
= ifp
->int_next
) {
68 if (ifp
->int_flags
& IFF_PASSIVE
)
72 * Don't send it on interfaces in the except list.
77 if (ifp
== trt
->rt_ifp
) {
86 dst
= ifp
->int_flags
& IFF_BROADCAST
? &ifp
->int_broadaddr
:
87 ifp
->int_flags
& IFF_POINTOPOINT
? &ifp
->int_dstaddr
:
89 flags
= ifp
->int_flags
& IFF_INTERFACE
? MSG_DONTROUTE
: 0;
90 (*f
)(dst
, flags
, ifp
, changesonly
);
95 * Output a preformed packet.
98 sndmsg(struct sockaddr
*dst
, int flags
, struct interface
*ifp
,
102 (*afswitch
[dst
->sa_family
].af_output
)
103 (ripsock
, flags
, dst
, sizeof (struct rip
));
104 TRACE_OUTPUT(ifp
, dst
, sizeof (struct rip
));
108 * Supply dst with the contents of the routing tables.
109 * If this won't fit in one packet, chop it up into several.
111 * This must be done using the split horizon algorithm.
112 * 1. Don't send routing info to the interface from where it was received.
113 * 2. Don't publish an interface to itself.
114 * 3. If a route is received from more than one interface and the cost is
115 * the same, don't publish it on either interface. I am calling this
119 supply(struct sockaddr
*dst
, int flags
, struct interface
*ifp
,
123 struct rt_entry
*crt
; /* Clone route */
126 struct netinfo
*n
= msg
->rip_nets
;
127 struct sockaddr_ipx
*sipx
= (struct sockaddr_ipx
*) dst
;
128 af_output_t
*output
= afswitch
[dst
->sa_family
].af_output
;
129 int size
, metric
, ticks
;
133 if (sipx
->sipx_port
== 0)
134 sipx
->sipx_port
= htons(IPXPORT_RIP
);
136 msg
->rip_cmd
= ntohs(RIPCMD_RESPONSE
);
137 for (rh
= nethash
; rh
< &nethash
[ROUTEHASHSIZ
]; rh
++)
138 for (rt
= rh
->rt_forw
; rt
!= (struct rt_entry
*)rh
; rt
= rt
->rt_forw
) {
139 size
= (char *)n
- (char *)msg
;
140 if (size
>= ((MAXRIPNETS
* sizeof (struct netinfo
)) +
141 sizeof (msg
->rip_cmd
))) {
142 (*output
)(ripsock
, flags
, dst
, size
);
143 TRACE_OUTPUT(ifp
, dst
, size
);
152 if (changesonly
&& !(rt
->rt_state
& RTS_CHANGED
))
156 * This should do rule one and two of the split horizon
159 if (rt
->rt_ifp
== ifp
)
164 * Look if we have clones (different routes to the same
165 * place with exactly the same cost).
167 * We should not publish on any of the clone interfaces.
171 if (crt
->rt_ifp
== ifp
)
176 sipx
= (struct sockaddr_ipx
*)&rt
->rt_dst
;
177 if ((rt
->rt_flags
& (RTF_HOST
|RTF_GATEWAY
)) == RTF_HOST
)
178 sipx
= (struct sockaddr_ipx
*)&rt
->rt_router
;
179 if (rt
->rt_metric
== HOPCNT_INFINITY
)
180 metric
= HOPCNT_INFINITY
;
182 metric
= rt
->rt_metric
+ 1;
184 * We don't advertize routes with more than 15 hops.
186 if (metric
>= HOPCNT_INFINITY
)
189 /* XXX One day we should cater for slow interfaces also. */
190 ticks
= rt
->rt_ticks
+ 1;
191 net
= sipx
->sipx_addr
.x_net
;
194 * Make sure that we don't put out a two net entries
195 * for a pt to pt link (one for the G route, one for the if)
196 * This is a kludge, and won't work if there are lots of nets.
198 for (nn
= msg
->rip_nets
; nn
< n
; nn
++) {
199 if (ipx_neteqnn(net
, nn
->rip_dst
)) {
200 if (ticks
< ntohs(nn
->rip_ticks
)) {
201 nn
->rip_metric
= htons(metric
);
202 nn
->rip_ticks
= htons(ticks
);
203 } else if ((ticks
== ntohs(nn
->rip_ticks
)) &&
204 (metric
< ntohs(nn
->rip_metric
))) {
205 nn
->rip_metric
= htons(metric
);
206 nn
->rip_ticks
= htons(ticks
);
212 n
->rip_metric
= htons(metric
);
213 n
->rip_ticks
= htons(ticks
);
217 if (n
!= msg
->rip_nets
) {
218 size
= (char *)n
- (char *)msg
;
219 (*output
)(ripsock
, flags
, dst
, size
);
220 TRACE_OUTPUT(ifp
, dst
, size
);