xref: /csrg-svn/sbin/routed/inet.c (revision 28994)
121994Sdist /*
221994Sdist  * Copyright (c) 1983 Regents of the University of California.
321994Sdist  * All rights reserved.  The Berkeley software License Agreement
421994Sdist  * specifies the terms and conditions for redistribution.
521994Sdist  */
621994Sdist 
716395Skarels #ifndef lint
8*28994Skarels static char sccsid[] = "@(#)inet.c	5.4 (Berkeley) 06/03/86";
921994Sdist #endif not lint
1021994Sdist 
1116395Skarels /*
1216395Skarels  * Temporarily, copy these routines from the kernel,
1316395Skarels  * as we need to know about subnets.
1416395Skarels  */
1516395Skarels #include "defs.h"
1616395Skarels 
1721846Skarels extern struct interface *ifnet;
1821846Skarels 
1916395Skarels /*
2021846Skarels  * Formulate an Internet address from network + host.
2116395Skarels  */
2216395Skarels struct in_addr
2321846Skarels inet_makeaddr(net, host)
2421846Skarels 	u_long net, host;
2516395Skarels {
2621846Skarels 	register struct interface *ifp;
2721846Skarels 	register u_long mask;
2816395Skarels 	u_long addr;
2916395Skarels 
3021846Skarels 	if (IN_CLASSA(net))
3121846Skarels 		mask = IN_CLASSA_HOST;
3221846Skarels 	else if (IN_CLASSB(net))
3321846Skarels 		mask = IN_CLASSB_HOST;
3416395Skarels 	else
3521846Skarels 		mask = IN_CLASSC_HOST;
3621846Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
3721846Skarels 		if ((ifp->int_netmask & net) == ifp->int_net) {
3821846Skarels 			mask = ~ifp->int_subnetmask;
3921846Skarels 			break;
4021846Skarels 		}
4121846Skarels 	addr = net | (host & mask);
4216395Skarels 	addr = htonl(addr);
4316395Skarels 	return (*(struct in_addr *)&addr);
4416395Skarels }
4516395Skarels 
4616395Skarels /*
4716395Skarels  * Return the network number from an internet address.
4816395Skarels  */
4916395Skarels inet_netof(in)
5016395Skarels 	struct in_addr in;
5116395Skarels {
5216395Skarels 	register u_long i = ntohl(in.s_addr);
5321846Skarels 	register u_long net;
5416429Skarels 	register struct interface *ifp;
5516395Skarels 
5621846Skarels 	if (IN_CLASSA(i))
5721846Skarels 		net = i & IN_CLASSA_NET;
5821846Skarels 	else if (IN_CLASSB(i))
5921846Skarels 		net = i & IN_CLASSB_NET;
6021846Skarels 	else
6121846Skarels 		net = i & IN_CLASSC_NET;
6216429Skarels 
6316429Skarels 	/*
6421846Skarels 	 * Check whether network is a subnet;
6516429Skarels 	 * if so, return subnet number.
6616429Skarels 	 */
6721846Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
6821846Skarels 		if ((ifp->int_netmask & net) == ifp->int_net)
6921846Skarels 			return (i & ifp->int_subnetmask);
7016429Skarels 	return (net);
7116395Skarels }
7216395Skarels 
7316395Skarels /*
7416395Skarels  * Return the host portion of an internet address.
7516395Skarels  */
7616395Skarels inet_lnaof(in)
7716395Skarels 	struct in_addr in;
7816395Skarels {
7916395Skarels 	register u_long i = ntohl(in.s_addr);
8021846Skarels 	register u_long net, host;
8116429Skarels 	register struct interface *ifp;
8216395Skarels 
8316395Skarels 	if (IN_CLASSA(i)) {
8421846Skarels 		net = i & IN_CLASSA_NET;
8521846Skarels 		host = i & IN_CLASSA_HOST;
8616395Skarels 	} else if (IN_CLASSB(i)) {
8721846Skarels 		net = i & IN_CLASSB_NET;
8821846Skarels 		host = i & IN_CLASSB_HOST;
8916395Skarels 	} else {
9021846Skarels 		net = i & IN_CLASSC_NET;
9121846Skarels 		host = i & IN_CLASSC_HOST;
9216395Skarels 	}
9316395Skarels 
9416429Skarels 	/*
9521846Skarels 	 * Check whether network is a subnet;
9616429Skarels 	 * if so, use the modified interpretation of `host'.
9716429Skarels 	 */
9821846Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
9921846Skarels 		if ((ifp->int_netmask & net) == ifp->int_net)
10021846Skarels 			return (host &~ ifp->int_subnetmask);
10116429Skarels 	return (host);
10216395Skarels }
10327231Skarels 
10427231Skarels /*
10527231Skarels  * Return RTF_HOST if the address is
10627231Skarels  * for an Internet host, RTF_SUBNET for a subnet,
10727231Skarels  * 0 for a network.
10827231Skarels  */
10927231Skarels inet_rtflags(sin)
11027231Skarels 	struct sockaddr_in *sin;
11127231Skarels {
11227231Skarels 	register u_long i = ntohl(sin->sin_addr.s_addr);
11327231Skarels 	register u_long net, host;
11427231Skarels 	register struct interface *ifp;
11527231Skarels 
11627231Skarels 	if (IN_CLASSA(i)) {
11727231Skarels 		net = i & IN_CLASSA_NET;
11827231Skarels 		host = i & IN_CLASSA_HOST;
11927231Skarels 	} else if (IN_CLASSB(i)) {
12027231Skarels 		net = i & IN_CLASSB_NET;
12127231Skarels 		host = i & IN_CLASSB_HOST;
12227231Skarels 	} else {
12327231Skarels 		net = i & IN_CLASSC_NET;
12427231Skarels 		host = i & IN_CLASSC_HOST;
12527231Skarels 	}
12627231Skarels 
12727231Skarels 	/*
12827231Skarels 	 * Check whether this network is subnetted;
12927231Skarels 	 * if so, check whether this is a subnet or a host.
13027231Skarels 	 */
13127231Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
13227231Skarels 		if (net == ifp->int_net) {
133*28994Skarels 			if (host &~ ifp->int_subnetmask)
134*28994Skarels 				return (RTF_HOST);
135*28994Skarels 			else if (ifp->int_subnetmask != ifp->int_netmask)
13627231Skarels 				return (RTF_SUBNET);
13727231Skarels 			else
138*28994Skarels 				return (0);		/* network */
13927231Skarels 		}
140*28994Skarels 	if (host == 0)
141*28994Skarels 		return (0);	/* network */
142*28994Skarels 	else
143*28994Skarels 		return (RTF_HOST);
14427231Skarels }
14527231Skarels 
14627231Skarels /*
147*28994Skarels  * Return true if a route to subnet of route rt should be sent to dst.
14827231Skarels  * Send it only if dst is on the same logical network,
149*28994Skarels  * or the route is the "internal" route for the net.
15027231Skarels  */
15128906Skarels inet_sendsubnet(rt, dst)
15228906Skarels 	struct rt_entry *rt;
15328906Skarels 	struct sockaddr_in *dst;
15427231Skarels {
15528906Skarels 	register u_long r =
15628906Skarels 	    ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr);
15727231Skarels 	register u_long d = ntohl(dst->sin_addr.s_addr);
15827231Skarels 
15928906Skarels 	if (IN_CLASSA(r)) {
16028906Skarels 		if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) {
16128906Skarels 			if ((r & IN_CLASSA_HOST) == 0)
16228906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
16327231Skarels 			return (1);
16428906Skarels 		}
165*28994Skarels 		if (r & IN_CLASSA_HOST)
166*28994Skarels 			return (0);
167*28994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
16828906Skarels 	} else if (IN_CLASSB(r)) {
16928906Skarels 		if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) {
17028906Skarels 			if ((r & IN_CLASSB_HOST) == 0)
17128906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
17227231Skarels 			return (1);
17328906Skarels 		}
174*28994Skarels 		if (r & IN_CLASSB_HOST)
175*28994Skarels 			return (0);
176*28994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
17727231Skarels 	} else {
17828906Skarels 		if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) {
17928906Skarels 			if ((r & IN_CLASSC_HOST) == 0)
18028906Skarels 				return ((rt->rt_state & RTS_INTERNAL) == 0);
18127231Skarels 			return (1);
18228906Skarels 		}
183*28994Skarels 		if (r & IN_CLASSC_HOST)
184*28994Skarels 			return (0);
185*28994Skarels 		return ((rt->rt_state & RTS_INTERNAL) != 0);
18627231Skarels 	}
18727231Skarels }
188