diff options
-rw-r--r-- | usr.sbin/ppp/ppp/bundle.c | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/bundle.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ipcp.c | 13 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radius.c | 167 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radius.h | 21 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/throughput.c | 14 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/throughput.h | 4 |
7 files changed, 213 insertions, 12 deletions
diff --git a/usr.sbin/ppp/ppp/bundle.c b/usr.sbin/ppp/ppp/bundle.c index 3727ec96948..527d0699180 100644 --- a/usr.sbin/ppp/ppp/bundle.c +++ b/usr.sbin/ppp/ppp/bundle.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: bundle.c,v 1.46 2000/08/18 00:02:10 brian Exp $ + * $OpenBSD: bundle.c,v 1.47 2000/08/28 22:44:41 brian Exp $ */ #include <sys/param.h> @@ -902,6 +902,7 @@ bundle_Destroy(struct bundle *bundle) #ifndef NORADIUS /* Tell the radius server the bad news */ + log_Printf(LogDEBUG, "Radius: Destroy called from bundle_Destroy\n"); radius_Destroy(&bundle->radius); #endif diff --git a/usr.sbin/ppp/ppp/bundle.h b/usr.sbin/ppp/ppp/bundle.h index 37b793a0efc..f3879ab6c64 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.17 2000/07/11 22:13:02 brian Exp $ + * $OpenBSD: bundle.h,v 1.18 2000/08/28 22:44:41 brian Exp $ */ #define PHASE_DEAD 0 /* Link is dead */ @@ -136,6 +136,7 @@ struct bundle { #ifndef NORADIUS struct radius radius; /* Info retrieved from radius server */ + struct radacct radacct; #endif }; diff --git a/usr.sbin/ppp/ppp/ipcp.c b/usr.sbin/ppp/ppp/ipcp.c index 108bbc143b9..7ad0d342d70 100644 --- a/usr.sbin/ppp/ppp/ipcp.c +++ b/usr.sbin/ppp/ppp/ipcp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $OpenBSD: ipcp.c,v 1.25 2000/07/19 11:06:34 brian Exp $ + * $OpenBSD: ipcp.c,v 1.26 2000/08/28 22:44:41 brian Exp $ * * TODO: * o Support IPADDRS properly @@ -959,6 +959,12 @@ IpcpLayerDown(struct fsm *fp) s = "Interface configuration error !"; log_Printf(LogIPCP, "%s: LayerDown: %s\n", fp->link->name, s); +#ifndef NORADIUS + radius_Account(&fp->bundle->radius, &fp->bundle->radacct, + fp->bundle->links, RAD_STOP, &ipcp->peer_ip, &ipcp->ifmask, + &ipcp->throughput); +#endif + /* * XXX this stuff should really live in the FSM. Our config should * associate executable sections in files with events. @@ -1011,6 +1017,11 @@ IpcpLayerUp(struct fsm *fp) if (!ipcp_InterfaceUp(ipcp)) return 0; +#ifndef NORADIUS + radius_Account(&fp->bundle->radius, &fp->bundle->radacct, fp->bundle->links, + RAD_START, &ipcp->peer_ip, &ipcp->ifmask, &ipcp->throughput); +#endif + /* * XXX this stuff should really live in the FSM. Our config should * associate executable sections in files with events. diff --git a/usr.sbin/ppp/ppp/radius.c b/usr.sbin/ppp/ppp/radius.c index 67d39fc799a..32712f8c6e8 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.7 2000/02/27 01:38:28 brian Exp $ + * $OpenBSD: radius.c,v 1.8 2000/08/28 22:44:41 brian Exp $ * */ @@ -117,6 +117,12 @@ radius_Process(struct radius *r, int got) rad_close(r->cx.rad); return; + case RAD_ACCOUNTING_RESPONSE: + log_Printf(LogPHASE, "Radius: Accounting response received\n"); + /* No further processing for accounting requests, please */ + rad_close(r->cx.rad); + return; + case -1: log_Printf(LogPHASE, "radius: %s\n", rad_strerror(r->cx.rad)); auth_Failure(r->cx.auth); @@ -325,6 +331,7 @@ radius_Init(struct radius *r) r->desc.Read = radius_Read; r->desc.Write = radius_Write; memset(&r->cx.timer, '\0', sizeof r->cx.timer); + log_Printf(LogDEBUG, "Radius: radius_Init\n"); } /* @@ -334,6 +341,7 @@ void radius_Destroy(struct radius *r) { r->valid = 0; + log_Printf(LogDEBUG, "Radius: radius_Destroy\n"); timer_Stop(&r->cx.timer); route_DeleteAll(&r->routes); if (r->cx.fd != -1) { @@ -368,8 +376,8 @@ radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, radius_Destroy(r); - if ((r->cx.rad = rad_open()) == NULL) { - log_Printf(LogERROR, "rad_open: %s\n", strerror(errno)); + if ((r->cx.rad = rad_auth_open()) == NULL) { + log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno)); return; } @@ -462,6 +470,159 @@ radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, } /* + * 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) +{ + struct ttyent *ttyp; + struct timeval tv; + int got, slot; + char hostname[MAXHOSTNAMELEN]; + struct hostent *hp; + struct in_addr hostaddr; + + if (!*r->cfg.file) + return; + + if (r->cx.fd != -1) + /* + * We assume that our name/key/challenge is the same as last time, + * and just continue to wait for the RADIUS server(s). + */ + return; + + radius_Destroy(r); + + if ((r->cx.rad = rad_auth_open()) == NULL) { + log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno)); + return; + } + + if (rad_config(r->cx.rad, r->cfg.file) != 0) { + log_Printf(LogERROR, "rad_config: %s\n", rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + + if (rad_create_request(r->cx.rad, RAD_ACCOUNTING_REQUEST) != 0) { + log_Printf(LogERROR, "rad_create_request: %s\n", rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + + /* Grab some accounting data and initialize structure */ + if (acct_type == RAD_START) { + ac->rad_parent = r; + /* Fetch username from datalink */ + strncpy(ac->user_name, dl->peer.authname, sizeof ac->user_name); + ac->user_name[AUTHLEN-1] = '\0'; + + ac->authentic = 2; /* Assume RADIUS verified auth data */ + + /* Generate a session ID */ + snprintf(ac->session_id, sizeof ac->session_id, "%s%d-%s%lu", + dl->bundle->cfg.auth.name, (int)getpid(), + dl->peer.authname, (unsigned long)stats->uptime); + + /* And grab our MP socket name */ + 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) { + log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + + if (gethostname(hostname, sizeof hostname) != 0) + log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno)); + else { + if ((hp = gethostbyname(hostname)) != NULL) { + hostaddr.s_addr = *(u_long *)hp->h_addr; + if (rad_put_addr(r->cx.rad, RAD_NAS_IP_ADDRESS, hostaddr) != 0) { + log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", + rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + } + if (rad_put_string(r->cx.rad, RAD_NAS_IDENTIFIER, hostname) != 0) { + log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", + rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + } + + if (dl->physical->handler && + dl->physical->handler->type == TTY_DEVICE) { + setttyent(); + for (slot = 1; (ttyp = getttyent()); ++slot) + if (!strcmp(ttyp->ty_name, dl->physical->name.base)) { + if(rad_put_int(r->cx.rad, RAD_NAS_PORT, slot) != 0) { + log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", + rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + endttyent(); + return; + } + break; + } + endttyent(); + } + + if (rad_put_int(r->cx.rad, RAD_ACCT_STATUS_TYPE, acct_type) != 0 || + rad_put_string(r->cx.rad, RAD_ACCT_SESSION_ID, ac->session_id) != 0 || + rad_put_string(r->cx.rad, RAD_ACCT_MULTI_SESSION_ID, + ac->multi_session_id) != 0 || + rad_put_int(r->cx.rad, RAD_ACCT_DELAY_TIME, 0) != 0) { +/* XXX ACCT_DELAY_TIME should be increased each time a packet is waiting */ + log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + + if (acct_type == RAD_STOP) + /* Show some statistics */ + if (rad_put_int(r->cx.rad, RAD_ACCT_INPUT_OCTETS, stats->OctetsIn) != 0 || + rad_put_int(r->cx.rad, RAD_ACCT_INPUT_PACKETS, stats->PacketsIn) != 0 || + rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_OCTETS, stats->OctetsOut) != 0 || + rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_PACKETS, stats->PacketsOut) + != 0 || + rad_put_int(r->cx.rad, RAD_ACCT_SESSION_TIME, throughput_uptime(stats)) + != 0) { + log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + + if ((got = rad_init_send_request(r->cx.rad, &r->cx.fd, &tv))) + radius_Process(r, got); + else { + log_Printf(LogDEBUG, "Using radius_Timeout [%p]\n", radius_Timeout); + r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS; + r->cx.timer.func = radius_Timeout; + r->cx.timer.name = "radius"; + r->cx.timer.arg = r; + r->cx.auth = NULL; /* Not valid for accounting requests */ + timer_Start(&r->cx.timer); + } +} + +/* * How do things look at the moment ? */ void diff --git a/usr.sbin/ppp/ppp/radius.h b/usr.sbin/ppp/ppp/radius.h index a686dbc9327..a497fe50c4e 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.3 2000/02/27 01:38:28 brian Exp $ + * $OpenBSD: radius.h,v 1.4 2000/08/28 22:44:42 brian Exp $ */ struct radius { @@ -45,6 +45,16 @@ struct radius { } cfg; }; +struct radacct { + struct radius *rad_parent; /* "Parent" struct radius stored in bundle */ + char user_name[AUTHLEN]; /* Session User-Name */ + 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; +}; + #define descriptor2radius(d) \ ((d)->type == RADIUS_DESCRIPTOR ? (struct radius *)(d) : NULL) @@ -56,3 +66,12 @@ extern void radius_Destroy(struct radius *); extern void radius_Show(struct radius *, struct prompt *); extern void radius_Authenticate(struct radius *, struct authinfo *, const char *, const char *, const char *); +extern void radius_Account(struct radius *, struct radacct *, + struct datalink *, int, struct in_addr *, + struct in_addr *, struct pppThroughput *); + +/* An (int) parameter to radius_Account, from radlib.h */ +#if !defined(RAD_START) +#define RAD_START 1 +#define RAD_STOP 2 +#endif diff --git a/usr.sbin/ppp/ppp/throughput.c b/usr.sbin/ppp/ppp/throughput.c index 4e9b6b74e14..ddd225f289f 100644 --- a/usr.sbin/ppp/ppp/throughput.c +++ b/usr.sbin/ppp/ppp/throughput.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: throughput.c,v 1.8 2000/08/15 10:26:39 brian Exp $ + * $OpenBSD: throughput.c,v 1.9 2000/08/28 22:44:42 brian Exp $ */ #include <sys/types.h> @@ -44,7 +44,7 @@ void throughput_init(struct pppThroughput *t, int period) { - t->OctetsIn = t->OctetsOut = 0; + t->OctetsIn = t->OctetsOut = t->PacketsIn = t->PacketsOut = 0; t->SamplePeriod = period; t->in.SampleOctets = (long long *) calloc(period, sizeof *t->in.SampleOctets); @@ -111,6 +111,8 @@ throughput_disp(struct pppThroughput *t, struct prompt *prompt) divisor = secs_up ? secs_up : 1; prompt_Printf(prompt, "%llu octets in, %llu octets out\n", t->OctetsIn, t->OctetsOut); + prompt_Printf(prompt, "%llu packets in, %llu packets out\n", + t->PacketsIn, t->PacketsOut); if (t->rolling) { prompt_Printf(prompt, " overall %6qu bytes/sec\n", (t->OctetsIn + t->OctetsOut) / divisor); @@ -137,8 +139,10 @@ throughput_log(struct pppThroughput *t, int level, const char *title) if (title == NULL) title = ""; log_Printf(level, "%s%sConnect time: %d secs: %llu octets in, %llu octets" - " out\n", title, *title ? ": " : "", secs_up, t->OctetsIn, - t->OctetsOut); + " out\n", title, *title ? ": " : "", secs_up, t->OctetsIn, + t->OctetsOut); + log_Printf(level, "%s%s: %llu packets in, %llu packets out\n", + title, *title ? ": " : "", t->PacketsIn, t->PacketsOut); if (secs_up == 0) secs_up = 1; if (t->rolling) @@ -235,12 +239,14 @@ void throughput_addin(struct pppThroughput *t, long long n) { t->OctetsIn += n; + t->PacketsIn++; } void throughput_addout(struct pppThroughput *t, long long n) { t->OctetsOut += n; + t->PacketsOut++; } void diff --git a/usr.sbin/ppp/ppp/throughput.h b/usr.sbin/ppp/ppp/throughput.h index 86e5d1c49ed..26536ce5d50 100644 --- a/usr.sbin/ppp/ppp/throughput.h +++ b/usr.sbin/ppp/ppp/throughput.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: throughput.h,v 1.6 2000/08/15 10:26:39 brian Exp $ + * $OpenBSD: throughput.h,v 1.7 2000/08/28 22:44:42 brian Exp $ */ #define SAMPLE_PERIOD 5 /* Default sample period */ @@ -37,6 +37,8 @@ struct pppThroughput { time_t uptime, downtime; unsigned long long OctetsIn; unsigned long long OctetsOut; + unsigned long long PacketsIn; + unsigned long long PacketsOut; int SamplePeriod; struct { unsigned long long *SampleOctets; |