From b2f8595268e72c1668eb8f2e4d942b6290266db5 Mon Sep 17 00:00:00 2001 From: "Alexandr D. Kanevskiy" Date: Sat, 13 Jul 2002 06:24:36 +0000 Subject: [PATCH] Experemental per session traffic limiting. Usefull for VPN with per megabyte billing. (Works for me) --- pppd/Makefile.linux | 8 ++- pppd/auth.c | 51 ++++++++++++++++++- pppd/options.c | 47 ++++++++++++++++- pppd/plugins/radius/Makefile.linux | 5 ++ pppd/plugins/radius/radius.c | 13 ++++- .../radius/radiusclient/etc/dictionary | 14 +++++ .../radiusclient/include/radiusclient.h | 14 ++++- pppd/pppd.h | 19 ++++++- 8 files changed, 163 insertions(+), 8 deletions(-) diff --git a/pppd/Makefile.linux b/pppd/Makefile.linux index 7a84836..9fc4453 100644 --- a/pppd/Makefile.linux +++ b/pppd/Makefile.linux @@ -1,6 +1,6 @@ # # pppd makefile for Linux -# $Id: Makefile.linux,v 1.50 2002/06/10 13:46:28 dfs Exp $ +# $Id: Makefile.linux,v 1.51 2002/07/13 06:24:36 kad Exp $ # # Default installation locations @@ -72,6 +72,8 @@ PLUGIN=y #CBCP=y +MAXOCTETS=y + INCLUDE_DIRS= -I../include COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MMAP @@ -154,6 +156,10 @@ ifdef CBCP CFLAGS += -DCBCP_SUPPORT endif +ifdef MAXOCTETS + CFLAGS += -DMAXOCTETS +endif + INSTALL= install -o root install: pppd diff --git a/pppd/auth.c b/pppd/auth.c index 727c69d..a1e9fd2 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -32,7 +32,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: auth.c,v 1.77 2002/05/21 17:26:49 dfs Exp $" +#define RCSID "$Id: auth.c,v 1.78 2002/07/13 06:24:36 kad Exp $" #include #include @@ -217,6 +217,10 @@ static int set_noauth_addr __P((char **)); static void check_access __P((FILE *, char *)); static int wordlist_count __P((struct wordlist *)); +#ifdef MAXOCTETS +static void check_maxoctets __P((void *)); +#endif + /* * Authentication-related options. */ @@ -827,6 +831,11 @@ np_up(unit, proto) if (maxconnect > 0) TIMEOUT(connect_time_expired, 0, maxconnect); +#ifdef MAXOCTETS + if (maxoctets > 0) + TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); +#endif + /* * Detach now, if the updetach option was given. */ @@ -846,6 +855,9 @@ np_down(unit, proto) if (--num_np_up == 0) { UNTIMEOUT(check_idle, NULL); UNTIMEOUT(connect_time_expired, NULL); +#ifdef MAXOCTETS + UNTIMEOUT(check_maxoctets, NULL); +#endif new_phase(PHASE_NETWORK); } } @@ -863,6 +875,43 @@ np_finished(unit, proto) } } +#ifdef MAXOCTETS +static void +check_maxoctets(arg) + void *arg; +{ + int diff; + unsigned int used; + + update_link_stats(ifunit); + link_stats_valid=0; + + switch(maxoctets_dir) { + case PPP_OCTETS_DIRECTION_IN: + used = link_stats.bytes_in; + break; + case PPP_OCTETS_DIRECTION_OUT: + used = link_stats.bytes_out; + break; + case PPP_OCTETS_DIRECTION_MAX: + used = (link_stats.bytes_in > link_stats.bytes_out) ? link_stats.bytes_in : link_stats.bytes_out; + break; + default: + used = link_stats.bytes_in+link_stats.bytes_out; + break; + } + diff = maxoctets - used; + if(diff < 0) { + notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); + lcp_close(0, "Traffic limit"); + need_holdoff = 0; + status = EXIT_TRAFFIC_LIMIT; + } else { + TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); + } +} +#endif + /* * check_idle - check whether the link has been idle for long * enough that we can shut it down. diff --git a/pppd/options.c b/pppd/options.c index b20f075..223d1fa 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: options.c,v 1.83 2002/04/02 13:54:59 dfs Exp $" +#define RCSID "$Id: options.c,v 1.84 2002/07/13 06:24:36 kad Exp $" #include #include @@ -86,6 +86,13 @@ bool dump_options; /* print out option values */ bool dryrun; /* print out option values and exit */ char *domain; /* domain name set by domain option */ +#ifdef MAXOCTETS +unsigned int maxoctets = 0; /* default - no limit */ +int maxoctets_dir = 0; /* default - sum of traffic */ +int maxoctets_timeout = 1; /* default 1 second */ +#endif + + extern option_t auth_options[]; extern struct stat devstat; @@ -123,6 +130,10 @@ static int setpassfilter __P((char **)); static int setactivefilter __P((char **)); #endif +#ifdef MAXOCTETS +static int setmodir __P((char **)); +#endif + static option_t *find_option __P((const char *name)); static int process_option __P((option_t *, char *, char **)); static int n_arguments __P((option_t *)); @@ -262,6 +273,19 @@ option_t general_options[] = { "set filter for active pkts", OPT_PRIO }, #endif +#ifdef MAXOCTETS + { "maxoctets", o_int, &maxoctets, + "Set connection traffic limit", + OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, + { "mo", o_int, &maxoctets, + "Set connection traffic limit", + OPT_ALIAS | OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, + { "mo-direction", o_special, setmodir, + "Set direction for limit traffic (sum,in,out,max)" }, + { "mo-timeout", o_int, &maxoctets_timeout, + "Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 }, +#endif + { NULL } }; @@ -902,7 +926,7 @@ print_option(opt, mainopt, printer, arg) break; default: - printer(arg, "# %s value (type %d??)", opt->name, opt->type); + printer(arg, "# %s value (type %d\?\?)", opt->name, opt->type); break; } printer(arg, "\t\t# (from %s)\n", mainopt->source); @@ -1463,6 +1487,25 @@ setlogfile(argv) log_default = 0; return 1; } +#ifdef MAXOCTETS +static int +setmodir(argv) + char **argv; +{ + if(*argv == NULL) + return 0; + if(!strcmp(*argv,"in")) { + maxoctets_dir = PPP_OCTETS_DIRECTION_IN; + } else if (!strcmp(*argv,"out")) { + maxoctets_dir = PPP_OCTETS_DIRECTION_OUT; + } else if (!strcmp(*argv,"max")) { + maxoctets_dir = PPP_OCTETS_DIRECTION_MAX; + } else { + maxoctets_dir = PPP_OCTETS_DIRECTION_SUM; + } + return 1; +} +#endif #ifdef PLUGIN static int diff --git a/pppd/plugins/radius/Makefile.linux b/pppd/plugins/radius/Makefile.linux index 2c7b3ff..30a3ac4 100644 --- a/pppd/plugins/radius/Makefile.linux +++ b/pppd/plugins/radius/Makefile.linux @@ -12,6 +12,8 @@ CFLAGS=-I../.. -I../../../include -Iradiusclient/include -O2 CHAPMS=y # Uncomment the next line to include support for MPPE. MPPE=y +# Uncomment the next lint to include support for traffic limiting +MAXOCTETS=y ifdef CHAPMS CFLAGS += -DCHAPMS=1 @@ -19,6 +21,9 @@ ifdef MPPE CFLAGS += -DMPPE=1 endif endif +ifdef MAXOCTETS +CFLAGS += -DMAXOCTETS=1 +endif all: $(PLUGIN) diff --git a/pppd/plugins/radius/radius.c b/pppd/plugins/radius/radius.c index 55461b9..29b2836 100644 --- a/pppd/plugins/radius/radius.c +++ b/pppd/plugins/radius/radius.c @@ -24,7 +24,7 @@ * ***********************************************************************/ static char const RCSID[] = -"$Id: radius.c,v 1.9 2002/04/02 14:09:34 dfs Exp $"; +"$Id: radius.c,v 1.10 2002/07/13 06:24:36 kad Exp $"; #include "pppd.h" #include "chap.h" @@ -504,7 +504,16 @@ radius_setparams(chap_state *cstate, VALUE_PAIR *vp, char *msg, /* Session timeout */ maxconnect = vp->lvalue; break; - +#ifdef MAXOCTETS + case PW_SESSION_OCTETS_LIMIT: + /* Session traffic limit */ + maxoctets = vp->lvalue; + break; + case PW_OCTETS_DIRECTION: + /* Session traffic limit direction check */ + maxoctets_dir = vp->lvalue & 3; + break; +#endif case PW_FRAMED_IP_ADDRESS: /* seting up remote IP addresses */ remote = vp->lvalue; diff --git a/pppd/plugins/radius/radiusclient/etc/dictionary b/pppd/plugins/radius/radiusclient/etc/dictionary index 8de308c..0778aa9 100644 --- a/pppd/plugins/radius/radiusclient/etc/dictionary +++ b/pppd/plugins/radius/radiusclient/etc/dictionary @@ -113,6 +113,14 @@ ATTRIBUTE Group 1005 string ATTRIBUTE Crypt-Password 1006 string ATTRIBUTE Connect-Rate 1007 integer +# +# Experimental, implementation specific attributes +# +# Limit session traffic +ATTRIBUTE Session-Octets-Limit 227 integer +# What to assume as limit - 0 in+out, 1 in, 2 out, 3 max(in,out) +ATTRIBUTE Octets-Direction 228 integer + # # Integer Translations # @@ -230,4 +238,10 @@ VALUE Add-Port-To-IP-Address Yes 1 #VALUE Server-Config Password-Expiration 30 #VALUE Server-Config Password-Warning 5 +# Octets-Direction +VALUE Octets-Direction Sum 0 +VALUE Octets-Direction Input 1 +VALUE Octets-Direction Output 2 +VALUE Octets-Direction Maximum 3 + INCLUDE /etc/radiusclient/dictionary.microsoft diff --git a/pppd/plugins/radius/radiusclient/include/radiusclient.h b/pppd/plugins/radius/radiusclient/include/radiusclient.h index 74df910..710765f 100644 --- a/pppd/plugins/radius/radiusclient/include/radiusclient.h +++ b/pppd/plugins/radius/radiusclient/include/radiusclient.h @@ -1,5 +1,5 @@ /* - * $Id: radiusclient.h,v 1.6 2002/04/02 14:09:34 dfs Exp $ + * $Id: radiusclient.h,v 1.7 2002/07/13 06:24:36 kad Exp $ * * Copyright (C) 1995,1996,1997,1998 Lars Fenneberg * @@ -193,6 +193,11 @@ typedef struct pw_auth_hdr #define PW_USER_ID 222 /* string */ #define PW_USER_REALM 223 /* string */ + +/* Session limits */ +#define PW_SESSION_OCTETS_LIMIT 227 /* integer */ +#define PW_OCTETS_DIRECTION 228 /* integer */ + /* Integer Translations */ /* SERVICE TYPES */ @@ -294,6 +299,13 @@ typedef struct pw_auth_hdr #define PW_LOCAL 2 #define PW_REMOTE 3 +/* Session-Octets-Limit */ +#define PW_OCTETS_DIRECTION_SUM 0 +#define PW_OCTETS_DIRECTION_IN 1 +#define PW_OCTETS_DIRECTION_OUT 2 +#define PW_OCTETS_DIRECTION_MAX 3 + + /* Vendor codes */ #define VENDOR_NONE (-1) #define VENDOR_MICROSOFT 311 diff --git a/pppd/pppd.h b/pppd/pppd.h index 3ade18e..2ccdfa6 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -16,7 +16,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: pppd.h,v 1.68 2002/05/21 17:26:49 dfs Exp $ + * $Id: pppd.h,v 1.69 2002/07/13 06:24:36 kad Exp $ */ /* @@ -287,6 +287,20 @@ extern char *bundle_name; /* bundle name for multilink */ extern bool dump_options; /* print out option values */ extern bool dryrun; /* check everything, print options, exit */ +#ifdef MAXOCTETS +extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ +extern int maxoctets_dir; /* Direction : + 0 - in+out (default) + 1 - in + 2 - out + 3 - max(in,out) */ +extern int maxoctets_timeout; /* Timeout for check of octets limit */ +#define PPP_OCTETS_DIRECTION_SUM 0 +#define PPP_OCTETS_DIRECTION_IN 1 +#define PPP_OCTETS_DIRECTION_OUT 2 +#define PPP_OCTETS_DIRECTION_MAX 3 +#endif + #ifdef PPP_FILTER extern struct bpf_program pass_filter; /* Filter for pkts to pass */ extern struct bpf_program active_filter; /* Filter for link-active pkts */ @@ -736,6 +750,9 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #define EXIT_LOOPBACK 17 #define EXIT_INIT_FAILED 18 #define EXIT_AUTH_TOPEER_FAILED 19 +#ifdef MAXOCTETS +#define EXIT_TRAFFIC_LIMIT 20 +#endif /* * Debug macros. Slightly useful for finding bugs in pppd, not particularly -- 2.39.2