summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/ifconfig/ifconfig.c64
-rw-r--r--sbin/route/route.c96
2 files changed, 128 insertions, 32 deletions
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 3e1af69..8b567bf 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -94,6 +94,11 @@ static const char rcsid[] =
#include "ifconfig.h"
+/* wrapper for KAME-special getnameinfo() */
+#ifndef NI_WITHSCOPEID
+#define NI_WITHSCOPEID 0
+#endif
+
struct ifreq ifr, ridreq;
struct ifaliasreq addreq;
#ifdef INET6
@@ -119,7 +124,7 @@ static int ip6lifetime;
struct afswtch;
#ifdef INET6
-char ntop_buf[INET6_ADDRSTRLEN]; /*inet_ntop()*/
+char addr_buf[MAXHOSTNAMELEN *2 + 1]; /*for getnameinfo()*/
#endif
void Perror __P((const char *cmd));
@@ -969,6 +974,7 @@ in6_status(s, info)
u_int32_t flags6;
struct in6_addrlifetime lifetime;
time_t t = time(NULL);
+ int error;
memset(&null_sin, 0, sizeof(null_sin));
@@ -995,9 +1001,24 @@ in6_status(s, info)
lifetime = ifr6.ifr_ifru.ifru_lifetime;
close(s6);
- printf("\tinet6 %s ", inet_ntop(AF_INET6, &sin->sin6_addr,
- ntop_buf, sizeof(ntop_buf)));
+ /* XXX: embedded link local addr check */
+ if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr) &&
+ *(u_short *)&sin->sin6_addr.s6_addr[2] != 0) {
+ u_short index;
+
+ index = *(u_short *)&sin->sin6_addr.s6_addr[2];
+ *(u_short *)&sin->sin6_addr.s6_addr[2] = 0;
+ if (sin->sin6_scope_id == 0)
+ sin->sin6_scope_id = ntohs(index);
+ }
+ error = getnameinfo((struct sockaddr *)sin, sin->sin6_len, addr_buf,
+ sizeof(addr_buf), NULL, 0,
+ NI_NUMERICHOST|NI_WITHSCOPEID);
+ if (error != 0)
+ inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf,
+ sizeof(addr_buf));
+ printf("\tinet6 %s ", addr_buf);
if (flags & IFF_POINTOPOINT) {
/* note RTAX_BRD overlap with IFF_BROADCAST */
@@ -1007,8 +1028,27 @@ in6_status(s, info)
* address.
*/
if (sin && sin->sin6_family == AF_INET6) {
- printf("--> %s ", inet_ntop(AF_INET6, &sin->sin6_addr,
- ntop_buf, sizeof(ntop_buf)));
+ int error;
+
+ /* XXX: embedded link local addr check */
+ if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr) &&
+ *(u_short *)&sin->sin6_addr.s6_addr[2] != 0) {
+ u_short index;
+
+ index = *(u_short *)&sin->sin6_addr.s6_addr[2];
+ *(u_short *)&sin->sin6_addr.s6_addr[2] = 0;
+ if (sin->sin6_scope_id == 0)
+ sin->sin6_scope_id = ntohs(index);
+ }
+
+ error = getnameinfo((struct sockaddr *)sin,
+ sin->sin6_len, addr_buf,
+ sizeof(addr_buf), NULL, 0,
+ NI_NUMERICHOST|NI_WITHSCOPEID);
+ if (error != 0)
+ inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf,
+ sizeof(addr_buf));
+ printf("--> %s ", addr_buf);
}
}
@@ -1213,6 +1253,8 @@ in6_getaddr(s, which)
int which;
{
register struct sockaddr_in6 *sin = sin6tab[which];
+ struct addrinfo hints, *res;
+ int error = -1;
newaddr &= 1;
@@ -1220,8 +1262,16 @@ in6_getaddr(s, which)
if (which != MASK)
sin->sin6_family = AF_INET6;
- if (inet_pton(AF_INET6, s, &sin->sin6_addr) != 1)
- errx(1, "%s: bad value", s);
+ if (sin->sin6_family == AF_INET6) {
+ bzero(&hints, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET6;
+ error = getaddrinfo(s, NULL, &hints, &res);
+ }
+ if (error != 0) {
+ if (inet_pton(AF_INET6, s, &sin->sin6_addr) != 1)
+ errx(1, "%s: bad value", s);
+ } else
+ bcopy(res->ai_addr, sin, res->ai_addrlen);
}
void
diff --git a/sbin/route/route.c b/sbin/route/route.c
index 3a87f51..6e67c40 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -72,6 +72,11 @@ static const char rcsid[] =
#include <sysexits.h>
#include <unistd.h>
+/* wrapper for KAME-special getnameinfo() */
+#ifndef NI_WITHSCOPEID
+#define NI_WITHSCOPEID 0
+#endif
+
struct keytab {
char *kt_cp;
int kt_i;
@@ -104,6 +109,9 @@ struct rt_metrics rt_metrics;
u_long rtm_inits;
int atalk_aton __P((const char *, struct at_addr *));
char *atalk_ntoa __P((struct at_addr));
+#ifdef INET6
+char *inet6_ntoa __P((struct sockaddr *sa));
+#endif
char *routename(), *netname();
void flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf();
void print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();
@@ -114,7 +122,7 @@ extern char *iso_ntoa();
void usage __P((const char *)) __dead2;
#ifdef INET6
-char ntop_buf[INET6_ADDRSTRLEN]; /*for inet_ntop()*/
+char name_buf[MAXHOSTNAMELEN * 2 + 1]; /*for getnameinfo()*/
#endif
void
@@ -361,17 +369,8 @@ routename(sa)
#ifdef INET6
case AF_INET6:
- { struct sockaddr_in6 *sin6;
- int gap;
-
- sin6 = (struct sockaddr_in6 *)sa;
- gap = sizeof(struct sockaddr_in6) - sin6->sin6_len;
- if (gap > 0)
- bzero((char *)(sin6) + sin6->sin6_len, gap);
- (void) snprintf(line, sizeof(line), "%s",
- inet_ntop(AF_INET6, &sin6->sin6_addr,
- ntop_buf, sizeof(ntop_buf)));
- }
+ (void) snprintf(line, sizeof(line), "%s", inet6_ntoa(sa));
+ break;
#endif
case AF_APPLETALK:
@@ -473,17 +472,8 @@ netname(sa)
#ifdef INET6
case AF_INET6:
- { struct in6_addr in6;
- int gap;
-
- in6 = ((struct sockaddr_in6 *)sa)->sin6_addr;
- gap = sizeof(struct sockaddr_in6) - sa->sa_len;
- if (gap > 0)
- bzero((char *)(&in6 + 1) - gap, gap);
- (void)snprintf(line, sizeof(line), "%s",
- inet_ntop(AF_INET6, &in6, ntop_buf,
- sizeof(ntop_buf)));
- }
+ (void) snprintf(line, sizeof(line), "%s", inet6_ntoa(sa));
+ break;
#endif
case AF_APPLETALK:
@@ -917,11 +907,25 @@ getaddr(which, s, hpp)
switch (afamily) {
#ifdef INET6
case AF_INET6:
- if (inet_pton(AF_INET6, s, (void *)&su->sin6.sin6_addr) != 1) {
- (void) fprintf(stderr, "%s: bad value\n", s);
+ {
+ struct addrinfo hints, *res;
+ int error;
+
+ bzero(&hints, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET6;
+
+ error = getaddrinfo(s, NULL, &hints, &res);
+ if (error != 0) {
+ (void) fprintf(stderr, "%s: bad value\n",
+ gai_strerror(error));
+ if (error == EAI_SYSTEM)
+ (void) fprintf(stderr, "%s\n",
+ strerror(errno));
exit(1);
}
+ bcopy(res->ai_addr, &su->sa, res->ai_addrlen);
return 0;
+ }
#endif
#ifdef NS
@@ -1613,3 +1617,45 @@ atalk_ntoa(struct at_addr at)
(void) snprintf(buf, sizeof(buf), "%u.%u", ntohs(at.s_net), at.s_node);
return(buf);
}
+
+#ifdef INET6
+char *
+inet6_ntoa(struct sockaddr *sa)
+{
+ char *cp;
+ struct sockaddr_in6 *sin6;
+ int error = -1, gap;
+
+ cp = NULL;
+ sin6 = (struct sockaddr_in6 *)sa;
+ gap = sizeof(struct sockaddr_in6) - sin6->sin6_len;
+ if (gap > 0)
+ bzero((char *)(sin6) + sin6->sin6_len, gap);
+
+ /* XXX: embedded link local addr check */
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
+ *(u_short *)&sin6->sin6_addr.s6_addr[2] != 0) {
+ u_short index;
+
+ index = *(u_short *)&sin6->sin6_addr.s6_addr[2];
+ *(u_short *)&sin6->sin6_addr.s6_addr[2] = 0;
+ if (sin6->sin6_scope_id == 0)
+ sin6->sin6_scope_id = ntohs(index);
+ }
+
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || sa->sa_len < 4)
+ cp = "default";
+ if (cp == 0 && !nflag)
+ error = getnameinfo(sa, sa->sa_len, name_buf, sizeof(name_buf),
+ NULL, 0, NI_NAMEREQD);
+ if (error != 0)
+ error = getnameinfo(sa, sa->sa_len, name_buf,
+ sizeof(name_buf), NULL, 0,
+ NI_NUMERICHOST|NI_WITHSCOPEID);
+ if (error != 0)
+ inet_ntop(AF_INET6, &sin6->sin6_addr, name_buf,
+ sizeof(name_buf));
+
+ return (cp != NULL) ? cp : name_buf;
+}
+#endif
OpenPOWER on IntegriCloud