sap_input.c revision 11820
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 * 3111820Sjulian * $Id: sap_input.c,v 1.6 1995/10/11 18:57:27 jhay Exp $ 3211820Sjulian */ 3311820Sjulian 3411820Sjulian/* 3511820Sjulian * IPX Routing Table Management Daemon 3611820Sjulian */ 3711820Sjulian#include "defs.h" 3811820Sjulian 3911820Sjulian 4011820Sjulian/* 4111820Sjulian * Process a newly received packet. 4211820Sjulian */ 4311820Sjulianvoid 4411820Sjuliansap_input(from, size) 4511820Sjulian struct sockaddr *from; 4611820Sjulian int size; 4711820Sjulian{ 4811820Sjulian struct sap_entry *sap; 4911820Sjulian struct sap_info *n; 5011820Sjulian struct interface *ifp = 0; 5111820Sjulian int newsize; 5211820Sjulian struct afswitch *afp; 5311820Sjulian struct sockaddr_ipx *ipxp; 5411820Sjulian 5511820Sjulian ifp = if_ifwithnet(from); 5611820Sjulian ipxp = (struct sockaddr_ipx *)from; 5711820Sjulian if (ifp == 0) { 5811820Sjulian if(ftrace) { 5911820Sjulian fprintf(ftrace, "Received bogus packet from %s\n", 6011820Sjulian ipxdp_ntoa(&ipxp->sipx_addr)); 6111820Sjulian } 6211820Sjulian return; 6311820Sjulian } 6411820Sjulian 6511820Sjulian if (ftrace) 6611820Sjulian dumpsappacket(ftrace, "received", from, (char *)sap_msg , size); 6711820Sjulian 6811820Sjulian if (from->sa_family >= AF_MAX) 6911820Sjulian return; 7011820Sjulian afp = &afswitch[from->sa_family]; 7111820Sjulian 7211820Sjulian size -= sizeof (u_short) /* command */; 7311820Sjulian n = sap_msg->sap; 7411820Sjulian 7511820Sjulian switch (ntohs(sap_msg->sap_cmd)) { 7611820Sjulian 7711820Sjulian case SAP_REQ_NEAR: 7811820Sjulian if (ftrace) 7911820Sjulian fprintf(ftrace, "Received a sap REQ_NEAR packet.\n"); 8011820Sjulian sap = sap_nearestserver(n->ServType, ifp); 8111820Sjulian if (sap == NULL) 8211820Sjulian return; 8311820Sjulian sap_msg->sap_cmd = htons(SAP_RESP_NEAR); 8411820Sjulian *n = sap->sap; 8511820Sjulian n->hops = htons(ntohs(n->hops) + 1); 8611820Sjulian if (ntohs(n->hops) >= HOPCNT_INFINITY) 8711820Sjulian return; 8811820Sjulian 8911820Sjulian newsize = sizeof(struct sap_info) + sizeof(struct sap_packet); 9011820Sjulian (*afp->af_output)(sapsock, 0, from, newsize); 9111820Sjulian if (ftrace) { 9211820Sjulian fprintf(ftrace, "sap_nearestserver %X %s returned:\n", 9311820Sjulian ntohs(n->ServType), 9411820Sjulian ifp->int_name); 9511820Sjulian fprintf(ftrace, " service %04X %-20.20s " 9611820Sjulian "addr %s.%04X metric %d\n", 9711820Sjulian ntohs(sap->sap.ServType), 9811820Sjulian sap->sap.ServName, 9911820Sjulian ipxdp_ntoa(&sap->sap.ipx), 10011820Sjulian ntohs(sap->sap.ipx.x_port), 10111820Sjulian ntohs(sap->sap.hops)); 10211820Sjulian } 10311820Sjulian return; 10411820Sjulian 10511820Sjulian case SAP_REQ: 10611820Sjulian if (ftrace) 10711820Sjulian fprintf(ftrace, "Received a sap REQ packet.\n"); 10811820Sjulian 10911820Sjulian sap_supply(from, 0, ifp, n->ServType); 11011820Sjulian return; 11111820Sjulian 11211820Sjulian case SAP_RESP_NEAR: 11311820Sjulian /* XXX We do nothing here, for the moment. 11411820Sjulian * Maybe we should check if the service is in our table? 11511820Sjulian * 11611820Sjulian */ 11711820Sjulian if (ftrace) 11811820Sjulian fprintf(ftrace, "Received a sap RESP_NEAR packet.\n"); 11911820Sjulian 12011820Sjulian return; 12111820Sjulian 12211820Sjulian case SAP_RESP: 12311820Sjulian if (ftrace) 12411820Sjulian fprintf(ftrace, "Received a sap RESP packet.\n"); 12511820Sjulian 12611820Sjulian (*afp->af_canon)(from); 12711820Sjulian 12811820Sjulian for (; size > 0; size -= sizeof (struct sap_info), n++) { 12911820Sjulian if (size < sizeof (struct netinfo)) 13011820Sjulian break; 13111820Sjulian sap = sap_lookup(n->ServType, n->ServName); 13211820Sjulian if (sap == 0) { 13311820Sjulian sap_add(n, from); 13411820Sjulian continue; 13511820Sjulian } 13611820Sjulian 13711820Sjulian /* 13811820Sjulian * A clone is a different route to the same service 13911820Sjulian * with exactly the same cost (metric). 14011820Sjulian * They must all be recorded because those interfaces 14111820Sjulian * must be handled in the same way as the first route 14211820Sjulian * to that service. ie When using the split horizon 14311820Sjulian * algorithm we must look at these interfaces also. 14411820Sjulian * 14511820Sjulian * Update if from gateway and different, 14611820Sjulian * from anywhere and less hops or 14711820Sjulian * getting stale and equivalent. 14811820Sjulian * 14911820Sjulian * XXX I don't think this is quite right yet. 15011820Sjulian */ 15111820Sjulian if (((ifp != sap->ifp) || 15211820Sjulian !equal(&sap->source, from)) && 15311820Sjulian (n->hops == sap->sap.hops) && 15411820Sjulian (ntohs(n->hops) != HOPCNT_INFINITY)) { 15511820Sjulian register struct sap_entry *tsap = sap->clone; 15611820Sjulian 15711820Sjulian while (tsap) { 15811820Sjulian if ((ifp == tsap->ifp) && 15911820Sjulian equal(&tsap->source, from)) { 16011820Sjulian tsap->timer = 0; 16111820Sjulian break; 16211820Sjulian } 16311820Sjulian } 16411820Sjulian if (tsap == NULL) { 16511820Sjulian sap_add_clone(sap, n, from); 16611820Sjulian } 16711820Sjulian continue; 16811820Sjulian } 16911820Sjulian if (((ifp == sap->ifp) && 17011820Sjulian equal(&sap->source, from) && 17111820Sjulian (n->hops != sap->sap.hops)) || 17211820Sjulian (ntohs(n->hops) < ntohs(sap->sap.hops)) || 17311820Sjulian (sap->timer > (EXPIRE_TIME*2/3) && 17411820Sjulian ntohs(sap->sap.hops) == ntohs(n->hops))) { 17511820Sjulian sap_change(sap, n, from); 17611820Sjulian } 17711820Sjulian } 17811820Sjulian return; 17911820Sjulian } 18011820Sjulian} 181