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