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