xref: /csrg-svn/sbin/routed/inet.c (revision 61540)
121994Sdist /*
2*61540Sbostic  * Copyright (c) 1983, 1993
3*61540Sbostic  *	The Regents of the University of California.  All rights reserved.
433489Sbostic  *
542712Sbostic  * %sccs.include.redist.c%
621994Sdist  */
721994Sdist 
816395Skarels #ifndef lint
9*61540Sbostic static char sccsid[] = "@(#)inet.c	8.1 (Berkeley) 06/05/93";
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 /*
10652583Ssklower  * Return the netmask pertaining to an internet address.
10752583Ssklower  */
10852583Ssklower inet_maskof(in)
10952583Ssklower 	struct in_addr in;
11052583Ssklower {
11152583Ssklower 	register u_long i = ntohl(in.s_addr);
11252583Ssklower 	register u_long mask;
11352583Ssklower 	register struct interface *ifp;
11452583Ssklower 
11552910Ssklower 	if (i == 0) {
11652910Ssklower 		mask = 0;
11752910Ssklower 	} else if (IN_CLASSA(i)) {
11852583Ssklower 		mask = IN_CLASSA_NET;
11952583Ssklower 	} else if (IN_CLASSB(i)) {
12052583Ssklower 		mask = i & IN_CLASSB_NET;
12152583Ssklower 	} else
12252583Ssklower 		mask = i & IN_CLASSC_NET;
12352583Ssklower 
12452583Ssklower 	/*
12552583Ssklower 	 * Check whether network is a subnet;
12652583Ssklower 	 * if so, use the modified interpretation of `host'.
12752583Ssklower 	 */
12852583Ssklower 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
12952583Ssklower 		if ((ifp->int_netmask & i) == ifp->int_net)
13052583Ssklower 			mask = ifp->int_subnetmask;
13152583Ssklower 	return (htonl(mask));
13252583Ssklower }
13352583Ssklower 
13452583Ssklower /*
13527231Skarels  * Return RTF_HOST if the address is
13627231Skarels  * for an Internet host, RTF_SUBNET for a subnet,
13727231Skarels  * 0 for a network.
13827231Skarels  */
13927231Skarels inet_rtflags(sin)
14027231Skarels 	struct sockaddr_in *sin;
14127231Skarels {
14227231Skarels 	register u_long i = ntohl(sin->sin_addr.s_addr);
14327231Skarels 	register u_long net, host;
14427231Skarels 	register struct interface *ifp;
14527231Skarels 
14627231Skarels 	if (IN_CLASSA(i)) {
14727231Skarels 		net = i & IN_CLASSA_NET;
14827231Skarels 		host = i & IN_CLASSA_HOST;
14927231Skarels 	} else if (IN_CLASSB(i)) {
15027231Skarels 		net = i & IN_CLASSB_NET;
15127231Skarels 		host = i & IN_CLASSB_HOST;
15227231Skarels 	} else {
15327231Skarels 		net = i & IN_CLASSC_NET;
15427231Skarels 		host = i & IN_CLASSC_HOST;
15527231Skarels 	}
15627231Skarels 
15727231Skarels 	/*
15827231Skarels 	 * Check whether this network is subnetted;
15927231Skarels 	 * if so, check whether this is a subnet or a host.
16027231Skarels 	 */
16127231Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
16227231Skarels 		if (net == ifp->int_net) {
16328994Skarels 			if (host &~ ifp->int_subnetmask)
16428994Skarels 				return (RTF_HOST);
16528994Skarels 			else if (ifp->int_subnetmask != ifp->int_netmask)
16627231Skarels 				return (RTF_SUBNET);
16727231Skarels 			else
16828994Skarels 				return (0);		/* network */
16927231Skarels 		}
17028994Skarels 	if (host == 0)
17128994Skarels 		return (0);	/* network */
17228994Skarels 	else
17328994Skarels 		return (RTF_HOST);
17427231Skarels }
17527231Skarels 
17627231Skarels /*
17731220Skarels  * Return true if a route to subnet/host of route rt should be sent to dst.
17831220Skarels  * Send it only if dst is on the same logical network if not "internal",
17931220Skarels  * otherwise only if the route is the "internal" route for the logical net.
18027231Skarels  */
18131220Skarels inet_sendroute(rt, dst)
18228906Skarels 	struct rt_entry *rt;
18328906Skarels 	struct sockaddr_in *dst;
18427231Skarels {
18528906Skarels 	register u_long r =
18628906Skarels 	    ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr);
18727231Skarels 	register u_long d = ntohl(dst->sin_addr.s_addr);
18827231Skarels 
18928906Skarels 	if (IN_CLASSA(r)) {
19028906Skarels 		if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) {
19128906Skarels 			if ((r & IN_CLASSA_HOST) == 0)
19228906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
19327231Skarels 			return (1);
19428906Skarels 		}
19528994Skarels 		if (r & IN_CLASSA_HOST)
19628994Skarels 			return (0);
19728994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
19828906Skarels 	} else if (IN_CLASSB(r)) {
19928906Skarels 		if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) {
20028906Skarels 			if ((r & IN_CLASSB_HOST) == 0)
20128906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
20227231Skarels 			return (1);
20328906Skarels 		}
20428994Skarels 		if (r & IN_CLASSB_HOST)
20528994Skarels 			return (0);
20628994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
20727231Skarels 	} else {
20828906Skarels 		if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) {
20928906Skarels 			if ((r & IN_CLASSC_HOST) == 0)
21028906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
21127231Skarels 			return (1);
21228906Skarels 		}
21328994Skarels 		if (r & IN_CLASSC_HOST)
21428994Skarels 			return (0);
21528994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
21627231Skarels 	}
21727231Skarels }
218