summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ppp/ppp/bundle.c3
-rw-r--r--usr.sbin/ppp/ppp/bundle.h3
-rw-r--r--usr.sbin/ppp/ppp/ipcp.c13
-rw-r--r--usr.sbin/ppp/ppp/radius.c167
-rw-r--r--usr.sbin/ppp/ppp/radius.h21
-rw-r--r--usr.sbin/ppp/ppp/throughput.c14
-rw-r--r--usr.sbin/ppp/ppp/throughput.h4
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;