summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoritojun <>2000-04-26 14:46:47 +0000
committeritojun <>2000-04-26 14:46:47 +0000
commit5e878c0e17bc8bd1f2a61d2702264ebad9534cad (patch)
treec4690c8ad9437c3758eb0c1adac30fccefebfcba
parent8738c88e88662a775664d029d71e0085093dcd9f (diff)
downloadopenbsd-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.c185
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
82static char *ip6_sa2str __P((struct sockaddr_in6 *, char *, int)); 88static int ip6_parsenumeric __P((const struct sockaddr *, char *, char *,
89 int, int));
90static 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
289static int
290ip6_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 */
298static char * 335static int
299ip6_sa2str(sa6, buf, flags) 336ip6_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 */