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
inet_makeaddr(net,host)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 */
inet_maskof(inaddr)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