support extended scoped address notation (fe80::1%de0).
it hides implementation detail (embedded ifid) from the users.
This commit is contained in:
parent
8bd19349a1
commit
bfbec7cf43
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: route.c,v 1.35 1999/12/03 05:43:00 itojun Exp $ */
|
||||
/* $NetBSD: route.c,v 1.36 2000/04/20 12:08:50 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1989, 1991, 1993
|
||||
|
@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1991, 1993\n\
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)route.c 8.6 (Berkeley) 4/28/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: route.c,v 1.35 1999/12/03 05:43:00 itojun Exp $");
|
||||
__RCSID("$NetBSD: route.c,v 1.36 2000/04/20 12:08:50 itojun Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -86,6 +86,9 @@ static char *any_ntoa __P((const struct sockaddr *));
|
|||
static void set_metric __P((char *, int));
|
||||
static void newroute __P((int, char **));
|
||||
static void inet_makenetandmask __P((u_int32_t, struct sockaddr_in *));
|
||||
#ifdef INET6
|
||||
static void inet6_makenetandmask __P((struct sockaddr_in6 *));
|
||||
#endif
|
||||
static int getaddr __P((int, char *, struct hostent **));
|
||||
static void flushroutes __P((int, char *[]));
|
||||
#ifndef SMALL
|
||||
|
@ -381,9 +384,6 @@ routename(sa)
|
|||
static char domain[MAXHOSTNAMELEN + 1];
|
||||
static int first = 1;
|
||||
struct in_addr in;
|
||||
#ifdef INET6
|
||||
static char ntop_buf[NI_MAXHOST];
|
||||
#endif
|
||||
|
||||
if (first) {
|
||||
first = 0;
|
||||
|
@ -429,14 +429,35 @@ routename(sa)
|
|||
#ifndef SMALL
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
{ struct in6_addr in6;
|
||||
int gap;
|
||||
{
|
||||
struct sockaddr_in6 sin6;
|
||||
int niflags;
|
||||
|
||||
in6 = ((struct sockaddr_in6 *)sa)->sin6_addr;
|
||||
gap = 24 - sa->sa_len;
|
||||
if (gap > 0)
|
||||
bzero((char *)(&in6 + 1) - gap, gap);
|
||||
return ((char *)inet_ntop(AF_INET6, &in6, ntop_buf, sizeof(ntop_buf)));
|
||||
#ifdef NI_WITHSCOPEID
|
||||
niflags = NI_WITHSCOPEID;
|
||||
#else
|
||||
niflags = 0;
|
||||
#endif
|
||||
if (nflag)
|
||||
niflags |= NI_NUMERICHOST;
|
||||
memset(&sin6, 0, sizeof(sin6));
|
||||
memcpy(&sin6, sa, sa->sa_len);
|
||||
sin6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
sin6.sin6_family = AF_INET6;
|
||||
#ifdef __KAME__
|
||||
if (sa->sa_len == sizeof(struct sockaddr_in6) &&
|
||||
IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr) &&
|
||||
sin6.sin6_scope_id == 0) {
|
||||
sin6.sin6_scope_id =
|
||||
ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]);
|
||||
sin6.sin6_addr.s6_addr[2] = 0;
|
||||
sin6.sin6_addr.s6_addr[3] = 0;
|
||||
}
|
||||
#endif
|
||||
if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
|
||||
line, sizeof(line), NULL, 0, niflags) != 0)
|
||||
strncpy(line, "invalid", sizeof(line));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -479,9 +500,6 @@ netname(sa)
|
|||
u_int32_t i;
|
||||
int subnetshift;
|
||||
struct in_addr in;
|
||||
#ifdef INET6
|
||||
static char ntop_buf[NI_MAXHOST];
|
||||
#endif
|
||||
|
||||
switch (sa->sa_family) {
|
||||
|
||||
|
@ -547,14 +565,35 @@ netname(sa)
|
|||
#ifndef SMALL
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
{ struct in6_addr in6;
|
||||
int gap;
|
||||
{
|
||||
struct sockaddr_in6 sin6;
|
||||
int niflags;
|
||||
|
||||
in6 = ((struct sockaddr_in6 *)sa)->sin6_addr;
|
||||
gap = 24 - sa->sa_len;
|
||||
if (gap > 0)
|
||||
bzero((char *)(&in6 + 1) - gap, gap);
|
||||
return ((char *)inet_ntop(AF_INET6, &in6, ntop_buf, sizeof(ntop_buf)));
|
||||
#ifdef NI_WITHSCOPEID
|
||||
niflags = NI_WITHSCOPEID;
|
||||
#else
|
||||
niflags = 0;
|
||||
#endif
|
||||
if (nflag)
|
||||
niflags |= NI_NUMERICHOST;
|
||||
memset(&sin6, 0, sizeof(sin6));
|
||||
memcpy(&sin6, sa, sa->sa_len);
|
||||
sin6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
sin6.sin6_family = AF_INET6;
|
||||
#ifdef __KAME__
|
||||
if (sa->sa_len == sizeof(struct sockaddr_in6) &&
|
||||
IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr) &&
|
||||
sin6.sin6_scope_id == 0) {
|
||||
sin6.sin6_scope_id =
|
||||
ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]);
|
||||
sin6.sin6_addr.s6_addr[2] = 0;
|
||||
sin6.sin6_addr.s6_addr[3] = 0;
|
||||
}
|
||||
#endif
|
||||
if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
|
||||
line, sizeof(line), NULL, 0, niflags) != 0)
|
||||
strncpy(line, "invalid", sizeof(line));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -903,6 +942,37 @@ inet_makenetandmask(net, sin)
|
|||
sin->sin_len = 1 + cp - (char *)sin;
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
/*
|
||||
* XXX the function may need more improvement...
|
||||
*/
|
||||
static void
|
||||
inet6_makenetandmask(sin6)
|
||||
struct sockaddr_in6 *sin6;
|
||||
{
|
||||
char *plen;
|
||||
struct in6_addr in6;
|
||||
|
||||
plen = NULL;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
|
||||
sin6->sin6_scope_id == 0) {
|
||||
plen = "0";
|
||||
} else if ((sin6->sin6_addr.s6_addr[0] & 0xe0) == 0x20) {
|
||||
/* aggregatable global unicast - RFC2374 */
|
||||
memset(&in6, 0, sizeof(in6));
|
||||
if (!memcmp(&sin6->sin6_addr.s6_addr[8], &in6.s6_addr[8], 8))
|
||||
plen = "64";
|
||||
else
|
||||
plen = "128";
|
||||
}
|
||||
|
||||
if (plen) {
|
||||
rtm_addrs |= RTA_NETMASK;
|
||||
prefixlen(plen);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interpret an argument as a network address of some kind,
|
||||
* returning 1 if a host address, 0 if a network address.
|
||||
|
@ -970,11 +1040,33 @@ getaddr(which, s, hpp)
|
|||
#ifndef SMALL
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (inet_pton(AF_INET6, s, (void *)&su->sin6.sin6_addr) != 1) {
|
||||
{
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = afamily; /*AF_INET6*/
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||
if (getaddrinfo(s, "0", &hints, &res) != 0 ||
|
||||
res->ai_family != AF_INET6 ||
|
||||
res->ai_addrlen != sizeof(su->sin6)) {
|
||||
(void) fprintf(stderr, "%s: bad value\n", s);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(&su->sin6, res->ai_addr, sizeof(su->sin6));
|
||||
#ifdef __KAME__
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&su->sin6.sin6_addr) &&
|
||||
su->sin6.sin6_scope_id) {
|
||||
*(u_int16_t *)&su->sin6.sin6_addr.s6_addr[2] =
|
||||
htons(su->sin6.sin6_scope_id);
|
||||
su->sin6.sin6_scope_id = 0;
|
||||
}
|
||||
#endif
|
||||
if (which == RTA_DST)
|
||||
inet6_makenetandmask(&su->sin6);
|
||||
freeaddrinfo(res);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
case AF_NS:
|
||||
|
|
Loading…
Reference in New Issue