- Add startup-config(5) manpage.

- Add snoopctl, throttlectl plugins.
- Update documentation.
This commit is contained in:
bodea 2004-11-17 15:08:19 +00:00
parent bf0a00f106
commit f5071c422d
12 changed files with 584 additions and 106 deletions

View file

@ -5,8 +5,9 @@
- Cleanup: make a bunch of global functions/variables static.
- Remove reference to old -a command line argument.
- Add l2tpns(8) and nsctl(8) manpages from Jonathan McDowell.
- Add startup-config(5) manpage [FIXME].
- Add startup-config(5) manpage.
- Revise nsctl to allow arbitrary strings/args to be passed to plugins.
- Add snoopctl, throttlectl plugins.
* Mon Nov 15 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.7
- Fix socket creation in host_unreachable() (thanks to Bjørn Augestad)

View file

@ -146,6 +146,7 @@ set ipaddress 192.168.1.1
set boolean true
</PRE>
<P>
<UL>
<LI><B>debug</B> (int)<BR>
Sets the level of messages that will be written to the log file. The value
@ -162,28 +163,24 @@ highest. A rough description of the levels is:
Note that the higher you set the debugging level, the slower the program
will run. Also, at level 5 a LOT of information will be logged. This should
only ever be used for working out why it doesn't work at all.
<P>
</LI>
<LI><B>log_file</B> (string)<BR>
This will be where all logging and debugging information is written
to. This can be either a filename, such as <EM>/var/log/l2tpns</EM>, or
to. This may be either a filename, such as <EM>/var/log/l2tpns</EM>, or
the special magic string <EM>syslog:facility</EM>, where <EM>facility</EM>
is any one of the syslog logging facilities, such as local5.
<P>
</LI>
<LI><B>pid_file</B> (string)<BR>
If this is set, the process id will be written to this file. The filename must
contain an absolute path.
<P>
If set, the process id will be written to the specified file. The
value must be an absolute path.
</LI>
<LI><B>l2tp_secret</B> (string)<BR>
This sets the string that l2tpns will use for authenticating tunnel request.
This must be the same as the LAC, or authentication will fail. This will
only actually be used if the LAC requests authentication.
<P>
The secret used by l2tpns for authenticating tunnel request. Must be
the same as the LAC, or authentication will fail. Only actually be
used if the LAC requests authentication.
</LI>
<LI><B>primary_dns</B> (ip address)
@ -191,7 +188,6 @@ only actually be used if the LAC requests authentication.
Whenever a PPP connection is established, DNS servers will be sent to the
user, both a primary and a secondary. If either is set to 0.0.0.0, then that
one will not be sent.
<P>
</LI>
<LI><B>save_state</B> (boolean)<BR>
@ -200,24 +196,21 @@ ip_address_pool, session and tunnel tables to disk prior to exiting to
be re-loaded at startup. The validity of this data is obviously quite
short and the intent is to allow an sessions to be retained over a
software upgrade.
<P>
</LI>
<LI><B>primary_radius</B> (ip address)
<LI><B>secondary_radius</B> (ip address)<BR>
This sets the radius servers used for both authentication and
accounting. If the primary server does not respond, then the
secondary radius server will be tried.
<P>
Sets the radius servers used for both authentication and accounting.
If the primary server does not respond, then the secondary radius
server will be tried.
</LI>
<LI><B>primary_radius_port</B> (short)
<LI><B>secondary_radius_port</B> (short)<BR>
This sets the authentication ports for the primary and secondary
radius servers. The accounting port is one more than the authentication
port. If no radius ports are given, the authentication port defaults to 1645,
and the accounting port to 1646.
<P>
Sets the authentication ports for the primary and secondary radius
servers. The accounting port is one more than the authentication
port. If no radius ports are given, the authentication port defaults
to 1645, and the accounting port to 1646.
</LI>
<LI><B>radius_accounting</B> (boolean)<BR>
@ -225,13 +218,11 @@ If set to true, then radius accounting packets will be sent. This
means that a Start record will be sent when the session is
successfully authenticated, and a Stop record will be sent when the
session is closed.
<P>
</LI>
<LI><B>radius_secret</B> (string)<BR>
This secret will be used in all radius queries. If this is not set then
radius queries will fail.
<P>
</LI>
<LI><B>bind_address</B> (ip address)<BR>
@ -239,28 +230,29 @@ When the tun interface is created, it is assigned the address
specified here. If no address is given, 1.1.1.1 is used. Packets
containing user traffic should be routed via this address if given,
otherwise the primary address of the machine.
<P>
</LI>
<LI><B>peer_address</B> (ip address)<BR>
Address to send to clients as the default gateway.
</L1>
<LI><B>send_garp</B> (boolean)<BR>
Determines whether or not to send a gratuitous ARP for the
bind_address when the server is ready to handle traffic (default:
true).<BR>
This value is ignored if BGP is configured.
<P>
</LI>
<LI><B>throttle_speed</B> (int)<BR>
Sets the speed (in kbits/s) which sessions will be limited to. If this is
set to 0, then throttling will not be used at all. Note: You can set this by
the CLI, but changes will not affect currently connected users.
<P>
Sets the default speed (in kbits/s) which sessions will be limited to.
If this is set to 0, then throttling will not be used at all. Note:
You can set this by the CLI, but changes will not affect currently
connected users.
</LI>
<LI><B>throttle_buckets</B> (int)<BR>
Number of token buckets to allocate for throttling. Each throttled
session requires two buckets (in and out).
<P>
</LI>
<LI><B>accounting_dir</B> (string)<BR>
@ -271,89 +263,81 @@ Following the header is a single line for every connected user, fields
separated by a space.<BR> The fields are username, ip, qos,
uptxoctets, downrxoctets. The qos field is 1 if a standard user, and
2 if the user is throttled.
<P>
</LI>
<LI><B>setuid</B> (int)<BR>
After starting up and binding the interface, change UID to this. This
doesn't work properly.
<P>
</LI>
<LI><B>dump_speed</B> (boolean)<BR>
If set to true, then the current bandwidth utilization will be logged every
second. Even if this is disabled, you can see this information by running
the <EM>uptime</EM> command on the CLI.
<P>
</LI>
<LI><B>cleanup_interval</B> (int)<BR>
Interval between regular cleanups (in seconds).
<P>
</LI>
<LI><B>multi_read_count</B> (int)<BR>
Number of packets to read off each of the UDP and TUN fds when
returned as readable by select (default: 10). Avoids incurring the
unnecessary system call overhead of select on busy servers.
<P>
</LI>
<LI><B>scheduler_fifo</B> (boolean)<BR>
Sets the scheduling policy for the l2tpns process to SCHED_FIFO. This
causes the kernel to immediately preempt any currently SCHED_OTHER
causes the kernel to immediately preempt any currently running SCHED_OTHER
(normal) process in favour of l2tpns when it becomes runnable.
Ignored on uniprocessor systems.
<P>
</LI>
<LI><B>lock_pages</B> (boolean)<BR>
Keep all pages mapped by the l2tpns process in memory.
<P>
</LI>
<LI><B>icmp_rate</B> (int)<BR>
Maximum number of host unreachable icmp packets to send per second.
<P>
Maximum number of host unreachable ICMP packets to send per second.
</LI>
<LI><B>cluster_address</B> (ip address)<BR>
Multicast cluster address (default: 239.192.13.13). See the section
on <A HREF="#Clustering">Clustering</A> for more information.
<P>
</LI>
<LI><B>cluster_interface</B> (string)<BR>
Interface for cluster packets (default: eth0).
<P>
</LI>
<LI><B>cluster_hb_interval</B> (int)<BR>
Interval in tenths of a second between cluster heartbeat/pings.
<P>
</LI>
<LI><B>cluster_hb_timeout</B> (int)<BR>
Cluster heartbeat timeout in tenths of a second. A new master will be
elected when this interval has been passed without seeing a heartbeat
from the master.
<P>
</LI>
<LI><B>as_number</B> (int)<BR>
Defines the local AS number for BGP (see <A HREF="#Routing">Routing</A>).
<P>
</LI>
<LI><B>bgp_peer1</B> (string)
<LI><B>bgp_peer1_as</B> (int)
<LI><B>bgp_peer2</B> (string)
<LI><B>bgp_peer2_as</B> (int)<BR>
<P>
DNS name (or IP) and AS number of BGP peers.
</LI>
</UL>
<P>BGP routing configuration is entered by the command:
The routing configuration section is entered by the command
<DL><DD><B>router bgp</B> <I>as</I></DL>
where <I>as</I> specifies the local AS number.
<P>Subsequent lines prefixed with
<DL><DD><B>neighbour</B> <I>peer</I></DL>
define the attributes of BGP neighhbours. Valid commands are:
<DL>
<DD><B>neighbour</B> <I>peer</I> <B>remote-as</B> <I>as</I>
<DD><B>neighbout</B> <I>peer</I> <B>timers</B> <I>keepalive hold</I>
</DL>
Where <I>peer</I> specifies the BGP neighbour as either a hostname or
IP address, <I>as</I> is the remote AS number and <I>keepalive</I>,
<I>hold</I> are the timer values in seconds.
<H3 ID="users">users</H3>
Usernames and passwords for the command-line interface are stored in
@ -411,8 +395,7 @@ A running l2tpns process can be controlled in a number of ways. The primary
method of control is by the Command-Line Interface (CLI).<P>
You can also remotely send commands to modules via the nsctl client
provided. This currently only works with the walled garden module, but
modification is trivial to support other modules.<P>
provided.<P>
Also, there are a number of signals that l2tpns understands and takes action
when it receives them.
@ -642,16 +625,13 @@ this way, although some may require a restart to take effect.<P>
<H3 ID="nsctl">nsctl</H3>
nsctl was implemented (badly) to allow messages to be passed to modules.<P>
nsctl allows messages to be passed to plugins.<P>
You must pass at least 2 parameters: <EM>host</EM> and <EM>command</EM>. The
host is the address of the l2tpns server which you want to send the message
to.<P>
Arguments are <EM>command</EM> and optional <EM>args</EM>. See
<STRONG>nsctl</STRONG>(8) for more details.<P>
Command can currently be either <EM>garden</EM> or <EM>ungarden</EM>. With
both of these commands, you must give a session ID as the 3rd parameter.
This will activate or deactivate the walled garden for a session
temporarily.
Built-in command are <EM>load_plugin</EM>, <EM>unload_plugin</EM> and
<EM>help</EM>. Any other commands are passed to plugins for processing.
<H3 ID="Signals">Signals</H3>

View file

@ -2,10 +2,10 @@
.de Id
.ds Dt \\$4 \\$5
..
.Id $Id: nsctl.8,v 1.1 2004/11/17 08:23:35 bodea Exp $
.Id $Id: nsctl.8,v 1.2 2004/11/17 15:08:19 bodea Exp $
.TH NSCTL 8 "\*(Dt" L2TPNS "System Management Commands"
.SH NAME
nsctl \- Issue commands to l2tpns plugins
nsctl \- manage running l2tpns instance
.SH SYNOPSIS
.B nsctl
.RB [ \-d ]
@ -17,10 +17,10 @@ nsctl \- Issue commands to l2tpns plugins
.RI [ arg " ...]"
.SH DESCRIPTION
.B nsctl
is part of the
sends commands to a running
.B l2tpns
package. It allows the system administrator to send manage plugin
features of a running l2tpns process.
process. It provides both for the loading or unloading of plugins and
also the management of sessions via functions provided by those plugins.
.SH OPTIONS
.TP
.B \-d
@ -59,7 +59,9 @@ Any other value of
if any)
are sent to
.B l2tpns
as-is, to be passed to each plugin in turn (and possibly acted upon).
as-is, to be passed to each plugin which registers a
.B plugin_control
function in turn (in which it may be acted upon).
.SH SEE ALSO
.BR l2tpns (8)
.SH AUTHOR

203
Docs/startup-config.5 Normal file
View file

@ -0,0 +1,203 @@
.\" -*- nroff -*-
.de Id
.ds Dt \\$4 \\$5
..
.Id $Id: startup-config.5,v 1.1 2004/11/17 15:08:19 bodea Exp $
.TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
.SH NAME
startup\-config \- configuration file for l2tpns
.SH SYNOPSIS
/etc/l2tpns/startup-config
.SH DESCRIPTION
.B startup-config
is the configuration file for
.BR l2tpns .
.PP
The format is plain text, in the same format as accepted by the
configuration mode of
.BR l2tpns 's
telnet administrative interface. Comments are indicated by either the
character
.B #
or
.BR ! .
.SS SETTINGS
Settings are specified with
.IP
.BI "set " "variable value"
.PP
The following
.IR variable s
may be set:
.RS
.TP
.B debug
Set the level of debugging messages written to the log file. The
value should be between 0 and 5, with 0 being no debugging, and 5
being the highest.
.TP
.B log_file
This will be where all logging and debugging information is written
to. This may be either a filename, such as
.BR /var/log/l2tpns ,
or the string
.BR syslog : \fIfacility\fR ,
where
.I facility
is any one of the syslog logging facilities, such as
.BR local5 .
.TP
.B pid_file
If set, the process id will be written to the specified file. The
value must be an absolute path.
.TP
.B l2tp_secret
The secret used by
.B l2tpns
for authenticating tunnel request. Must be the same as the LAC, or
authentication will fail. Only actually be used if the LAC requests
authentication.
.TP
.BR primary_dns , " secondary_dns"
Whenever a PPP connection is established, DNS servers will be sent to the
user, both a primary and a secondary. If either is set to 0.0.0.0, then that
one will not be sent.
.TP
.B save_state
When
.B l2tpns
receives a STGTERM it will write out its current ip_address_pool,
session and tunnel tables to disk prior to exiting to be re-loaded at
startup. The validity of this data is obviously quite short and the
intent is to allow an sessions to be retained over a software upgrade.
.TP
.BR primary_radius , " secondary_radius"
Sets the RADIUS servers used for both authentication and accounting.
If the primary server does not respond, then the secondary RADIUS
server will be tried.
.TP
.BR primary_radius_port , " secondary_radius_port"
Sets the authentication ports for the primary and secondary RADIUS
servers. The accounting port is one more than the authentication
port. If no ports are given, authentication defaults to 1645, and
accounting to 1646.
.TP
.B radius_accounting
If set to true, then RADIUS accounting packets will be sent. A
.B Start
record will be sent when the session is successfully authenticated,
and a
.B Stop
record when the session is closed.
.TP
.B radius_secret
Secret to be used in RADIUS packets.
.TP
.B bind_address
When the tun interface is created, it is assigned the address
specified here. If no address is given, 1.1.1.1 is used. Packets
containing user traffic should be routed via this address if given,
otherwise the primary address of the machine.
.TP
.B peer_address
Address to send to clients as the default gateway.
.TP
.B send_garp
Determines whether or not to send a gratuitous ARP for the
.B bind_address
when the server is ready to handle traffic (default: true). This
setting is ignored if BGP is configured.
.TP
.B throttle_speed
Sets the default speed (in kbits/s) which sessions will be limited to.
.TP
.B throttle_buckets
Number of token buckets to allocate for throttling. Each throttled
session requires two buckets (in and out).
.TP
.B accounting_dir
If set to a directory, then every 5 minutes the current usage for
every connected use will be dumped to a file in this directory.
.TP
.B setuid
After starting up and binding the interface, change UID to this. This
doesn't work properly.
.TP
.B dump_speed
If set to true, then the current bandwidth utilization will be logged
every second. Even if this is disabled, you can see this information
by running the
.B
uptime
command on the CLI.
.TP
.B cleanup_interval
Interval between regular cleanups (in seconds).
.TP
.B multi_read_count
Number of packets to read off each of the UDP and TUN fds when
returned as readable by select (default: 10). Avoids incurring the
unnecessary system call overhead of select on busy servers.
.TP
.B scheduler_fifo
Sets the scheduling policy for the
.B l2tpns
process to
.BR SCHED_FIFO .
This causes the kernel to immediately preempt any currently running
.B SCHED_OTHER
(normal) process in favour of
.B l2tpns
when it becomes runnable.
.br
Ignored on uniprocessor systems.
.TP
.B lock_pages
Keep all pages mapped by the
.B l2tpns
process in memory.
.TP
.B icmp_rate
Maximum number of host unreachable ICMP packets to send per second.
.TP
.B cluster_address
Multicast cluster address (default: 239.192.13.13).
.TP
.B cluster_interface
Interface for cluster packets (default: eth0).
.TP
.B cluster_hb_interval
Interval in tenths of a second between cluster heartbeat/pings.
.TP
.B cluster_hb_timeout
Cluster heartbeat timeout in tenths of a second. A new master will be
elected when this interval has been passed without seeing a heartbeat
from the master.
.RE
.SS BGP ROUTING
The routing configuration section is entered by the command
.IP
.BI "router bgp " as
.PP
where
.I as
specifies the local AS number.
.PP
Subsequent lines prefixed with
.BI "neighbour " peer
define the attributes of BGP neighhbours. Valid commands are:
.IP
.BI "neighbour " peer " remote-as " as
.br
.BI "neighbour " peer " timers " "keepalive hold"
.PP
Where
.I peer
specifies the BGP neighbour as either a hostname or IP address,
.I as
is the remote AS number and
.IR keepalive ,
.I hold
are the timer values in seconds.
.SH SEE ALSO
.BR l2tpns (8)

View file

@ -31,22 +31,12 @@ LDFLAGS =
LDLIBS = -lm
INSTALL = install -c -D -o root -g root
OBJS = arp.o \
bgp.o \
cli.o \
cluster.o \
constants.o \
control.o \
icmp.o \
l2tpns.o \
ll.o \
md5.o \
ppp.o \
radius.o \
tbf.o \
util.o
OBJS = arp.o bgp.o cli.o cluster.o constants.o control.o icmp.o \
l2tpns.o ll.o md5.o ppp.o radius.o tbf.o util.o
PLUGINS = garden.so throttlectl.so autothrottle.so snoopctl.so \
autosnoop.so stripdomain.so setrxspeed.so
PLUGINS = garden.so autothrottle.so autosnoop.so stripdomain.so setrxspeed.so
TARGETS = l2tpns nsctl generateload bounce $(PLUGINS)
all: $(TARGETS)
@ -100,6 +90,7 @@ install: all
echo '***' Installing default config files in $(DESTDIR)$(etcdir) - remember to adjust them; \
suffix=; \
fi; \
$(INSTALL) -m 0600 etc/startup-config.default $(DESTDIR)$(etcdir)/startup-config$$suffix; \
$(INSTALL) -m 0644 etc/ip_pool.default $(DESTDIR)$(etcdir)/ip_pool$$suffix; \
$(INSTALL) -m 0600 etc/users.default $(DESTDIR)$(etcdir)/users$$suffix
@ -132,7 +123,9 @@ radius.o: radius.c md5.h constants.h l2tpns.h plugin.h util.h
tbf.o: tbf.c l2tpns.h util.h tbf.h
util.o: util.c l2tpns.h bgp.h
garden.so: garden.c l2tpns.h plugin.h control.h
throttlectl.so: throttlectl.c l2tpns.h plugin.h control.h
autothrottle.so: autothrottle.c l2tpns.h plugin.h
snoopctl.so: snoopctl.c l2tpns.h plugin.h control.h
autosnoop.so: autosnoop.c l2tpns.h plugin.h
stripdomain.so: stripdomain.c l2tpns.h plugin.h
setrxspeed.so: setrxspeed.c l2tpns.h plugin.h

View file

@ -17,5 +17,7 @@ set accounting_dir "/var/run/l2tpns/acct/"
set setuid 0
set dump_speed no
load plugin "garden"
load plugin "throttlectl"
load plugin "autothrottle"
load plugin "snoopctl"
load plugin "autosnoop"

View file

@ -9,7 +9,7 @@
/* walled garden */
char const *cvs_id = "$Id: garden.c,v 1.13 2004/11/17 08:23:34 bodea Exp $";
char const *cvs_id = "$Id: garden.c,v 1.14 2004/11/17 15:08:19 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
static struct pluginfuncs *p = 0;
@ -76,22 +76,25 @@ int plugin_kill_session(struct param_new_session *data)
}
char *plugin_control_help[] = {
" garden USER|SID Put user into the walled garden",
" ungarden USER|SID Release user",
" garden USER|SID Put user into the walled garden",
" ungarden USER|SID Release user from garden",
0
};
int plugin_control(struct param_control *data)
{
sessionidt session;
sessiont *s = 0;
sessionidt s;
sessiont *sess = 0;
int flag;
char *end;
if (data->argc < 1 || (strcmp(data->argv[0], "garden") && strcmp(data->argv[0], "ungarden")))
if (data->argc < 1)
return PLUGIN_RET_OK;
if (strcmp(data->argv[0], "garden") && strcmp(data->argv[0], "ungarden"))
return PLUGIN_RET_OK; // not for us
flag = data->argv[0][0] == 'g';
flag = data->argv[0][0] != 'u';
if (!iam_master) // All garden processing happens on the master.
{
@ -107,8 +110,8 @@ int plugin_control(struct param_control *data)
return PLUGIN_RET_STOP;
}
if (!(session = strtol(data->argv[0], &end, 10)) || *end)
session = p->get_session_by_username(data->argv[0]);
if (!(session = strtol(data->argv[1], &end, 10)) || *end)
session = p->get_session_by_username(data->argv[1]);
if (session)
s = p->get_session_by_id(session);
@ -128,6 +131,8 @@ int plugin_control(struct param_control *data)
}
garden_session(s, flag);
p->sesssion_changed(session);
data->response = NSCTL_RES_OK;
data->additional = 0;
@ -149,7 +154,7 @@ int plugin_become_master(void)
}
// Called for each active session after becoming master
int plugin_new_session_master(sessiont * s)
int plugin_new_session_master(sessiont *s)
{
if (s->walled_garden)
{

View file

@ -4,7 +4,7 @@
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
// vim: sw=8 ts=8
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.51 2004/11/17 08:23:34 bodea Exp $";
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.52 2004/11/17 15:08:19 bodea Exp $";
#include <arpa/inet.h>
#include <assert.h>
@ -3760,10 +3760,12 @@ static int add_plugin(char *plugin_name)
sessionbyuser,
sessiontbysessionidt,
sessionidtbysessiont,
sessionkill,
radiusnew,
radiussend,
getconfig,
sessionkill,
throttle_session,
cluster_send_session,
};
void *p = open_plugin(plugin_name, 1);

View file

@ -16,13 +16,12 @@ struct {
char *usage;
int action;
} builtins[] = {
{ "load_plugin", " PLUGIN Load named plugin", NSCTL_REQ_LOAD },
{ "unload_plugin", " PLUGIN Unload named plugin", NSCTL_REQ_UNLOAD },
{ "help", " List available commands", NSCTL_REQ_HELP },
{ "load_plugin", " PLUGIN Load named plugin", NSCTL_REQ_LOAD },
{ "unload_plugin", " PLUGIN Unload named plugin", NSCTL_REQ_UNLOAD },
{ "help", " List available commands", NSCTL_REQ_HELP },
{ 0 }
};
static int debug = 0;
static int timeout = 2; // 2 seconds
static char *me;

View file

@ -31,10 +31,12 @@ struct pluginfuncs
sessionidt (*get_session_by_username)(char *username);
sessiont *(*get_session_by_id)(sessionidt s);
sessionidt (*get_id_by_session)(sessiont *s);
void (*sessionkill)(sessionidt s, char *reason);
u16 (*radiusnew)(sessionidt s);
void (*radiussend)(u16 r, u8 state);
void *(*getconfig)(char *key, enum config_typet type);
void (*sessionkill)(sessionidt s, char *reason);
void (*throttle)(sessionidt s, int rate_in, int rate_out);
int (*session_changed)(int sid);
};
struct param_pre_auth

138
snoopctl.c Normal file
View file

@ -0,0 +1,138 @@
#include <string.h>
#include "l2tpns.h"
#include "plugin.h"
#include "control.h"
/* snoop control */
char const *cvs_id = "$Id: snoopctl.c,v 1.1 2004/11/17 15:08:19 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
static struct pluginfuncs *p = 0;
char *plugin_control_help[] = {
" snoop USER|SID IP PORT Intercept user traffic",
" unsnoop USER|SID Stop intercepting user",
0
};
static int iam_master = 0;
int plugin_init(struct pluginfuncs *funcs)
{
if (!funcs)
return 0;
p = funcs;
return 1;
}
int plugin_become_master(void)
{
iam_master = 1;
return PLUGIN_RET_OK;
}
int plugin_control(struct param_control *data)
{
sessionidt session;
sessiont *s = 0;
int flag;
char *end;
if (data->argc < 1)
return PLUGIN_RET_OK;
if (strcmp(data->argv[0], "snoop") && strcmp(data->argv[0], "unsnoop"))
return PLUGIN_RET_OK; // not for us
flag = data->argv[0][0] != 'u';
if (!iam_master)
{
data->response = NSCTL_RES_ERR;
data->additional = "must be run on the cluster master";
return PLUGIN_RET_STOP;
}
if (flag)
{
if (data->argc != 4)
{
data->response = NSCTL_RES_ERR;
data->additional = "requires username or session id and host, port";
return PLUGIN_RET_STOP;
}
}
else
{
if (data->argc != 2)
{
data->response = NSCTL_RES_ERR;
data->additional = "requires username or session id";
return PLUGIN_RET_STOP;
}
}
if (!(session = strtol(data->argv[1], &end, 10)) || *end)
session = p->get_session_by_username(data->argv[1]);
if (session)
s = p->get_session_by_id(session);
if (!s || !s->ip)
{
data->response = NSCTL_RES_ERR;
data->additional = "session not found";
return PLUGIN_RET_STOP;
}
if (flag)
{
ipt ip = inet_addr(data->argv[2]);
u16 port = atoi(data->argv[3]);
if (!ip || ip == INADDR_NONE)
{
data->response = NSCTL_RES_ERR;
data->additional = "invalid ip address";
return PLUGIN_RET_STOP;
}
if (!port)
{
data->response = NSCTL_RES_ERR;
data->additional = "invalid port";
return PLUGIN_RET_STOP;
}
if (ip == s->snoop_ip && port == s->snoop_port)
{
data->response = NSCTL_RES_ERR;
data->additional = "already intercepted";
return PLUGIN_RET_STOP;
}
s->snoop_ip = ip;
s->snoop_port = port;
}
else
{
if (!s->snoop_ip)
{
data->response = NSCTL_RES_ERR;
data->additional = "not intercepted";
return PLUGIN_RET_STOP;
}
s->snoop_ip = 0;
s->snoop_port = 0;
}
p->sesssion_changed(session);
data->response = NSCTL_RES_OK;
data->additional = 0;
return PLUGIN_RET_STOP;
}

151
throttlectl.c Normal file
View file

@ -0,0 +1,151 @@
#include <string.h>
#include "l2tpns.h"
#include "plugin.h"
#include "control.h"
/* throttle control */
char const *cvs_id = "$Id: throttlectl.c,v 1.1 2004/11/17 15:08:19 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
static struct pluginfuncs *p = 0;
char *plugin_control_help[] = {
" throttle USER|SID [RATE|[in|out] RATE ...] Throttle user traffic",
" unthrottle USER|SID Stop throttling user",
0
};
static int iam_master = 0;
int plugin_init(struct pluginfuncs *funcs)
{
if (!funcs)
return 0;
p = funcs;
return 1;
}
int plugin_become_master(void)
{
iam_master = 1;
return PLUGIN_RET_OK;
}
int plugin_control(struct param_control *data)
{
sessionidt session;
sessiont *s = 0;
int flag;
char *end;
int rate_in = 0;
int rate_out = 0;
if (data->argc < 1)
return PLUGIN_RET_OK;
if (strcmp(data->argv[0], "throttle")
&& strcmp(data->argv[0], "unthrottle"))
return PLUGIN_RET_OK; // not for us
flag = data->argv[0][0] != 'g';
if (!iam_master)
{
data->response = NSCTL_RES_ERR;
data->additional = "must be run on the cluster master";
return PLUGIN_RET_STOP;
}
if (flag)
{
if (data->argc < 2 || data->argc > 4)
{
data->response = NSCTL_RES_ERR;
data->additional = "requires username or session id and optional rate(s)";
return PLUGIN_RET_STOP;
}
}
else
{
if (data->argc != 2)
{
data->response = NSCTL_RES_ERR;
data->additional = "requires username or session id";
return PLUGIN_RET_STOP;
}
}
if (!(session = strtol(data->argv[1], &end, 10)) || *end)
session = p->get_session_by_username(data->argv[1]);
if (session)
s = p->get_session_by_id(session);
if (!s || !s->ip)
{
data->response = NSCTL_RES_ERR;
data->additional = "session not found";
return PLUGIN_RET_STOP;
}
if (flag)
{
rate_in = rate_out = -1;
if (data->argc == 2)
{
unsigned long *rate = p->getconfig("throttle_speed", UNSIGNED_LONG);
rate_in = rate_out = *rate;
}
else if (data->argc == 3)
{
rate_in = rate_out = atoi(data->argv[2]);
}
else
{
int i;
for (i = 2; i < data->argc - 1; i += 2)
{
int len = strlen(data->argv[i]);
if (!strncmp(data->argv[i], "in", len))
{
rate_in = atoi(argv[i+1]);
}
else if (!strncmp(data->argv[i], "out", len))
{
rate_out = atoi(argv[i+1]);
}
else
{
data->response = NSCTL_RES_ERR;
data->additional = "invalid rate";
return PLUGIN_RET_STOP;
}
}
}
if (!rate_in || !rate_out)
{
data->response = NSCTL_RES_ERR;
data->additional = "invalid rate";
return PLUGIN_RET_STOP;
}
}
if (rate_in != -1 && rate_in == s->throttle_in &&
rate_out != -1 && rate_out == s->throttle_out)
{
data->response = NSCTL_RES_ERR;
data->additional = flag ? "already throttled" : "not throttled";
return PLUGIN_RET_STOP;
}
p->throttle(session, rate_in, rate_out);
p->sesssion_changed(session);
data->response = NSCTL_RES_OK;
data->additional = 0;
return PLUGIN_RET_STOP;
}