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