2 * Copyright (c) 1995 John Hay. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by John Hay.
15 * 4. Neither the name of the author nor the names of any co-contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY John Hay AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL John Hay OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * $FreeBSD: src/usr.sbin/IPXrouted/sap_output.c,v 1.9 1999/08/28 01:15:04 peter Exp $
32 * $DragonFly: src/usr.sbin/IPXrouted/sap_output.c,v 1.4 2004/06/19 20:38:22 joerg Exp $
36 * Routing Table Management Daemon
42 * Apply the function "f" to all non-passive
43 * interfaces. If the interface supports the
44 * use of broadcasting use it, otherwise address
45 * the output to the known router.
48 sap_supply_toall(int changesonly
)
50 struct interface
*ifp
;
52 struct sockaddr_ipx
*ipx_dst
;
54 extern struct interface
*ifnet
;
56 ipx_dst
= (struct sockaddr_ipx
*)&dst
;
58 for (ifp
= ifnet
; ifp
; ifp
= ifp
->int_next
) {
59 if (ifp
->int_flags
& IFF_PASSIVE
)
62 dst
= ifp
->int_flags
& IFF_BROADCAST
? ifp
->int_broadaddr
:
63 ifp
->int_flags
& IFF_POINTOPOINT
? ifp
->int_dstaddr
:
66 ipx_dst
->sipx_addr
.x_port
= htons(IPXPORT_SAP
);
68 flags
= ifp
->int_flags
& IFF_INTERFACE
? MSG_DONTROUTE
: 0;
69 sap_supply(&dst
, flags
, ifp
, SAP_WILDCARD
, changesonly
);
74 sapsndmsg(struct sockaddr
*dst
, int flags
, struct interface
*ifp
,
77 struct sockaddr t_dst
;
78 struct sockaddr_ipx
*ipx_dst
;
81 ipx_dst
= (struct sockaddr_ipx
*)&t_dst
;
83 if (ipx_dst
->sipx_addr
.x_port
== 0)
84 ipx_dst
->sipx_addr
.x_port
= htons(IPXPORT_SAP
);
86 (*afswitch
[dst
->sa_family
].af_output
)
87 (sapsock
, flags
, &t_dst
,
88 sizeof (struct sap_packet
) + sizeof(u_short
));
89 TRACE_SAP_OUTPUT(ifp
, &t_dst
,
90 sizeof (struct sap_packet
) + sizeof(u_short
));
94 * Supply dst with the contents of the SAP tables. If the ServType ==
95 * SAP_WILDCARD (0xFFFF) supply the whole table, otherwise only the
96 * services that are of ServType. If this won't fit in one packet, chop
99 * This must be done using the split horizon algorithm.
100 * 1. Don't send SAP info to the interface from where it was received.
101 * 2. If a service is received from more than one interface and the cost is
102 * the same, don't publish it on either interface. I am calling this
106 sap_supply(struct sockaddr
*dst
, int flags
, struct interface
*ifp
,
107 int ServType
, int changesonly
)
109 struct sap_entry
*sap
;
110 struct sap_entry
*csap
; /* Clone route */
112 struct sap_info
*n
= sap_msg
->sap
;
113 struct sap_hash
*base
= sap_head
;
114 struct sockaddr_ipx
*sipx
= (struct sockaddr_ipx
*) dst
;
115 af_output_t
*output
= afswitch
[dst
->sa_family
].af_output
;
119 if (sipx
->sipx_port
== 0)
120 sipx
->sipx_port
= htons(IPXPORT_SAP
);
122 sap_msg
->sap_cmd
= ntohs(SAP_RESP
);
124 for (sh
= base
; sh
< &base
[SAPHASHSIZ
]; sh
++)
125 for (sap
= sh
->forw
; sap
!= (struct sap_entry
*)sh
; sap
= sap
->forw
) {
126 size
= (char *)n
- (char *)sap_msg
;
127 if (size
>= ((MAXSAPENTRIES
* sizeof (struct sap_info
)) +
128 sizeof (sap_msg
->sap_cmd
))) {
129 (*output
)(sapsock
, flags
, dst
, size
);
130 TRACE_SAP_OUTPUT(ifp
, dst
, size
);
139 if (changesonly
&& !(sap
->state
& RTS_CHANGED
))
143 * Check for the servicetype except if the ServType is
144 * a wildcard (0xFFFF).
146 if ((ServType
!= SAP_WILDCARD
) &&
147 (ServType
!= sap
->sap
.ServType
))
151 * This should do rule one and two of the split horizon
159 * Look if we have clones (different routes to the same
160 * place with exactly the same cost).
162 * We should not publish on any of the clone interfaces.
166 if (csap
->ifp
== ifp
)
172 * Don't advertise services with more than 15 hops. It
173 * will be confused with a service that has gone down.
175 if (ntohs(sap
->sap
.hops
) == (HOPCNT_INFINITY
- 1))
177 metric
= min(ntohs(sap
->sap
.hops
) + 1, HOPCNT_INFINITY
);
180 n
->hops
= htons(metric
);
185 if (n
!= sap_msg
->sap
) {
186 size
= (char *)n
- (char *)sap_msg
;
187 (*output
)(sapsock
, flags
, dst
, size
);
188 TRACE_SAP_OUTPUT(ifp
, dst
, size
);