xref: /csrg-svn/sys/netinet/in.c (revision 16377)
1*16377Skarels /*	in.c	6.2	84/04/12	*/
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 
41*16377Skarels 	if (net < IN_CLASSA_MAX)
428694Sroot 		addr = (net << IN_CLASSA_NSHIFT) | host;
43*16377Skarels 	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*16377Skarels 	register net;
597159Ssam 
60*16377Skarels 	if (IN_CLASSA(i)) {
61*16377Skarels 		net = ((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT;
62*16377Skarels 		if (in_localnet(net) && IN_SUBNETA(i))
63*16377Skarels 			return (((i)&IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT);
64*16377Skarels 		else
65*16377Skarels 			return (net);
66*16377Skarels 	} else if (IN_CLASSB(i)) {
67*16377Skarels 		net = ((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT;
68*16377Skarels 		if (in_localnet(net) && IN_SUBNETB(i))
69*16377Skarels 			return (((i)&IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT);
70*16377Skarels 		else
71*16377Skarels 			return (net);
72*16377Skarels 	} else {
738694Sroot 		return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
74*16377Skarels 	}
757159Ssam }
767159Ssam 
777159Ssam /*
788595Sroot  * Return the host portion of an internet address.
797159Ssam  */
807159Ssam in_lnaof(in)
817159Ssam 	struct in_addr in;
827159Ssam {
838937Sroot 	register u_long i = ntohl(in.s_addr);
847159Ssam 
85*16377Skarels 	if (IN_CLASSA(i)) {
86*16377Skarels 		if (IN_SUBNETA(i) &&
87*16377Skarels 		    in_localnet(((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT))
88*16377Skarels 			return ((i)&IN_CLASSA_SUBHOST);
89*16377Skarels 		else
90*16377Skarels 			return ((i)&IN_CLASSA_HOST);
91*16377Skarels 	} else if (IN_CLASSB(i)) {
92*16377Skarels 		if (IN_SUBNETB(i) &&
93*16377Skarels 		    in_localnet(((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT) )
94*16377Skarels 			return ((i)&IN_CLASSB_SUBHOST);
95*16377Skarels 		else
96*16377Skarels 			return ((i)&IN_CLASSB_HOST);
97*16377Skarels 	} else {
988694Sroot 		return ((i)&IN_CLASSC_HOST);
99*16377Skarels 	}
1007159Ssam }
1017159Ssam 
1027159Ssam /*
103*16377Skarels  * Return true if the network is a ``local'' net
104*16377Skarels  * (one for which we can interpret the host part).
105*16377Skarels  */
106*16377Skarels in_localnet(net)
107*16377Skarels 	register int net;
108*16377Skarels {
109*16377Skarels 	register struct ifnet *ifp;
110*16377Skarels 
111*16377Skarels 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
112*16377Skarels 		if (ifp->if_addr.sa_family != AF_INET)
113*16377Skarels 			continue;
114*16377Skarels 		if (ifp->if_flags & IFF_LOCAL) {
115*16377Skarels 			if (ifp->if_net == net)
116*16377Skarels 				return (1);
117*16377Skarels 			if ((ifp->if_net >> SUBNETSHIFT) == net)
118*16377Skarels 				return (1);
119*16377Skarels 		}
120*16377Skarels 	}
121*16377Skarels 	return (0);
122*16377Skarels }
123*16377Skarels 
124*16377Skarels /*
1257159Ssam  * Initialize an interface's routing
1267159Ssam  * table entry according to the network.
1277159Ssam  * INTERNET SPECIFIC.
1287159Ssam  */
1297159Ssam if_rtinit(ifp, flags)
1307159Ssam 	register struct ifnet *ifp;
1317159Ssam 	int flags;
1327159Ssam {
1337159Ssam 	struct sockaddr_in sin;
1347159Ssam 
1357159Ssam 	if (ifp->if_flags & IFF_ROUTE)
1367159Ssam 		return;
1377159Ssam 	bzero((caddr_t)&sin, sizeof (sin));
1387159Ssam 	sin.sin_family = AF_INET;
13911566Ssam 	sin.sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY);
1408637Sroot 	rtinit((struct sockaddr *)&sin, &ifp->if_addr, flags);
1417159Ssam }
1427159Ssam #endif
143