diff options
author | itojun <> | 2000-04-26 14:46:47 +0000 |
---|---|---|
committer | itojun <> | 2000-04-26 14:46:47 +0000 |
commit | 5e878c0e17bc8bd1f2a61d2702264ebad9534cad (patch) | |
tree | c4690c8ad9437c3758eb0c1adac30fccefebfcba | |
parent | 8738c88e88662a775664d029d71e0085093dcd9f (diff) | |
download | openbsd-5e878c0e17bc8bd1f2a61d2702264ebad9534cad.tar.gz openbsd-5e878c0e17bc8bd1f2a61d2702264ebad9534cad.tar.bz2 openbsd-5e878c0e17bc8bd1f2a61d2702264ebad9534cad.zip |
bring in latest KAME implementation.
conforms to draft-ietf-ipngwg-scopedaddr-format-01.txt.
behavior change: returns numeric scopeid if we can't convert to string
removed #if 0'ed portion which we will never revisit.
-rw-r--r-- | src/lib/libc/net/getnameinfo.c | 185 |
1 files changed, 112 insertions, 73 deletions
diff --git a/src/lib/libc/net/getnameinfo.c b/src/lib/libc/net/getnameinfo.c index c174b8a7ea..33e628c623 100644 --- a/src/lib/libc/net/getnameinfo.c +++ b/src/lib/libc/net/getnameinfo.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: getnameinfo.c,v 1.12 2000/03/13 02:22:12 itojun Exp $ */ | 1 | /* $OpenBSD: getnameinfo.c,v 1.13 2000/04/26 14:46:47 itojun Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | 4 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
@@ -37,9 +37,15 @@ | |||
37 | * - RFC2553 says that we should raise error on short buffer. X/Open says | 37 | * - RFC2553 says that we should raise error on short buffer. X/Open says |
38 | * we need to truncate the result. We obey RFC2553 (and X/Open should be | 38 | * we need to truncate the result. We obey RFC2553 (and X/Open should be |
39 | * modified). | 39 | * modified). |
40 | * - What is "local" in NI_FQDN? | ||
41 | * - NI_NAMEREQD and NI_NUMERICHOST conflict with each other. | ||
42 | * - (KAME extension) NI_WITHSCOPEID when called with global address, | ||
43 | * and sin6_scope_id filled | ||
40 | */ | 44 | */ |
41 | 45 | ||
46 | #ifndef INET6 | ||
42 | #define INET6 | 47 | #define INET6 |
48 | #endif | ||
43 | 49 | ||
44 | #include <sys/types.h> | 50 | #include <sys/types.h> |
45 | #include <sys/socket.h> | 51 | #include <sys/socket.h> |
@@ -79,7 +85,9 @@ struct sockinet { | |||
79 | }; | 85 | }; |
80 | 86 | ||
81 | #ifdef INET6 | 87 | #ifdef INET6 |
82 | static char *ip6_sa2str __P((struct sockaddr_in6 *, char *, int)); | 88 | static int ip6_parsenumeric __P((const struct sockaddr *, char *, char *, |
89 | int, int)); | ||
90 | static int ip6_sa2str __P((struct sockaddr_in6 *, char *, size_t, int)); | ||
83 | #endif | 91 | #endif |
84 | 92 | ||
85 | #define ENI_NOSOCKET 0 | 93 | #define ENI_NOSOCKET 0 |
@@ -207,69 +215,40 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) | |||
207 | /* NUMERICHOST and NAMEREQD conflicts with each other */ | 215 | /* NUMERICHOST and NAMEREQD conflicts with each other */ |
208 | if (flags & NI_NAMEREQD) | 216 | if (flags & NI_NAMEREQD) |
209 | return ENI_NOHOSTNAME; | 217 | return ENI_NOHOSTNAME; |
210 | if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) | ||
211 | == NULL) | ||
212 | return ENI_SYSTEM; | ||
213 | numaddrlen = strlen(numaddr); | ||
214 | if (numaddrlen + 1 > hostlen) /* don't forget terminator */ | ||
215 | return ENI_MEMORY; | ||
216 | strcpy(host, numaddr); | ||
217 | #if defined(INET6) && defined(NI_WITHSCOPEID) | ||
218 | if (afd->a_af == AF_INET6 && | ||
219 | (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)addr) || | ||
220 | IN6_IS_ADDR_MULTICAST((struct in6_addr *)addr)) && | ||
221 | ((struct sockaddr_in6 *)sa)->sin6_scope_id) { | ||
222 | #ifndef ALWAYS_WITHSCOPE | ||
223 | if (flags & NI_WITHSCOPEID) | ||
224 | #endif /* !ALWAYS_WITHSCOPE */ | ||
225 | { | ||
226 | char scopebuf[MAXHOSTNAMELEN], *s; | ||
227 | int scopelen; | ||
228 | |||
229 | if ((s = ip6_sa2str((struct sockaddr_in6 *)sa, | ||
230 | scopebuf, 0)) == NULL) | ||
231 | /* XXX what should we do? */ | ||
232 | strcpy(scopebuf, "0"); | ||
233 | 218 | ||
234 | scopelen = strlen(scopebuf); | 219 | switch(afd->a_af) { |
235 | if (scopelen + 1 + numaddrlen + 1 > hostlen) | 220 | #ifdef INET6 |
236 | return ENI_MEMORY; | 221 | case AF_INET6: |
222 | { | ||
223 | int error; | ||
237 | 224 | ||
238 | #if 0 | 225 | if ((error = ip6_parsenumeric(sa, addr, host, |
239 | /* | 226 | hostlen, flags)) != 0) |
240 | * construct <scopeid><delim><numeric-addr> | 227 | return(error); |
241 | */ | 228 | break; |
242 | /* | 229 | } |
243 | * Shift the host string to allocate | ||
244 | * space for the scope ID part. | ||
245 | */ | ||
246 | memmove(host + scopelen + 1, host, | ||
247 | numaddrlen); | ||
248 | /* copy the scope ID and the delimiter */ | ||
249 | memcpy(host, scopebuf, scopelen); | ||
250 | host[scopelen] = SCOPE_DELIMITER; | ||
251 | host[scopelen + 1 + numaddrlen] = '\0'; | ||
252 | #else | ||
253 | /* | ||
254 | * construct <numeric-addr><delim><scopeid> | ||
255 | */ | ||
256 | memcpy(host + numaddrlen + 1, scopebuf, | ||
257 | scopelen); | ||
258 | host[numaddrlen] = SCOPE_DELIMITER; | ||
259 | host[numaddrlen + 1 + scopelen] = '\0'; | ||
260 | #endif | 230 | #endif |
261 | } | 231 | default: |
232 | if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) | ||
233 | == NULL) | ||
234 | return ENI_SYSTEM; | ||
235 | numaddrlen = strlen(numaddr); | ||
236 | if (numaddrlen + 1 > hostlen) /* don't forget terminator */ | ||
237 | return ENI_MEMORY; | ||
238 | strcpy(host, numaddr); | ||
239 | break; | ||
262 | } | 240 | } |
263 | #endif /* INET6 */ | ||
264 | } else { | 241 | } else { |
265 | hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); | 242 | hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); |
266 | h_error = h_errno; | 243 | h_error = h_errno; |
267 | 244 | ||
268 | if (hp) { | 245 | if (hp) { |
269 | #if 0 | 246 | #if 0 |
247 | /* | ||
248 | * commented out, since "for local host" is not | ||
249 | * implemented here - see RFC2553 p30 | ||
250 | */ | ||
270 | if (flags & NI_NOFQDN) { | 251 | if (flags & NI_NOFQDN) { |
271 | char *p; | ||
272 | |||
273 | p = strchr(hp->h_name, '.'); | 252 | p = strchr(hp->h_name, '.'); |
274 | if (p) | 253 | if (p) |
275 | *p = '\0'; | 254 | *p = '\0'; |
@@ -282,23 +261,82 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) | |||
282 | } else { | 261 | } else { |
283 | if (flags & NI_NAMEREQD) | 262 | if (flags & NI_NAMEREQD) |
284 | return ENI_NOHOSTNAME; | 263 | return ENI_NOHOSTNAME; |
285 | if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) | 264 | switch(afd->a_af) { |
286 | == NULL) | 265 | #ifdef INET6 |
287 | return ENI_NOHOSTNAME; | 266 | case AF_INET6: |
288 | if (strlen(numaddr) > hostlen) | 267 | { |
289 | return ENI_MEMORY; | 268 | int error; |
290 | strcpy(host, numaddr); | 269 | |
270 | if ((error = ip6_parsenumeric(sa, addr, host, | ||
271 | hostlen, | ||
272 | flags)) != 0) | ||
273 | return(error); | ||
274 | break; | ||
275 | } | ||
276 | #endif | ||
277 | default: | ||
278 | if (inet_ntop(afd->a_af, addr, host, | ||
279 | hostlen) == NULL) | ||
280 | return ENI_SYSTEM; | ||
281 | break; | ||
282 | } | ||
291 | } | 283 | } |
292 | } | 284 | } |
293 | return SUCCESS; | 285 | return SUCCESS; |
294 | } | 286 | } |
295 | 287 | ||
296 | #ifdef INET6 | 288 | #ifdef INET6 |
289 | static int | ||
290 | ip6_parsenumeric(sa, addr, host, hostlen, flags) | ||
291 | const struct sockaddr *sa; | ||
292 | char *addr, *host; | ||
293 | int flags, hostlen; | ||
294 | { | ||
295 | int numaddrlen; | ||
296 | char numaddr[512]; | ||
297 | |||
298 | if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) | ||
299 | == NULL) | ||
300 | return ENI_SYSTEM; | ||
301 | |||
302 | numaddrlen = strlen(numaddr); | ||
303 | if (numaddrlen + 1 > hostlen) /* don't forget terminator */ | ||
304 | return ENI_MEMORY; | ||
305 | strcpy(host, numaddr); | ||
306 | |||
307 | #ifdef NI_WITHSCOPEID | ||
308 | if (((struct sockaddr_in6 *)sa)->sin6_scope_id) { | ||
309 | if (flags & NI_WITHSCOPEID) | ||
310 | { | ||
311 | char scopebuf[MAXHOSTNAMELEN]; | ||
312 | int scopelen; | ||
313 | |||
314 | /* ip6_sa2str never fails */ | ||
315 | scopelen = ip6_sa2str((struct sockaddr_in6 *)sa, | ||
316 | scopebuf, sizeof(scopebuf), | ||
317 | 0); | ||
318 | if (scopelen + 1 + numaddrlen + 1 > hostlen) | ||
319 | return ENI_MEMORY; | ||
320 | /* | ||
321 | * construct <numeric-addr><delim><scopeid> | ||
322 | */ | ||
323 | memcpy(host + numaddrlen + 1, scopebuf, | ||
324 | scopelen); | ||
325 | host[numaddrlen] = SCOPE_DELIMITER; | ||
326 | host[numaddrlen + 1 + scopelen] = '\0'; | ||
327 | } | ||
328 | } | ||
329 | #endif /* NI_WITHSCOPEID */ | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
297 | /* ARGSUSED */ | 334 | /* ARGSUSED */ |
298 | static char * | 335 | static int |
299 | ip6_sa2str(sa6, buf, flags) | 336 | ip6_sa2str(sa6, buf, bufsiz, flags) |
300 | struct sockaddr_in6 *sa6; | 337 | struct sockaddr_in6 *sa6; |
301 | char *buf; | 338 | char *buf; |
339 | size_t bufsiz; | ||
302 | int flags; | 340 | int flags; |
303 | { | 341 | { |
304 | unsigned int ifindex = (unsigned int)sa6->sin6_scope_id; | 342 | unsigned int ifindex = (unsigned int)sa6->sin6_scope_id; |
@@ -306,19 +344,20 @@ ip6_sa2str(sa6, buf, flags) | |||
306 | 344 | ||
307 | #ifdef notyet | 345 | #ifdef notyet |
308 | if (flags & NI_NUMERICSCOPE) { | 346 | if (flags & NI_NUMERICSCOPE) { |
309 | sprintf(buf, "%d", sa6->sin6_scope_id); | 347 | return(snprintf(buf, bufsiz, "%d", sa6->sin6_scope_id)); |
310 | return(buf); | ||
311 | } | 348 | } |
312 | #endif | 349 | #endif |
313 | 350 | ||
314 | if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) | 351 | /* if_indextoname() does not take buffer size. not a good api... */ |
315 | return(if_indextoname(ifindex, buf)); | 352 | if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) && |
316 | 353 | bufsiz >= IF_NAMESIZE) { | |
317 | if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6)) | 354 | char *p = if_indextoname(ifindex, buf); |
318 | return(NULL); /* XXX */ | 355 | if (p) { |
319 | if (IN6_IS_ADDR_MC_ORGLOCAL(a6)) | 356 | return(strlen(p)); |
320 | return(NULL); /* XXX */ | 357 | } |
358 | } | ||
321 | 359 | ||
322 | return(NULL); /* XXX */ | 360 | /* last resort */ |
361 | return(snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id)); | ||
323 | } | 362 | } |
324 | #endif | 363 | #endif /* INET6 */ |