diff options
author | shin <shin@FreeBSD.org> | 1999-12-07 17:39:16 +0000 |
---|---|---|
committer | shin <shin@FreeBSD.org> | 1999-12-07 17:39:16 +0000 |
commit | 70f0bdf6818a73c858bc47a23afc1e9d7c56d716 (patch) | |
tree | 446280db4239de7d7d9030c47d2c30515a265a54 /sbin/route | |
parent | 7bdf4b7db0db632bec3b1040d83cdfbdb35e59cd (diff) | |
download | FreeBSD-src-70f0bdf6818a73c858bc47a23afc1e9d7c56d716.zip FreeBSD-src-70f0bdf6818a73c858bc47a23afc1e9d7c56d716.tar.gz |
udp IPv6 support, IPv6/IPv4 tunneling support in kernel,
packet divert at kernel for IPv6/IPv4 translater daemon
This includes queue related patch submitted by jburkhol@home.com.
Submitted by: queue related patch from jburkhol@home.com
Reviewed by: freebsd-arch, cvs-committers
Obtained from: KAME project
Diffstat (limited to 'sbin/route')
-rw-r--r-- | sbin/route/Makefile | 2 | ||||
-rw-r--r-- | sbin/route/keywords | 3 | ||||
-rw-r--r-- | sbin/route/route.8 | 25 | ||||
-rw-r--r-- | sbin/route/route.c | 150 |
4 files changed, 172 insertions, 8 deletions
diff --git a/sbin/route/Makefile b/sbin/route/Makefile index 56679e1..e581d8c 100644 --- a/sbin/route/Makefile +++ b/sbin/route/Makefile @@ -1,9 +1,11 @@ # @(#)Makefile 8.1 (Berkeley) 6/5/93 +# $FreeBSD$ PROG= route MAN8= route.8 SRCS= route.c keywords.h CFLAGS+=-I. -Wall -DNS +#CFLAGS+=-DINET6 CLEANFILES+=keywords.h BINMODE=4555 diff --git a/sbin/route/keywords b/sbin/route/keywords index 07a0ddc..00080a7 100644 --- a/sbin/route/keywords +++ b/sbin/route/keywords @@ -1,4 +1,5 @@ # @(#)keywords 8.2 (Berkeley) 3/19/94 +# $FreeBSD$ add atalk @@ -19,6 +20,7 @@ interface ifa ifp inet +inet6 iso link llinfo @@ -31,6 +33,7 @@ net netmask nostatic osi +prefixlen proto1 proto2 recvpipe diff --git a/sbin/route/route.8 b/sbin/route/route.8 index 04cd23a..d8a36b9 100644 --- a/sbin/route/route.8 +++ b/sbin/route/route.8 @@ -69,7 +69,7 @@ Bypass attempts to print host and network names symbolically when reporting actions. (The process of translating between symbolic names and numerical equivalents can be quite time consuming, and may require correct operation of the network; thus it may be expedient -to forgo this, especially when attempting to repair networking operations). +to forgot this, especially when attempting to repair networking operations). .It Fl v (verbose) Print additional details. .It Fl q @@ -120,6 +120,7 @@ When the address family may is specified by any of the .Fl osi , .Fl xns , .Fl atalk , +.Fl inet6 , or .Fl inet modifiers, only routes having destinations with addresses in the @@ -225,6 +226,28 @@ One specifies an additional ensuing address parameter The implicit network mask generated in the AF_INET case can be overridden by making sure this option follows the destination parameter. .Pp +For +.Dv AF_INET6 , +the +.Fl prefixlen +qualifier +is available instead of the +.Fl mask +qualifier because non-continuous masks are not allowed in IPv6. +For example, +.Fl prefixlen Li 32 +specifies network mask of +.Li ffff:ffff:0000:0000:0000:0000:0000:0000 +to be used. +The default value of prefixlen is 64 to get along with +the aggregatable address. +But 0 is assumed if +.Cm default +is specified. +Note that the qualifier works only for +.Dv AF_INET6 +address family. +.Pp Routes have associated flags which influence operation of the protocols when sending to destinations matched by the routes. These flags may be set (or sometimes cleared) diff --git a/sbin/route/route.c b/sbin/route/route.c index e0260b1..8576d75 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -84,6 +84,9 @@ struct ortentry route; union sockunion { struct sockaddr sa; struct sockaddr_in sin; +#ifdef INET6 + struct sockaddr_in6 sin6; +#endif struct sockaddr_at sat; #ifdef NS struct sockaddr_ns sns; @@ -105,10 +108,15 @@ char *routename(), *netname(); void flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf(); void print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr(); int getaddr(), rtmsg(), x25_makemask(); +int prefixlen(); extern char *iso_ntoa(); void usage __P((const char *)) __dead2; +#ifdef INET6 +char ntop_buf[INET6_ADDRSTRLEN]; /*for inet_ntop()*/ +#endif + void usage(cp) const char *cp; @@ -219,6 +227,11 @@ flushroutes(argc, argv) case K_INET: af = AF_INET; break; +#ifdef INET6 + case K_INET6: + af = AF_INET6; + break; +#endif case K_ATALK: af = AF_APPLETALK; break; @@ -346,6 +359,21 @@ routename(sa) break; } +#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))); + } +#endif + case AF_APPLETALK: (void) snprintf(line, sizeof(line), "atalk %s", atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr)); @@ -443,6 +471,21 @@ netname(sa) break; } +#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))); + } +#endif + case AF_APPLETALK: (void) snprintf(line, sizeof(line), "atalk %s", atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr)); @@ -526,6 +569,19 @@ newroute(argc, argv) af = AF_INET; aflen = sizeof(struct sockaddr_in); break; +#ifdef INET6 + case K_INET6: + af = AF_INET6; + aflen = sizeof(struct sockaddr_in6); + if (prefixlen("64") != 64) { + fprintf(stderr, "internal error: " + "setting prefixlen=64\n"); + exit(1); + } + forcenet = 0; + ishost = 1; + break; +#endif case K_ATALK: af = AF_APPLETALK; aflen = sizeof(struct sockaddr_at); @@ -614,6 +670,17 @@ newroute(argc, argv) case K_NET: forcenet++; break; + case K_PREFIXLEN: + if (!--argc) + usage((char *)NULL); + if (prefixlen(*++argv) == -1) { + forcenet = 0; + ishost = 1; + } else { + forcenet = 1; + ishost = 0; + } + break; case K_MTU: case K_HOPCOUNT: case K_EXPIRE: @@ -641,8 +708,15 @@ newroute(argc, argv) } } } - if (forcehost) + if (forcehost) { ishost = 1; +#ifdef INET6 + if (af == AF_INET6) { + rtm_addrs &= ~RTA_NETMASK; + memset((void *)&so_mask, 0, sizeof(so_mask)); + } +#endif + } if (forcenet) ishost = 0; flags |= RTF_UP; @@ -754,11 +828,13 @@ getaddr(which, s, hpp) struct netent *np; u_long val; char *q,qs; + int afamily; /* local copy of af so we can change it */ if (af == 0) { af = AF_INET; aflen = sizeof(struct sockaddr_in); } + afamily = af; rtm_addrs |= which; switch (which) { case RTA_DST: @@ -818,6 +894,7 @@ getaddr(which, s, hpp) break; case RTA_IFP: su = &so_ifp; + afamily = AF_LINK; break; case RTA_IFA: su = &so_ifa; @@ -827,7 +904,7 @@ getaddr(which, s, hpp) /*NOTREACHED*/ } su->sa.sa_len = aflen; - su->sa.sa_family = af; /* cases that don't want it have left already */ + su->sa.sa_family = afamily; /* cases that don't want it have left already */ if (strcmp(s, "default") == 0) { /* * Default is net 0.0.0.0/0 @@ -844,7 +921,16 @@ getaddr(which, s, hpp) } return (0); } - switch (af) { + 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); + exit(1); + } + return 0; +#endif + #ifdef NS case AF_NS: if (which == RTA_DST) { @@ -926,6 +1012,51 @@ netdone: errx(EX_NOHOST, "bad address: %s", s); } +int +prefixlen(s) + char *s; +{ + int len = atoi(s), q, r; + int max; + char *p; + + rtm_addrs |= RTA_NETMASK; + switch (af) { +#ifdef INET6 + case AF_INET6: + max = 128; + p = (char *)&so_mask.sin6.sin6_addr; + break; +#endif + case AF_INET: + max = 32; + p = (char *)&so_mask.sin.sin_addr; + break; + default: + (void) fprintf(stderr, "prefixlen not supported in this af\n"); + exit(1); + /*NOTREACHED*/ + } + + if (len < 0 || max < len) { + (void) fprintf(stderr, "%s: bad value\n", s); + exit(1); + } + + q = len >> 3; + r = len & 7; + so_mask.sa.sa_family = af; + so_mask.sa.sa_len = aflen; + memset((void *)p, 0, max / 8); + if (q > 0) + memset((void *)p, 0xff, q); + if (r > 0) + *((u_char *)p + q) = (0xff00 >> r) & 0xff; + if (len == max) + return -1; + else + return len; +} #ifdef NS short ns_nullh[] = {0,0,0}; @@ -971,9 +1102,9 @@ ns_print(sns) else *cport = 0; - (void) snprintf(mybuf, sizeof(mybuf), "%lxH.%s%s", - (unsigned long)ntohl(net.long_e), - host, cport); + (void) snprintf(mybuf, sizeof(mybuf), "%lxH.%s%s", + (unsigned long)ntohl(net.long_e), + host, cport); return (mybuf); } #endif @@ -1017,8 +1148,10 @@ monitor() exit(0); } for(;;) { + time_t now; n = read(s, msg, 2048); - (void) printf("got message of size %d\n", n); + now = time(NULL); + (void) printf("got message of size %d on %s", n, ctime(&now)); print_rtmsg((struct rt_msghdr *)msg, n); } } @@ -1115,6 +1248,9 @@ mask_addr() case AF_NS: #endif case AF_INET: +#ifdef INET6 + case AF_INET6: +#endif case AF_APPLETALK: case 0: return; |