|
Lines 174-202
Link Here
|
| 174 |
* ifsin: address of interface being examined. |
174 |
* ifsin: address of interface being examined. |
| 175 |
* clntsin: address that client want us to contact |
175 |
* clntsin: address that client want us to contact |
| 176 |
* it on |
176 |
* it on |
| 177 |
* servsin: local address of RPC service. |
|
|
| 178 |
* sinmask: netmask of this interface |
177 |
* sinmask: netmask of this interface |
| 179 |
* newsin: initially a copy of clntsin, eventually |
|
|
| 180 |
* the merged address |
| 181 |
*/ |
178 |
*/ |
| 182 |
servsin = (struct sockaddr_in *)serv_sa; |
|
|
| 183 |
clntsin = (struct sockaddr_in *)clnt_sa; |
179 |
clntsin = (struct sockaddr_in *)clnt_sa; |
| 184 |
sinmask = (struct sockaddr_in *)ifap->ifa_netmask; |
180 |
sinmask = (struct sockaddr_in *)ifap->ifa_netmask; |
| 185 |
newsin = (struct sockaddr_in *)&ss; |
|
|
| 186 |
ifsin = (struct sockaddr_in *)ifap->ifa_addr; |
181 |
ifsin = (struct sockaddr_in *)ifap->ifa_addr; |
| 187 |
if (!bitmaskcmp(&ifsin->sin_addr, &clntsin->sin_addr, |
182 |
if (!bitmaskcmp(&ifsin->sin_addr, &clntsin->sin_addr, |
| 188 |
&sinmask->sin_addr, sizeof (struct in_addr))) { |
183 |
&sinmask->sin_addr, sizeof (struct in_addr))) |
| 189 |
/* |
|
|
| 190 |
* Found it. |
| 191 |
*/ |
| 192 |
memcpy(newsin, ifap->ifa_addr, |
| 193 |
clnt_sa->sa_len); |
| 194 |
newsin->sin_port = servsin->sin_port; |
| 195 |
tbuf.len = clnt_sa->sa_len; |
| 196 |
tbuf.maxlen = sizeof (struct sockaddr_storage); |
| 197 |
tbuf.buf = newsin; |
| 198 |
goto found; |
184 |
goto found; |
| 199 |
} |
|
|
| 200 |
break; |
185 |
break; |
| 201 |
#ifdef INET6 |
186 |
#ifdef INET6 |
| 202 |
case AF_INET6: |
187 |
case AF_INET6: |
|
Lines 205-214
Link Here
|
| 205 |
* ifsin6: address of interface being examined. |
190 |
* ifsin6: address of interface being examined. |
| 206 |
* clntsin6: address that client want us to contact |
191 |
* clntsin6: address that client want us to contact |
| 207 |
* it on |
192 |
* it on |
| 208 |
* servsin6: local address of RPC service. |
|
|
| 209 |
* sin6mask: netmask of this interface |
193 |
* sin6mask: netmask of this interface |
| 210 |
* newsin6: initially a copy of clntsin, eventually |
|
|
| 211 |
* the merged address |
| 212 |
* |
194 |
* |
| 213 |
* For v6 link local addresses, if the client contacted |
195 |
* For v6 link local addresses, if the client contacted |
| 214 |
* us via a link-local address, and wants us to reply |
196 |
* us via a link-local address, and wants us to reply |
|
Lines 218-244
Link Here
|
| 218 |
ifsin6 = (struct sockaddr_in6 *)ifap->ifa_addr; |
200 |
ifsin6 = (struct sockaddr_in6 *)ifap->ifa_addr; |
| 219 |
in6_fillscopeid(ifsin6); |
201 |
in6_fillscopeid(ifsin6); |
| 220 |
clntsin6 = (struct sockaddr_in6 *)clnt_sa; |
202 |
clntsin6 = (struct sockaddr_in6 *)clnt_sa; |
| 221 |
servsin6 = (struct sockaddr_in6 *)serv_sa; |
|
|
| 222 |
sin6mask = (struct sockaddr_in6 *)ifap->ifa_netmask; |
203 |
sin6mask = (struct sockaddr_in6 *)ifap->ifa_netmask; |
| 223 |
newsin6 = (struct sockaddr_in6 *)&ss; |
|
|
| 224 |
if (IN6_IS_ADDR_LINKLOCAL(&ifsin6->sin6_addr) && |
204 |
if (IN6_IS_ADDR_LINKLOCAL(&ifsin6->sin6_addr) && |
| 225 |
IN6_IS_ADDR_LINKLOCAL(&realsin6->sin6_addr) && |
205 |
IN6_IS_ADDR_LINKLOCAL(&realsin6->sin6_addr) && |
| 226 |
IN6_IS_ADDR_LINKLOCAL(&clntsin6->sin6_addr)) { |
206 |
IN6_IS_ADDR_LINKLOCAL(&clntsin6->sin6_addr)) { |
| 227 |
if (ifsin6->sin6_scope_id != |
207 |
if (ifsin6->sin6_scope_id != |
| 228 |
realsin6->sin6_scope_id) |
208 |
realsin6->sin6_scope_id) |
| 229 |
continue; |
209 |
continue; |
| 230 |
match: |
|
|
| 231 |
memcpy(newsin6, ifsin6, clnt_sa->sa_len); |
| 232 |
newsin6->sin6_port = servsin6->sin6_port; |
| 233 |
tbuf.maxlen = sizeof (struct sockaddr_storage); |
| 234 |
tbuf.len = clnt_sa->sa_len; |
| 235 |
tbuf.buf = newsin6; |
| 236 |
goto found; |
210 |
goto found; |
| 237 |
} |
211 |
} |
| 238 |
if (!bitmaskcmp(&ifsin6->sin6_addr, |
212 |
if (!bitmaskcmp(&ifsin6->sin6_addr, |
| 239 |
&clntsin6->sin6_addr, &sin6mask->sin6_addr, |
213 |
&clntsin6->sin6_addr, &sin6mask->sin6_addr, |
| 240 |
sizeof (struct in6_addr))) |
214 |
sizeof (struct in6_addr))) |
| 241 |
goto match; |
215 |
goto found; |
| 242 |
break; |
216 |
break; |
| 243 |
#endif |
217 |
#endif |
| 244 |
default: |
218 |
default: |
|
Lines 268-275
Link Here
|
| 268 |
} |
242 |
} |
| 269 |
ifap = bestif; |
243 |
ifap = bestif; |
| 270 |
found: |
244 |
found: |
| 271 |
if (ifap != NULL) |
245 |
if (ifap != NULL) { |
|
|
246 |
memcpy(newsin, ifap->ifa_addr, clnt_sa->sa_len); |
| 247 |
tbuf.len = clnt_sa->sa_len; |
| 248 |
tbuf.maxlen = sizeof (struct sockaddr_storage); |
| 249 |
tbuf.buf = &ss; |
| 250 |
|
| 251 |
switch (clnt->sa_family) { |
| 252 |
case AF_INET: |
| 253 |
servsin = (struct sockaddr_in *)serv_sa; |
| 254 |
newsin = (struct sockaddr_in *)&ss; |
| 255 |
newsin->sin_port = servsin->sin_port; |
| 256 |
break; |
| 257 |
#ifdef INET6 |
| 258 |
case AF_INET6: |
| 259 |
servsin6 = (struct sockaddr_in6 *)serv_sa; |
| 260 |
newsin6 = (struct sockaddr_in6 *)&ss; |
| 261 |
newsin6->sin6_port = servsin6->sin6_port; |
| 262 |
break; |
| 263 |
#endif |
| 264 |
default: |
| 265 |
goto freeit; |
| 266 |
} |
| 267 |
|
| 272 |
ret = taddr2uaddr(nconf, &tbuf); |
268 |
ret = taddr2uaddr(nconf, &tbuf); |
|
|
269 |
} |
| 273 |
freeit: |
270 |
freeit: |
| 274 |
freenetconfigent(nconf); |
271 |
freenetconfigent(nconf); |
| 275 |
free(serv_sa); |
272 |
free(serv_sa); |