diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2005-09-21 01:59:27 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2005-09-21 01:59:27 +0000 |
commit | 262606a9d0b37dfda3a71bb1fe1f6c2ce568c925 (patch) | |
tree | 65453ece9b96dd2e7fd29d27c65cf51a9fe13e05 /usr.sbin/ppp | |
parent | cc6820380396af432f8046febbda99ceb867f2eb (diff) |
IPV6PREFIX is set when Framed-IPv6-Prefix is defined, You may
want to pass the value to upper layer protocol such as DHCPv6
for prefix delegation.
From ume FreeBSD
Diffstat (limited to 'usr.sbin/ppp')
-rw-r--r-- | usr.sbin/ppp/ppp/command.c | 22 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ppp.8.m4 | 11 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radius.c | 46 |
3 files changed, 74 insertions, 5 deletions
diff --git a/usr.sbin/ppp/ppp/command.c b/usr.sbin/ppp/ppp/command.c index e1cf71fd638..dd69c8854cf 100644 --- a/usr.sbin/ppp/ppp/command.c +++ b/usr.sbin/ppp/ppp/command.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: command.c,v 1.88 2005/07/26 01:32:25 brad Exp $ + * $OpenBSD: command.c,v 1.89 2005/09/21 01:59:26 brad Exp $ */ #include <sys/param.h> @@ -493,6 +493,22 @@ substipv6(char *tgt, const char *oldstr, const struct ncpaddr *ip) { return subst(tgt, oldstr, ncpaddr_ntoa(ip)); } + +#ifndef NORADIUS +static char * +substipv6prefix(char *tgt, const char *oldstr, const uint8_t *ipv6prefix) +{ + uint8_t ipv6addr[INET6_ADDRSTRLEN]; + uint8_t prefix[INET6_ADDRSTRLEN + sizeof("/128") - 1]; + + if (ipv6prefix) { + inet_ntop(AF_INET6, &ipv6prefix[2], ipv6addr, sizeof(ipv6addr)); + snprintf(prefix, sizeof(prefix), "%s/%d", ipv6addr, ipv6prefix[1]); + } else + prefix[0] = '\0'; + return subst(tgt, oldstr, prefix); +} +#endif #endif void @@ -560,6 +576,10 @@ command_Expand(char **nargv, int argc, char const *const *oargv, nargv[arg] = substip(nargv[arg], "MYADDR", bundle->ncp.ipcp.my_ip); #ifndef NOINET6 nargv[arg] = substipv6(nargv[arg], "MYADDR6", &bundle->ncp.ipv6cp.myaddr); +#ifndef NORADIUS + nargv[arg] = substipv6prefix(nargv[arg], "IPV6PREFIX", + bundle->radius.ipv6prefix); +#endif #endif nargv[arg] = substull(nargv[arg], "OCTETSIN", oin); nargv[arg] = substull(nargv[arg], "OCTETSOUT", oout); diff --git a/usr.sbin/ppp/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp/ppp.8.m4 index 138cfea3c6a..6f9e6d098fe 100644 --- a/usr.sbin/ppp/ppp/ppp.8.m4 +++ b/usr.sbin/ppp/ppp/ppp.8.m4 @@ -25,7 +25,7 @@ changecom(,)dnl .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: ppp.8.m4,v 1.31 2005/09/21 01:16:05 brad Exp $ +.\" $OpenBSD: ppp.8.m4,v 1.32 2005/09/21 01:59:26 brad Exp $ .\" .Dd September 20, 1995 .Dt PPP 8 @@ -5397,6 +5397,11 @@ or .Dv HISADDR keywords. .Pp +.It RAD_FRAMED_IPV6_PREFIX +If this attribute is supplied, the value is substituted for IPV6PREFIX +in a command. +You may pass it to such as DHCPv6 for delegating an +IPv6 prefix to a peer. .It RAD_FRAMED_IPV6_ROUTE The received string is expected to be in the format .Ar dest Ns Op / Ns Ar bits @@ -5436,8 +5441,8 @@ would result in a default route to .Dv HISADDR6 . .Pp All RADIUS IPv6 routes are applied after any sticky routes are -applied, making RADIUS IPv6 routes override configured routes. This -also applies for RADIUS IPv6 routes that don't {include} the +applied, making RADIUS IPv6 routes override configured routes. +This also applies for RADIUS IPv6 routes that don't {include} the .Dv MYADDR6 or .Dv HISADDR6 diff --git a/usr.sbin/ppp/ppp/radius.c b/usr.sbin/ppp/ppp/radius.c index 05640ca6528..303c7000b9a 100644 --- a/usr.sbin/ppp/ppp/radius.c +++ b/usr.sbin/ppp/ppp/radius.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radius.c,v 1.28 2005/09/21 01:43:07 brad Exp $ + * $OpenBSD: radius.c,v 1.29 2005/09/21 01:59:26 brad Exp $ * */ @@ -219,6 +219,25 @@ demangle(struct radius *r, const void *mangled, size_t mlen, } #endif +/* XXX: This should go into librarius. */ +#ifndef NOINET6 +static uint8_t * +rad_cvt_ipv6prefix(const void *data, size_t len) +{ + const size_t ipv6len = sizeof(struct in6_addr) + 2; + uint8_t *s; + + if (len > ipv6len) + return NULL; + s = malloc(ipv6len); + if (s != NULL) { + memset(s, 0, ipv6len); + memcpy(s, data, len); + } + return s; +} +#endif + /* * rad_continue_send_request() has given us `got' (non-zero). Deal with it. */ @@ -236,6 +255,7 @@ radius_Process(struct radius *r, int got) u_int32_t ipaddr, vendor; struct in_addr ip; #ifndef NOINET6 + uint8_t ipv6addr[INET6_ADDRSTRLEN]; struct in6_addr ip6; #endif @@ -410,6 +430,13 @@ radius_Process(struct radius *r, int got) break; #ifndef NOINET6 + case RAD_FRAMED_IPV6_PREFIX: + free(r->ipv6prefix); + r->ipv6prefix = rad_cvt_ipv6prefix(data, len); + inet_ntop(AF_INET6, &r->ipv6prefix[2], ipv6addr, sizeof(ipv6addr)); + log_Printf(LogPHASE, " IPv6 %s/%d\n", ipv6addr, r->ipv6prefix[1]); + break; + case RAD_FRAMED_IPV6_ROUTE: /* * We expect a string of the format ``dest[/bits] gw [metrics]'' @@ -689,6 +716,7 @@ radius_Init(struct radius *r) r->msrepstr = NULL; r->repstr = NULL; #ifndef NOINET6 + r->ipv6prefix = NULL; r->ipv6routes = NULL; #endif r->errstr = NULL; @@ -721,6 +749,10 @@ radius_Destroy(struct radius *r) r->msrepstr = NULL; free(r->repstr); r->repstr = NULL; +#ifndef NOINET6 + free(r->ipv6prefix); + r->ipv6prefix = NULL; +#endif free(r->errstr); r->errstr = NULL; free(r->mppe.recvkey); @@ -1057,6 +1089,18 @@ radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, rad_close(r->cx.rad); return; } + if (r->ipv6prefix) { + /* + * Since PPP doesn't delegate an IPv6 prefix to a peer, + * Framed-IPv6-Prefix may be not used, actually. + */ + if (rad_put_attr(r->cx.rad, RAD_FRAMED_IPV6_PREFIX, r->ipv6prefix, + sizeof(struct in6_addr) + 2) != 0) { + log_Printf(LogERROR, "rad_put_attr: %s\n", rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + } break; #endif default: |