sync with the latest KAME tree.

- don't use FD_SETSIZE on select
- "sin" conflicts with math library, so use sin6
- other minor updates
This commit is contained in:
itojun 2001-09-05 01:17:31 +00:00
parent 2b3a9dde88
commit a12c72c978
1 changed files with 173 additions and 117 deletions

View File

@ -1,5 +1,5 @@
/* $NetBSD: route6d.c,v 1.28 2001/06/13 04:31:52 itojun Exp $ */
/* $KAME: route6d.c,v 1.60 2001/03/08 02:15:42 onoe Exp $ */
/* $NetBSD: route6d.c,v 1.29 2001/09/05 01:17:31 itojun Exp $ */
/* $KAME: route6d.c,v 1.73 2001/09/05 01:12:34 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: route6d.c,v 1.28 2001/06/13 04:31:52 itojun Exp $");
__RCSID("$NetBSD: route6d.c,v 1.29 2001/09/05 01:17:31 itojun Exp $");
#endif
#include <stdio.h>
@ -143,6 +143,7 @@ int loopifindex = 0; /* ditto */
fd_set sockvec; /* vector to select() for receiving */
int rtsock; /* the routing socket */
int ripsock; /* socket to send/receive RIP datagram */
int maxfd; /* maximum fd for select() */
struct rip6 *ripbuf; /* packet buffer for sending */
@ -433,6 +434,8 @@ main(argc, argv)
alarm(ripinterval(INIT_INTERVAL6));
for (ifcp = ifc; ifcp; ifcp = ifcp->ifc_next) {
if (iff_find(ifcp, 'N'))
continue;
if (ifcp->ifc_index > 0 && (ifcp->ifc_flags & IFF_UP))
sendrequest(ifcp);
}
@ -461,7 +464,7 @@ main(argc, argv)
FD_COPY(&sockvec, &recvec);
signo = 0;
switch (select(FD_SETSIZE, &recvec, 0, 0, 0)) {
switch (select(maxfd + 1, &recvec, 0, 0, 0)) {
case -1:
if (errno != EINTR) {
fatal("select");
@ -661,6 +664,7 @@ init()
memset(&sockvec, 0, sizeof(sockvec));
#endif
FD_SET(ripsock, &sockvec);
maxfd = ripsock;
if (nflag == 0) {
if ((rtsock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) {
@ -668,6 +672,8 @@ init()
/*NOTREACHED*/
}
FD_SET(rtsock, &sockvec);
if (rtsock > maxfd)
maxfd = rtsock;
} else
rtsock = -1; /*just for safety */
}
@ -682,9 +688,9 @@ static int nrt;
static struct netinfo6 *np;
void
ripflush(ifcp, sin)
ripflush(ifcp, sin6)
struct ifc *ifcp;
struct sockaddr_in6 *sin;
struct sockaddr_in6 *sin6;
{
int i;
int error;
@ -692,10 +698,10 @@ ripflush(ifcp, sin)
if (ifcp)
tracet(1, "Send(%s): info(%d) to %s.%d\n",
ifcp->ifc_name, nrt,
inet6_n2p(&sin->sin6_addr), ntohs(sin->sin6_port));
inet6_n2p(&sin6->sin6_addr), ntohs(sin6->sin6_port));
else
tracet(1, "Send: info(%d) to %s.%d\n",
nrt, inet6_n2p(&sin->sin6_addr), ntohs(sin->sin6_port));
nrt, inet6_n2p(&sin6->sin6_addr), ntohs(sin6->sin6_port));
if (dflag >= 2) {
np = ripbuf->rip6_nets;
for (i = 0; i < nrt; i++, np++) {
@ -718,7 +724,7 @@ ripflush(ifcp, sin)
trace(2, "\n");
}
}
error = sendpacket(sin, RIPSIZE(nrt));
error = sendpacket(sin6, RIPSIZE(nrt));
if (error == EAFNOSUPPORT) {
/* Protocol not supported */
tracet(1, "Could not send info to %s (%s): "
@ -733,9 +739,9 @@ ripflush(ifcp, sin)
* Generate RIP6_RESPONSE packets and send them.
*/
void
ripsend(ifcp, sin, flag)
ripsend(ifcp, sin6, flag)
struct ifc *ifcp;
struct sockaddr_in6 *sin;
struct sockaddr_in6 *sin6;
int flag;
{
struct riprt *rrt;
@ -759,12 +765,12 @@ ripsend(ifcp, sin, flag)
*np = rrt->rrt_info;
np++; nrt++;
if (nrt == maxrte) {
ripflush(NULL, sin);
ripflush(NULL, sin6);
nh = NULL;
}
}
if (nrt) /* Send last packet */
ripflush(NULL, sin);
ripflush(NULL, sin6);
return;
}
@ -783,11 +789,12 @@ ripsend(ifcp, sin, flag)
rrt_info.rip6_dest = in6addr_any;
rrt_info.rip6_plen = 0;
rrt_info.rip6_metric = 1;
rrt_info.rip6_metric += ifcp->ifc_metric;
rrt_info.rip6_tag = htons(routetag & 0xffff);
np = ripbuf->rip6_nets;
*np = rrt_info;
nrt = 1;
ripflush(ifcp, sin);
ripflush(ifcp, sin6);
return;
}
@ -820,7 +827,7 @@ ripsend(ifcp, sin, flag)
(rrt->rrt_rflags & RRTF_NH_NOT_LLADDR) == 0) {
if (nh == NULL || !IN6_ARE_ADDR_EQUAL(nh, &rrt->rrt_gw)) {
if (nrt == maxrte - 2)
ripflush(ifcp, sin);
ripflush(ifcp, sin6);
np->rip6_dest = rrt->rrt_gw;
if (IN6_IS_ADDR_LINKLOCAL(&np->rip6_dest))
SET_IN6_LINKLOCAL_IFINDEX(np->rip6_dest, 0);
@ -835,7 +842,7 @@ ripsend(ifcp, sin, flag)
rrt->rrt_rflags & RRTF_NH_NOT_LLADDR)) {
/* Reset nexthop */
if (nrt == maxrte - 2)
ripflush(ifcp, sin);
ripflush(ifcp, sin6);
memset(np, 0, sizeof(struct netinfo6));
np->rip6_metric = NEXTHOP_METRIC;
nh = NULL;
@ -846,12 +853,12 @@ ripsend(ifcp, sin, flag)
*np = rrt->rrt_info;
np++; nrt++;
if (nrt == maxrte) {
ripflush(ifcp, sin);
ripflush(ifcp, sin6);
nh = NULL;
}
}
if (nrt) /* Send last packet */
ripflush(ifcp, sin);
ripflush(ifcp, sin6);
}
/*
@ -958,8 +965,8 @@ tobeadv(rrt, ifcp)
* Send a rip packet actually.
*/
int
sendpacket(sin, len)
struct sockaddr_in6 *sin;
sendpacket(sin6, len)
struct sockaddr_in6 *sin6;
int len;
{
/*
@ -976,18 +983,18 @@ sendpacket(sin, len)
struct sockaddr_in6 sincopy;
/* do not overwrite the given sin */
sincopy = *sin;
sin = &sincopy;
sincopy = *sin6;
sin6 = &sincopy;
if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)
|| IN6_IS_ADDR_MULTICAST(&sin->sin6_addr)) {
idx = IN6_LINKLOCAL_IFINDEX(sin->sin6_addr);
SET_IN6_LINKLOCAL_IFINDEX(sin->sin6_addr, 0);
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)
|| IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
idx = IN6_LINKLOCAL_IFINDEX(sin6->sin6_addr);
SET_IN6_LINKLOCAL_IFINDEX(sin6->sin6_addr, 0);
} else
idx = 0;
m.msg_name = (caddr_t)sin;
m.msg_namelen = sizeof(*sin);
m.msg_name = (caddr_t)sin6;
m.msg_namelen = sizeof(*sin6);
iov[0].iov_base = (caddr_t)ripbuf;
iov[0].iov_len = len;
m.msg_iov = iov;
@ -1334,11 +1341,11 @@ sendrequest(ifcp)
* Process a RIP6_REQUEST packet.
*/
void
riprequest(ifcp, np, nn, sin)
riprequest(ifcp, np, nn, sin6)
struct ifc *ifcp;
struct netinfo6 *np;
int nn;
struct sockaddr_in6 *sin;
struct sockaddr_in6 *sin6;
{
int i;
struct riprt *rrt;
@ -1354,12 +1361,12 @@ riprequest(ifcp, np, nn, sin)
else
np->rip6_metric = HOPCNT_INFINITY6;
}
(void)sendpacket(sin, RIPSIZE(nn));
(void)sendpacket(sin6, RIPSIZE(nn));
return;
}
/* Whole routing table dump */
trace(1, "\tRIP Request -- whole routing table\n");
ripsend(ifcp, sin, RRTF_SENDANYWAY);
ripsend(ifcp, sin6, RRTF_SENDANYWAY);
}
/*
@ -1445,20 +1452,22 @@ ifconfig1(name, sa, ifcp, s)
int s;
{
struct in6_ifreq ifr;
const struct sockaddr_in6 *sin;
const struct sockaddr_in6 *sin6;
struct ifac *ifa;
int plen;
char buf[BUFSIZ];
sin = (const struct sockaddr_in6 *)sa;
ifr.ifr_addr = *sin;
sin6 = (const struct sockaddr_in6 *)sa;
if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && !lflag)
return;
ifr.ifr_addr = *sin6;
strcpy(ifr.ifr_name, name);
if (ioctl(s, SIOCGIFNETMASK_IN6, (char *)&ifr) < 0) {
fatal("ioctl: SIOCGIFNETMASK_IN6");
/*NOTREACHED*/
}
plen = sin6mask2len(&ifr.ifr_addr);
if ((ifa = ifa_match(ifcp, &sin->sin6_addr, plen)) != NULL) {
if ((ifa = ifa_match(ifcp, &sin6->sin6_addr, plen)) != NULL) {
/* same interface found */
/* need check if something changed */
/* XXX not yet implemented */
@ -1475,10 +1484,10 @@ ifconfig1(name, sa, ifcp, s)
ifa->ifa_conf = ifcp;
ifa->ifa_next = ifcp->ifc_addr;
ifcp->ifc_addr = ifa;
ifa->ifa_addr = sin->sin6_addr;
ifa->ifa_addr = sin6->sin6_addr;
ifa->ifa_plen = plen;
if (ifcp->ifc_flags & IFF_POINTOPOINT) {
ifr.ifr_addr = *sin;
ifr.ifr_addr = *sin6;
if (ioctl(s, SIOCGIFDSTADDR_IN6, (char *)&ifr) < 0) {
fatal("ioctl: SIOCGIFDSTADDR_IN6");
/*NOTREACHED*/
@ -1508,7 +1517,8 @@ ifconfig1(name, sa, ifcp, s)
ifcp->ifc_metric = ifr.ifr_metric;
trace(1, "\tindex: %d, mtu: %d, metric: %d\n",
ifcp->ifc_index, ifcp->ifc_mtu, ifcp->ifc_metric);
}
} else
ifcp->ifc_cflags |= IFC_CHANGED;
}
/*
@ -1527,6 +1537,7 @@ rtrecv()
struct ifc *ifcp, *ic;
int iface = 0, rtable = 0;
struct sockaddr_in6 *rta[RTAX_MAX];
struct sockaddr_in6 mask;
int i, addrs;
struct riprt *rrt;
@ -1539,6 +1550,14 @@ rtrecv()
len, (u_long)sizeof(*rtm));
return;
}
if (dflag >= 2) {
fprintf(stderr, "rtmsg:\n");
for (i = 0; i < len; i++) {
fprintf(stderr, "%02x ", buf[i] & 0xff);
if (i % 16 == 15) fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
}
for (p = buf; p - buf < len; p += ((struct rt_msghdr *)p)->rtm_msglen) {
/* safety against bogus message */
@ -1661,12 +1680,23 @@ rtrecv()
fatal("rtrecv: never reach here");
/*NOTREACHED*/
case RTM_DELETE:
if (!rta[RTAX_DST] || !rta[RTAX_GATEWAY]
|| !rta[RTAX_NETMASK]) {
trace(1, "\tsome of dst/gw/netamsk are unavailable, ignored\n");
if (!rta[RTAX_DST] || !rta[RTAX_GATEWAY]) {
trace(1, "\tsome of dst/gw/netamsk are "
"unavailable, ignored\n");
break;
}
if (rt_del(rta[RTAX_DST], rta[RTAX_GATEWAY], rta[RTAX_NETMASK]) == 0) {
if ((rtm->rtm_flags & RTF_HOST) != 0) {
mask.sin6_len = sizeof(mask);
memset(&mask.sin6_addr, 0xff,
sizeof(mask.sin6_addr));
rta[RTAX_NETMASK] = &mask;
} else if (!rta[RTAX_NETMASK]) {
trace(1, "\tsome of dst/gw/netamsk are "
"unavailable, ignored\n");
break;
}
if (rt_del(rta[RTAX_DST], rta[RTAX_GATEWAY],
rta[RTAX_NETMASK]) == 0) {
rtable++; /*just to be sure*/
}
break;
@ -1688,8 +1718,8 @@ rtrecv()
ifam->ifam_index);
break;
}
rt_deladdr(ifcp, rta[RTAX_IFA], rta[RTAX_NETMASK]);
iface++;
if (!rt_deladdr(ifcp, rta[RTAX_IFA], rta[RTAX_NETMASK]))
iface++;
break;
case RTM_OLDADD:
case RTM_OLDDEL:
@ -1787,8 +1817,7 @@ rt_del(sdst, sgw, smask)
gw = &in6addr_loopback;
prefix = rrt->rrt_info.rip6_plen;
} else {
trace(1, "\tunsupported af: (gw=%d, mask=%d)\n",
sgw->sin6_family, smask->sin6_family);
trace(1, "\tunsupported af: (gw=%d)\n", sgw->sin6_family);
return -1;
}
@ -1806,9 +1835,12 @@ rt_del(sdst, sgw, smask)
trace(1, "\tno route found\n");
return -1;
}
#if 0
if ((rrt->rrt_flags & RTF_STATIC) == 0) {
trace(1, "\tyou can delete static routes only\n");
} else if (memcmp(&rrt->rrt_gw, gw, sizeof(rrt->rrt_gw)) != 0) {
} else
#endif
if (!IN6_ARE_ADDR_EQUAL(&rrt->rrt_gw, gw)) {
trace(1, "\tgw mismatch: %s <-> ",
inet6_n2p(&rrt->rrt_gw));
trace(1, "%s\n", inet6_n2p(gw));
@ -1885,8 +1917,9 @@ rt_deladdr(ifcp, sifa, smask)
if ((rrt = rtsearch(&ni6, NULL)) != NULL) {
struct in6_addr none;
memset(&none, 0, sizeof(none));
if (rrt->rrt_index == ifcp->ifc_index
&& memcmp(&rrt->rrt_gw, &none, sizeof(rrt->rrt_gw)) == 0) {
if (rrt->rrt_index == ifcp->ifc_index &&
(IN6_ARE_ADDR_EQUAL(&rrt->rrt_gw, &none) ||
IN6_IS_ADDR_LOOPBACK(&rrt->rrt_gw))) {
trace(1, "\troute found, age it\n");
if (rrt->rrt_t == 0 || rrt->rrt_t > t_lifetime) {
rrt->rrt_t = t_lifetime;
@ -1911,14 +1944,13 @@ rt_deladdr(ifcp, sifa, smask)
inet6_n2p(&ni6.rip6_dest), ni6.rip6_plen,
ifcp->ifc_index);
if ((rrt = rtsearch(&ni6, NULL)) != NULL) {
if (rrt->rrt_index == ifcp->ifc_index
&& memcmp(&rrt->rrt_gw, &ifa->ifa_addr,
sizeof(rrt->rrt_gw)) == 0) {
if (rrt->rrt_index == ifcp->ifc_index &&
IN6_ARE_ADDR_EQUAL(&rrt->rrt_gw, &ifa->ifa_addr)) {
trace(1, "\troute found, age it\n");
if (rrt->rrt_t == 0 || rrt->rrt_t > t_lifetime) {
rrt->rrt_t = t_lifetime;
rrt->rrt_info.rip6_metric =
HOPCNT_INFINITY6;
HOPCNT_INFINITY6;
updated++;
}
} else {
@ -1943,7 +1975,7 @@ ifrt(ifcp, again)
int again;
{
struct ifac *ifa;
struct riprt *rrt, *search_rrt, *prev_rrt, *loop_rrt;
struct riprt *rrt = NULL, *search_rrt, *prev_rrt, *loop_rrt;
struct netinfo6 *np;
time_t t_lifetime;
int need_trigger = 0;
@ -1990,15 +2022,8 @@ ifrt(ifcp, again)
np = &rrt->rrt_info;
search_rrt = rtsearch(np, &prev_rrt);
if (search_rrt != NULL) {
if (search_rrt->rrt_info.rip6_metric >
if (search_rrt->rrt_info.rip6_metric <=
rrt->rrt_info.rip6_metric) {
if (prev_rrt)
prev_rrt->rrt_next = rrt->rrt_next;
else
riprt = rrt->rrt_next;
delroute(&rrt->rrt_info, &rrt->rrt_gw);
free(rrt);
} else {
/* Already have better route */
if (!again) {
trace(1, "route: %s/%d: "
@ -2006,9 +2031,14 @@ ifrt(ifcp, again)
inet6_n2p(&np->rip6_dest), np->rip6_plen,
ifcp->ifc_name);
}
free(rrt);
continue;
goto next;
}
if (prev_rrt)
prev_rrt->rrt_next = rrt->rrt_next;
else
riprt = rrt->rrt_next;
delroute(&rrt->rrt_info, &rrt->rrt_gw);
}
/* Attach the route to the list */
trace(1, "route: %s/%d: register route (%s)\n",
@ -2017,6 +2047,7 @@ ifrt(ifcp, again)
rrt->rrt_next = riprt;
riprt = rrt;
addroute(rrt, &rrt->rrt_gw, ifcp);
rrt = NULL;
sendrequest(ifcp);
ripsend(ifcp, &ifcp->ifc_ripsin, 0);
need_trigger = 1;
@ -2033,6 +2064,9 @@ ifrt(ifcp, again)
}
}
}
next:
if (rrt)
free(rrt);
}
return need_trigger;
}
@ -2048,7 +2082,7 @@ ifrt_p2p(ifcp, again)
int again;
{
struct ifac *ifa;
struct riprt *rrt;
struct riprt *rrt, *orrt, *prevrrt;
struct netinfo6 *np;
struct in6_addr addr, dest;
int advert, ignore, i;
@ -2144,11 +2178,13 @@ ifrt_p2p(ifcp, again)
case P2PADVERT_ADDR:
rrt->rrt_info.rip6_dest = ifa->ifa_addr;
rrt->rrt_info.rip6_plen = 128;
rrt->rrt_gw = in6addr_loopback;
category = "addr";
break;
case P2PADVERT_DEST:
rrt->rrt_info.rip6_dest = ifa->ifa_raddr;
rrt->rrt_info.rip6_plen = 128;
rrt->rrt_gw = ifa->ifa_addr;
category = "dest";
break;
}
@ -2168,9 +2204,9 @@ ifrt_p2p(ifcp, again)
noadv = "";
rrt->rrt_info.rip6_tag = htons(routetag & 0xffff);
rrt->rrt_info.rip6_metric = 1 + ifcp->ifc_metric;
memset(&rrt->rrt_gw, 0, sizeof(struct in6_addr));
np = &rrt->rrt_info;
if (rtsearch(np, NULL) == NULL) {
orrt = rtsearch(np, &prevrrt);
if (!orrt) {
/* Attach the route to the list */
trace(1, "route: %s/%d: register route "
"(%s on %s%s)\n",
@ -2178,6 +2214,19 @@ ifrt_p2p(ifcp, again)
category, ifcp->ifc_name, noadv);
rrt->rrt_next = riprt;
riprt = rrt;
} else if (rrt->rrt_index != orrt->rrt_index ||
rrt->rrt_info.rip6_metric != orrt->rrt_info.rip6_metric) {
/* swap route */
rrt->rrt_next = orrt->rrt_next;
if (prevrrt)
prevrrt->rrt_next = rrt;
else
riprt = rrt;
free(orrt);
trace(1, "route: %s/%d: update (%s on %s%s)\n",
inet6_n2p(&np->rip6_dest), np->rip6_plen,
category, ifcp->ifc_name, noadv);
} else {
/* Already found */
if (!again) {
@ -2357,10 +2406,10 @@ ifflags(flags)
strlcpy(buf, "", sizeof(buf));
#define IFFLAG(s, f) \
do { \
if (flags & f) { \
if (flags & (f)) { \
if (buf[0]) \
strlcat(buf, ",", sizeof(buf)); \
strlcat(buf, s, sizeof(buf)); \
strlcat(buf, (s), sizeof(buf)); \
} \
} while (0)
IFFLAG("UP", IFF_UP);
@ -2448,7 +2497,7 @@ rt_entry(rtm, again)
struct sockaddr_in6 *sin6_dst, *sin6_gw, *sin6_mask;
struct sockaddr_in6 *sin6_genmask, *sin6_ifp;
char *rtmp, *ifname = NULL;
struct riprt *rrt;
struct riprt *rrt, *orrt;
struct netinfo6 *np;
int s;
@ -2515,11 +2564,7 @@ rt_entry(rtm, again)
rrt->rrt_t = time(NULL);
if (aflag == 0 && (rtm->rtm_flags & RTF_STATIC))
rrt->rrt_t = 0; /* Don't age static routes */
#if 0
np->rip6_tag = htons(routetag & 0xffff);
#else
np->rip6_tag = 0;
#endif
np->rip6_metric = rtm->rtm_rmx.rmx_hopcount;
if (np->rip6_metric < 1)
np->rip6_metric = 1;
@ -2534,7 +2579,8 @@ rt_entry(rtm, again)
else
np->rip6_plen = 0;
if (rtsearch(np, NULL)) {
orrt = rtsearch(np, NULL);
if (orrt && orrt->rrt_info.rip6_metric != HOPCNT_INFINITY6) {
/* Already found */
if (!again) {
trace(1, "route: %s/%d flags %s: already registered\n",
@ -2589,8 +2635,18 @@ rt_entry(rtm, again)
}
/* Put it to the route list */
rrt->rrt_next = riprt;
riprt = rrt;
if (orrt && orrt->rrt_info.rip6_metric == HOPCNT_INFINITY6) {
/* replace route list */
rrt->rrt_next = orrt->rrt_next;
*orrt = *rrt;
trace(1, "route: %s/%d flags %s: replace new route\n",
inet6_n2p(&np->rip6_dest), np->rip6_plen,
rtflags(rtm));
free(rrt);
} else {
rrt->rrt_next = riprt;
riprt = rrt;
}
}
int
@ -2602,7 +2658,7 @@ addroute(rrt, gw, ifcp)
struct netinfo6 *np;
u_char buf[BUFSIZ], buf1[BUFSIZ], buf2[BUFSIZ];
struct rt_msghdr *rtm;
struct sockaddr_in6 *sin;
struct sockaddr_in6 *sin6;
int len;
np = &rrt->rrt_info;
@ -2628,24 +2684,24 @@ addroute(rrt, gw, ifcp)
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
rtm->rtm_rmx.rmx_hopcount = np->rip6_metric - 1;
rtm->rtm_inits = RTV_HOPCOUNT;
sin = (struct sockaddr_in6 *)&buf[sizeof(struct rt_msghdr)];
sin6 = (struct sockaddr_in6 *)&buf[sizeof(struct rt_msghdr)];
/* Destination */
sin->sin6_len = sizeof(struct sockaddr_in6);
sin->sin6_family = AF_INET6;
sin->sin6_addr = np->rip6_dest;
sin = (struct sockaddr_in6 *)((char *)sin + ROUNDUP(sin->sin6_len));
sin6->sin6_len = sizeof(struct sockaddr_in6);
sin6->sin6_family = AF_INET6;
sin6->sin6_addr = np->rip6_dest;
sin6 = (struct sockaddr_in6 *)((char *)sin6 + ROUNDUP(sin6->sin6_len));
/* Gateway */
sin->sin6_len = sizeof(struct sockaddr_in6);
sin->sin6_family = AF_INET6;
sin->sin6_addr = *gw;
sin = (struct sockaddr_in6 *)((char *)sin + ROUNDUP(sin->sin6_len));
sin6->sin6_len = sizeof(struct sockaddr_in6);
sin6->sin6_family = AF_INET6;
sin6->sin6_addr = *gw;
sin6 = (struct sockaddr_in6 *)((char *)sin6 + ROUNDUP(sin6->sin6_len));
/* Netmask */
sin->sin6_len = sizeof(struct sockaddr_in6);
sin->sin6_family = AF_INET6;
sin->sin6_addr = *(plen2mask(np->rip6_plen));
sin = (struct sockaddr_in6 *)((char *)sin + ROUNDUP(sin->sin6_len));
sin6->sin6_len = sizeof(struct sockaddr_in6);
sin6->sin6_family = AF_INET6;
sin6->sin6_addr = *(plen2mask(np->rip6_plen));
sin6 = (struct sockaddr_in6 *)((char *)sin6 + ROUNDUP(sin6->sin6_len));
len = (char *)sin - (char *)buf;
len = (char *)sin6 - (char *)buf;
rtm->rtm_msglen = len;
if (write(rtsock, buf, len) > 0)
return 0;
@ -2673,7 +2729,7 @@ delroute(np, gw)
{
u_char buf[BUFSIZ], buf2[BUFSIZ];
struct rt_msghdr *rtm;
struct sockaddr_in6 *sin;
struct sockaddr_in6 *sin6;
int len;
inet_ntop(AF_INET6, (void *)gw, (char *)buf2, sizeof(buf2));
@ -2695,24 +2751,24 @@ delroute(np, gw)
if (np->rip6_plen == sizeof(struct in6_addr) * 8)
rtm->rtm_flags |= RTF_HOST;
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
sin = (struct sockaddr_in6 *)&buf[sizeof(struct rt_msghdr)];
sin6 = (struct sockaddr_in6 *)&buf[sizeof(struct rt_msghdr)];
/* Destination */
sin->sin6_len = sizeof(struct sockaddr_in6);
sin->sin6_family = AF_INET6;
sin->sin6_addr = np->rip6_dest;
sin = (struct sockaddr_in6 *)((char *)sin + ROUNDUP(sin->sin6_len));
sin6->sin6_len = sizeof(struct sockaddr_in6);
sin6->sin6_family = AF_INET6;
sin6->sin6_addr = np->rip6_dest;
sin6 = (struct sockaddr_in6 *)((char *)sin6 + ROUNDUP(sin6->sin6_len));
/* Gateway */
sin->sin6_len = sizeof(struct sockaddr_in6);
sin->sin6_family = AF_INET6;
sin->sin6_addr = *gw;
sin = (struct sockaddr_in6 *)((char *)sin + ROUNDUP(sin->sin6_len));
sin6->sin6_len = sizeof(struct sockaddr_in6);
sin6->sin6_family = AF_INET6;
sin6->sin6_addr = *gw;
sin6 = (struct sockaddr_in6 *)((char *)sin6 + ROUNDUP(sin6->sin6_len));
/* Netmask */
sin->sin6_len = sizeof(struct sockaddr_in6);
sin->sin6_family = AF_INET6;
sin->sin6_addr = *(plen2mask(np->rip6_plen));
sin = (struct sockaddr_in6 *)((char *)sin + ROUNDUP(sin->sin6_len));
sin6->sin6_len = sizeof(struct sockaddr_in6);
sin6->sin6_family = AF_INET6;
sin6->sin6_addr = *(plen2mask(np->rip6_plen));
sin6 = (struct sockaddr_in6 *)((char *)sin6 + ROUNDUP(sin6->sin6_len));
len = (char *)sin - (char *)buf;
len = (char *)sin6 - (char *)buf;
rtm->rtm_msglen = len;
if (write(rtsock, buf, len) >= 0)
return 0;
@ -2742,7 +2798,7 @@ getroute(np, gw)
u_long myseq;
int len;
struct rt_msghdr *rtm;
struct sockaddr_in6 *sin;
struct sockaddr_in6 *sin6;
rtm = (struct rt_msghdr *)buf;
len = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in6);
@ -2753,10 +2809,10 @@ getroute(np, gw)
rtm->rtm_seq = myseq;
rtm->rtm_addrs = RTA_DST;
rtm->rtm_msglen = len;
sin = (struct sockaddr_in6 *)&buf[sizeof(struct rt_msghdr)];
sin->sin6_len = sizeof(struct sockaddr_in6);
sin->sin6_family = AF_INET6;
sin->sin6_addr = np->rip6_dest;
sin6 = (struct sockaddr_in6 *)&buf[sizeof(struct rt_msghdr)];
sin6->sin6_len = sizeof(struct sockaddr_in6);
sin6->sin6_family = AF_INET6;
sin6->sin6_addr = np->rip6_dest;
if (write(rtsock, buf, len) < 0) {
if (errno == ESRCH) /* No such route found */
return NULL;
@ -2770,13 +2826,13 @@ getroute(np, gw)
}
rtm = (struct rt_msghdr *)buf;
} while (rtm->rtm_seq != myseq || rtm->rtm_pid != pid);
sin = (struct sockaddr_in6 *)&buf[sizeof(struct rt_msghdr)];
sin6 = (struct sockaddr_in6 *)&buf[sizeof(struct rt_msghdr)];
if (rtm->rtm_addrs & RTA_DST) {
sin = (struct sockaddr_in6 *)
((char *)sin + ROUNDUP(sin->sin6_len));
sin6 = (struct sockaddr_in6 *)
((char *)sin6 + ROUNDUP(sin6->sin6_len));
}
if (rtm->rtm_addrs & RTA_GATEWAY) {
*gw = sin->sin6_addr;
*gw = sin6->sin6_addr;
return gw;
}
return NULL;