sap_output.c revision 19948
1260684Skaiw/* 2260684Skaiw * Copyright (c) 1995 John Hay. All rights reserved. 3260684Skaiw * 4260684Skaiw * Redistribution and use in source and binary forms, with or without 5260684Skaiw * modification, are permitted provided that the following conditions 6260684Skaiw * are met: 7260684Skaiw * 1. Redistributions of source code must retain the above copyright 8260684Skaiw * notice, this list of conditions and the following disclaimer. 9260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright 10260684Skaiw * notice, this list of conditions and the following disclaimer in the 11260684Skaiw * documentation and/or other materials provided with the distribution. 12260684Skaiw * 3. All advertising materials mentioning features or use of this software 13260684Skaiw * must display the following acknowledgement: 14260684Skaiw * This product includes software developed by John Hay. 15260684Skaiw * 4. Neither the name of the author nor the names of any co-contributors 16260684Skaiw * may be used to endorse or promote products derived from this software 17260684Skaiw * without specific prior written permission. 18260684Skaiw * 19260684Skaiw * THIS SOFTWARE IS PROVIDED BY John Hay AND CONTRIBUTORS ``AS IS'' AND 20260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22260684Skaiw * ARE DISCLAIMED. IN NO EVENT SHALL John Hay OR CONTRIBUTORS BE LIABLE 23260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29260684Skaiw * SUCH DAMAGE. 30260684Skaiw * 31260684Skaiw * $Id: sap_output.c,v 1.4 1996/04/13 15:13:24 jhay Exp $ 32260684Skaiw */ 33260684Skaiw 34260684Skaiw/* 35260684Skaiw * Routing Table Management Daemon 36260684Skaiw */ 37260684Skaiw#include <unistd.h> 38260684Skaiw#include "defs.h" 39260684Skaiw 40276371Semaste/* 41260684Skaiw * Apply the function "f" to all non-passive 42260684Skaiw * interfaces. If the interface supports the 43260684Skaiw * use of broadcasting use it, otherwise address 44260684Skaiw * the output to the known router. 45260684Skaiw */ 46260684Skaiwvoid 47260684Skaiwsap_supply_toall(void) 48260684Skaiw{ 49260684Skaiw register struct interface *ifp; 50260684Skaiw struct sockaddr dst; 51260684Skaiw register struct sockaddr_ipx *ipx_dst; 52260684Skaiw register int flags; 53260684Skaiw extern struct interface *ifnet; 54260684Skaiw 55260684Skaiw ipx_dst = (struct sockaddr_ipx *)&dst; 56260684Skaiw 57260684Skaiw for (ifp = ifnet; ifp; ifp = ifp->int_next) { 58260684Skaiw if (ifp->int_flags & IFF_PASSIVE) 59260684Skaiw continue; 60260684Skaiw 61260684Skaiw dst = ifp->int_flags & IFF_BROADCAST ? ifp->int_broadaddr : 62260684Skaiw ifp->int_flags & IFF_POINTOPOINT ? ifp->int_dstaddr : 63260684Skaiw ifp->int_addr; 64260684Skaiw 65260684Skaiw ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP); 66260684Skaiw 67260684Skaiw flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; 68260684Skaiw sap_supply(&dst, flags, ifp, SAP_WILDCARD); 69260684Skaiw } 70260684Skaiw} 71260684Skaiw 72260684Skaiwvoid 73260684Skaiwsapsndmsg(dst, flags, ifp) 74260684Skaiw struct sockaddr *dst; 75260684Skaiw int flags; 76260684Skaiw struct interface *ifp; 77260684Skaiw{ 78260684Skaiw struct sockaddr t_dst; 79260684Skaiw struct sockaddr_ipx *ipx_dst; 80260684Skaiw 81260684Skaiw t_dst = *dst; 82276371Semaste ipx_dst = (struct sockaddr_ipx *)&t_dst; 83260684Skaiw 84260684Skaiw if (ipx_dst->sipx_addr.x_port == 0) 85276371Semaste ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP); 86276371Semaste 87260684Skaiw (*afswitch[dst->sa_family].af_output) 88276371Semaste (sapsock, flags, &t_dst, 89260684Skaiw sizeof (struct sap_packet) + sizeof(u_short)); 90260684Skaiw TRACE_SAP_OUTPUT(ifp, &t_dst, 91260684Skaiw sizeof (struct sap_packet) + sizeof(u_short)); 92260684Skaiw} 93260684Skaiw 94260684Skaiw/* 95260684Skaiw * Supply dst with the contents of the SAP tables. If the ServType == 96260684Skaiw * SAP_WILDCARD (0xFFFF) supply the whole table, otherwise only the 97260684Skaiw * services that are of ServType. If this won't fit in one packet, chop 98260684Skaiw * it up into several. 99260684Skaiw * 100260684Skaiw * This must be done using the split horizon algorithm. 101260684Skaiw * 1. Don't send SAP info to the interface from where it was received. 102260684Skaiw * 2. If a service is received from more than one interface and the cost is 103260684Skaiw * the same, don't publish it on either interface. I am calling this 104260684Skaiw * clones. 105260684Skaiw */ 106260684Skaiwvoid 107260684Skaiwsap_supply(dst, flags, ifp, ServType) 108260684Skaiw struct sockaddr *dst; 109260684Skaiw int flags; 110 struct interface *ifp; 111 int ServType; 112{ 113 register struct sap_entry *sap; 114 register struct sap_entry *csap; /* Clone route */ 115 register struct sap_hash *sh; 116 register struct sap_info *n = sap_msg->sap; 117 struct sap_hash *base = sap_head; 118 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) dst; 119 af_output_t *output = afswitch[dst->sa_family].af_output; 120 int size, metric; 121 int delay = 0; 122 123 if (sipx->sipx_port == 0) 124 sipx->sipx_port = htons(IPXPORT_SAP); 125 126 sap_msg->sap_cmd = ntohs(SAP_RESP); 127 128 for (sh = base; sh < &base[SAPHASHSIZ]; sh++) 129 for (sap = sh->forw; sap != (struct sap_entry *)sh; sap = sap->forw) { 130 size = (char *)n - (char *)sap_msg; 131 if (size >= ((MAXSAPENTRIES * sizeof (struct sap_info)) + 132 sizeof (sap_msg->sap_cmd))) { 133 (*output)(sapsock, flags, dst, size); 134 TRACE_SAP_OUTPUT(ifp, dst, size); 135 n = sap_msg->sap; 136 delay++; 137 if(delay == 2) { 138 usleep(20000); 139 delay = 0; 140 } 141 } 142 143 /* 144 * Check for the servicetype except if the ServType is 145 * a wildcard (0xFFFF). 146 */ 147 if ((ServType != SAP_WILDCARD) && 148 (ServType != sap->sap.ServType)) 149 continue; 150 151 /* 152 * This should do rule one and two of the split horizon 153 * algorithm. 154 */ 155 if (sap->ifp == ifp) 156 continue; 157 158 /* 159 * Rule 2. 160 * Look if we have clones (different routes to the same 161 * place with exactly the same cost). 162 * 163 * We should not publish on any of the clone interfaces. 164 */ 165 csap = sap->clone; 166 while (csap) { 167 if (csap->ifp == ifp) 168 goto next; 169 csap = csap->clone; 170 } 171 172 /* 173 * Don't advertise services with more than 15 hops. It 174 * will be confused with a service that has gone down. 175 */ 176 if (ntohs(sap->sap.hops) == (HOPCNT_INFINITY - 1)) 177 continue; 178 metric = min(ntohs(sap->sap.hops) + 1, HOPCNT_INFINITY); 179 180 *n = sap->sap; 181 n->hops = htons(metric); 182 n++; 183next: 184 } 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); 189 } 190} 191 192