update filter refcounts
add cli commands for filtering/unfiltering
This commit is contained in:
parent
5e337e7ed9
commit
6d5c3ecb4d
4 changed files with 258 additions and 29 deletions
186
cli.c
186
cli.c
|
|
@ -2,7 +2,7 @@
|
|||
// vim: sw=8 ts=8
|
||||
|
||||
char const *cvs_name = "$Name: $";
|
||||
char const *cvs_id_cli = "$Id: cli.c,v 1.31 2004-11-27 21:10:50 bodea Exp $";
|
||||
char const *cvs_id_cli = "$Id: cli.c,v 1.32 2004-11-28 02:53:11 bodea Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
|
@ -115,6 +115,8 @@ static int cmd_restart_bgp(struct cli_def *cli, char *command, char **argv, int
|
|||
static int cmd_ip_access_list(struct cli_def *cli, char *command, char **argv, int argc);
|
||||
static int cmd_no_ip_access_list(struct cli_def *cli, char *command, char **argv, int argc);
|
||||
static int cmd_ip_access_list_rule(struct cli_def *cli, char *command, char **argv, int argc);
|
||||
static int cmd_filter(struct cli_def *cli, char *command, char **argv, int argc);
|
||||
static int cmd_no_filter(struct cli_def *cli, char *command, char **argv, int argc);
|
||||
|
||||
/* match if b is a substr of a */
|
||||
#define MATCH(a,b) (!strncmp((a), (b), strlen(b)))
|
||||
|
|
@ -169,8 +171,9 @@ void init_cli(char *hostname)
|
|||
cli_register_command(cli, c, "memory", cmd_write_memory, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Save the running config to flash");
|
||||
cli_register_command(cli, c, "terminal", cmd_show_run, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the running config");
|
||||
|
||||
cli_register_command(cli, NULL, "snoop", cmd_snoop, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Temporarily enable interception for a user");
|
||||
cli_register_command(cli, NULL, "throttle", cmd_throttle, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Temporarily enable throttling for a user");
|
||||
cli_register_command(cli, NULL, "snoop", cmd_snoop, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Enable interception of a session");
|
||||
cli_register_command(cli, NULL, "throttle", cmd_throttle, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Enable throttling of a session");
|
||||
cli_register_command(cli, NULL, "filter", cmd_filter, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Add filtering to a session");
|
||||
cli_register_command(cli, NULL, "debug", cmd_debug, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Set the level of logging that is shown on the console");
|
||||
|
||||
#ifdef BGP
|
||||
|
|
@ -179,8 +182,9 @@ void init_cli(char *hostname)
|
|||
#endif /* BGP */
|
||||
|
||||
c = cli_register_command(cli, NULL, "no", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
|
||||
cli_register_command(cli, c, "snoop", cmd_no_snoop, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Temporarily disable interception for a user");
|
||||
cli_register_command(cli, c, "throttle", cmd_no_throttle, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Temporarily disable throttling for a user");
|
||||
cli_register_command(cli, c, "snoop", cmd_no_snoop, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Disable interception of a session");
|
||||
cli_register_command(cli, c, "throttle", cmd_no_throttle, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Disable throttling of a session");
|
||||
cli_register_command(cli, c, "filter", cmd_no_filter, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Remove filtering from a session");
|
||||
cli_register_command(cli, c, "debug", cmd_no_debug, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Turn off logging of a certain level of debugging");
|
||||
|
||||
#ifdef BGP
|
||||
|
|
@ -1426,11 +1430,10 @@ static int cmd_throttle(struct cli_def *cli, char *command, char **argv, int arg
|
|||
int i;
|
||||
for (i = 1; i < argc - 1; i += 2)
|
||||
{
|
||||
int len = strlen(argv[i]);
|
||||
int r = 0;
|
||||
if (!strncasecmp(argv[i], "in", len))
|
||||
if (MATCH("in", argv[i]))
|
||||
r = rate_in = atoi(argv[i+1]);
|
||||
else if (!strncasecmp(argv[i], "out", len))
|
||||
else if (MATCH("out", argv[i]))
|
||||
r = rate_out = atoi(argv[i+1]);
|
||||
|
||||
if (r < 1)
|
||||
|
|
@ -1560,13 +1563,13 @@ static int cmd_debug(struct cli_def *cli, char *command, char **argv, int argc)
|
|||
if (argv[i][0] == 'c' && len < 2)
|
||||
len = 2; /* distinguish [cr]itical from [ca]lls */
|
||||
|
||||
if (!strncasecmp(argv[i], "critical", len)) { debug_flags.critical = 1; continue; }
|
||||
if (!strncasecmp(argv[i], "error", len)) { debug_flags.error = 1; continue; }
|
||||
if (!strncasecmp(argv[i], "warning", len)) { debug_flags.warning = 1; continue; }
|
||||
if (!strncasecmp(argv[i], "info", len)) { debug_flags.info = 1; continue; }
|
||||
if (!strncasecmp(argv[i], "calls", len)) { debug_flags.calls = 1; continue; }
|
||||
if (!strncasecmp(argv[i], "data", len)) { debug_flags.data = 1; continue; }
|
||||
if (!strncasecmp(argv[i], "all", len))
|
||||
if (!strncmp("critical", argv[i], len)) { debug_flags.critical = 1; continue; }
|
||||
if (!strncmp("error", argv[i], len)) { debug_flags.error = 1; continue; }
|
||||
if (!strncmp("warning", argv[i], len)) { debug_flags.warning = 1; continue; }
|
||||
if (!strncmp("info", argv[i], len)) { debug_flags.info = 1; continue; }
|
||||
if (!strncmp("calls", argv[i], len)) { debug_flags.calls = 1; continue; }
|
||||
if (!strncmp("data", argv[i], len)) { debug_flags.data = 1; continue; }
|
||||
if (!strncmp("all", argv[i], len))
|
||||
{
|
||||
memset(&debug_flags, 1, sizeof(debug_flags));
|
||||
debug_flags.data = 0;
|
||||
|
|
@ -1607,13 +1610,13 @@ static int cmd_no_debug(struct cli_def *cli, char *command, char **argv, int arg
|
|||
if (argv[i][0] == 'c' && len < 2)
|
||||
len = 2; /* distinguish [cr]itical from [ca]lls */
|
||||
|
||||
if (!strncasecmp(argv[i], "critical", len)) { debug_flags.critical = 0; continue; }
|
||||
if (!strncasecmp(argv[i], "error", len)) { debug_flags.error = 0; continue; }
|
||||
if (!strncasecmp(argv[i], "warning", len)) { debug_flags.warning = 0; continue; }
|
||||
if (!strncasecmp(argv[i], "info", len)) { debug_flags.info = 0; continue; }
|
||||
if (!strncasecmp(argv[i], "calls", len)) { debug_flags.calls = 0; continue; }
|
||||
if (!strncasecmp(argv[i], "data", len)) { debug_flags.data = 0; continue; }
|
||||
if (!strncasecmp(argv[i], "all", len))
|
||||
if (!strncmp("critical", argv[i], len)) { debug_flags.critical = 0; continue; }
|
||||
if (!strncmp("error", argv[i], len)) { debug_flags.error = 0; continue; }
|
||||
if (!strncmp("warning", argv[i], len)) { debug_flags.warning = 0; continue; }
|
||||
if (!strncmp("info", argv[i], len)) { debug_flags.info = 0; continue; }
|
||||
if (!strncmp("calls", argv[i], len)) { debug_flags.calls = 0; continue; }
|
||||
if (!strncmp("data", argv[i], len)) { debug_flags.data = 0; continue; }
|
||||
if (!strncmp("all", argv[i], len))
|
||||
{
|
||||
memset(&debug_flags, 0, sizeof(debug_flags));
|
||||
continue;
|
||||
|
|
@ -1769,7 +1772,7 @@ static int cmd_set(struct cli_def *cli, char *command, char **argv, int argc)
|
|||
{
|
||||
int len = strlen(argv[0])-1;
|
||||
for (i = 0; config_values[i].key; i++)
|
||||
if (!len || !strncmp(argv[0], config_values[i].key, len))
|
||||
if (!len || !strncmp(config_values[i].key, argv[0], len))
|
||||
cli_print(cli, " %s", config_values[i].key);
|
||||
}
|
||||
|
||||
|
|
@ -2826,6 +2829,143 @@ static int cmd_ip_access_list_rule(struct cli_def *cli, char *command, char **ar
|
|||
return CLI_OK;
|
||||
}
|
||||
|
||||
static int cmd_filter(struct cli_def *cli, char *command, char **argv, int argc)
|
||||
{
|
||||
sessionidt s;
|
||||
int i;
|
||||
|
||||
/* filter USER {in|out} FILTER ... */
|
||||
if (CLI_HELP_REQUESTED)
|
||||
{
|
||||
switch (argc)
|
||||
{
|
||||
case 1:
|
||||
return cli_arg_help(cli, 0,
|
||||
"USER", "Username of session to filter", NULL);
|
||||
|
||||
case 2:
|
||||
case 4:
|
||||
return cli_arg_help(cli, 0,
|
||||
"in", "Set incoming filter",
|
||||
"out", "Set outgoing filter", NULL);
|
||||
|
||||
case 3:
|
||||
case 5:
|
||||
return cli_arg_help(cli, argc == 5 && argv[4][1],
|
||||
"NAME", "Filter name", NULL);
|
||||
|
||||
default:
|
||||
return cli_arg_help(cli, argc > 1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!config->cluster_iam_master)
|
||||
{
|
||||
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address));
|
||||
return CLI_OK;
|
||||
}
|
||||
|
||||
if (argc != 3 && argc != 5)
|
||||
{
|
||||
cli_print(cli, "Specify a user and filters");
|
||||
return CLI_OK;
|
||||
}
|
||||
|
||||
if (!(s = sessionbyuser(argv[0])))
|
||||
{
|
||||
cli_print(cli, "User %s is not connected", argv[0]);
|
||||
return CLI_OK;
|
||||
}
|
||||
|
||||
cli_session_actions[s].filter_in = cli_session_actions[s].filter_out = -1;
|
||||
for (i = 1; i < argc; i += 2)
|
||||
{
|
||||
int *f = 0;
|
||||
int v;
|
||||
|
||||
if (MATCH("in", argv[i]))
|
||||
{
|
||||
if (session[s].filter_in)
|
||||
{
|
||||
cli_print(cli, "Input already filtered");
|
||||
return CLI_OK;
|
||||
}
|
||||
f = &cli_session_actions[s].filter_in;
|
||||
}
|
||||
else if (MATCH("out", argv[i]))
|
||||
{
|
||||
if (session[s].filter_out)
|
||||
{
|
||||
cli_print(cli, "Output already filtered");
|
||||
return CLI_OK;
|
||||
}
|
||||
f = &cli_session_actions[s].filter_out;
|
||||
}
|
||||
else
|
||||
{
|
||||
cli_print(cli, "Invalid filter specification");
|
||||
return CLI_OK;
|
||||
}
|
||||
|
||||
v = find_access_list(argv[i+1]);
|
||||
if (v < 0 || !*ip_filters[v].name)
|
||||
{
|
||||
cli_print(cli, "Access-list %s not defined", argv[i+1]);
|
||||
return CLI_OK;
|
||||
}
|
||||
|
||||
*f = v + 1;
|
||||
}
|
||||
|
||||
cli_print(cli, "Filtering user %s", argv[0]);
|
||||
cli_session_actions[s].action |= CLI_SESS_FILTER;
|
||||
|
||||
return CLI_OK;
|
||||
}
|
||||
|
||||
static int cmd_no_filter(struct cli_def *cli, char *command, char **argv, int argc)
|
||||
{
|
||||
int i;
|
||||
sessionidt s;
|
||||
|
||||
if (CLI_HELP_REQUESTED)
|
||||
return cli_arg_help(cli, argc > 1,
|
||||
"USER", "Username of session to remove filters from", NULL);
|
||||
|
||||
if (!config->cluster_iam_master)
|
||||
{
|
||||
cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address));
|
||||
return CLI_OK;
|
||||
}
|
||||
|
||||
if (!argc)
|
||||
{
|
||||
cli_print(cli, "Specify a user to remove filters from");
|
||||
return CLI_OK;
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (!(s = sessionbyuser(argv[i])))
|
||||
{
|
||||
cli_print(cli, "User %s is not connected", argv[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (session[s].filter_in || session[s].filter_out)
|
||||
{
|
||||
cli_print(cli, "Removing filters from user %s", argv[i]);
|
||||
cli_session_actions[s].action |= CLI_SESS_NOFILTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
cli_print(cli, "User %s not filtered", argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return CLI_OK;
|
||||
}
|
||||
|
||||
// Convert a string in the form of abcd.ef12.3456 into char[6]
|
||||
void parsemac(char *string, char mac[6])
|
||||
{
|
||||
|
|
|
|||
85
l2tpns.c
85
l2tpns.c
|
|
@ -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.57 2004-11-27 05:19:53 bodea Exp $";
|
||||
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.58 2004-11-28 02:53:11 bodea Exp $";
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
|
|
@ -1002,6 +1002,44 @@ void throttle_session(sessionidt s, int rate_in, int rate_out)
|
|||
}
|
||||
}
|
||||
|
||||
// add/remove filters from session (-1 = no change)
|
||||
void filter_session(sessionidt s, int filter_in, int filter_out)
|
||||
{
|
||||
if (!session[s].tunnel)
|
||||
return; // No-one home.
|
||||
|
||||
if (!*session[s].user)
|
||||
return; // User not logged in
|
||||
|
||||
// paranoia
|
||||
if (filter_in > MAXFILTER) filter_in = -1;
|
||||
if (filter_out > MAXFILTER) filter_out = -1;
|
||||
if (session[s].filter_in > MAXFILTER) session[s].filter_in = 0;
|
||||
if (session[s].filter_out > MAXFILTER) session[s].filter_out = 0;
|
||||
|
||||
if (filter_in >= 0)
|
||||
{
|
||||
if (session[s].filter_in)
|
||||
ip_filters[session[s].filter_in - 1].used--;
|
||||
|
||||
if (filter_in > 0)
|
||||
ip_filters[filter_in - 1].used++;
|
||||
|
||||
session[s].filter_in = filter_in;
|
||||
}
|
||||
|
||||
if (filter_out >= 0)
|
||||
{
|
||||
if (session[s].filter_out)
|
||||
ip_filters[session[s].filter_out - 1].used--;
|
||||
|
||||
if (filter_out > 0)
|
||||
ip_filters[filter_out - 1].used++;
|
||||
|
||||
session[s].filter_out = filter_out;
|
||||
}
|
||||
}
|
||||
|
||||
// start tidy shutdown of session
|
||||
void sessionshutdown(sessionidt s, char *reason)
|
||||
{
|
||||
|
|
@ -1081,6 +1119,10 @@ void sessionshutdown(sessionidt s, char *reason)
|
|||
if (!session[s].die)
|
||||
session[s].die = now() + 150; // Clean up in 15 seconds
|
||||
|
||||
// update filter refcounts
|
||||
if (session[s].filter_in) ip_filters[session[s].filter_in - 1].used--;
|
||||
if (session[s].filter_out) ip_filters[session[s].filter_out - 1].used--;
|
||||
|
||||
cluster_send_session(s);
|
||||
}
|
||||
|
||||
|
|
@ -2131,6 +2173,22 @@ static int regular_cleanups(void)
|
|||
send++;
|
||||
}
|
||||
|
||||
if (a & CLI_SESS_NOFILTER)
|
||||
{
|
||||
LOG(2, 0, s, session[s].tunnel, "Un-filtering session by CLI\n");
|
||||
filter_session(s, 0, 0);
|
||||
send++;
|
||||
}
|
||||
else if (a & CLI_SESS_FILTER)
|
||||
{
|
||||
LOG(2, 0, s, session[s].tunnel, "Filtering session by CLI (in=%d, out=%d)\n",
|
||||
cli_session_actions[s].filter_in,
|
||||
cli_session_actions[s].filter_out);
|
||||
|
||||
filter_session(s, cli_session_actions[s].filter_in, cli_session_actions[s].filter_out);
|
||||
send++;
|
||||
}
|
||||
|
||||
if (send)
|
||||
cluster_send_session(s);
|
||||
|
||||
|
|
@ -3729,6 +3787,31 @@ int load_session(sessionidt s, sessiont *new)
|
|||
}
|
||||
}
|
||||
|
||||
// check filters
|
||||
if (new->filter_in && (new->filter_in > MAXFILTER || !ip_filters[new->filter_in - 1].name[0]))
|
||||
{
|
||||
LOG(2, session[s].ip, s, session[s].tunnel, "Dropping invalid input filter %d\n", (int) new->filter_in);
|
||||
new->filter_in = 0;
|
||||
}
|
||||
|
||||
if (new->filter_out && (new->filter_out > MAXFILTER || !ip_filters[new->filter_out - 1].name[0]))
|
||||
{
|
||||
LOG(2, session[s].ip, s, session[s].tunnel, "Dropping invalid output filter %d\n", (int) new->filter_out);
|
||||
new->filter_out = 0;
|
||||
}
|
||||
|
||||
if (new->filter_in != session[s].filter_in)
|
||||
{
|
||||
if (session[s].filter_in) ip_filters[session[s].filter_in - 1].used--;
|
||||
if (new->filter_in) ip_filters[new->filter_in - 1].used++;
|
||||
}
|
||||
|
||||
if (new->filter_out != session[s].filter_out)
|
||||
{
|
||||
if (session[s].filter_out) ip_filters[session[s].filter_out - 1].used--;
|
||||
if (new->filter_out) ip_filters[new->filter_out - 1].used++;
|
||||
}
|
||||
|
||||
if (new->tunnel && s > config->cluster_highest_sessionid) // Maintain this in the slave. It's used
|
||||
// for walking the sessions to forward byte counts to the master.
|
||||
config->cluster_highest_sessionid = s;
|
||||
|
|
|
|||
6
l2tpns.h
6
l2tpns.h
|
|
@ -1,5 +1,5 @@
|
|||
// L2TPNS Global Stuff
|
||||
// $Id: l2tpns.h,v 1.38 2004-11-27 05:19:53 bodea Exp $
|
||||
// $Id: l2tpns.h,v 1.39 2004-11-28 02:53:11 bodea Exp $
|
||||
|
||||
#ifndef __L2TPNS_H__
|
||||
#define __L2TPNS_H__
|
||||
|
|
@ -124,6 +124,8 @@ struct cli_session_actions {
|
|||
u16 snoop_port;
|
||||
int throttle_in;
|
||||
int throttle_out;
|
||||
int filter_in;
|
||||
int filter_out;
|
||||
};
|
||||
|
||||
#define CLI_SESS_KILL 0x01
|
||||
|
|
@ -131,6 +133,8 @@ struct cli_session_actions {
|
|||
#define CLI_SESS_NOSNOOP 0x04
|
||||
#define CLI_SESS_THROTTLE 0x08
|
||||
#define CLI_SESS_NOTHROTTLE 0x10
|
||||
#define CLI_SESS_FILTER 0x20
|
||||
#define CLI_SESS_NOFILTER 0x40
|
||||
|
||||
struct cli_tunnel_actions {
|
||||
char action;
|
||||
|
|
|
|||
6
radius.c
6
radius.c
|
|
@ -1,6 +1,6 @@
|
|||
// L2TPNS Radius Stuff
|
||||
|
||||
char const *cvs_id_radius = "$Id: radius.c,v 1.16 2004-11-27 21:10:51 bodea Exp $";
|
||||
char const *cvs_id_radius = "$Id: radius.c,v 1.17 2004-11-28 02:53:11 bodea Exp $";
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -573,7 +573,9 @@ void processrad(u8 *buf, int len, char socket_index)
|
|||
!strncmp(ip_filters[i].name, filter, l))
|
||||
*f = i + 1;
|
||||
|
||||
if (!*f)
|
||||
if (*f)
|
||||
ip_filters[*f - 1].used++;
|
||||
else
|
||||
LOG(3, 0, s, session[s].tunnel, " Unknown filter\n");
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue