Do RADIUS accounting on IPV6CP.
MFC after: 1 week
This commit is contained in:
parent
3a0fbd5a35
commit
29e5dc90df
@ -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
|
||||
};
|
||||
|
||||
|
@ -872,8 +872,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,
|
||||
@ -939,8 +938,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,
|
||||
|
@ -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)
|
||||
|
@ -946,13 +946,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;
|
||||
@ -1009,21 +1028,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));
|
||||
|
@ -73,8 +73,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) \
|
||||
@ -89,9 +99,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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user