af.c revision 133248
1109998Smarkm/*
2160814Ssimon * Copyright (c) 1985, 1993
3160814Ssimon *	The Regents of the University of California.  All rights reserved.
4160814Ssimon *
5109998Smarkm * Copyright (c) 1995 John Hay.  All rights reserved.
6109998Smarkm *
7109998Smarkm * This file includes significant work done at Cornell University by
8109998Smarkm * Bill Nesheim.  That work included by permission.
9109998Smarkm *
10109998Smarkm * Redistribution and use in source and binary forms, with or without
11109998Smarkm * modification, are permitted provided that the following conditions
12109998Smarkm * are met:
13280304Sjkim * 1. Redistributions of source code must retain the above copyright
14109998Smarkm *    notice, this list of conditions and the following disclaimer.
15109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
16109998Smarkm *    notice, this list of conditions and the following disclaimer in the
17109998Smarkm *    documentation and/or other materials provided with the distribution.
18109998Smarkm * 4. Neither the name of the University nor the names of its contributors
19109998Smarkm *    may be used to endorse or promote products derived from this software
20109998Smarkm *    without specific prior written permission.
21109998Smarkm *
22109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23109998Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25109998Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26109998Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27109998Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28109998Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30109998Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31109998Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32109998Smarkm * SUCH DAMAGE.
33109998Smarkm *
34109998Smarkm * $FreeBSD: head/usr.sbin/IPXrouted/af.c 133248 2004-08-07 04:19:37Z imp $
35109998Smarkm */
36109998Smarkm
37109998Smarkm#ifndef lint
38109998Smarkmstatic const char sccsid[] = "@(#)af.c	8.1 (Berkeley) 6/5/93";
39109998Smarkm#endif /* not lint */
40109998Smarkm
41109998Smarkm#include "defs.h"
42109998Smarkm
43109998Smarkm/*
44109998Smarkm * Address family support routines
45109998Smarkm */
46109998Smarkmaf_hash_t	null_hash;
47109998Smarkmaf_netmatch_t	null_netmatch;
48109998Smarkmaf_output_t	null_output;
49109998Smarkmaf_portmatch_t	null_portmatch;
50109998Smarkmaf_portcheck_t	null_portcheck;
51109998Smarkmaf_checkhost_t	null_checkhost;
52109998Smarkmaf_ishost_t	null_ishost;
53109998Smarkmaf_canon_t	null_canon;
54109998Smarkm
55109998Smarkmvoid	ipxnet_hash(struct sockaddr_ipx *, struct afhash *);
56109998Smarkmint	ipxnet_netmatch(struct sockaddr_ipx *, struct sockaddr_ipx *);
57109998Smarkmvoid	ipxnet_output(int, int, struct sockaddr_ipx *, int);
58160814Ssimonint	ipxnet_portmatch(struct sockaddr_ipx *);
59160814Ssimonint	ipxnet_checkhost(struct sockaddr_ipx *);
60160814Ssimonint	ipxnet_ishost(struct sockaddr_ipx *);
61160814Ssimonvoid	ipxnet_canon(struct sockaddr_ipx *);
62160814Ssimon
63109998Smarkm#define NIL \
64109998Smarkm	{ null_hash,		null_netmatch,		null_output, \
65109998Smarkm	  null_portmatch,	null_portcheck,		null_checkhost, \
66238405Sjkim	  null_ishost,		null_canon }
67280304Sjkim#define	IPXNET \
68238405Sjkim	{ (af_hash_t *)ipxnet_hash, \
69238405Sjkim	  (af_netmatch_t *)ipxnet_netmatch, \
70109998Smarkm	  (af_output_t *)ipxnet_output, \
71109998Smarkm	  (af_portmatch_t *)ipxnet_portmatch, \
72109998Smarkm	  (af_portcheck_t *)ipxnet_portmatch, \
73280304Sjkim	  (af_checkhost_t *)ipxnet_checkhost, \
74280304Sjkim	  (af_ishost_t *)ipxnet_ishost, \
75280304Sjkim	  (af_canon_t *)ipxnet_canon }
76280304Sjkim
77280304Sjkimstruct afswitch afswitch[AF_MAX] =
78280304Sjkim	{ NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL,
79280304Sjkim	  NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL,
80280304Sjkim	  NIL, NIL, NIL, IPXNET, NIL, NIL };
81280304Sjkim
82280304Sjkimstruct sockaddr_ipx ipxnet_default = { sizeof(struct sockaddr_ipx), AF_IPX };
83280304Sjkim
84280304Sjkimunion ipx_net ipx_anynet;
85280304Sjkimunion ipx_net ipx_zeronet;
86280304Sjkim
87280304Sjkimvoid
88280304Sjkimipxnet_hash(sipx, hp)
89280304Sjkim	register struct sockaddr_ipx *sipx;
90280304Sjkim	struct afhash *hp;
91280304Sjkim{
92280304Sjkim	long hash;
93280304Sjkim#if 0
94280304Sjkim	u_short *s = sipx->sipx_addr.x_host.s_host;
95280304Sjkim#endif
96280304Sjkim	u_char *c;
97280304Sjkim
98280304Sjkim	c = sipx->sipx_addr.x_net.c_net;
99280304Sjkim
100280304Sjkim#define IMVAL	33
101280304Sjkim	hash = 0;
102280304Sjkim	hash = hash * IMVAL + *c++;
103280304Sjkim	hash = hash * IMVAL + *c++;
104280304Sjkim	hash = hash * IMVAL + *c++;
105280304Sjkim	hash = hash * IMVAL + *c++;
106280304Sjkim#undef IMVAL
107280304Sjkim
108280304Sjkim	hp->afh_nethash = hash;
109280304Sjkim	hp->afh_nethash ^= (hash >> 8);
110280304Sjkim	hp->afh_nethash ^= (hash >> 16);
111280304Sjkim	hp->afh_nethash ^= (hash >> 24);
112280304Sjkim
113109998Smarkm#if 0
114273149Sjkim	hash = 0;
115280304Sjkim	hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s;
116280304Sjkim	hp->afh_hosthash = hash;
117273149Sjkim#endif
118273149Sjkim}
119280304Sjkim
120280304Sjkimint
121109998Smarkmipxnet_netmatch(sxn1, sxn2)
122109998Smarkm	struct sockaddr_ipx *sxn1, *sxn2;
123280304Sjkim{
124280304Sjkim	return (ipx_neteq(sxn1->sipx_addr, sxn2->sipx_addr));
125109998Smarkm}
126280304Sjkim
127280304Sjkim/*
128280304Sjkim * Verify the message is from the right port.
129280304Sjkim */
130280304Sjkimint
131109998Smarkmipxnet_portmatch(sipx)
132109998Smarkm	register struct sockaddr_ipx *sipx;
133280304Sjkim{
134280304Sjkim
135280304Sjkim	return (ntohs(sipx->sipx_addr.x_port) == IPXPORT_RIP );
136280304Sjkim}
137280304Sjkim
138280304Sjkim
139280304Sjkim/*
140280304Sjkim * ipx output routine.
141280304Sjkim */
142280304Sjkim#ifdef DEBUG
143280304Sjkimint do_output = 0;
144109998Smarkm#endif
145109998Smarkmvoid
146280304Sjkimipxnet_output(s, flags, sipx, size)
147280304Sjkim	int s;
148280304Sjkim	int flags;
149280304Sjkim	struct sockaddr_ipx *sipx;
150280304Sjkim	int size;
151280304Sjkim{
152280304Sjkim	struct sockaddr_ipx dst;
153280304Sjkim
154280304Sjkim	dst = *sipx;
155280304Sjkim	sipx = &dst;
156280304Sjkim	if (sipx->sipx_addr.x_port == 0)
157109998Smarkm		sipx->sipx_addr.x_port = htons(IPXPORT_RIP);
158109998Smarkm#ifdef DEBUG
159280304Sjkim	if(do_output || ntohs(msg->rip_cmd) == RIPCMD_REQUEST)
160280304Sjkim#endif
161280304Sjkim	/*
162280304Sjkim	 * Kludge to allow us to get routes out to machines that
163280304Sjkim	 * don't know their addresses yet; send to that address on
164280304Sjkim	 * ALL connected nets
165280304Sjkim	 */
166280304Sjkim	 if (ipx_neteqnn(sipx->sipx_addr.x_net, ipx_zeronet)) {
167280304Sjkim	 	extern  struct interface *ifnet;
168109998Smarkm	 	register struct interface *ifp;
169280304Sjkim
170280304Sjkim		for (ifp = ifnet; ifp; ifp = ifp->int_next) {
171109998Smarkm			sipx->sipx_addr.x_net =
172280304Sjkim				satoipx_addr(ifp->int_addr).x_net;
173280304Sjkim			(void) sendto(s, msg, size, flags,
174280304Sjkim			    (struct sockaddr *)sipx, sizeof (*sipx));
175280304Sjkim		}
176280304Sjkim		return;
177280304Sjkim	}
178280304Sjkim
179280304Sjkim	(void) sendto(s, msg, size, flags,
180280304Sjkim	    (struct sockaddr *)sipx, sizeof (*sipx));
181280304Sjkim}
182280304Sjkim
183280304Sjkim/*
184109998Smarkm * Return 1 if we want this route.
185280304Sjkim * We use this to disallow route net G entries for one for multiple
186109998Smarkm * point to point links.
187109998Smarkm */
188280304Sjkimint
189280304Sjkimipxnet_checkhost(sipx)
190280304Sjkim	struct sockaddr_ipx *sipx;
191280304Sjkim{
192280304Sjkim	register struct interface *ifp = if_ifwithnet((struct sockaddr *)sipx);
193280304Sjkim	/*
194109998Smarkm	 * We want this route if there is no more than one
195280304Sjkim	 * point to point interface with this network.
196280304Sjkim	 */
197280304Sjkim	if (ifp == 0 || (ifp->int_flags & IFF_POINTOPOINT)==0) return (1);
198280304Sjkim	return (ifp->int_sq.n == ifp->int_sq.p);
199280304Sjkim}
200280304Sjkim
201280304Sjkim/*
202109998Smarkm * Return 1 if the address is
203280304Sjkim * for a host, 0 for a network.
204280304Sjkim */
205280304Sjkimint
206280304Sjkimipxnet_ishost(sipx)
207280304Sjkimstruct sockaddr_ipx *sipx;
208280304Sjkim{
209280304Sjkim	register u_short *s = sipx->sipx_addr.x_host.s_host;
210280304Sjkim
211160814Ssimon	if ((s[0]==0x0000) && (s[1]==0x0000) && (s[2]==0x0000))
212280304Sjkim		return (0);
213280304Sjkim	if ((s[0]==0xffff) && (s[1]==0xffff) && (s[2]==0xffff))
214280304Sjkim		return (0);
215280304Sjkim
216280304Sjkim	return (1);
217160814Ssimon}
218280304Sjkim
219280304Sjkimvoid
220280304Sjkimipxnet_canon(sipx)
221280304Sjkim	struct sockaddr_ipx *sipx;
222280304Sjkim{
223280304Sjkim
224280304Sjkim	sipx->sipx_addr.x_port = 0;
225280304Sjkim}
226280304Sjkim
227280304Sjkimvoid
228280304Sjkimnull_hash(addr, hp)
229280304Sjkim	struct sockaddr *addr;
230160814Ssimon	struct afhash *hp;
231280304Sjkim{
232280304Sjkim
233280304Sjkim	hp->afh_nethash = hp->afh_hosthash = 0;
234280304Sjkim}
235160814Ssimon
236280304Sjkimint
237160814Ssimonnull_netmatch(a1, a2)
238280304Sjkim	struct sockaddr *a1, *a2;
239280304Sjkim{
240280304Sjkim
241280304Sjkim	return (0);
242280304Sjkim}
243280304Sjkim
244160814Ssimonvoid
245160814Ssimonnull_output(s, f, a1, n)
246280304Sjkim	int s;
247280304Sjkim	int f;
248280304Sjkim	struct sockaddr *a1;
249280304Sjkim	int n;
250280304Sjkim{
251280304Sjkim
252160814Ssimon	;
253280304Sjkim}
254280304Sjkim
255280304Sjkimint
256280304Sjkimnull_portmatch(a1)
257280304Sjkim	struct sockaddr *a1;
258280304Sjkim{
259280304Sjkim
260160814Ssimon	return (0);
261280304Sjkim}
262280304Sjkim
263109998Smarkmint
264280304Sjkimnull_portcheck(a1)
265280304Sjkim	struct sockaddr *a1;
266280304Sjkim{
267280304Sjkim
268280304Sjkim	return (0);
269280304Sjkim}
270280304Sjkim
271109998Smarkmint
272280304Sjkimnull_ishost(a1)
273280304Sjkim	struct sockaddr *a1;
274109998Smarkm{
275280304Sjkim
276280304Sjkim	return (0);
277280304Sjkim}
278280304Sjkim
279280304Sjkimint
280280304Sjkimnull_checkhost(a1)
281280304Sjkim	struct sockaddr *a1;
282109998Smarkm{
283280304Sjkim
284280304Sjkim	return (0);
285109998Smarkm}
286280304Sjkim
287280304Sjkimvoid
288280304Sjkimnull_canon(a1)
289280304Sjkim	struct sockaddr *a1;
290280304Sjkim{
291280304Sjkim
292280304Sjkim	;
293109998Smarkm}
294280304Sjkim
295280304Sjkim