sap_output.c revision 12268
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 *
3112268Sjulian *	$Id: sap_output.c,v 1.1 1995/10/26 21:28:24 julian Exp $
3211820Sjulian */
3311820Sjulian
3411820Sjulian/*
3511820Sjulian * Routing Table Management Daemon
3611820Sjulian */
3711820Sjulian#include "defs.h"
3811820Sjulian
3911820Sjulian/*
4011820Sjulian * Apply the function "f" to all non-passive
4111820Sjulian * interfaces.  If the interface supports the
4211820Sjulian * use of broadcasting use it, otherwise address
4311820Sjulian * the output to the known router.
4411820Sjulian */
4511820Sjulianvoid
4611820Sjuliansap_supply_toall(void)
4711820Sjulian{
4811820Sjulian	register struct interface *ifp;
4911820Sjulian	struct sockaddr dst;
5011820Sjulian	register struct sockaddr_ipx *ipx_dst;
5111820Sjulian	register int flags;
5211820Sjulian	extern struct interface *ifnet;
5311820Sjulian
5411820Sjulian	ipx_dst = (struct sockaddr_ipx *)&dst;
5511820Sjulian
5611820Sjulian	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
5711820Sjulian		if (ifp->int_flags & IFF_PASSIVE)
5811820Sjulian			continue;
5911820Sjulian
6011820Sjulian		dst = ifp->int_flags & IFF_BROADCAST ? ifp->int_broadaddr :
6111820Sjulian		      ifp->int_flags & IFF_POINTOPOINT ? ifp->int_dstaddr :
6211820Sjulian		      ifp->int_addr;
6311820Sjulian
6412268Sjulian		ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP);
6512268Sjulian
6611820Sjulian		flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0;
6711820Sjulian		sap_supply(&dst, flags, ifp, SAP_WILDCARD);
6811820Sjulian	}
6911820Sjulian}
7011820Sjulian
7111820Sjulianvoid
7211820Sjuliansapsndmsg(dst, flags, ifp)
7311820Sjulian	struct sockaddr *dst;
7411820Sjulian	int flags;
7511820Sjulian	struct interface *ifp;
7611820Sjulian{
7711820Sjulian	struct sockaddr t_dst;
7811820Sjulian	struct sockaddr_ipx *ipx_dst;
7911820Sjulian
8011820Sjulian	t_dst = *dst;
8111820Sjulian	ipx_dst = (struct sockaddr_ipx *)&t_dst;
8211820Sjulian
8311820Sjulian	if (ipx_dst->sipx_addr.x_port == 0)
8411820Sjulian		ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP);
8511820Sjulian
8611820Sjulian        (*afswitch[dst->sa_family].af_output)
8711820Sjulian		(sapsock, flags, &t_dst,
8811820Sjulian		sizeof (struct sap_packet) + sizeof(u_short));
8911820Sjulian	TRACE_SAP_OUTPUT(ifp, &t_dst,
9011820Sjulian			 sizeof (struct sap_packet) + sizeof(u_short));
9111820Sjulian}
9211820Sjulian
9311820Sjulian/*
9411820Sjulian * Supply dst with the contents of the SAP tables. If the ServType ==
9511820Sjulian * SAP_WILDCARD (0xFFFF) supply the whole table, otherwise only the
9611820Sjulian * services that are of ServType. If this won't fit in one packet, chop
9711820Sjulian * it up into several.
9811820Sjulian *
9911820Sjulian * This must be done using the split horizon algorithm.
10011820Sjulian * 1. Don't send SAP info to the interface from where it was received.
10111820Sjulian * 2. If a service is received from more than one interface and the cost is
10211820Sjulian *    the same, don't publish it on either interface. I am calling this
10311820Sjulian *    clones.
10411820Sjulian */
10511820Sjulianvoid
10611820Sjuliansap_supply(dst, flags, ifp, ServType)
10711820Sjulian	struct sockaddr *dst;
10811820Sjulian	int flags;
10911820Sjulian	struct interface *ifp;
11011820Sjulian	int ServType;
11111820Sjulian{
11211820Sjulian	register struct sap_entry *sap;
11311820Sjulian	register struct sap_entry *csap; /* Clone route */
11411820Sjulian	register struct sap_hash *sh;
11511820Sjulian	register struct sap_info *n = sap_msg->sap;
11611820Sjulian	struct sap_hash *base = sap_head;
11711820Sjulian	struct sockaddr_ipx *sipx =  (struct sockaddr_ipx *) dst;
11811820Sjulian	af_output_t *output = afswitch[dst->sa_family].af_output;
11911820Sjulian	int size, metric;
12011820Sjulian
12111820Sjulian	if (sipx->sipx_port == 0)
12211820Sjulian		sipx->sipx_port = htons(IPXPORT_SAP);
12311820Sjulian
12411820Sjulian	sap_msg->sap_cmd = ntohs(SAP_RESP);
12511820Sjulian
12611820Sjulian	for (sh = base; sh < &base[SAPHASHSIZ]; sh++)
12711820Sjulian	for (sap = sh->forw; sap != (struct sap_entry *)sh; sap = sap->forw) {
12811820Sjulian		size = (char *)n - (char *)sap_msg;
12911820Sjulian		if (size > MAXPACKETSIZE - sizeof (struct sap_info)) {
13011820Sjulian			(*output)(sapsock, flags, dst, size);
13111820Sjulian			TRACE_SAP_OUTPUT(ifp, dst, size);
13211820Sjulian			n = sap_msg->sap;
13311820Sjulian		}
13411820Sjulian
13511820Sjulian		/*
13611820Sjulian		 * Check for the servicetype except if the ServType is
13711820Sjulian		 * a wildcard (0xFFFF).
13811820Sjulian		 */
13911820Sjulian		if ((ServType != SAP_WILDCARD) &&
14011820Sjulian		    (ServType != sap->sap.ServType))
14111820Sjulian			continue;
14211820Sjulian
14311820Sjulian		/*
14411820Sjulian		 * This should do rule one and two of the split horizon
14511820Sjulian		 * algorithm.
14611820Sjulian		 */
14711820Sjulian		if (sap->ifp == ifp)
14811820Sjulian			continue;
14911820Sjulian
15011820Sjulian		/*
15111820Sjulian		 * Rule 2.
15211820Sjulian		 * Look if we have clones (different routes to the same
15311820Sjulian		 * place with exactly the same cost).
15411820Sjulian		 *
15511820Sjulian		 * We should not publish on any of the clone interfaces.
15611820Sjulian		 */
15711820Sjulian		csap = sap->clone;
15811820Sjulian		while (csap) {
15911820Sjulian			if (csap->ifp == ifp)
16011820Sjulian				continue;
16111820Sjulian			csap = csap->clone;
16211820Sjulian		}
16311820Sjulian
16411820Sjulian		/*
16511820Sjulian		 * Don't advertise services with more than 15 hops. It
16611820Sjulian		 * will be confused with a service that has gone down.
16711820Sjulian		 */
16811820Sjulian		if (ntohs(sap->sap.hops) == (HOPCNT_INFINITY - 1))
16911820Sjulian			continue;
17011820Sjulian		metric = min(ntohs(sap->sap.hops) + 1, HOPCNT_INFINITY);
17111820Sjulian
17211820Sjulian		*n = sap->sap;
17311820Sjulian		n->hops = htons(metric);
17411820Sjulian		n++;
17511820Sjulian	}
17611820Sjulian	if (n != sap_msg->sap) {
17711820Sjulian		size = (char *)n - (char *)sap_msg;
17811820Sjulian		(*output)(sapsock, flags, dst, size);
17911820Sjulian		TRACE_SAP_OUTPUT(ifp, dst, size);
18011820Sjulian	}
18111820Sjulian}
18211820Sjulian
183