xref: /original-bsd/sbin/routed/inet.c (revision 27393bdf)
1 /*
2  * Copyright (c) 1983, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)inet.c	8.3 (Berkeley) 12/30/94";
10 #endif /* not lint */
11 
12 /*
13  * Temporarily, copy these routines from the kernel,
14  * as we need to know about subnets.
15  */
16 #include "defs.h"
17 
18 extern struct interface *ifnet;
19 
20 /*
21  * Formulate an Internet address from network + host.
22  */
23 struct in_addr
24 inet_makeaddr(net, host)
25 	u_long net, host;
26 {
27 	register struct interface *ifp;
28 	register u_long mask;
29 	u_long addr;
30 
31 	if (IN_CLASSA(net))
32 		mask = IN_CLASSA_HOST;
33 	else if (IN_CLASSB(net))
34 		mask = IN_CLASSB_HOST;
35 	else
36 		mask = IN_CLASSC_HOST;
37 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
38 		if ((ifp->int_netmask & net) == ifp->int_net) {
39 			mask = ~ifp->int_subnetmask;
40 			break;
41 		}
42 	addr = net | (host & mask);
43 	addr = htonl(addr);
44 	return (*(struct in_addr *)&addr);
45 }
46 
47 /*
48  * Return the network number from an internet address.
49  */
50 inet_netof(in)
51 	struct in_addr in;
52 {
53 	register u_long i = ntohl(in.s_addr);
54 	register u_long net;
55 	register struct interface *ifp;
56 
57 	if (IN_CLASSA(i))
58 		net = i & IN_CLASSA_NET;
59 	else if (IN_CLASSB(i))
60 		net = i & IN_CLASSB_NET;
61 	else
62 		net = i & IN_CLASSC_NET;
63 
64 	/*
65 	 * Check whether network is a subnet;
66 	 * if so, return subnet number.
67 	 */
68 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
69 		if ((ifp->int_netmask & net) == ifp->int_net)
70 			return (i & ifp->int_subnetmask);
71 	return (net);
72 }
73 
74 /*
75  * Return the host portion of an internet address.
76  */
77 inet_lnaof(in)
78 	struct in_addr in;
79 {
80 	register u_long i = ntohl(in.s_addr);
81 	register u_long net, host;
82 	register struct interface *ifp;
83 
84 	if (IN_CLASSA(i)) {
85 		net = i & IN_CLASSA_NET;
86 		host = i & IN_CLASSA_HOST;
87 	} else if (IN_CLASSB(i)) {
88 		net = i & IN_CLASSB_NET;
89 		host = i & IN_CLASSB_HOST;
90 	} else {
91 		net = i & IN_CLASSC_NET;
92 		host = i & IN_CLASSC_HOST;
93 	}
94 
95 	/*
96 	 * Check whether network is a subnet;
97 	 * if so, use the modified interpretation of `host'.
98 	 */
99 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
100 		if ((ifp->int_netmask & net) == ifp->int_net)
101 			return (host &~ ifp->int_subnetmask);
102 	return (host);
103 }
104 
105 /*
106  * Return the netmask pertaining to an internet address.
107  */
108 inet_maskof(inaddr)
109 	u_long inaddr;
110 {
111 	register u_long i = ntohl(inaddr);
112 	register u_long mask;
113 	register struct interface *ifp;
114 
115 	if (i == 0) {
116 		mask = 0;
117 	} else if (IN_CLASSA(i)) {
118 		mask = IN_CLASSA_NET;
119 	} else if (IN_CLASSB(i)) {
120 		mask = IN_CLASSB_NET;
121 	} else
122 		mask = IN_CLASSC_NET;
123 
124 	/*
125 	 * Check whether network is a subnet;
126 	 * if so, use the modified interpretation of `host'.
127 	 */
128 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
129 		if ((ifp->int_netmask & i) == ifp->int_net)
130 			mask = ifp->int_subnetmask;
131 	return (htonl(mask));
132 }
133 
134 /*
135  * Return RTF_HOST if the address is
136  * for an Internet host, RTF_SUBNET for a subnet,
137  * 0 for a network.
138  */
139 inet_rtflags(sin)
140 	struct sockaddr_in *sin;
141 {
142 	register u_long i = ntohl(sin->sin_addr.s_addr);
143 	register u_long net, host;
144 	register struct interface *ifp;
145 
146 	if (IN_CLASSA(i)) {
147 		net = i & IN_CLASSA_NET;
148 		host = i & IN_CLASSA_HOST;
149 	} else if (IN_CLASSB(i)) {
150 		net = i & IN_CLASSB_NET;
151 		host = i & IN_CLASSB_HOST;
152 	} else {
153 		net = i & IN_CLASSC_NET;
154 		host = i & IN_CLASSC_HOST;
155 	}
156 
157 	/*
158 	 * Check whether this network is subnetted;
159 	 * if so, check whether this is a subnet or a host.
160 	 */
161 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
162 		if (net == ifp->int_net) {
163 			if (host &~ ifp->int_subnetmask)
164 				return (RTF_HOST);
165 			else if (ifp->int_subnetmask != ifp->int_netmask)
166 				return (RTF_SUBNET);
167 			else
168 				return (0);		/* network */
169 		}
170 	if (host == 0)
171 		return (0);	/* network */
172 	else
173 		return (RTF_HOST);
174 }
175 
176 /*
177  * Return true if a route to subnet/host of route rt should be sent to dst.
178  * Send it only if dst is on the same logical network if not "internal",
179  * otherwise only if the route is the "internal" route for the logical net.
180  */
181 inet_sendroute(rt, dst)
182 	struct rt_entry *rt;
183 	struct sockaddr_in *dst;
184 {
185 	register u_long r =
186 	    ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr);
187 	register u_long d = ntohl(dst->sin_addr.s_addr);
188 
189 	if (IN_CLASSA(r)) {
190 		if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) {
191 			if ((r & IN_CLASSA_HOST) == 0)
192 				return ((rt->rt_state & RTS_INTERNAL) == 0);
193 			return (1);
194 		}
195 		if (r & IN_CLASSA_HOST)
196 			return (0);
197 		return ((rt->rt_state & RTS_INTERNAL) != 0);
198 	} else if (IN_CLASSB(r)) {
199 		if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) {
200 			if ((r & IN_CLASSB_HOST) == 0)
201 				return ((rt->rt_state & RTS_INTERNAL) == 0);
202 			return (1);
203 		}
204 		if (r & IN_CLASSB_HOST)
205 			return (0);
206 		return ((rt->rt_state & RTS_INTERNAL) != 0);
207 	} else {
208 		if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) {
209 			if ((r & IN_CLASSC_HOST) == 0)
210 				return ((rt->rt_state & RTS_INTERNAL) == 0);
211 			return (1);
212 		}
213 		if (r & IN_CLASSC_HOST)
214 			return (0);
215 		return ((rt->rt_state & RTS_INTERNAL) != 0);
216 	}
217 }
218