xref: /csrg-svn/sbin/routed/af.c (revision 31497)
121992Sdist /*
221992Sdist  * Copyright (c) 1983 Regents of the University of California.
321992Sdist  * All rights reserved.  The Berkeley software License Agreement
421992Sdist  * specifies the terms and conditions for redistribution.
521992Sdist  */
621992Sdist 
76916Ssam #ifndef lint
8*31497Skarels static char sccsid[] = "@(#)af.c	5.6 (Berkeley) 06/15/87";
921992Sdist #endif not lint
106916Ssam 
1110243Ssam #include "defs.h"
126916Ssam 
136916Ssam /*
146916Ssam  * Address family support routines
156916Ssam  */
166916Ssam int	inet_hash(), inet_netmatch(), inet_output(),
177026Ssam 	inet_portmatch(), inet_portcheck(),
1831220Skarels 	inet_checkhost(), inet_rtflags(), inet_sendroute(), inet_canon();
1926340Skarels char	*inet_format();
2027230Skarels 
2126340Skarels #define NIL	{ 0 }
226916Ssam #define	INET \
236916Ssam 	{ inet_hash,		inet_netmatch,		inet_output, \
247026Ssam 	  inet_portmatch,	inet_portcheck,		inet_checkhost, \
2531220Skarels 	  inet_rtflags,		inet_sendroute,		inet_canon, \
2627230Skarels 	  inet_format \
2727230Skarels 	}
286916Ssam 
2927230Skarels struct afswitch afswitch[AF_MAX] = {
3027230Skarels 	NIL,		/* 0- unused */
3127230Skarels 	NIL,		/* 1- Unix domain, unused */
3227230Skarels 	INET,		/* Internet */
3327230Skarels };
346916Ssam 
3526340Skarels int af_max = sizeof(afswitch) / sizeof(afswitch[0]);
3626340Skarels 
3716325Skarels struct sockaddr_in inet_default = { AF_INET, INADDR_ANY };
3816325Skarels 
396916Ssam inet_hash(sin, hp)
406916Ssam 	register struct sockaddr_in *sin;
416916Ssam 	struct afhash *hp;
426916Ssam {
4321838Skarels 	register u_long n;
446916Ssam 
4521838Skarels 	n = inet_netof(sin->sin_addr);
4621838Skarels 	if (n)
4721838Skarels 	    while ((n & 0xff) == 0)
4821838Skarels 		n >>= 8;
4921838Skarels 	hp->afh_nethash = n;
5010243Ssam 	hp->afh_hosthash = ntohl(sin->sin_addr.s_addr);
517133Swnj 	hp->afh_hosthash &= 0x7fffffff;
526916Ssam }
536916Ssam 
546916Ssam inet_netmatch(sin1, sin2)
556916Ssam 	struct sockaddr_in *sin1, *sin2;
566916Ssam {
576916Ssam 
588365Ssam 	return (inet_netof(sin1->sin_addr) == inet_netof(sin2->sin_addr));
596916Ssam }
606916Ssam 
616916Ssam /*
626916Ssam  * Verify the message is from the right port.
636916Ssam  */
646916Ssam inet_portmatch(sin)
659023Ssam 	register struct sockaddr_in *sin;
666916Ssam {
677133Swnj 
6810243Ssam 	return (sin->sin_port == sp->s_port);
696916Ssam }
706916Ssam 
716916Ssam /*
727026Ssam  * Verify the message is from a "trusted" port.
737026Ssam  */
747026Ssam inet_portcheck(sin)
7510243Ssam 	struct sockaddr_in *sin;
767026Ssam {
777026Ssam 
7810243Ssam 	return (ntohs(sin->sin_port) <= IPPORT_RESERVED);
797026Ssam }
807026Ssam 
817026Ssam /*
826916Ssam  * Internet output routine.
836916Ssam  */
8410243Ssam inet_output(s, flags, sin, size)
8510243Ssam 	int s, flags;
866916Ssam 	struct sockaddr_in *sin;
876916Ssam 	int size;
886916Ssam {
896916Ssam 	struct sockaddr_in dst;
906916Ssam 
916916Ssam 	dst = *sin;
926916Ssam 	sin = &dst;
939023Ssam 	if (sin->sin_port == 0)
9410243Ssam 		sin->sin_port = sp->s_port;
9510243Ssam 	if (sendto(s, packet, size, flags, sin, sizeof (*sin)) < 0)
9610243Ssam 		perror("sendto");
976916Ssam }
986916Ssam 
996916Ssam /*
1007793Ssam  * Return 1 if the address is believed
1017793Ssam  * for an Internet host -- THIS IS A KLUDGE.
1026916Ssam  */
1036916Ssam inet_checkhost(sin)
1046916Ssam 	struct sockaddr_in *sin;
1056916Ssam {
10616741Skarels 	u_long i = ntohl(sin->sin_addr.s_addr);
10716435Skarels 
108*31497Skarels #ifndef IN_EXPERIMENTAL
109*31497Skarels #define	IN_EXPERIMENTAL(i)	(((long) (i) & 0xe0000000) == 0xe0000000)
110*31497Skarels #endif
11110243Ssam 
112*31497Skarels 	if (IN_EXPERIMENTAL(i) || sin->sin_port != 0)
11316325Skarels 		return (0);
11416435Skarels 	if (i != 0 && (i & 0xff000000) == 0)
11516325Skarels 		return (0);
11625352Skarels 	for (i = 0; i < sizeof(sin->sin_zero)/sizeof(sin->sin_zero[0]); i++)
11725352Skarels 		if (sin->sin_zero[i])
11825352Skarels 			return (0);
11916325Skarels 	return (1);
12016128Skarels }
12116128Skarels 
1226916Ssam inet_canon(sin)
1236916Ssam 	struct sockaddr_in *sin;
1246916Ssam {
12510243Ssam 
1266916Ssam 	sin->sin_port = 0;
1276916Ssam }
1286916Ssam 
12926340Skarels char *
13026340Skarels inet_format(sin)
13126340Skarels 	struct sockaddr_in *sin;
1326916Ssam {
13326340Skarels 	char *inet_ntoa();
1346916Ssam 
13526340Skarels 	return (inet_ntoa(sin->sin_addr));
1366916Ssam }
137