diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2005-09-21 01:43:08 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2005-09-21 01:43:08 +0000 |
commit | cc6820380396af432f8046febbda99ceb867f2eb (patch) | |
tree | 1e5a227d5cd32ab0fa7c15002b518982242f93d1 /usr.sbin | |
parent | 80f7eed5cc8a4974151407b6fbde542635e507e4 (diff) |
Do RADIUS accounting on IPV6CP.
From ume FreeBSD
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/ppp/ppp/bundle.h | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ipcp.c | 8 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ipv6cp.c | 45 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radius.c | 56 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radius.h | 24 |
5 files changed, 115 insertions, 23 deletions
diff --git a/usr.sbin/ppp/ppp/bundle.h b/usr.sbin/ppp/ppp/bundle.h index 1523285c74d..268ea568fcc 100644 --- a/usr.sbin/ppp/ppp/bundle.h +++ b/usr.sbin/ppp/ppp/bundle.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: bundle.h,v 1.25 2005/07/18 22:51:03 brad Exp $ + * $OpenBSD: bundle.h,v 1.26 2005/09/21 01:43:06 brad Exp $ */ #define PHASE_DEAD 0 /* Link is dead */ @@ -146,6 +146,9 @@ struct bundle { #ifndef NORADIUS struct radius radius; /* Info retrieved from radius server */ struct radacct radacct; +#ifndef NOINET6 + struct radacct radacct6; +#endif #endif }; diff --git a/usr.sbin/ppp/ppp/ipcp.c b/usr.sbin/ppp/ppp/ipcp.c index 6463c44c28e..935effe62e4 100644 --- a/usr.sbin/ppp/ppp/ipcp.c +++ b/usr.sbin/ppp/ppp/ipcp.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: ipcp.c,v 1.41 2005/07/17 19:13:24 brad Exp $ + * $OpenBSD: ipcp.c,v 1.42 2005/09/21 01:43:07 brad Exp $ */ #include <sys/param.h> @@ -873,8 +873,7 @@ IpcpLayerDown(struct fsm *fp) #ifndef NORADIUS radius_Account(&fp->bundle->radius, &fp->bundle->radacct, - fp->bundle->links, RAD_STOP, &ipcp->peer_ip, &ipcp->ifmask, - &ipcp->throughput); + fp->bundle->links, RAD_STOP, &ipcp->throughput); if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) system_Select(fp->bundle, fp->bundle->radius.filterid, LINKDOWNFILE, @@ -940,8 +939,9 @@ IpcpLayerUp(struct fsm *fp) return 0; #ifndef NORADIUS + radius_Account_Set_Ip(&fp->bundle->radacct, &ipcp->peer_ip, &ipcp->ifmask); radius_Account(&fp->bundle->radius, &fp->bundle->radacct, fp->bundle->links, - RAD_START, &ipcp->peer_ip, &ipcp->ifmask, &ipcp->throughput); + RAD_START, &ipcp->throughput); if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) system_Select(fp->bundle, fp->bundle->radius.filterid, LINKUPFILE, diff --git a/usr.sbin/ppp/ppp/ipv6cp.c b/usr.sbin/ppp/ppp/ipv6cp.c index df17924adac..6adbdf2c840 100644 --- a/usr.sbin/ppp/ppp/ipv6cp.c +++ b/usr.sbin/ppp/ppp/ipv6cp.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: ipv6cp.c,v 1.7 2005/09/21 01:16:05 brad Exp $ + * $OpenBSD: ipv6cp.c,v 1.8 2005/09/21 01:43:07 brad Exp $ */ #include <sys/param.h> @@ -472,13 +472,33 @@ ipv6cp_LayerUp(struct fsm *fp) log_Printf(LogIPV6CP, "myaddr %s hisaddr = %s\n", tbuff, ncpaddr_ntoa(&ipv6cp->hisaddr)); - /* XXX: Call radius_Account() */ +#ifndef NORADIUS + radius_Account_Set_Ipv6(&fp->bundle->radacct6, ipv6cp->his_ifid); + radius_Account(&fp->bundle->radius, &fp->bundle->radacct6, + fp->bundle->links, RAD_START, &ipv6cp->throughput); + + /* + * XXX: Avoid duplicate evaluation of filterid between IPCP and + * IPV6CP. When IPCP is enabled and rejected, filterid is not + * evaluated. + */ + if (!Enabled(fp->bundle, OPT_IPCP)) { + if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) + system_Select(fp->bundle, fp->bundle->radius.filterid, LINKUPFILE, + NULL, NULL); + } +#endif /* * XXX this stuff should really live in the FSM. Our config should * associate executable sections in files with events. */ if (system_Select(fp->bundle, tbuff, LINKUPFILE, NULL, NULL) < 0) { + /* + * XXX: Avoid duplicate evaluation of label between IPCP and + * IPV6CP. When IPCP is enabled and rejected, label is not + * evaluated. + */ if (bundle_GetLabel(fp->bundle) && !Enabled(fp->bundle, OPT_IPCP)) { if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle), LINKUPFILE, NULL, NULL) < 0) @@ -505,13 +525,32 @@ ipv6cp_LayerDown(struct fsm *fp) snprintf(addr, sizeof addr, "%s", ncpaddr_ntoa(&ipv6cp->myaddr)); log_Printf(LogIPV6CP, "%s: LayerDown: %s\n", fp->link->name, addr); - /* XXX: Call radius_Account() */ +#ifndef NORADIUS + radius_Account(&fp->bundle->radius, &fp->bundle->radacct6, + fp->bundle->links, RAD_STOP, &ipv6cp->throughput); + + /* + * XXX: Avoid duplicate evaluation of filterid between IPCP and + * IPV6CP. When IPCP is enabled and rejected, filterid is not + * evaluated. + */ + if (!Enabled(fp->bundle, OPT_IPCP)) { + if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) + system_Select(fp->bundle, fp->bundle->radius.filterid, LINKDOWNFILE, + NULL, NULL); + } +#endif /* * XXX this stuff should really live in the FSM. Our config should * associate executable sections in files with events. */ if (system_Select(fp->bundle, addr, LINKDOWNFILE, NULL, NULL) < 0) { + /* + * XXX: Avoid duplicate evaluation of label between IPCP and + * IPV6CP. When IPCP is enabled and rejected, label is not + * evaluated. + */ if (bundle_GetLabel(fp->bundle) && !Enabled(fp->bundle, OPT_IPCP)) { if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle), LINKDOWNFILE, NULL, NULL) < 0) diff --git a/usr.sbin/ppp/ppp/radius.c b/usr.sbin/ppp/ppp/radius.c index 6a3050259c1..05640ca6528 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.27 2005/09/21 01:16:05 brad Exp $ + * $OpenBSD: radius.c,v 1.28 2005/09/21 01:43:07 brad Exp $ * */ @@ -949,13 +949,32 @@ radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, return 1; } +/* Fetch IP, netmask from IPCP */ +void +radius_Account_Set_Ip(struct radacct *ac, struct in_addr *peer_ip, + struct in_addr *netmask) +{ + ac->proto = PROTO_IPCP; + memcpy(&ac->ip.addr, peer_ip, sizeof(ac->ip.addr)); + memcpy(&ac->ip.mask, netmask, sizeof(ac->ip.mask)); +} + +#ifndef NOINET6 +/* Fetch interface-id from IPV6CP */ +void +radius_Account_Set_Ipv6(struct radacct *ac, u_char *ifid) +{ + ac->proto = PROTO_IPV6CP; + memcpy(&ac->ipv6.ifid, ifid, sizeof(ac->ipv6.ifid)); +} +#endif + /* * Send an accounting request to the RADIUS server */ void radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, - int acct_type, struct in_addr *peer_ip, struct in_addr *netmask, - struct pppThroughput *stats) + int acct_type, struct pppThroughput *stats) { struct timeval tv; int got; @@ -1012,21 +1031,38 @@ radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, snprintf(ac->multi_session_id, sizeof ac->multi_session_id, "%s", dl->bundle->ncp.mp.active ? dl->bundle->ncp.mp.server.socket.sun_path : ""); - - /* Fetch IP, netmask from IPCP */ - memcpy(&ac->ip, peer_ip, sizeof(ac->ip)); - memcpy(&ac->mask, netmask, sizeof(ac->mask)); }; if (rad_put_string(r->cx.rad, RAD_USER_NAME, ac->user_name) != 0 || rad_put_int(r->cx.rad, RAD_SERVICE_TYPE, RAD_FRAMED) != 0 || - rad_put_int(r->cx.rad, RAD_FRAMED_PROTOCOL, RAD_PPP) != 0 || - rad_put_addr(r->cx.rad, RAD_FRAMED_IP_ADDRESS, ac->ip) != 0 || - rad_put_addr(r->cx.rad, RAD_FRAMED_IP_NETMASK, ac->mask) != 0) { + rad_put_int(r->cx.rad, RAD_FRAMED_PROTOCOL, RAD_PPP) != 0) { log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); rad_close(r->cx.rad); return; } + switch (ac->proto) { + case PROTO_IPCP: + if (rad_put_addr(r->cx.rad, RAD_FRAMED_IP_ADDRESS, ac->ip.addr) != 0 || + rad_put_addr(r->cx.rad, RAD_FRAMED_IP_NETMASK, ac->ip.mask) != 0) { + log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + break; +#ifndef NOINET6 + case PROTO_IPV6CP: + if (rad_put_attr(r->cx.rad, RAD_FRAMED_INTERFACE_ID, ac->ipv6.ifid, + sizeof(ac->ipv6.ifid)) != 0) { + log_Printf(LogERROR, "rad_put_attr: %s\n", rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + break; +#endif + default: + /* We don't log any protocol specific information */ + break; + } if (gethostname(hostname, sizeof hostname) != 0) log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno)); diff --git a/usr.sbin/ppp/ppp/radius.h b/usr.sbin/ppp/ppp/radius.h index 406761e4043..7fa40f57356 100644 --- a/usr.sbin/ppp/ppp/radius.h +++ b/usr.sbin/ppp/ppp/radius.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: radius.h,v 1.12 2005/09/21 01:16:05 brad Exp $ + * $OpenBSD: radius.h,v 1.13 2005/09/21 01:43:07 brad Exp $ */ #define MPPE_POLICY_ALLOWED 1 @@ -74,8 +74,18 @@ struct radacct { char session_id[256]; /* Unique session ID */ char multi_session_id[51]; /* Unique MP session ID */ int authentic; /* How the session has been authenticated */ - struct in_addr ip; - struct in_addr mask; + u_short proto; /* Protocol number */ + union { + struct { + struct in_addr addr; + struct in_addr mask; + } ip; +#ifndef NOINET6 + struct { + u_char ifid[8]; + } ipv6; +#endif + }; }; #define descriptor2radius(d) \ @@ -90,9 +100,13 @@ extern void radius_Show(struct radius *, struct prompt *); extern int radius_Authenticate(struct radius *, struct authinfo *, const char *, const char *, int, const char *, int); +extern void radius_Account_Set_Ip(struct radacct *, struct in_addr *, + struct in_addr *); +#ifndef NOINET6 +extern void radius_Account_Set_Ipv6(struct radacct *, u_char *); +#endif extern void radius_Account(struct radius *, struct radacct *, - struct datalink *, int, struct in_addr *, - struct in_addr *, struct pppThroughput *); + struct datalink *, int, struct pppThroughput *); /* An (int) parameter to radius_Account, from radlib.h */ #if !defined(RAD_START) |