Kernel part of bluetooth stack ported by Dmitry Komissaroff. Very much work
[dragonfly.git] / usr.sbin / IPXrouted / sap_input.c
blob787bc343eb8aec65672a796c98ca3099915c5b32
1 /*
2 * Copyright (c) 1995 John Hay. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by John Hay.
15 * 4. Neither the name of the author nor the names of any co-contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY John Hay AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL John Hay OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
31 * $FreeBSD: src/usr.sbin/IPXrouted/sap_input.c,v 1.7 1999/08/28 01:15:04 peter Exp $
32 * $DragonFly: src/usr.sbin/IPXrouted/sap_input.c,v 1.3 2004/03/11 09:38:59 hmp Exp $
36 * IPX Routing Table Management Daemon
38 #include "defs.h"
40 int dognreply = 1;
43 * Process a newly received packet.
45 void
46 sap_input(struct sockaddr *from, int size)
48 int newsize;
49 int sapchanged = 0;
50 struct sap_entry *sap;
51 struct sap_info *n;
52 struct interface *ifp = 0;
53 struct afswitch *afp;
54 struct sockaddr_ipx *ipxp;
56 ifp = if_ifwithnet(from);
57 ipxp = (struct sockaddr_ipx *)from;
58 if (ifp == 0) {
59 if(ftrace) {
60 fprintf(ftrace, "Received bogus packet from %s\n",
61 ipxdp_ntoa(&ipxp->sipx_addr));
63 return;
66 if (ftrace)
67 dumpsappacket(ftrace, "received", from, (char *)sap_msg , size);
69 if (from->sa_family >= AF_MAX)
70 return;
71 afp = &afswitch[from->sa_family];
73 size -= sizeof (u_short) /* command */;
74 n = sap_msg->sap;
76 switch (ntohs(sap_msg->sap_cmd)) {
78 case SAP_REQ_NEAR:
79 if (ftrace)
80 fprintf(ftrace, "Received a sap REQ_NEAR packet.\n");
81 if (!dognreply)
82 return;
83 sap = sap_nearestserver(n->ServType, ifp);
84 if (sap == NULL)
85 return;
86 sap_msg->sap_cmd = htons(SAP_RESP_NEAR);
87 *n = sap->sap;
88 n->hops = htons(ntohs(n->hops) + 1);
89 if (ntohs(n->hops) >= HOPCNT_INFINITY)
90 return;
92 newsize = sizeof(struct sap_info) + sizeof(struct sap_packet);
93 (*afp->af_output)(sapsock, 0, from, newsize);
94 if (ftrace) {
95 fprintf(ftrace, "sap_nearestserver %X %s returned:\n",
96 ntohs(n->ServType),
97 ifp->int_name);
98 fprintf(ftrace, " service %04X %-20.20s "
99 "addr %s.%04X metric %d\n",
100 ntohs(sap->sap.ServType),
101 sap->sap.ServName,
102 ipxdp_ntoa(&sap->sap.ipx),
103 ntohs(sap->sap.ipx.x_port),
104 ntohs(sap->sap.hops));
106 return;
108 case SAP_REQ:
109 if (ftrace)
110 fprintf(ftrace, "Received a sap REQ packet.\n");
112 sap_supply(from, 0, ifp, n->ServType, 0);
113 return;
115 case SAP_RESP_NEAR:
116 /* XXX We do nothing here, for the moment.
117 * Maybe we should check if the service is in our table?
120 if (ftrace)
121 fprintf(ftrace, "Received a sap RESP_NEAR packet.\n");
123 return;
125 case SAP_RESP:
126 if (ftrace)
127 fprintf(ftrace, "Received a sap RESP packet.\n");
129 (*afp->af_canon)(from);
131 for (; size > 0; size -= sizeof (struct sap_info), n++) {
132 if (size < sizeof (struct netinfo))
133 break;
135 * The idea here is that if the hop count is more
136 * than INFINITY it is bogus and should be discarded.
137 * If it is equal to INFINITY it is a message to say
138 * that a service went down. If we don't allready
139 * have it in our tables discard it. Otherwise
140 * update our table and set the timer to EXPIRE_TIME
141 * so that it is removed next time we go through the
142 * tables.
144 if (ntohs(n->hops) > HOPCNT_INFINITY)
145 continue;
146 sap = sap_lookup(n->ServType, n->ServName);
147 if (sap == 0) {
148 if (ntohs(n->hops) == HOPCNT_INFINITY)
149 continue;
150 sap_add(n, from);
151 sapchanged = 1;
152 continue;
156 * A clone is a different route to the same service
157 * with exactly the same cost (metric).
158 * They must all be recorded because those interfaces
159 * must be handled in the same way as the first route
160 * to that service. ie When using the split horizon
161 * algorithm we must look at these interfaces also.
163 * Update if from gateway and different,
164 * from anywhere and less hops or
165 * getting stale and equivalent.
167 if (((ifp != sap->ifp) ||
168 !equal(&sap->source, from)) &&
169 (n->hops == sap->sap.hops) &&
170 (ntohs(n->hops) != HOPCNT_INFINITY)) {
171 struct sap_entry *tsap = sap->clone;
173 while (tsap) {
174 if ((ifp == tsap->ifp) &&
175 equal(&tsap->source, from)) {
176 tsap->timer = 0;
177 break;
179 tsap = tsap->clone;
181 if (tsap == NULL) {
182 sap_add_clone(sap, n, from);
184 continue;
186 if ((ifp == sap->ifp) &&
187 equal(&sap->source, from) &&
188 (ntohs(n->hops) == ntohs(sap->sap.hops)))
189 sap->timer = 0;
190 else if (((ifp == sap->ifp) &&
191 equal(&sap->source, from) &&
192 (n->hops != sap->sap.hops)) ||
193 (ntohs(n->hops) < ntohs(sap->sap.hops)) ||
194 (sap->timer > (EXPIRE_TIME*2/3) &&
195 ntohs(sap->sap.hops) == ntohs(n->hops) &&
196 ntohs(n->hops) != HOPCNT_INFINITY)) {
197 sap_change(sap, n, from);
198 sapchanged = 1;
201 if (sapchanged) {
202 struct sap_entry *sap;
203 struct sap_hash *sh;
204 sap_supply_toall(1);
206 for (sh = sap_head; sh < &sap_head[SAPHASHSIZ]; sh++)
207 for (sap = sh->forw;
208 sap != (struct sap_entry *)sh;
209 sap = sap->forw)
210 sap->state &= ~RTS_CHANGED;
212 return;