summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2005-09-21 01:59:27 +0000
committerBrad Smith <brad@cvs.openbsd.org>2005-09-21 01:59:27 +0000
commit262606a9d0b37dfda3a71bb1fe1f6c2ce568c925 (patch)
tree65453ece9b96dd2e7fd29d27c65cf51a9fe13e05
parentcc6820380396af432f8046febbda99ceb867f2eb (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
-rw-r--r--usr.sbin/ppp/ppp/command.c22
-rw-r--r--usr.sbin/ppp/ppp/ppp.8.m411
-rw-r--r--usr.sbin/ppp/ppp/radius.c46
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: