Commit | Line | Data |
---|---|---|
99578149 | 1 | /* in.c 6.5 84/10/19 */ |
8473bbab | 2 | |
20666ad3 JB |
3 | #include "param.h" |
4 | #include "mbuf.h" | |
5 | #include "protosw.h" | |
6 | #include "socket.h" | |
7 | #include "socketvar.h" | |
8 | #include "in.h" | |
9 | #include "in_systm.h" | |
6187f8f4 SL |
10 | #include "../net/if.h" |
11 | #include "../net/route.h" | |
8473bbab SL |
12 | #include "../net/af.h" |
13 | ||
14 | #ifdef INET | |
15 | inet_hash(sin, hp) | |
16 | register struct sockaddr_in *sin; | |
17 | struct afhash *hp; | |
18 | { | |
a8d3bf7f | 19 | |
8473bbab | 20 | hp->afh_nethash = in_netof(sin->sin_addr); |
2c48b3f8 | 21 | hp->afh_hosthash = ntohl(sin->sin_addr.s_addr); |
8473bbab SL |
22 | } |
23 | ||
24 | inet_netmatch(sin1, sin2) | |
25 | struct sockaddr_in *sin1, *sin2; | |
26 | { | |
a8d3bf7f | 27 | |
6f117122 | 28 | return (in_netof(sin1->sin_addr) == in_netof(sin2->sin_addr)); |
8473bbab SL |
29 | } |
30 | ||
31 | /* | |
32 | * Formulate an Internet address from network + host. Used in | |
33 | * building addresses stored in the ifnet structure. | |
34 | */ | |
35 | struct in_addr | |
36 | if_makeaddr(net, host) | |
37 | int net, host; | |
38 | { | |
39 | u_long addr; | |
40 | ||
3adde5ac | 41 | if (net < IN_CLASSA_MAX) |
6e7edb25 | 42 | addr = (net << IN_CLASSA_NSHIFT) | host; |
3adde5ac | 43 | else if (net < IN_CLASSB_MAX) |
6e7edb25 | 44 | addr = (net << IN_CLASSB_NSHIFT) | host; |
8473bbab | 45 | else |
6e7edb25 | 46 | addr = (net << IN_CLASSC_NSHIFT) | host; |
8473bbab | 47 | addr = htonl(addr); |
8473bbab SL |
48 | return (*(struct in_addr *)&addr); |
49 | } | |
50 | ||
51 | /* | |
a8d3bf7f | 52 | * Return the network number from an internet address. |
8473bbab SL |
53 | */ |
54 | in_netof(in) | |
55 | struct in_addr in; | |
56 | { | |
2c48b3f8 | 57 | register u_long i = ntohl(in.s_addr); |
083b2954 MK |
58 | register u_long net, subnet; |
59 | register struct ifnet *ifp; | |
8473bbab | 60 | |
3adde5ac | 61 | if (IN_CLASSA(i)) { |
083b2954 MK |
62 | net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT; |
63 | if (IN_SUBNETA(i)) { | |
64 | subnet = (i & IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT; | |
65 | /* Fall through and check whether a subnet */ | |
66 | } else | |
3adde5ac MK |
67 | return (net); |
68 | } else if (IN_CLASSB(i)) { | |
083b2954 MK |
69 | net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT; |
70 | if (IN_SUBNETB(i)) { | |
71 | subnet = (i & IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT; | |
72 | /* Fall through and check whether a subnet */ | |
73 | } else | |
3adde5ac MK |
74 | return (net); |
75 | } else { | |
083b2954 | 76 | return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); |
3adde5ac | 77 | } |
083b2954 MK |
78 | |
79 | /* | |
80 | * Check whether network is a subnet of a `local' network; | |
81 | * if so, return subnet number. | |
82 | */ | |
83 | for (ifp = ifnet; ifp; ifp = ifp->if_next) { | |
84 | if (ifp->if_addr.sa_family != AF_INET) | |
85 | continue; | |
86 | if (ifp->if_flags & IFF_LOCAL) { | |
87 | if (ifp->if_net == net) | |
88 | return (subnet); | |
89 | if ((ifp->if_net >> SUBNETSHIFT) == net) | |
90 | return (subnet); | |
91 | /* | |
92 | * Hack for use in setting if_net initially. | |
93 | */ | |
94 | if (ifp->if_net == 0) { | |
95 | register struct sockaddr_in *sin; | |
96 | sin = (struct sockaddr_in *) &ifp->if_addr; | |
97 | if (sin->sin_addr.s_addr == in.s_addr) | |
98 | return (subnet); | |
99 | } | |
100 | } | |
101 | } | |
102 | return (net); | |
8473bbab SL |
103 | } |
104 | ||
105 | /* | |
a8d3bf7f | 106 | * Return the host portion of an internet address. |
8473bbab SL |
107 | */ |
108 | in_lnaof(in) | |
109 | struct in_addr in; | |
110 | { | |
2c48b3f8 | 111 | register u_long i = ntohl(in.s_addr); |
083b2954 MK |
112 | register u_long net, host, subhost; |
113 | register struct ifnet *ifp; | |
8473bbab | 114 | |
3adde5ac | 115 | if (IN_CLASSA(i)) { |
083b2954 MK |
116 | if (IN_SUBNETA(i)) { |
117 | net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT; | |
118 | host = i & IN_CLASSA_HOST; | |
119 | subhost = i & IN_CLASSA_SUBHOST; | |
120 | /* Fall through and check whether a subnet */ | |
121 | } else | |
122 | return (i & IN_CLASSA_HOST); | |
3adde5ac | 123 | } else if (IN_CLASSB(i)) { |
083b2954 MK |
124 | if (IN_SUBNETB(i)) { |
125 | net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT; | |
126 | host = i & IN_CLASSB_HOST; | |
127 | subhost = i & IN_CLASSB_SUBHOST; | |
128 | /* Fall through and check whether a subnet */ | |
129 | } else | |
130 | return (i & IN_CLASSB_HOST); | |
3adde5ac | 131 | } else { |
083b2954 | 132 | return (i & IN_CLASSC_HOST); |
3adde5ac | 133 | } |
3adde5ac | 134 | |
083b2954 MK |
135 | /* |
136 | * Check whether network is a subnet of a `local' network; | |
137 | * if so, use the modified interpretation of `host'. | |
138 | */ | |
3adde5ac MK |
139 | for (ifp = ifnet; ifp; ifp = ifp->if_next) { |
140 | if (ifp->if_addr.sa_family != AF_INET) | |
141 | continue; | |
142 | if (ifp->if_flags & IFF_LOCAL) { | |
143 | if (ifp->if_net == net) | |
083b2954 | 144 | return (subhost); |
3adde5ac | 145 | if ((ifp->if_net >> SUBNETSHIFT) == net) |
083b2954 | 146 | return (subhost); |
3adde5ac MK |
147 | } |
148 | } | |
083b2954 | 149 | return (host); |
8473bbab SL |
150 | } |
151 | ||
99578149 MK |
152 | /* |
153 | * Return 1 if an internet address is for a ``local'' host. | |
154 | */ | |
155 | in_localaddr(in) | |
156 | struct in_addr in; | |
157 | { | |
158 | register u_long i = ntohl(in.s_addr); | |
159 | register u_long net; | |
160 | register struct ifnet *ifp; | |
161 | ||
162 | if (IN_CLASSA(i)) | |
163 | net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT; | |
164 | else if (IN_CLASSB(i)) | |
165 | net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT; | |
166 | else | |
167 | net = (i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT; | |
168 | ||
169 | for (ifp = ifnet; ifp; ifp = ifp->if_next) { | |
170 | if (ifp->if_addr.sa_family != AF_INET) | |
171 | continue; | |
172 | if (ifp->if_flags & IFF_LOCAL) { | |
173 | if (ifp->if_net == net) | |
174 | return (1); | |
175 | if ((ifp->if_net >> SUBNETSHIFT) == net) | |
176 | return (1); | |
177 | } | |
178 | } | |
179 | return (0); | |
180 | } | |
181 | ||
8473bbab SL |
182 | /* |
183 | * Initialize an interface's routing | |
184 | * table entry according to the network. | |
185 | * INTERNET SPECIFIC. | |
186 | */ | |
187 | if_rtinit(ifp, flags) | |
188 | register struct ifnet *ifp; | |
189 | int flags; | |
190 | { | |
191 | struct sockaddr_in sin; | |
192 | ||
8473bbab SL |
193 | if (ifp->if_flags & IFF_ROUTE) |
194 | return; | |
195 | bzero((caddr_t)&sin, sizeof (sin)); | |
196 | sin.sin_family = AF_INET; | |
6f117122 | 197 | sin.sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY); |
a1edc12b | 198 | rtinit((struct sockaddr *)&sin, &ifp->if_addr, flags); |
8473bbab SL |
199 | } |
200 | #endif |