diff options
author | itojun <> | 2000-02-09 12:22:09 +0000 |
---|---|---|
committer | itojun <> | 2000-02-09 12:22:09 +0000 |
commit | e198d71e66f565f1b105993a32008bab5c57e8e1 (patch) | |
tree | f29e4fda4e3e94b78fbed3641620d51be04592c6 /src/lib/libc/net/getnameinfo.c | |
parent | 4d2790bdcdf21e6500928a62b17cfc7e296d4a5a (diff) | |
download | openbsd-e198d71e66f565f1b105993a32008bab5c57e8e1.tar.gz openbsd-e198d71e66f565f1b105993a32008bab5c57e8e1.tar.bz2 openbsd-e198d71e66f565f1b105993a32008bab5c57e8e1.zip |
revise extended scoped address format support. delimiter and the order
is changed, based on discussion in ipngwg scoped address cabal.
past code: fe80::1@de0
now: de0%fe80::1
this will be in sync with next extended address format proposal
(which should be final - I don't want to make this kind of change again).
Diffstat (limited to 'src/lib/libc/net/getnameinfo.c')
-rw-r--r-- | src/lib/libc/net/getnameinfo.c | 77 |
1 files changed, 59 insertions, 18 deletions
diff --git a/src/lib/libc/net/getnameinfo.c b/src/lib/libc/net/getnameinfo.c index 8b2ca299ef..e203cd5d16 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.7 2000/01/17 08:15:27 itojun Exp $ */ | 1 | /* $OpenBSD: getnameinfo.c,v 1.8 2000/02/09 12:22:09 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. |
@@ -78,6 +78,10 @@ struct sockinet { | |||
78 | u_short si_port; | 78 | u_short si_port; |
79 | }; | 79 | }; |
80 | 80 | ||
81 | #ifdef INET6 | ||
82 | static char *ip6_sa2str __P((struct sockaddr_in6 *, char *, int)); | ||
83 | #endif | ||
84 | |||
81 | #define ENI_NOSOCKET 0 | 85 | #define ENI_NOSOCKET 0 |
82 | #define ENI_NOSERVNAME 1 | 86 | #define ENI_NOSERVNAME 1 |
83 | #define ENI_NOHOSTNAME 2 | 87 | #define ENI_NOHOSTNAME 2 |
@@ -198,13 +202,16 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) | |||
198 | * means that the caller does not want the result. | 202 | * means that the caller does not want the result. |
199 | */ | 203 | */ |
200 | } else if (flags & NI_NUMERICHOST) { | 204 | } else if (flags & NI_NUMERICHOST) { |
205 | int numaddrlen; | ||
206 | |||
201 | /* NUMERICHOST and NAMEREQD conflicts with each other */ | 207 | /* NUMERICHOST and NAMEREQD conflicts with each other */ |
202 | if (flags & NI_NAMEREQD) | 208 | if (flags & NI_NAMEREQD) |
203 | return ENI_NOHOSTNAME; | 209 | return ENI_NOHOSTNAME; |
204 | if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) | 210 | if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) |
205 | == NULL) | 211 | == NULL) |
206 | return ENI_SYSTEM; | 212 | return ENI_SYSTEM; |
207 | if (strlen(numaddr) > hostlen) | 213 | numaddrlen = strlen(numaddr); |
214 | if (numaddrlen + 1 > hostlen) /* don't forget terminator */ | ||
208 | return ENI_MEMORY; | 215 | return ENI_MEMORY; |
209 | strcpy(host, numaddr); | 216 | strcpy(host, numaddr); |
210 | #if defined(INET6) && defined(NI_WITHSCOPEID) | 217 | #if defined(INET6) && defined(NI_WITHSCOPEID) |
@@ -216,24 +223,34 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) | |||
216 | if (flags & NI_WITHSCOPEID) | 223 | if (flags & NI_WITHSCOPEID) |
217 | #endif /* !ALWAYS_WITHSCOPE */ | 224 | #endif /* !ALWAYS_WITHSCOPE */ |
218 | { | 225 | { |
219 | char *ep = strchr(host, '\0'); | 226 | char scopebuf[MAXHOSTNAMELEN], *s; |
220 | unsigned int ifindex = | 227 | int scopelen; |
221 | ((struct sockaddr_in6 *)sa)->sin6_scope_id; | ||
222 | 228 | ||
223 | *ep = SCOPE_DELIMITER; | 229 | if ((s = ip6_sa2str((struct sockaddr_in6 *)sa, |
224 | if ((if_indextoname(ifindex, ep + 1)) == NULL) | 230 | scopebuf, 0)) == NULL) |
225 | /* XXX what should we do? */ | 231 | /* XXX what should we do? */ |
226 | strncpy(ep + 1, "???", 3); | 232 | strcpy(scopebuf, "0"); |
233 | |||
234 | scopelen = strlen(scopebuf); | ||
235 | if (scopelen + 1 + numaddrlen + 1 > hostlen) | ||
236 | return ENI_MEMORY; | ||
237 | |||
238 | /* | ||
239 | * Shift the host string to allocate | ||
240 | * space for the scope ID part. | ||
241 | */ | ||
242 | memmove(host + scopelen + 1, host, | ||
243 | numaddrlen); | ||
244 | /* copy the scope ID and the delimiter */ | ||
245 | memcpy(host, scopebuf, scopelen); | ||
246 | host[scopelen] = SCOPE_DELIMITER; | ||
247 | host[scopelen + 1 + numaddrlen] = '\0'; | ||
227 | } | 248 | } |
228 | } | 249 | } |
229 | #endif /* INET6 */ | 250 | #endif /* INET6 */ |
230 | } else { | 251 | } else { |
231 | #ifdef USE_GETIPNODEBY | ||
232 | hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); | ||
233 | #else | ||
234 | hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); | 252 | hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); |
235 | h_error = h_errno; | 253 | h_error = h_errno; |
236 | #endif | ||
237 | 254 | ||
238 | if (hp) { | 255 | if (hp) { |
239 | if (flags & NI_NOFQDN) { | 256 | if (flags & NI_NOFQDN) { |
@@ -241,15 +258,9 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) | |||
241 | if (p) *p = '\0'; | 258 | if (p) *p = '\0'; |
242 | } | 259 | } |
243 | if (strlen(hp->h_name) > hostlen) { | 260 | if (strlen(hp->h_name) > hostlen) { |
244 | #ifdef USE_GETIPNODEBY | ||
245 | freehostent(hp); | ||
246 | #endif | ||
247 | return ENI_MEMORY; | 261 | return ENI_MEMORY; |
248 | } | 262 | } |
249 | strcpy(host, hp->h_name); | 263 | strcpy(host, hp->h_name); |
250 | #ifdef USE_GETIPNODEBY | ||
251 | freehostent(hp); | ||
252 | #endif | ||
253 | } else { | 264 | } else { |
254 | if (flags & NI_NAMEREQD) | 265 | if (flags & NI_NAMEREQD) |
255 | return ENI_NOHOSTNAME; | 266 | return ENI_NOHOSTNAME; |
@@ -263,3 +274,33 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) | |||
263 | } | 274 | } |
264 | return SUCCESS; | 275 | return SUCCESS; |
265 | } | 276 | } |
277 | |||
278 | #ifdef INET6 | ||
279 | /* ARGSUSED */ | ||
280 | static char * | ||
281 | ip6_sa2str(sa6, buf, flags) | ||
282 | struct sockaddr_in6 *sa6; | ||
283 | char *buf; | ||
284 | int flags; | ||
285 | { | ||
286 | unsigned int ifindex = (unsigned int)sa6->sin6_scope_id; | ||
287 | struct in6_addr *a6 = &sa6->sin6_addr; | ||
288 | |||
289 | #ifdef notyet | ||
290 | if (flags & NI_NUMERICSCOPE) { | ||
291 | sprintf(buf, "%d", sa6->sin6_scope_id); | ||
292 | return(buf); | ||
293 | } | ||
294 | #endif | ||
295 | |||
296 | if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) | ||
297 | return(if_indextoname(ifindex, buf)); | ||
298 | |||
299 | if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6)) | ||
300 | return(NULL); /* XXX */ | ||
301 | if (IN6_IS_ADDR_MC_ORGLOCAL(a6)) | ||
302 | return(NULL); /* XXX */ | ||
303 | |||
304 | return(NULL); /* XXX */ | ||
305 | } | ||
306 | #endif | ||