xref: /csrg-svn/sbin/routed/inet.c (revision 52583)
121994Sdist /*
221994Sdist  * Copyright (c) 1983 Regents of the University of California.
333489Sbostic  * All rights reserved.
433489Sbostic  *
542712Sbostic  * %sccs.include.redist.c%
621994Sdist  */
721994Sdist 
816395Skarels #ifndef lint
9*52583Ssklower static char sccsid[] = "@(#)inet.c	5.9 (Berkeley) 02/19/92";
1033489Sbostic #endif /* not lint */
1121994Sdist 
1216395Skarels /*
1316395Skarels  * Temporarily, copy these routines from the kernel,
1416395Skarels  * as we need to know about subnets.
1516395Skarels  */
1616395Skarels #include "defs.h"
1716395Skarels 
1821846Skarels extern struct interface *ifnet;
1921846Skarels 
2016395Skarels /*
2121846Skarels  * Formulate an Internet address from network + host.
2216395Skarels  */
2316395Skarels struct in_addr
2421846Skarels inet_makeaddr(net, host)
2521846Skarels 	u_long net, host;
2616395Skarels {
2721846Skarels 	register struct interface *ifp;
2821846Skarels 	register u_long mask;
2916395Skarels 	u_long addr;
3016395Skarels 
3121846Skarels 	if (IN_CLASSA(net))
3221846Skarels 		mask = IN_CLASSA_HOST;
3321846Skarels 	else if (IN_CLASSB(net))
3421846Skarels 		mask = IN_CLASSB_HOST;
3516395Skarels 	else
3621846Skarels 		mask = IN_CLASSC_HOST;
3721846Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
3821846Skarels 		if ((ifp->int_netmask & net) == ifp->int_net) {
3921846Skarels 			mask = ~ifp->int_subnetmask;
4021846Skarels 			break;
4121846Skarels 		}
4221846Skarels 	addr = net | (host & mask);
4316395Skarels 	addr = htonl(addr);
4416395Skarels 	return (*(struct in_addr *)&addr);
4516395Skarels }
4616395Skarels 
4716395Skarels /*
4816395Skarels  * Return the network number from an internet address.
4916395Skarels  */
5016395Skarels inet_netof(in)
5116395Skarels 	struct in_addr in;
5216395Skarels {
5316395Skarels 	register u_long i = ntohl(in.s_addr);
5421846Skarels 	register u_long net;
5516429Skarels 	register struct interface *ifp;
5616395Skarels 
5721846Skarels 	if (IN_CLASSA(i))
5821846Skarels 		net = i & IN_CLASSA_NET;
5921846Skarels 	else if (IN_CLASSB(i))
6021846Skarels 		net = i & IN_CLASSB_NET;
6121846Skarels 	else
6221846Skarels 		net = i & IN_CLASSC_NET;
6316429Skarels 
6416429Skarels 	/*
6521846Skarels 	 * Check whether network is a subnet;
6616429Skarels 	 * if so, return subnet number.
6716429Skarels 	 */
6821846Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
6921846Skarels 		if ((ifp->int_netmask & net) == ifp->int_net)
7021846Skarels 			return (i & ifp->int_subnetmask);
7116429Skarels 	return (net);
7216395Skarels }
7316395Skarels 
7416395Skarels /*
7516395Skarels  * Return the host portion of an internet address.
7616395Skarels  */
7716395Skarels inet_lnaof(in)
7816395Skarels 	struct in_addr in;
7916395Skarels {
8016395Skarels 	register u_long i = ntohl(in.s_addr);
8121846Skarels 	register u_long net, host;
8216429Skarels 	register struct interface *ifp;
8316395Skarels 
8416395Skarels 	if (IN_CLASSA(i)) {
8521846Skarels 		net = i & IN_CLASSA_NET;
8621846Skarels 		host = i & IN_CLASSA_HOST;
8716395Skarels 	} else if (IN_CLASSB(i)) {
8821846Skarels 		net = i & IN_CLASSB_NET;
8921846Skarels 		host = i & IN_CLASSB_HOST;
9016395Skarels 	} else {
9121846Skarels 		net = i & IN_CLASSC_NET;
9221846Skarels 		host = i & IN_CLASSC_HOST;
9316395Skarels 	}
9416395Skarels 
9516429Skarels 	/*
9621846Skarels 	 * Check whether network is a subnet;
9716429Skarels 	 * if so, use the modified interpretation of `host'.
9816429Skarels 	 */
9921846Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
10021846Skarels 		if ((ifp->int_netmask & net) == ifp->int_net)
10121846Skarels 			return (host &~ ifp->int_subnetmask);
10216429Skarels 	return (host);
10316395Skarels }
10427231Skarels 
10527231Skarels /*
106*52583Ssklower  * Return the netmask pertaining to an internet address.
107*52583Ssklower  */
108*52583Ssklower inet_maskof(in)
109*52583Ssklower 	struct in_addr in;
110*52583Ssklower {
111*52583Ssklower 	register u_long i = ntohl(in.s_addr);
112*52583Ssklower 	register u_long mask;
113*52583Ssklower 	register struct interface *ifp;
114*52583Ssklower 
115*52583Ssklower 	if (IN_CLASSA(i)) {
116*52583Ssklower 		mask = IN_CLASSA_NET;
117*52583Ssklower 	} else if (IN_CLASSB(i)) {
118*52583Ssklower 		mask = i & IN_CLASSB_NET;
119*52583Ssklower 	} else
120*52583Ssklower 		mask = i & IN_CLASSC_NET;
121*52583Ssklower 
122*52583Ssklower 	/*
123*52583Ssklower 	 * Check whether network is a subnet;
124*52583Ssklower 	 * if so, use the modified interpretation of `host'.
125*52583Ssklower 	 */
126*52583Ssklower 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
127*52583Ssklower 		if ((ifp->int_netmask & i) == ifp->int_net)
128*52583Ssklower 			mask = ifp->int_subnetmask;
129*52583Ssklower 	return (htonl(mask));
130*52583Ssklower }
131*52583Ssklower 
132*52583Ssklower /*
13327231Skarels  * Return RTF_HOST if the address is
13427231Skarels  * for an Internet host, RTF_SUBNET for a subnet,
13527231Skarels  * 0 for a network.
13627231Skarels  */
13727231Skarels inet_rtflags(sin)
13827231Skarels 	struct sockaddr_in *sin;
13927231Skarels {
14027231Skarels 	register u_long i = ntohl(sin->sin_addr.s_addr);
14127231Skarels 	register u_long net, host;
14227231Skarels 	register struct interface *ifp;
14327231Skarels 
14427231Skarels 	if (IN_CLASSA(i)) {
14527231Skarels 		net = i & IN_CLASSA_NET;
14627231Skarels 		host = i & IN_CLASSA_HOST;
14727231Skarels 	} else if (IN_CLASSB(i)) {
14827231Skarels 		net = i & IN_CLASSB_NET;
14927231Skarels 		host = i & IN_CLASSB_HOST;
15027231Skarels 	} else {
15127231Skarels 		net = i & IN_CLASSC_NET;
15227231Skarels 		host = i & IN_CLASSC_HOST;
15327231Skarels 	}
15427231Skarels 
15527231Skarels 	/*
15627231Skarels 	 * Check whether this network is subnetted;
15727231Skarels 	 * if so, check whether this is a subnet or a host.
15827231Skarels 	 */
15927231Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
16027231Skarels 		if (net == ifp->int_net) {
16128994Skarels 			if (host &~ ifp->int_subnetmask)
16228994Skarels 				return (RTF_HOST);
16328994Skarels 			else if (ifp->int_subnetmask != ifp->int_netmask)
16427231Skarels 				return (RTF_SUBNET);
16527231Skarels 			else
16628994Skarels 				return (0);		/* network */
16727231Skarels 		}
16828994Skarels 	if (host == 0)
16928994Skarels 		return (0);	/* network */
17028994Skarels 	else
17128994Skarels 		return (RTF_HOST);
17227231Skarels }
17327231Skarels 
17427231Skarels /*
17531220Skarels  * Return true if a route to subnet/host of route rt should be sent to dst.
17631220Skarels  * Send it only if dst is on the same logical network if not "internal",
17731220Skarels  * otherwise only if the route is the "internal" route for the logical net.
17827231Skarels  */
17931220Skarels inet_sendroute(rt, dst)
18028906Skarels 	struct rt_entry *rt;
18128906Skarels 	struct sockaddr_in *dst;
18227231Skarels {
18328906Skarels 	register u_long r =
18428906Skarels 	    ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr);
18527231Skarels 	register u_long d = ntohl(dst->sin_addr.s_addr);
18627231Skarels 
18728906Skarels 	if (IN_CLASSA(r)) {
18828906Skarels 		if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) {
18928906Skarels 			if ((r & IN_CLASSA_HOST) == 0)
19028906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
19127231Skarels 			return (1);
19228906Skarels 		}
19328994Skarels 		if (r & IN_CLASSA_HOST)
19428994Skarels 			return (0);
19528994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
19628906Skarels 	} else if (IN_CLASSB(r)) {
19728906Skarels 		if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) {
19828906Skarels 			if ((r & IN_CLASSB_HOST) == 0)
19928906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
20027231Skarels 			return (1);
20128906Skarels 		}
20228994Skarels 		if (r & IN_CLASSB_HOST)
20328994Skarels 			return (0);
20428994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
20527231Skarels 	} else {
20628906Skarels 		if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) {
20728906Skarels 			if ((r & IN_CLASSC_HOST) == 0)
20828906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
20927231Skarels 			return (1);
21028906Skarels 		}
21128994Skarels 		if (r & IN_CLASSC_HOST)
21228994Skarels 			return (0);
21328994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
21427231Skarels 	}
21527231Skarels }
216