sap_output.c revision 11820
1281681Srpaulo/* 2281681Srpaulo * Copyright (c) 1995 John Hay. All rights reserved. 3281681Srpaulo * 4281681Srpaulo * Redistribution and use in source and binary forms, with or without 5281681Srpaulo * modification, are permitted provided that the following conditions 6281681Srpaulo * are met: 7281681Srpaulo * 1. Redistributions of source code must retain the above copyright 8281681Srpaulo * notice, this list of conditions and the following disclaimer. 9281681Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 10281681Srpaulo * notice, this list of conditions and the following disclaimer in the 11281681Srpaulo * documentation and/or other materials provided with the distribution. 12281681Srpaulo * 3. All advertising materials mentioning features or use of this software 13281681Srpaulo * must display the following acknowledgement: 14281681Srpaulo * This product includes software developed by John Hay. 15281681Srpaulo * 4. Neither the name of the author nor the names of any co-contributors 16281681Srpaulo * may be used to endorse or promote products derived from this software 17281681Srpaulo * without specific prior written permission. 18281681Srpaulo * 19281681Srpaulo * THIS SOFTWARE IS PROVIDED BY John Hay AND CONTRIBUTORS ``AS IS'' AND 20281681Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21281681Srpaulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22281681Srpaulo * ARE DISCLAIMED. IN NO EVENT SHALL John Hay OR CONTRIBUTORS BE LIABLE 23281681Srpaulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24281681Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25281681Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26281681Srpaulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27281681Srpaulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28281681Srpaulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29281681Srpaulo * SUCH DAMAGE. 30281681Srpaulo * 31281681Srpaulo * $Id: sap_output.c,v 1.4 1995/10/11 18:57:28 jhay Exp $ 32281681Srpaulo */ 33281681Srpaulo 34281681Srpaulo/* 35281681Srpaulo * Routing Table Management Daemon 36281681Srpaulo */ 37281681Srpaulo#include "defs.h" 38281681Srpaulo 39281681Srpaulo/* 40281681Srpaulo * Apply the function "f" to all non-passive 41281681Srpaulo * interfaces. If the interface supports the 42281681Srpaulo * use of broadcasting use it, otherwise address 43281681Srpaulo * the output to the known router. 44281681Srpaulo */ 45281681Srpaulovoid 46281681Srpaulosap_supply_toall(void) 47281681Srpaulo{ 48281681Srpaulo register struct interface *ifp; 49281681Srpaulo struct sockaddr dst; 50281681Srpaulo register struct sockaddr_ipx *ipx_dst; 51281681Srpaulo register int flags; 52281681Srpaulo extern struct interface *ifnet; 53281681Srpaulo 54281681Srpaulo ipx_dst = (struct sockaddr_ipx *)&dst; 55281681Srpaulo 56281681Srpaulo for (ifp = ifnet; ifp; ifp = ifp->int_next) { 57281681Srpaulo if (ifp->int_flags & IFF_PASSIVE) 58281681Srpaulo continue; 59281681Srpaulo 60281681Srpaulo dst = ifp->int_flags & IFF_BROADCAST ? ifp->int_broadaddr : 61281681Srpaulo ifp->int_flags & IFF_POINTOPOINT ? ifp->int_dstaddr : 62281681Srpaulo ifp->int_addr; 63281681Srpaulo if (ipx_dst->sipx_addr.x_port == 0) 64281681Srpaulo ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP); 65281681Srpaulo 66281681Srpaulo flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; 67281681Srpaulo sap_supply(&dst, flags, ifp, SAP_WILDCARD); 68281681Srpaulo } 69281681Srpaulo} 70281681Srpaulo 71281681Srpaulovoid 72281681Srpaulosapsndmsg(dst, flags, ifp) 73281681Srpaulo struct sockaddr *dst; 74281681Srpaulo int flags; 75281681Srpaulo struct interface *ifp; 76281681Srpaulo{ 77281681Srpaulo struct sockaddr t_dst; 78281681Srpaulo struct sockaddr_ipx *ipx_dst; 79281681Srpaulo 80281681Srpaulo t_dst = *dst; 81281681Srpaulo ipx_dst = (struct sockaddr_ipx *)&t_dst; 82281681Srpaulo 83281681Srpaulo if (ipx_dst->sipx_addr.x_port == 0) 84281681Srpaulo ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP); 85281681Srpaulo 86281681Srpaulo (*afswitch[dst->sa_family].af_output) 87281681Srpaulo (sapsock, flags, &t_dst, 88281681Srpaulo sizeof (struct sap_packet) + sizeof(u_short)); 89281681Srpaulo TRACE_SAP_OUTPUT(ifp, &t_dst, 90281681Srpaulo sizeof (struct sap_packet) + sizeof(u_short)); 91281681Srpaulo} 92281681Srpaulo 93281681Srpaulo/* 94281681Srpaulo * Supply dst with the contents of the SAP tables. If the ServType == 95281681Srpaulo * SAP_WILDCARD (0xFFFF) supply the whole table, otherwise only the 96281681Srpaulo * services that are of ServType. If this won't fit in one packet, chop 97281681Srpaulo * it up into several. 98281681Srpaulo * 99281681Srpaulo * This must be done using the split horizon algorithm. 100281681Srpaulo * 1. Don't send SAP info to the interface from where it was received. 101281681Srpaulo * 2. If a service is received from more than one interface and the cost is 102281681Srpaulo * the same, don't publish it on either interface. I am calling this 103281681Srpaulo * clones. 104281681Srpaulo */ 105281681Srpaulovoid 106281681Srpaulosap_supply(dst, flags, ifp, ServType) 107281681Srpaulo struct sockaddr *dst; 108281681Srpaulo int flags; 109281681Srpaulo struct interface *ifp; 110281681Srpaulo int ServType; 111281681Srpaulo{ 112281681Srpaulo register struct sap_entry *sap; 113281681Srpaulo register struct sap_entry *csap; /* Clone route */ 114281681Srpaulo register struct sap_hash *sh; 115281681Srpaulo register struct sap_info *n = sap_msg->sap; 116281681Srpaulo struct sap_hash *base = sap_head; 117281681Srpaulo struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) dst; 118281681Srpaulo af_output_t *output = afswitch[dst->sa_family].af_output; 119281681Srpaulo int size, metric; 120281681Srpaulo 121281681Srpaulo if (sipx->sipx_port == 0) 122281681Srpaulo sipx->sipx_port = htons(IPXPORT_SAP); 123281681Srpaulo 124281681Srpaulo sap_msg->sap_cmd = ntohs(SAP_RESP); 125281681Srpaulo 126281681Srpaulo for (sh = base; sh < &base[SAPHASHSIZ]; sh++) 127281681Srpaulo for (sap = sh->forw; sap != (struct sap_entry *)sh; sap = sap->forw) { 128281681Srpaulo size = (char *)n - (char *)sap_msg; 129281681Srpaulo if (size > MAXPACKETSIZE - sizeof (struct sap_info)) { 130281681Srpaulo (*output)(sapsock, flags, dst, size); 131281681Srpaulo TRACE_SAP_OUTPUT(ifp, dst, size); 132281681Srpaulo n = sap_msg->sap; 133281681Srpaulo } 134281681Srpaulo 135281681Srpaulo /* 136281681Srpaulo * Check for the servicetype except if the ServType is 137281681Srpaulo * a wildcard (0xFFFF). 138281681Srpaulo */ 139281681Srpaulo if ((ServType != SAP_WILDCARD) && 140281681Srpaulo (ServType != sap->sap.ServType)) 141281681Srpaulo continue; 142281681Srpaulo 143281681Srpaulo /* 144281681Srpaulo * This should do rule one and two of the split horizon 145281681Srpaulo * algorithm. 146281681Srpaulo */ 147281681Srpaulo if (sap->ifp == ifp) 148281681Srpaulo continue; 149281681Srpaulo 150281681Srpaulo /* 151281681Srpaulo * Rule 2. 152281681Srpaulo * Look if we have clones (different routes to the same 153281681Srpaulo * place with exactly the same cost). 154281681Srpaulo * 155281681Srpaulo * We should not publish on any of the clone interfaces. 156281681Srpaulo */ 157281681Srpaulo csap = sap->clone; 158281681Srpaulo while (csap) { 159281681Srpaulo if (csap->ifp == ifp) 160281681Srpaulo continue; 161281681Srpaulo csap = csap->clone; 162281681Srpaulo } 163281681Srpaulo 164281681Srpaulo /* 165281681Srpaulo * Don't advertise services with more than 15 hops. It 166281681Srpaulo * will be confused with a service that has gone down. 167281681Srpaulo */ 168281681Srpaulo if (ntohs(sap->sap.hops) == (HOPCNT_INFINITY - 1)) 169281681Srpaulo continue; 170281681Srpaulo metric = min(ntohs(sap->sap.hops) + 1, HOPCNT_INFINITY); 171281681Srpaulo 172281681Srpaulo *n = sap->sap; 173281681Srpaulo n->hops = htons(metric); 174281681Srpaulo n++; 175281681Srpaulo } 176281681Srpaulo if (n != sap_msg->sap) { 177281681Srpaulo size = (char *)n - (char *)sap_msg; 178281681Srpaulo (*output)(sapsock, flags, dst, size); 179281681Srpaulo TRACE_SAP_OUTPUT(ifp, dst, size); 180281681Srpaulo } 181281681Srpaulo} 182281681Srpaulo 183281681Srpaulo