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
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
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
43 * Process a newly received packet.
46 sap_input(struct sockaddr
*from
, int size
)
50 struct sap_entry
*sap
;
52 struct interface
*ifp
= 0;
54 struct sockaddr_ipx
*ipxp
;
56 ifp
= if_ifwithnet(from
);
57 ipxp
= (struct sockaddr_ipx
*)from
;
60 fprintf(ftrace
, "Received bogus packet from %s\n",
61 ipxdp_ntoa(&ipxp
->sipx_addr
));
67 dumpsappacket(ftrace
, "received", from
, (char *)sap_msg
, size
);
69 if (from
->sa_family
>= AF_MAX
)
71 afp
= &afswitch
[from
->sa_family
];
73 size
-= sizeof (u_short
) /* command */;
76 switch (ntohs(sap_msg
->sap_cmd
)) {
80 fprintf(ftrace
, "Received a sap REQ_NEAR packet.\n");
83 sap
= sap_nearestserver(n
->ServType
, ifp
);
86 sap_msg
->sap_cmd
= htons(SAP_RESP_NEAR
);
88 n
->hops
= htons(ntohs(n
->hops
) + 1);
89 if (ntohs(n
->hops
) >= HOPCNT_INFINITY
)
92 newsize
= sizeof(struct sap_info
) + sizeof(struct sap_packet
);
93 (*afp
->af_output
)(sapsock
, 0, from
, newsize
);
95 fprintf(ftrace
, "sap_nearestserver %X %s returned:\n",
98 fprintf(ftrace
, " service %04X %-20.20s "
99 "addr %s.%04X metric %d\n",
100 ntohs(sap
->sap
.ServType
),
102 ipxdp_ntoa(&sap
->sap
.ipx
),
103 ntohs(sap
->sap
.ipx
.x_port
),
104 ntohs(sap
->sap
.hops
));
110 fprintf(ftrace
, "Received a sap REQ packet.\n");
112 sap_supply(from
, 0, ifp
, n
->ServType
, 0);
116 /* XXX We do nothing here, for the moment.
117 * Maybe we should check if the service is in our table?
121 fprintf(ftrace
, "Received a sap RESP_NEAR packet.\n");
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
))
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
144 if (ntohs(n
->hops
) > HOPCNT_INFINITY
)
146 sap
= sap_lookup(n
->ServType
, n
->ServName
);
148 if (ntohs(n
->hops
) == HOPCNT_INFINITY
)
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
;
174 if ((ifp
== tsap
->ifp
) &&
175 equal(&tsap
->source
, from
)) {
182 sap_add_clone(sap
, n
, from
);
186 if ((ifp
== sap
->ifp
) &&
187 equal(&sap
->source
, from
) &&
188 (ntohs(n
->hops
) == ntohs(sap
->sap
.hops
)))
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
);
202 struct sap_entry
*sap
;
206 for (sh
= sap_head
; sh
< &sap_head
[SAPHASHSIZ
]; sh
++)
208 sap
!= (struct sap_entry
*)sh
;
210 sap
->state
&= ~RTS_CHANGED
;