af.c revision 50479
111820Sjulian/*
211820Sjulian * Copyright (c) 1985, 1993
311820Sjulian *	The Regents of the University of California.  All rights reserved.
411820Sjulian *
511820Sjulian * Copyright (c) 1995 John Hay.  All rights reserved.
611820Sjulian *
711820Sjulian * This file includes significant work done at Cornell University by
811820Sjulian * Bill Nesheim.  That work included by permission.
911820Sjulian *
1011820Sjulian * Redistribution and use in source and binary forms, with or without
1111820Sjulian * modification, are permitted provided that the following conditions
1211820Sjulian * are met:
1311820Sjulian * 1. Redistributions of source code must retain the above copyright
1411820Sjulian *    notice, this list of conditions and the following disclaimer.
1511820Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1611820Sjulian *    notice, this list of conditions and the following disclaimer in the
1711820Sjulian *    documentation and/or other materials provided with the distribution.
1811820Sjulian * 3. All advertising materials mentioning features or use of this software
1911820Sjulian *    must display the following acknowledgement:
2011820Sjulian *	This product includes software developed by the University of
2111820Sjulian *	California, Berkeley and its contributors.
2211820Sjulian * 4. Neither the name of the University nor the names of its contributors
2311820Sjulian *    may be used to endorse or promote products derived from this software
2411820Sjulian *    without specific prior written permission.
2511820Sjulian *
2611820Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2711820Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2811820Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2911820Sjulian * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3011820Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3111820Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3211820Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3311820Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3411820Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3511820Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3611820Sjulian * SUCH DAMAGE.
3711820Sjulian *
3850479Speter * $FreeBSD: head/usr.sbin/IPXrouted/af.c 50479 1999-08-28 01:35:59Z peter $
3911820Sjulian */
4011820Sjulian
4111820Sjulian#ifndef lint
4211820Sjulianstatic char sccsid[] = "@(#)af.c	8.1 (Berkeley) 6/5/93";
4311820Sjulian#endif /* not lint */
4411820Sjulian
4511820Sjulian#include "defs.h"
4611820Sjulian
4711820Sjulian/*
4811820Sjulian * Address family support routines
4911820Sjulian */
5011820Sjulianaf_hash_t	null_hash;
5111820Sjulianaf_netmatch_t	null_netmatch;
5211820Sjulianaf_output_t	null_output;
5311820Sjulianaf_portmatch_t	null_portmatch;
5411820Sjulianaf_portcheck_t	null_portcheck;
5511820Sjulianaf_checkhost_t	null_checkhost;
5611820Sjulianaf_ishost_t	null_ishost;
5711820Sjulianaf_canon_t	null_canon;
5811820Sjulian
5911820Sjulianvoid	ipxnet_hash(struct sockaddr_ipx *, struct afhash *);
6011820Sjulianint	ipxnet_netmatch(struct sockaddr_ipx *, struct sockaddr_ipx *);
6111820Sjulianvoid	ipxnet_output(int, int, struct sockaddr_ipx *, int);
6211820Sjulianint	ipxnet_portmatch(struct sockaddr_ipx *);
6311820Sjulianint	ipxnet_checkhost(struct sockaddr_ipx *);
6411820Sjulianint	ipxnet_ishost(struct sockaddr_ipx *);
6511820Sjulianvoid	ipxnet_canon(struct sockaddr_ipx *);
6611820Sjulian
6711820Sjulian#define NIL \
6811820Sjulian	{ null_hash,		null_netmatch,		null_output, \
6911820Sjulian	  null_portmatch,	null_portcheck,		null_checkhost, \
7011820Sjulian	  null_ishost,		null_canon }
7111820Sjulian#define	IPXNET \
7211820Sjulian	{ (af_hash_t *)ipxnet_hash, \
7311820Sjulian	  (af_netmatch_t *)ipxnet_netmatch, \
7411820Sjulian	  (af_output_t *)ipxnet_output, \
7511820Sjulian	  (af_portmatch_t *)ipxnet_portmatch, \
7611820Sjulian	  (af_portcheck_t *)ipxnet_portmatch, \
7711820Sjulian	  (af_checkhost_t *)ipxnet_checkhost, \
7811820Sjulian	  (af_ishost_t *)ipxnet_ishost, \
7911820Sjulian	  (af_canon_t *)ipxnet_canon }
8011820Sjulian
8111820Sjulianstruct afswitch afswitch[AF_MAX] =
8211820Sjulian	{ NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL,
8311820Sjulian	  NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL,
8411820Sjulian	  NIL, NIL, NIL, IPXNET, NIL, NIL };
8511820Sjulian
8611820Sjulianstruct sockaddr_ipx ipxnet_default = { sizeof(struct sockaddr_ipx), AF_IPX };
8711820Sjulian
8811820Sjulianunion ipx_net ipx_anynet;
8911820Sjulianunion ipx_net ipx_zeronet;
9011820Sjulian
9111820Sjulianvoid
9211820Sjulianipxnet_hash(sipx, hp)
9311820Sjulian	register struct sockaddr_ipx *sipx;
9411820Sjulian	struct afhash *hp;
9511820Sjulian{
9627244Sjhay	long hash;
9727244Sjhay#if 0
9827244Sjhay	u_short *s = sipx->sipx_addr.x_host.s_host;
9927244Sjhay#endif
10027244Sjhay	u_char *c;
10111820Sjulian
10227244Sjhay	c = sipx->sipx_addr.x_net.c_net;
10327244Sjhay
10427244Sjhay#define IMVAL	33
10527244Sjhay	hash = 0;
10627244Sjhay	hash = hash * IMVAL + *c++;
10727244Sjhay	hash = hash * IMVAL + *c++;
10827244Sjhay	hash = hash * IMVAL + *c++;
10927244Sjhay	hash = hash * IMVAL + *c++;
11027244Sjhay#undef IMVAL
11127244Sjhay
11227244Sjhay	hp->afh_nethash = hash;
11327244Sjhay	hp->afh_nethash ^= (hash >> 8);
11427244Sjhay	hp->afh_nethash ^= (hash >> 16);
11527244Sjhay	hp->afh_nethash ^= (hash >> 24);
11627244Sjhay
11727244Sjhay#if 0
11827244Sjhay	hash = 0;
11911820Sjulian	hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s;
12011820Sjulian	hp->afh_hosthash = hash;
12127244Sjhay#endif
12211820Sjulian}
12311820Sjulian
12411820Sjulianint
12511820Sjulianipxnet_netmatch(sxn1, sxn2)
12611820Sjulian	struct sockaddr_ipx *sxn1, *sxn2;
12711820Sjulian{
12811820Sjulian	return (ipx_neteq(sxn1->sipx_addr, sxn2->sipx_addr));
12911820Sjulian}
13011820Sjulian
13111820Sjulian/*
13211820Sjulian * Verify the message is from the right port.
13311820Sjulian */
13411820Sjulianint
13511820Sjulianipxnet_portmatch(sipx)
13611820Sjulian	register struct sockaddr_ipx *sipx;
13711820Sjulian{
13811820Sjulian
13911820Sjulian	return (ntohs(sipx->sipx_addr.x_port) == IPXPORT_RIP );
14011820Sjulian}
14111820Sjulian
14211820Sjulian
14311820Sjulian/*
14411820Sjulian * ipx output routine.
14511820Sjulian */
14611820Sjulian#ifdef DEBUG
14711820Sjulianint do_output = 0;
14811820Sjulian#endif
14911820Sjulianvoid
15011820Sjulianipxnet_output(s, flags, sipx, size)
15111820Sjulian	int s;
15211820Sjulian	int flags;
15311820Sjulian	struct sockaddr_ipx *sipx;
15411820Sjulian	int size;
15511820Sjulian{
15611820Sjulian	struct sockaddr_ipx dst;
15711820Sjulian
15811820Sjulian	dst = *sipx;
15911820Sjulian	sipx = &dst;
16011820Sjulian	if (sipx->sipx_addr.x_port == 0)
16111820Sjulian		sipx->sipx_addr.x_port = htons(IPXPORT_RIP);
16211820Sjulian#ifdef DEBUG
16311820Sjulian	if(do_output || ntohs(msg->rip_cmd) == RIPCMD_REQUEST)
16411820Sjulian#endif
16511820Sjulian	/*
16611820Sjulian	 * Kludge to allow us to get routes out to machines that
16711820Sjulian	 * don't know their addresses yet; send to that address on
16811820Sjulian	 * ALL connected nets
16911820Sjulian	 */
17011820Sjulian	 if (ipx_neteqnn(sipx->sipx_addr.x_net, ipx_zeronet)) {
17111820Sjulian	 	extern  struct interface *ifnet;
17211820Sjulian	 	register struct interface *ifp;
17311820Sjulian
17411820Sjulian		for (ifp = ifnet; ifp; ifp = ifp->int_next) {
17511820Sjulian			sipx->sipx_addr.x_net =
17611820Sjulian				satoipx_addr(ifp->int_addr).x_net;
17711820Sjulian			(void) sendto(s, msg, size, flags,
17811820Sjulian			    (struct sockaddr *)sipx, sizeof (*sipx));
17911820Sjulian		}
18011820Sjulian		return;
18111820Sjulian	}
18211820Sjulian
18311820Sjulian	(void) sendto(s, msg, size, flags,
18411820Sjulian	    (struct sockaddr *)sipx, sizeof (*sipx));
18511820Sjulian}
18611820Sjulian
18711820Sjulian/*
18811820Sjulian * Return 1 if we want this route.
18911820Sjulian * We use this to disallow route net G entries for one for multiple
19011820Sjulian * point to point links.
19111820Sjulian */
19211820Sjulianint
19311820Sjulianipxnet_checkhost(sipx)
19411820Sjulian	struct sockaddr_ipx *sipx;
19511820Sjulian{
19611820Sjulian	register struct interface *ifp = if_ifwithnet((struct sockaddr *)sipx);
19711820Sjulian	/*
19811820Sjulian	 * We want this route if there is no more than one
19911820Sjulian	 * point to point interface with this network.
20011820Sjulian	 */
20111820Sjulian	if (ifp == 0 || (ifp->int_flags & IFF_POINTOPOINT)==0) return (1);
20211820Sjulian	return (ifp->int_sq.n == ifp->int_sq.p);
20311820Sjulian}
20411820Sjulian
20511820Sjulian/*
20611820Sjulian * Return 1 if the address is
20711820Sjulian * for a host, 0 for a network.
20811820Sjulian */
20911820Sjulianint
21011820Sjulianipxnet_ishost(sipx)
21111820Sjulianstruct sockaddr_ipx *sipx;
21211820Sjulian{
21311820Sjulian	register u_short *s = sipx->sipx_addr.x_host.s_host;
21411820Sjulian
21512620Sjulian	if ((s[0]==0x0000) && (s[1]==0x0000) && (s[2]==0x0000))
21612620Sjulian		return (0);
21711820Sjulian	if ((s[0]==0xffff) && (s[1]==0xffff) && (s[2]==0xffff))
21811820Sjulian		return (0);
21912620Sjulian
22012620Sjulian	return (1);
22111820Sjulian}
22211820Sjulian
22311820Sjulianvoid
22411820Sjulianipxnet_canon(sipx)
22511820Sjulian	struct sockaddr_ipx *sipx;
22611820Sjulian{
22711820Sjulian
22811820Sjulian	sipx->sipx_addr.x_port = 0;
22911820Sjulian}
23011820Sjulian
23111820Sjulianvoid
23211820Sjuliannull_hash(addr, hp)
23311820Sjulian	struct sockaddr *addr;
23411820Sjulian	struct afhash *hp;
23511820Sjulian{
23611820Sjulian
23711820Sjulian	hp->afh_nethash = hp->afh_hosthash = 0;
23811820Sjulian}
23911820Sjulian
24011820Sjulianint
24111820Sjuliannull_netmatch(a1, a2)
24211820Sjulian	struct sockaddr *a1, *a2;
24311820Sjulian{
24411820Sjulian
24511820Sjulian	return (0);
24611820Sjulian}
24711820Sjulian
24811820Sjulianvoid
24911820Sjuliannull_output(s, f, a1, n)
25011820Sjulian	int s;
25111820Sjulian	int f;
25211820Sjulian	struct sockaddr *a1;
25311820Sjulian	int n;
25411820Sjulian{
25511820Sjulian
25611820Sjulian	;
25711820Sjulian}
25811820Sjulian
25911820Sjulianint
26011820Sjuliannull_portmatch(a1)
26111820Sjulian	struct sockaddr *a1;
26211820Sjulian{
26311820Sjulian
26411820Sjulian	return (0);
26511820Sjulian}
26611820Sjulian
26711820Sjulianint
26811820Sjuliannull_portcheck(a1)
26911820Sjulian	struct sockaddr *a1;
27011820Sjulian{
27111820Sjulian
27211820Sjulian	return (0);
27311820Sjulian}
27411820Sjulian
27511820Sjulianint
27611820Sjuliannull_ishost(a1)
27711820Sjulian	struct sockaddr *a1;
27811820Sjulian{
27911820Sjulian
28011820Sjulian	return (0);
28111820Sjulian}
28211820Sjulian
28311820Sjulianint
28411820Sjuliannull_checkhost(a1)
28511820Sjulian	struct sockaddr *a1;
28611820Sjulian{
28711820Sjulian
28811820Sjulian	return (0);
28911820Sjulian}
29011820Sjulian
29111820Sjulianvoid
29211820Sjuliannull_canon(a1)
29311820Sjulian	struct sockaddr *a1;
29411820Sjulian{
29511820Sjulian
29611820Sjulian	;
29711820Sjulian}
29811820Sjulian
299