xref: /csrg-svn/sbin/routed/af.c (revision 61540)
121992Sdist /*
2*61540Sbostic  * Copyright (c) 1983, 1993
3*61540Sbostic  *	The Regents of the University of California.  All rights reserved.
433489Sbostic  *
542712Sbostic  * %sccs.include.redist.c%
621992Sdist  */
721992Sdist 
86916Ssam #ifndef lint
9*61540Sbostic static char sccsid[] = "@(#)af.c	8.1 (Berkeley) 06/05/93";
1033489Sbostic #endif /* not lint */
116916Ssam 
1210243Ssam #include "defs.h"
136916Ssam 
146916Ssam /*
156916Ssam  * Address family support routines
166916Ssam  */
176916Ssam int	inet_hash(), inet_netmatch(), inet_output(),
187026Ssam 	inet_portmatch(), inet_portcheck(),
1931220Skarels 	inet_checkhost(), inet_rtflags(), inet_sendroute(), inet_canon();
2026340Skarels char	*inet_format();
2127230Skarels 
2226340Skarels #define NIL	{ 0 }
236916Ssam #define	INET \
246916Ssam 	{ inet_hash,		inet_netmatch,		inet_output, \
257026Ssam 	  inet_portmatch,	inet_portcheck,		inet_checkhost, \
2631220Skarels 	  inet_rtflags,		inet_sendroute,		inet_canon, \
2727230Skarels 	  inet_format \
2827230Skarels 	}
296916Ssam 
3027230Skarels struct afswitch afswitch[AF_MAX] = {
3127230Skarels 	NIL,		/* 0- unused */
3227230Skarels 	NIL,		/* 1- Unix domain, unused */
3327230Skarels 	INET,		/* Internet */
3427230Skarels };
356916Ssam 
3626340Skarels int af_max = sizeof(afswitch) / sizeof(afswitch[0]);
3726340Skarels 
3838684Ssklower struct sockaddr_in inet_default = {
3938684Ssklower #ifdef RTM_ADD
4038684Ssklower 	sizeof (inet_default),
4138684Ssklower #endif
4238684Ssklower 	AF_INET, INADDR_ANY };
4316325Skarels 
inet_hash(sin,hp)446916Ssam inet_hash(sin, hp)
456916Ssam 	register struct sockaddr_in *sin;
466916Ssam 	struct afhash *hp;
476916Ssam {
4821838Skarels 	register u_long n;
496916Ssam 
5021838Skarels 	n = inet_netof(sin->sin_addr);
5121838Skarels 	if (n)
5221838Skarels 	    while ((n & 0xff) == 0)
5321838Skarels 		n >>= 8;
5421838Skarels 	hp->afh_nethash = n;
5510243Ssam 	hp->afh_hosthash = ntohl(sin->sin_addr.s_addr);
567133Swnj 	hp->afh_hosthash &= 0x7fffffff;
576916Ssam }
586916Ssam 
596916Ssam inet_netmatch(sin1, sin2)
606916Ssam 	struct sockaddr_in *sin1, *sin2;
616916Ssam {
626916Ssam 
638365Ssam 	return (inet_netof(sin1->sin_addr) == inet_netof(sin2->sin_addr));
646916Ssam }
656916Ssam 
666916Ssam /*
676916Ssam  * Verify the message is from the right port.
686916Ssam  */
inet_portmatch(sin)696916Ssam inet_portmatch(sin)
709023Ssam 	register struct sockaddr_in *sin;
716916Ssam {
727133Swnj 
7310243Ssam 	return (sin->sin_port == sp->s_port);
746916Ssam }
756916Ssam 
766916Ssam /*
777026Ssam  * Verify the message is from a "trusted" port.
787026Ssam  */
797026Ssam inet_portcheck(sin)
8010243Ssam 	struct sockaddr_in *sin;
817026Ssam {
827026Ssam 
8310243Ssam 	return (ntohs(sin->sin_port) <= IPPORT_RESERVED);
847026Ssam }
857026Ssam 
867026Ssam /*
876916Ssam  * Internet output routine.
886916Ssam  */
inet_output(s,flags,sin,size)8910243Ssam inet_output(s, flags, sin, size)
9010243Ssam 	int s, flags;
916916Ssam 	struct sockaddr_in *sin;
926916Ssam 	int size;
936916Ssam {
946916Ssam 	struct sockaddr_in dst;
956916Ssam 
966916Ssam 	dst = *sin;
976916Ssam 	sin = &dst;
989023Ssam 	if (sin->sin_port == 0)
9910243Ssam 		sin->sin_port = sp->s_port;
10038684Ssklower 	if (sin->sin_len == 0)
10138684Ssklower 		sin->sin_len = sizeof (*sin);
10246784Sbostic 	if (sendto(s, packet, size, flags,
10346784Sbostic 	    (struct sockaddr *)sin, sizeof (*sin)) < 0)
10410243Ssam 		perror("sendto");
1056916Ssam }
1066916Ssam 
1076916Ssam /*
1087793Ssam  * Return 1 if the address is believed
1097793Ssam  * for an Internet host -- THIS IS A KLUDGE.
1106916Ssam  */
1116916Ssam inet_checkhost(sin)
1126916Ssam 	struct sockaddr_in *sin;
1136916Ssam {
11416741Skarels 	u_long i = ntohl(sin->sin_addr.s_addr);
11516435Skarels 
11631497Skarels #ifndef IN_EXPERIMENTAL
11731497Skarels #define	IN_EXPERIMENTAL(i)	(((long) (i) & 0xe0000000) == 0xe0000000)
11831497Skarels #endif
11910243Ssam 
12031497Skarels 	if (IN_EXPERIMENTAL(i) || sin->sin_port != 0)
12116325Skarels 		return (0);
12216435Skarels 	if (i != 0 && (i & 0xff000000) == 0)
12316325Skarels 		return (0);
12425352Skarels 	for (i = 0; i < sizeof(sin->sin_zero)/sizeof(sin->sin_zero[0]); i++)
12525352Skarels 		if (sin->sin_zero[i])
12625352Skarels 			return (0);
12716325Skarels 	return (1);
12816128Skarels }
12916128Skarels 
1306916Ssam inet_canon(sin)
1316916Ssam 	struct sockaddr_in *sin;
1326916Ssam {
13310243Ssam 
1346916Ssam 	sin->sin_port = 0;
13538684Ssklower 	sin->sin_len = sizeof(*sin);
1366916Ssam }
1376916Ssam 
13826340Skarels char *
inet_format(sin)13926340Skarels inet_format(sin)
14026340Skarels 	struct sockaddr_in *sin;
1416916Ssam {
14226340Skarels 	char *inet_ntoa();
1436916Ssam 
14426340Skarels 	return (inet_ntoa(sin->sin_addr));
1456916Ssam }
146