Support IPv6 scoped addr in ifconfig and route

IPv6 scoped addr display is not yet supported by ifconfig
   and route. Now almost of IPv6 apps support it, so its support
   in ifconfig and route is important to keep consisetncy, and
   to avoid user confusion.

Approved by: jkh
This commit is contained in:
Yoshinobu Inoue 2000-02-10 03:03:09 +00:00
parent be26adb5b6
commit 94fafad064
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=57108
2 changed files with 128 additions and 32 deletions

View File

@ -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

View File

@ -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