xref: /csrg-svn/sbin/routed/inet.c (revision 42712)
121994Sdist /*
221994Sdist  * Copyright (c) 1983 Regents of the University of California.
333489Sbostic  * All rights reserved.
433489Sbostic  *
5*42712Sbostic  * %sccs.include.redist.c%
621994Sdist  */
721994Sdist 
816395Skarels #ifndef lint
9*42712Sbostic static char sccsid[] = "@(#)inet.c	5.8 (Berkeley) 06/01/90";
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 /*
10627231Skarels  * Return RTF_HOST if the address is
10727231Skarels  * for an Internet host, RTF_SUBNET for a subnet,
10827231Skarels  * 0 for a network.
10927231Skarels  */
11027231Skarels inet_rtflags(sin)
11127231Skarels 	struct sockaddr_in *sin;
11227231Skarels {
11327231Skarels 	register u_long i = ntohl(sin->sin_addr.s_addr);
11427231Skarels 	register u_long net, host;
11527231Skarels 	register struct interface *ifp;
11627231Skarels 
11727231Skarels 	if (IN_CLASSA(i)) {
11827231Skarels 		net = i & IN_CLASSA_NET;
11927231Skarels 		host = i & IN_CLASSA_HOST;
12027231Skarels 	} else if (IN_CLASSB(i)) {
12127231Skarels 		net = i & IN_CLASSB_NET;
12227231Skarels 		host = i & IN_CLASSB_HOST;
12327231Skarels 	} else {
12427231Skarels 		net = i & IN_CLASSC_NET;
12527231Skarels 		host = i & IN_CLASSC_HOST;
12627231Skarels 	}
12727231Skarels 
12827231Skarels 	/*
12927231Skarels 	 * Check whether this network is subnetted;
13027231Skarels 	 * if so, check whether this is a subnet or a host.
13127231Skarels 	 */
13227231Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
13327231Skarels 		if (net == ifp->int_net) {
13428994Skarels 			if (host &~ ifp->int_subnetmask)
13528994Skarels 				return (RTF_HOST);
13628994Skarels 			else if (ifp->int_subnetmask != ifp->int_netmask)
13727231Skarels 				return (RTF_SUBNET);
13827231Skarels 			else
13928994Skarels 				return (0);		/* network */
14027231Skarels 		}
14128994Skarels 	if (host == 0)
14228994Skarels 		return (0);	/* network */
14328994Skarels 	else
14428994Skarels 		return (RTF_HOST);
14527231Skarels }
14627231Skarels 
14727231Skarels /*
14831220Skarels  * Return true if a route to subnet/host of route rt should be sent to dst.
14931220Skarels  * Send it only if dst is on the same logical network if not "internal",
15031220Skarels  * otherwise only if the route is the "internal" route for the logical net.
15127231Skarels  */
15231220Skarels inet_sendroute(rt, dst)
15328906Skarels 	struct rt_entry *rt;
15428906Skarels 	struct sockaddr_in *dst;
15527231Skarels {
15628906Skarels 	register u_long r =
15728906Skarels 	    ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr);
15827231Skarels 	register u_long d = ntohl(dst->sin_addr.s_addr);
15927231Skarels 
16028906Skarels 	if (IN_CLASSA(r)) {
16128906Skarels 		if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) {
16228906Skarels 			if ((r & IN_CLASSA_HOST) == 0)
16328906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
16427231Skarels 			return (1);
16528906Skarels 		}
16628994Skarels 		if (r & IN_CLASSA_HOST)
16728994Skarels 			return (0);
16828994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
16928906Skarels 	} else if (IN_CLASSB(r)) {
17028906Skarels 		if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) {
17128906Skarels 			if ((r & IN_CLASSB_HOST) == 0)
17228906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
17327231Skarels 			return (1);
17428906Skarels 		}
17528994Skarels 		if (r & IN_CLASSB_HOST)
17628994Skarels 			return (0);
17728994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
17827231Skarels 	} else {
17928906Skarels 		if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) {
18028906Skarels 			if ((r & IN_CLASSC_HOST) == 0)
18128906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
18227231Skarels 			return (1);
18328906Skarels 		}
18428994Skarels 		if (r & IN_CLASSC_HOST)
18528994Skarels 			return (0);
18628994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
18727231Skarels 	}
18827231Skarels }
189