better heuristic
[unix-history] / usr / src / sbin / routed / inet.c
CommitLineData
5ff67f98
DF
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
76a2200d 7#ifndef lint
97cb3618 8static char sccsid[] = "@(#)inet.c 5.4 (Berkeley) %G%";
5ff67f98
DF
9#endif not lint
10
76a2200d
MK
11/*
12 * Temporarily, copy these routines from the kernel,
13 * as we need to know about subnets.
14 */
15#include "defs.h"
16
d002aa8c
MK
17extern struct interface *ifnet;
18
76a2200d 19/*
d002aa8c 20 * Formulate an Internet address from network + host.
76a2200d
MK
21 */
22struct in_addr
d002aa8c
MK
23inet_makeaddr(net, host)
24 u_long net, host;
76a2200d 25{
d002aa8c
MK
26 register struct interface *ifp;
27 register u_long mask;
76a2200d
MK
28 u_long addr;
29
d002aa8c
MK
30 if (IN_CLASSA(net))
31 mask = IN_CLASSA_HOST;
32 else if (IN_CLASSB(net))
33 mask = IN_CLASSB_HOST;
76a2200d 34 else
d002aa8c
MK
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);
76a2200d
MK
42 addr = htonl(addr);
43 return (*(struct in_addr *)&addr);
44}
45
46/*
47 * Return the network number from an internet address.
48 */
49inet_netof(in)
50 struct in_addr in;
51{
52 register u_long i = ntohl(in.s_addr);
d002aa8c 53 register u_long net;
e1fe8748 54 register struct interface *ifp;
76a2200d 55
d002aa8c
MK
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;
e1fe8748
MK
62
63 /*
d002aa8c 64 * Check whether network is a subnet;
e1fe8748
MK
65 * if so, return subnet number.
66 */
d002aa8c
MK
67 for (ifp = ifnet; ifp; ifp = ifp->int_next)
68 if ((ifp->int_netmask & net) == ifp->int_net)
69 return (i & ifp->int_subnetmask);
e1fe8748 70 return (net);
76a2200d
MK
71}
72
73/*
74 * Return the host portion of an internet address.
75 */
76inet_lnaof(in)
77 struct in_addr in;
78{
79 register u_long i = ntohl(in.s_addr);
d002aa8c 80 register u_long net, host;
e1fe8748 81 register struct interface *ifp;
76a2200d
MK
82
83 if (IN_CLASSA(i)) {
d002aa8c
MK
84 net = i & IN_CLASSA_NET;
85 host = i & IN_CLASSA_HOST;
76a2200d 86 } else if (IN_CLASSB(i)) {
d002aa8c
MK
87 net = i & IN_CLASSB_NET;
88 host = i & IN_CLASSB_HOST;
76a2200d 89 } else {
d002aa8c
MK
90 net = i & IN_CLASSC_NET;
91 host = i & IN_CLASSC_HOST;
76a2200d 92 }
76a2200d 93
e1fe8748 94 /*
d002aa8c 95 * Check whether network is a subnet;
e1fe8748
MK
96 * if so, use the modified interpretation of `host'.
97 */
d002aa8c
MK
98 for (ifp = ifnet; ifp; ifp = ifp->int_next)
99 if ((ifp->int_netmask & net) == ifp->int_net)
100 return (host &~ ifp->int_subnetmask);
e1fe8748 101 return (host);
76a2200d 102}
4fad5a6e
MK
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 */
109inet_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
4fad5a6e
MK
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) {
97cb3618
MK
133 if (host &~ ifp->int_subnetmask)
134 return (RTF_HOST);
135 else if (ifp->int_subnetmask != ifp->int_netmask)
4fad5a6e
MK
136 return (RTF_SUBNET);
137 else
97cb3618 138 return (0); /* network */
4fad5a6e 139 }
97cb3618
MK
140 if (host == 0)
141 return (0); /* network */
142 else
143 return (RTF_HOST);
4fad5a6e
MK
144}
145
146/*
97cb3618 147 * Return true if a route to subnet of route rt should be sent to dst.
4fad5a6e 148 * Send it only if dst is on the same logical network,
97cb3618 149 * or the route is the "internal" route for the net.
4fad5a6e 150 */
09069ad0
MK
151inet_sendsubnet(rt, dst)
152 struct rt_entry *rt;
153 struct sockaddr_in *dst;
4fad5a6e 154{
09069ad0
MK
155 register u_long r =
156 ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr);
4fad5a6e
MK
157 register u_long d = ntohl(dst->sin_addr.s_addr);
158
09069ad0
MK
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);
4fad5a6e 163 return (1);
09069ad0 164 }
97cb3618
MK
165 if (r & IN_CLASSA_HOST)
166 return (0);
167 return ((rt->rt_state & RTS_INTERNAL) != 0);
09069ad0
MK
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);
4fad5a6e 172 return (1);
09069ad0 173 }
97cb3618
MK
174 if (r & IN_CLASSB_HOST)
175 return (0);
176 return ((rt->rt_state & RTS_INTERNAL) != 0);
4fad5a6e 177 } else {
09069ad0
MK
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);
4fad5a6e 181 return (1);
09069ad0 182 }
97cb3618
MK
183 if (r & IN_CLASSC_HOST)
184 return (0);
185 return ((rt->rt_state & RTS_INTERNAL) != 0);
4fad5a6e
MK
186 }
187}