xref: /csrg-svn/sys/netinet/in.c (revision 16413)
1*16413Skarels /*	in.c	6.3	84/04/24	*/
27159Ssam 
37159Ssam #include "../h/param.h"
47159Ssam #include "../h/mbuf.h"
57159Ssam #include "../h/protosw.h"
67159Ssam #include "../h/socket.h"
77159Ssam #include "../h/socketvar.h"
88397Swnj #include "../netinet/in.h"
98397Swnj #include "../netinet/in_systm.h"
107166Ssam #include "../net/if.h"
117166Ssam #include "../net/route.h"
127159Ssam #include "../net/af.h"
137159Ssam 
147159Ssam #ifdef INET
157159Ssam inet_hash(sin, hp)
167159Ssam 	register struct sockaddr_in *sin;
177159Ssam 	struct afhash *hp;
187159Ssam {
198595Sroot 
207159Ssam 	hp->afh_nethash = in_netof(sin->sin_addr);
218937Sroot 	hp->afh_hosthash = ntohl(sin->sin_addr.s_addr);
227159Ssam }
237159Ssam 
247159Ssam inet_netmatch(sin1, sin2)
257159Ssam 	struct sockaddr_in *sin1, *sin2;
267159Ssam {
278595Sroot 
2811566Ssam 	return (in_netof(sin1->sin_addr) == in_netof(sin2->sin_addr));
297159Ssam }
307159Ssam 
317159Ssam /*
327159Ssam  * Formulate an Internet address from network + host.  Used in
337159Ssam  * building addresses stored in the ifnet structure.
347159Ssam  */
357159Ssam struct in_addr
367159Ssam if_makeaddr(net, host)
377159Ssam 	int net, host;
387159Ssam {
397159Ssam 	u_long addr;
407159Ssam 
4116377Skarels 	if (net < IN_CLASSA_MAX)
428694Sroot 		addr = (net << IN_CLASSA_NSHIFT) | host;
4316377Skarels 	else if (net < IN_CLASSB_MAX)
448694Sroot 		addr = (net << IN_CLASSB_NSHIFT) | host;
457159Ssam 	else
468694Sroot 		addr = (net << IN_CLASSC_NSHIFT) | host;
477159Ssam 	addr = htonl(addr);
487159Ssam 	return (*(struct in_addr *)&addr);
497159Ssam }
507159Ssam 
517159Ssam /*
528595Sroot  * Return the network number from an internet address.
537159Ssam  */
547159Ssam in_netof(in)
557159Ssam 	struct in_addr in;
567159Ssam {
578937Sroot 	register u_long i = ntohl(in.s_addr);
58*16413Skarels 	register u_long net, subnet;
59*16413Skarels 	register struct ifnet *ifp;
607159Ssam 
6116377Skarels 	if (IN_CLASSA(i)) {
62*16413Skarels 		net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT;
63*16413Skarels 		if (IN_SUBNETA(i)) {
64*16413Skarels 			subnet = (i & IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT;
65*16413Skarels 			/* Fall through and check whether a subnet */
66*16413Skarels 		} else
6716377Skarels 			return (net);
6816377Skarels 	} else if (IN_CLASSB(i)) {
69*16413Skarels 		net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT;
70*16413Skarels 		if (IN_SUBNETB(i)) {
71*16413Skarels 			subnet = (i & IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT;
72*16413Skarels 			/* Fall through and check whether a subnet */
73*16413Skarels 		} else
7416377Skarels 			return (net);
7516377Skarels 	} else {
76*16413Skarels 		return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
7716377Skarels 	}
78*16413Skarels 
79*16413Skarels 	/*
80*16413Skarels 	 * Check whether network is a subnet of a `local' network;
81*16413Skarels 	 * if so, return subnet number.
82*16413Skarels 	 */
83*16413Skarels 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
84*16413Skarels 		if (ifp->if_addr.sa_family != AF_INET)
85*16413Skarels 			continue;
86*16413Skarels 		if (ifp->if_flags & IFF_LOCAL) {
87*16413Skarels 			if (ifp->if_net == net)
88*16413Skarels 				return (subnet);
89*16413Skarels 			if ((ifp->if_net >> SUBNETSHIFT) == net)
90*16413Skarels 				return (subnet);
91*16413Skarels 			/*
92*16413Skarels 			 * Hack for use in setting if_net initially.
93*16413Skarels 			 */
94*16413Skarels 			if (ifp->if_net == 0) {
95*16413Skarels 				register struct sockaddr_in *sin;
96*16413Skarels 				sin = (struct sockaddr_in *) &ifp->if_addr;
97*16413Skarels 				if (sin->sin_addr.s_addr == in.s_addr)
98*16413Skarels 					return (subnet);
99*16413Skarels 			}
100*16413Skarels 		}
101*16413Skarels 	}
102*16413Skarels 	return (net);
1037159Ssam }
1047159Ssam 
1057159Ssam /*
1068595Sroot  * Return the host portion of an internet address.
1077159Ssam  */
1087159Ssam in_lnaof(in)
1097159Ssam 	struct in_addr in;
1107159Ssam {
1118937Sroot 	register u_long i = ntohl(in.s_addr);
112*16413Skarels 	register u_long net, host, subhost;
113*16413Skarels 	register struct ifnet *ifp;
1147159Ssam 
11516377Skarels 	if (IN_CLASSA(i)) {
116*16413Skarels 		if (IN_SUBNETA(i)) {
117*16413Skarels 			net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT;
118*16413Skarels 			host = i & IN_CLASSA_HOST;
119*16413Skarels 			subhost = i & IN_CLASSA_SUBHOST;
120*16413Skarels 			/* Fall through and check whether a subnet */
121*16413Skarels 		} else
122*16413Skarels 			return (i & IN_CLASSA_HOST);
12316377Skarels 	} else if (IN_CLASSB(i)) {
124*16413Skarels 		if (IN_SUBNETB(i)) {
125*16413Skarels 			net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT;
126*16413Skarels 			host = i & IN_CLASSB_HOST;
127*16413Skarels 			subhost = i & IN_CLASSB_SUBHOST;
128*16413Skarels 			/* Fall through and check whether a subnet */
129*16413Skarels 		} else
130*16413Skarels 			return (i & IN_CLASSB_HOST);
13116377Skarels 	} else {
132*16413Skarels 		return (i & IN_CLASSC_HOST);
13316377Skarels 	}
1347159Ssam 
135*16413Skarels 	/*
136*16413Skarels 	 * Check whether network is a subnet of a `local' network;
137*16413Skarels 	 * if so, use the modified interpretation of `host'.
138*16413Skarels 	 */
13916377Skarels 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
14016377Skarels 		if (ifp->if_addr.sa_family != AF_INET)
14116377Skarels 			continue;
14216377Skarels 		if (ifp->if_flags & IFF_LOCAL) {
14316377Skarels 			if (ifp->if_net == net)
144*16413Skarels 			    return (subhost);
14516377Skarels 			if ((ifp->if_net >> SUBNETSHIFT) == net)
146*16413Skarels 			    return (subhost);
14716377Skarels 		}
14816377Skarels 	}
149*16413Skarels 	return (host);
15016377Skarels }
15116377Skarels 
15216377Skarels /*
1537159Ssam  * Initialize an interface's routing
1547159Ssam  * table entry according to the network.
1557159Ssam  * INTERNET SPECIFIC.
1567159Ssam  */
1577159Ssam if_rtinit(ifp, flags)
1587159Ssam 	register struct ifnet *ifp;
1597159Ssam 	int flags;
1607159Ssam {
1617159Ssam 	struct sockaddr_in sin;
1627159Ssam 
1637159Ssam 	if (ifp->if_flags & IFF_ROUTE)
1647159Ssam 		return;
1657159Ssam 	bzero((caddr_t)&sin, sizeof (sin));
1667159Ssam 	sin.sin_family = AF_INET;
16711566Ssam 	sin.sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY);
1688637Sroot 	rtinit((struct sockaddr *)&sin, &ifp->if_addr, flags);
1697159Ssam }
1707159Ssam #endif
171