use getaddrinfo/getnameinfo to parse ipv6 addresses instead of
authorreyk <reyk@openbsd.org>
Thu, 17 Jul 2008 15:10:14 +0000 (15:10 +0000)
committerreyk <reyk@openbsd.org>
Thu, 17 Jul 2008 15:10:14 +0000 (15:10 +0000)
inet_pton/inet_ntop to allow specifing and printing the IPv6 scope
identifier. synced host_v6() with ntpd's version to use getaddrinfo()
instead of inet_pton() - host_v4, host_v6, and host_dns could all use
getaddrinfo in a single function by specifing different flags but this
would diverge from the other daemons using this common interface so we
keep this little overhead.

discussed with henning@
ok pyr@

usr.sbin/relayd/log.c
usr.sbin/relayd/parse.y

index c90c1fd..e9cd8cf 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: log.c,v 1.11 2007/12/07 17:17:00 reyk Exp $   */
+/*     $OpenBSD: log.c,v 1.12 2008/07/17 15:10:14 reyk Exp $   */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -34,6 +34,7 @@
 #include <string.h>
 #include <syslog.h>
 #include <event.h>
+#include <netdb.h>
 
 #include <openssl/ssl.h>
 
@@ -218,15 +219,10 @@ print_availability(u_long cnt, u_long up)
 const char *
 print_host(struct sockaddr_storage *ss, char *buf, size_t len)
 {
-       int af = ss->ss_family;
-       void *ptr;
-
-       bzero(buf, len);
-       if (af == AF_INET)
-               ptr = &((struct sockaddr_in *)ss)->sin_addr;
-       else
-               ptr = &((struct sockaddr_in6 *)ss)->sin6_addr;
-       return (inet_ntop(af, ptr, buf, len));
+       if (getnameinfo((struct sockaddr *)ss, ss->ss_len,
+           buf, len, NULL, 0, NI_NUMERICHOST) != 0)
+               return (NULL);
+       return (buf);
 }
 
 const char *
index 7172341..fad5025 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parse.y,v 1.115 2008/06/11 18:21:19 reyk Exp $        */
+/*     $OpenBSD: parse.y,v 1.116 2008/07/17 15:10:15 reyk Exp $        */
 
 /*
  * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
@@ -1966,20 +1966,28 @@ host_v4(const char *s)
 struct address *
 host_v6(const char *s)
 {
-       struct in6_addr          ina6;
-       struct sockaddr_in6     *sin6;
-       struct address          *h;
+       struct addrinfo          hints, *res;
+       struct sockaddr_in6     *sa_in6;
+       struct address          *h = NULL;
 
-       bzero(&ina6, sizeof(ina6));
-       if (inet_pton(AF_INET6, s, &ina6) != 1)
-               return (NULL);
-
-       if ((h = calloc(1, sizeof(*h))) == NULL)
-               fatal(NULL);
-       sin6 = (struct sockaddr_in6 *)&h->ss;
-       sin6->sin6_len = sizeof(struct sockaddr_in6);
-       sin6->sin6_family = AF_INET6;
-       memcpy(&sin6->sin6_addr, &ina6, sizeof(ina6));
+       bzero(&hints, sizeof(hints));
+       hints.ai_family = AF_INET6;
+       hints.ai_socktype = SOCK_DGRAM; /* dummy */
+       hints.ai_flags = AI_NUMERICHOST;
+       if (getaddrinfo(s, "0", &hints, &res) == 0) {
+               if ((h = calloc(1, sizeof(*h))) == NULL)
+                       fatal(NULL);
+               sa_in6 = (struct sockaddr_in6 *)&h->ss;
+               sa_in6->sin6_len = sizeof(struct sockaddr_in6);
+               sa_in6->sin6_family = AF_INET6;
+               memcpy(&sa_in6->sin6_addr,
+                   &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
+                   sizeof(sa_in6->sin6_addr));
+               sa_in6->sin6_scope_id =
+                   ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
+
+               freeaddrinfo(res);
+       }
 
        return (h);
 }