xref: /original-bsd/sbin/routed/inet.c (revision 5656414f)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)inet.c	5.8 (Berkeley) 06/01/90";
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 RTF_HOST if the address is
107  * for an Internet host, RTF_SUBNET for a subnet,
108  * 0 for a network.
109  */
110 inet_rtflags(sin)
111 	struct sockaddr_in *sin;
112 {
113 	register u_long i = ntohl(sin->sin_addr.s_addr);
114 	register u_long net, host;
115 	register struct interface *ifp;
116 
117 	if (IN_CLASSA(i)) {
118 		net = i & IN_CLASSA_NET;
119 		host = i & IN_CLASSA_HOST;
120 	} else if (IN_CLASSB(i)) {
121 		net = i & IN_CLASSB_NET;
122 		host = i & IN_CLASSB_HOST;
123 	} else {
124 		net = i & IN_CLASSC_NET;
125 		host = i & IN_CLASSC_HOST;
126 	}
127 
128 	/*
129 	 * Check whether this network is subnetted;
130 	 * if so, check whether this is a subnet or a host.
131 	 */
132 	for (ifp = ifnet; ifp; ifp = ifp->int_next)
133 		if (net == ifp->int_net) {
134 			if (host &~ ifp->int_subnetmask)
135 				return (RTF_HOST);
136 			else if (ifp->int_subnetmask != ifp->int_netmask)
137 				return (RTF_SUBNET);
138 			else
139 				return (0);		/* network */
140 		}
141 	if (host == 0)
142 		return (0);	/* network */
143 	else
144 		return (RTF_HOST);
145 }
146 
147 /*
148  * Return true if a route to subnet/host of route rt should be sent to dst.
149  * Send it only if dst is on the same logical network if not "internal",
150  * otherwise only if the route is the "internal" route for the logical net.
151  */
152 inet_sendroute(rt, dst)
153 	struct rt_entry *rt;
154 	struct sockaddr_in *dst;
155 {
156 	register u_long r =
157 	    ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr);
158 	register u_long d = ntohl(dst->sin_addr.s_addr);
159 
160 	if (IN_CLASSA(r)) {
161 		if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) {
162 			if ((r & IN_CLASSA_HOST) == 0)
163 				return ((rt->rt_state & RTS_INTERNAL) == 0);
164 			return (1);
165 		}
166 		if (r & IN_CLASSA_HOST)
167 			return (0);
168 		return ((rt->rt_state & RTS_INTERNAL) != 0);
169 	} else if (IN_CLASSB(r)) {
170 		if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) {
171 			if ((r & IN_CLASSB_HOST) == 0)
172 				return ((rt->rt_state & RTS_INTERNAL) == 0);
173 			return (1);
174 		}
175 		if (r & IN_CLASSB_HOST)
176 			return (0);
177 		return ((rt->rt_state & RTS_INTERNAL) != 0);
178 	} else {
179 		if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) {
180 			if ((r & IN_CLASSC_HOST) == 0)
181 				return ((rt->rt_state & RTS_INTERNAL) == 0);
182 			return (1);
183 		}
184 		if (r & IN_CLASSC_HOST)
185 			return (0);
186 		return ((rt->rt_state & RTS_INTERNAL) != 0);
187 	}
188 }
189