xref: /csrg-svn/sbin/routed/inet.c (revision 27231)
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*27231Skarels static char sccsid[] = "@(#)inet.c	5.2 (Berkeley) 04/20/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 }
103*27231Skarels 
104*27231Skarels /*
105*27231Skarels  * Return RTF_HOST if the address is
106*27231Skarels  * for an Internet host, RTF_SUBNET for a subnet,
107*27231Skarels  * 0 for a network.
108*27231Skarels  */
109*27231Skarels inet_rtflags(sin)
110*27231Skarels 	struct sockaddr_in *sin;
111*27231Skarels {
112*27231Skarels 	register u_long i = ntohl(sin->sin_addr.s_addr);
113*27231Skarels 	register u_long net, host;
114*27231Skarels 	register struct interface *ifp;
115*27231Skarels 
116*27231Skarels 	if (IN_CLASSA(i)) {
117*27231Skarels 		net = i & IN_CLASSA_NET;
118*27231Skarels 		host = i & IN_CLASSA_HOST;
119*27231Skarels 	} else if (IN_CLASSB(i)) {
120*27231Skarels 		net = i & IN_CLASSB_NET;
121*27231Skarels 		host = i & IN_CLASSB_HOST;
122*27231Skarels 	} else {
123*27231Skarels 		net = i & IN_CLASSC_NET;
124*27231Skarels 		host = i & IN_CLASSC_HOST;
125*27231Skarels 	}
126*27231Skarels 
127*27231Skarels 	if (host == 0)
128*27231Skarels 		return (0);	/* network */
129*27231Skarels 	/*
130*27231Skarels 	 * Check whether this network is subnetted;
131*27231Skarels 	 * if so, check whether this is a subnet or a host.
132*27231Skarels 	 */
133*27231Skarels 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
134*27231Skarels 		if (net == ifp->int_net) {
135*27231Skarels 			if ((host &~ ifp->int_subnetmask) == 0)
136*27231Skarels 				return (RTF_SUBNET);
137*27231Skarels 			else
138*27231Skarels 				return (RTF_HOST);
139*27231Skarels 		}
140*27231Skarels 	return (RTF_HOST);
141*27231Skarels }
142*27231Skarels 
143*27231Skarels /*
144*27231Skarels  * Return true if a route to subnet rtsin should be sent to dst.
145*27231Skarels  * Send it only if dst is on the same logical network,
146*27231Skarels  * or the route turns out to be for the net (aka subnet 0).
147*27231Skarels  */
148*27231Skarels inet_sendsubnet(rtsin, dst)
149*27231Skarels 	struct sockaddr_in *rtsin, *dst;
150*27231Skarels {
151*27231Skarels 	register u_long rt = ntohl(rtsin->sin_addr.s_addr);
152*27231Skarels 	register u_long d = ntohl(dst->sin_addr.s_addr);
153*27231Skarels 
154*27231Skarels 	if (IN_CLASSA(rt)) {
155*27231Skarels 		if ((rt & IN_CLASSA_HOST) == 0)
156*27231Skarels 			return (1);
157*27231Skarels 		return ((rt & IN_CLASSA_NET) == (d & IN_CLASSA_NET));
158*27231Skarels 	} else if (IN_CLASSB(rt)) {
159*27231Skarels 		if ((rt & IN_CLASSB_HOST) == 0)
160*27231Skarels 			return (1);
161*27231Skarels 		return ((rt & IN_CLASSB_NET) == (d & IN_CLASSB_NET));
162*27231Skarels 	} else {
163*27231Skarels 		if ((rt & IN_CLASSC_HOST) == 0)
164*27231Skarels 			return (1);
165*27231Skarels 		return ((rt & IN_CLASSC_NET) == (d & IN_CLASSC_NET));
166*27231Skarels 	}
167*27231Skarels }
168