View | Details | Raw Unified | Return to bug 26806
Collapse All | Expand All

(-)util.c (-29 / +26 lines)
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);

Return to bug 26806