sap_output.c revision 19948
111820Sjulian/*
211820Sjulian * Copyright (c) 1995 John Hay.  All rights reserved.
311820Sjulian *
411820Sjulian * Redistribution and use in source and binary forms, with or without
511820Sjulian * modification, are permitted provided that the following conditions
611820Sjulian * are met:
711820Sjulian * 1. Redistributions of source code must retain the above copyright
811820Sjulian *    notice, this list of conditions and the following disclaimer.
911820Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1011820Sjulian *    notice, this list of conditions and the following disclaimer in the
1111820Sjulian *    documentation and/or other materials provided with the distribution.
1211820Sjulian * 3. All advertising materials mentioning features or use of this software
1311820Sjulian *    must display the following acknowledgement:
1411820Sjulian *	This product includes software developed by John Hay.
1511820Sjulian * 4. Neither the name of the author nor the names of any co-contributors
1611820Sjulian *    may be used to endorse or promote products derived from this software
1711820Sjulian *    without specific prior written permission.
1811820Sjulian *
1911820Sjulian * THIS SOFTWARE IS PROVIDED BY John Hay AND CONTRIBUTORS ``AS IS'' AND
2011820Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2111820Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2211820Sjulian * ARE DISCLAIMED.  IN NO EVENT SHALL John Hay OR CONTRIBUTORS BE LIABLE
2311820Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2411820Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2511820Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2611820Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2711820Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2811820Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2911820Sjulian * SUCH DAMAGE.
3011820Sjulian *
3119948Sjhay *	$Id: sap_output.c,v 1.4 1996/04/13 15:13:24 jhay Exp $
3211820Sjulian */
3311820Sjulian
3411820Sjulian/*
3511820Sjulian * Routing Table Management Daemon
3611820Sjulian */
3719948Sjhay#include <unistd.h>
3811820Sjulian#include "defs.h"
3911820Sjulian
4011820Sjulian/*
4111820Sjulian * Apply the function "f" to all non-passive
4211820Sjulian * interfaces.  If the interface supports the
4311820Sjulian * use of broadcasting use it, otherwise address
4411820Sjulian * the output to the known router.
4511820Sjulian */
4611820Sjulianvoid
4711820Sjuliansap_supply_toall(void)
4811820Sjulian{
4911820Sjulian	register struct interface *ifp;
5011820Sjulian	struct sockaddr dst;
5111820Sjulian	register struct sockaddr_ipx *ipx_dst;
5211820Sjulian	register int flags;
5311820Sjulian	extern struct interface *ifnet;
5411820Sjulian
5511820Sjulian	ipx_dst = (struct sockaddr_ipx *)&dst;
5611820Sjulian
5711820Sjulian	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
5811820Sjulian		if (ifp->int_flags & IFF_PASSIVE)
5911820Sjulian			continue;
6011820Sjulian
6111820Sjulian		dst = ifp->int_flags & IFF_BROADCAST ? ifp->int_broadaddr :
6211820Sjulian		      ifp->int_flags & IFF_POINTOPOINT ? ifp->int_dstaddr :
6311820Sjulian		      ifp->int_addr;
6411820Sjulian
6512268Sjulian		ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP);
6612268Sjulian
6711820Sjulian		flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0;
6811820Sjulian		sap_supply(&dst, flags, ifp, SAP_WILDCARD);
6911820Sjulian	}
7011820Sjulian}
7111820Sjulian
7211820Sjulianvoid
7311820Sjuliansapsndmsg(dst, flags, ifp)
7411820Sjulian	struct sockaddr *dst;
7511820Sjulian	int flags;
7611820Sjulian	struct interface *ifp;
7711820Sjulian{
7811820Sjulian	struct sockaddr t_dst;
7911820Sjulian	struct sockaddr_ipx *ipx_dst;
8011820Sjulian
8111820Sjulian	t_dst = *dst;
8211820Sjulian	ipx_dst = (struct sockaddr_ipx *)&t_dst;
8311820Sjulian
8411820Sjulian	if (ipx_dst->sipx_addr.x_port == 0)
8511820Sjulian		ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP);
8611820Sjulian
8711820Sjulian        (*afswitch[dst->sa_family].af_output)
8811820Sjulian		(sapsock, flags, &t_dst,
8911820Sjulian		sizeof (struct sap_packet) + sizeof(u_short));
9011820Sjulian	TRACE_SAP_OUTPUT(ifp, &t_dst,
9111820Sjulian			 sizeof (struct sap_packet) + sizeof(u_short));
9211820Sjulian}
9311820Sjulian
9411820Sjulian/*
9511820Sjulian * Supply dst with the contents of the SAP tables. If the ServType ==
9611820Sjulian * SAP_WILDCARD (0xFFFF) supply the whole table, otherwise only the
9711820Sjulian * services that are of ServType. If this won't fit in one packet, chop
9811820Sjulian * it up into several.
9911820Sjulian *
10011820Sjulian * This must be done using the split horizon algorithm.
10111820Sjulian * 1. Don't send SAP info to the interface from where it was received.
10211820Sjulian * 2. If a service is received from more than one interface and the cost is
10311820Sjulian *    the same, don't publish it on either interface. I am calling this
10411820Sjulian *    clones.
10511820Sjulian */
10611820Sjulianvoid
10711820Sjuliansap_supply(dst, flags, ifp, ServType)
10811820Sjulian	struct sockaddr *dst;
10911820Sjulian	int flags;
11011820Sjulian	struct interface *ifp;
11111820Sjulian	int ServType;
11211820Sjulian{
11311820Sjulian	register struct sap_entry *sap;
11411820Sjulian	register struct sap_entry *csap; /* Clone route */
11511820Sjulian	register struct sap_hash *sh;
11611820Sjulian	register struct sap_info *n = sap_msg->sap;
11711820Sjulian	struct sap_hash *base = sap_head;
11811820Sjulian	struct sockaddr_ipx *sipx =  (struct sockaddr_ipx *) dst;
11911820Sjulian	af_output_t *output = afswitch[dst->sa_family].af_output;
12011820Sjulian	int size, metric;
12119948Sjhay	int delay = 0;
12211820Sjulian
12311820Sjulian	if (sipx->sipx_port == 0)
12411820Sjulian		sipx->sipx_port = htons(IPXPORT_SAP);
12511820Sjulian
12611820Sjulian	sap_msg->sap_cmd = ntohs(SAP_RESP);
12711820Sjulian
12811820Sjulian	for (sh = base; sh < &base[SAPHASHSIZ]; sh++)
12911820Sjulian	for (sap = sh->forw; sap != (struct sap_entry *)sh; sap = sap->forw) {
13011820Sjulian		size = (char *)n - (char *)sap_msg;
13115248Sjhay		if (size >= ((MAXSAPENTRIES * sizeof (struct sap_info)) +
13215248Sjhay				sizeof (sap_msg->sap_cmd))) {
13311820Sjulian			(*output)(sapsock, flags, dst, size);
13411820Sjulian			TRACE_SAP_OUTPUT(ifp, dst, size);
13511820Sjulian			n = sap_msg->sap;
13619948Sjhay			delay++;
13719948Sjhay			if(delay == 2) {
13819948Sjhay				usleep(20000);
13919948Sjhay				delay = 0;
14019948Sjhay			}
14111820Sjulian		}
14211820Sjulian
14311820Sjulian		/*
14411820Sjulian		 * Check for the servicetype except if the ServType is
14511820Sjulian		 * a wildcard (0xFFFF).
14611820Sjulian		 */
14711820Sjulian		if ((ServType != SAP_WILDCARD) &&
14811820Sjulian		    (ServType != sap->sap.ServType))
14911820Sjulian			continue;
15011820Sjulian
15111820Sjulian		/*
15211820Sjulian		 * This should do rule one and two of the split horizon
15311820Sjulian		 * algorithm.
15411820Sjulian		 */
15511820Sjulian		if (sap->ifp == ifp)
15611820Sjulian			continue;
15711820Sjulian
15811820Sjulian		/*
15911820Sjulian		 * Rule 2.
16011820Sjulian		 * Look if we have clones (different routes to the same
16111820Sjulian		 * place with exactly the same cost).
16211820Sjulian		 *
16311820Sjulian		 * We should not publish on any of the clone interfaces.
16411820Sjulian		 */
16511820Sjulian		csap = sap->clone;
16611820Sjulian		while (csap) {
16711820Sjulian			if (csap->ifp == ifp)
16812630Sjulian				goto next;
16911820Sjulian			csap = csap->clone;
17011820Sjulian		}
17111820Sjulian
17211820Sjulian		/*
17311820Sjulian		 * Don't advertise services with more than 15 hops. It
17411820Sjulian		 * will be confused with a service that has gone down.
17511820Sjulian		 */
17611820Sjulian		if (ntohs(sap->sap.hops) == (HOPCNT_INFINITY - 1))
17711820Sjulian			continue;
17811820Sjulian		metric = min(ntohs(sap->sap.hops) + 1, HOPCNT_INFINITY);
17911820Sjulian
18011820Sjulian		*n = sap->sap;
18111820Sjulian		n->hops = htons(metric);
18211820Sjulian		n++;
18312630Sjuliannext:
18411820Sjulian	}
18511820Sjulian	if (n != sap_msg->sap) {
18611820Sjulian		size = (char *)n - (char *)sap_msg;
18711820Sjulian		(*output)(sapsock, flags, dst, size);
18811820Sjulian		TRACE_SAP_OUTPUT(ifp, dst, size);
18911820Sjulian	}
19011820Sjulian}
19111820Sjulian
192