add Cisco-AVPairs to RADIUS accounting records via plugin_radius_account
authorBrendan O'Dea <bod@optus.net>
Tue, 11 Oct 2005 09:04:53 +0000 (09:04 +0000)
committerBrendan O'Dea <bod@optus.net>
Tue, 11 Oct 2005 09:04:53 +0000 (09:04 +0000)
12 files changed:
Changes
autosnoop.c
autothrottle.c
garden.c
l2tpns.c
plugin.h
radius.c
sessionctl.c
setrxspeed.c
snoopctl.c
stripdomain.c
throttlectl.c

diff --git a/Changes b/Changes
index dfeabaa..aee33c3 100644 (file)
--- a/Changes
+++ b/Changes
@@ -3,6 +3,7 @@
 - Fix RADIUS authentication on DAE responses.
 - Don't send tunnel HELLO when there are pending control messages.
 - Move plugin_radius_reset from *ctl to auto* plugins.
+- Add Cisco-AVPairs to RADIUS accounting records via plugin_radius_account.
 
 * Mon Sep 19 2005 Brendan O'Dea <bod@optus.net> 2.1.8
 - Move code from signal handlers into mainloop, avoiding a race
index 0a971de..570c147 100644 (file)
@@ -4,46 +4,72 @@
 
 /* set up intercept based on RADIUS reply */
 
-char const *cvs_id = "$Id: autosnoop.c,v 1.11 2005-10-11 07:59:09 bodea Exp $";
+char const *cvs_id = "$Id: autosnoop.c,v 1.12 2005-10-11 09:04:53 bodea Exp $";
 
 int plugin_api_version = PLUGIN_API_VERSION;
-struct pluginfuncs *p;
+static struct pluginfuncs *f = 0;
 
 int plugin_radius_response(struct param_radius_response *data)
 {
-       if (!strcmp(data->key, "intercept"))
+    if (!strcmp(data->key, "intercept"))
+    {
+       char *p;
+       data->s->snoop_ip = 0;
+       data->s->snoop_port = 0;
+       if ((p = strchr(data->value, ':')))
        {
-               char *x;
+           *p++ = 0;
+           if (*data->value)
+               data->s->snoop_ip = inet_addr(data->value);
+
+           if (data->s->snoop_ip == INADDR_NONE)
                data->s->snoop_ip = 0;
-               data->s->snoop_port = 0;
-               if ((x = strchr(data->value, ':')))
-               {
-                       *x++ = 0;
-                       if (*data->value) data->s->snoop_ip = inet_addr(data->value);
-                       if (data->s->snoop_ip == INADDR_NONE) data->s->snoop_ip = 0;
-                       if (*x) data->s->snoop_port = atoi(x);
-                       p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
-                               "         Intercepting user to %s:%d\n",
-                               p->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port);
-               }
-               else
-               {
-                       p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
-                               "         Not Intercepting user (reply string should be intercept=ip:port)\n");
-               }
+
+           if (*p)
+               data->s->snoop_port = atoi(p);
+
+           f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+               "         Intercepting user to %s:%d\n",
+               f->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port);
+       }
+       else
+       {
+           f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+                   "         Not Intercepting user (reply string should"
+                   " be intercept=ip:port)\n");
        }
+    }
 
        return PLUGIN_RET_OK;
 }
 
 int plugin_radius_reset(struct param_radius_reset *data)
 {
-       data->s->snoop_ip = 0;
-       data->s->snoop_port = 0;
-       return PLUGIN_RET_OK;
+    data->s->snoop_ip = 0;
+    data->s->snoop_port = 0;
+    return PLUGIN_RET_OK;
+}
+
+int plugin_radius_account(struct param_radius_account *data)
+{
+    if (data->s->snoop_ip && data->s->snoop_port)
+    {
+       uint8_t *p = *data->packet;
+
+       *p = 26;                                // vendor-specific
+       *(uint32_t *) (p + 2) = htonl(9);       // Cisco
+       p[6] = 1;                               // Cisco-AVPair
+       p[7] = 2 + sprintf((char *) p + 8, "intercept=%s:%d",
+           f->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port);
+
+       p[1] = p[7] + 6;
+       *data->packet += p[1];
+    }
+
+    return PLUGIN_RET_OK;
 }
 
 int plugin_init(struct pluginfuncs *funcs)
 {
-       return ((p = funcs)) ? 1 : 0;
+    return ((f = funcs)) ? 1 : 0;
 }
index 051b9a8..c427c46 100644 (file)
  * throttle=no
  */
 
-char const *cvs_id = "$Id: autothrottle.c,v 1.15 2005-10-11 07:59:09 bodea Exp $";
+char const *cvs_id = "$Id: autothrottle.c,v 1.16 2005-10-11 09:04:53 bodea Exp $";
 
 int plugin_api_version = PLUGIN_API_VERSION;
-struct pluginfuncs *p;
+static struct pluginfuncs *f = 0;
 
 #define THROTTLE_KEY "lcp:interface-config"
 
 int plugin_radius_response(struct param_radius_response *data)
 {
-       if (!strncmp(data->key, THROTTLE_KEY, sizeof(THROTTLE_KEY) - 1))
+    if (!strncmp(data->key, THROTTLE_KEY, sizeof(THROTTLE_KEY) - 1))
+    {
+       char *sp = strchr(data->value, ' ');
+       char type;
+       int rate;
+
+       if (!sp || sp - data->value < 4 ||
+           strncmp("service-policy", data->value, sp - data->value))
+           return PLUGIN_RET_OK;
+
+       while (*sp == ' ') sp++;
+       data->value = sp;
+
+       if (!(sp = strchr(data->value, ' ')) ||
+           (strncmp("input", data->value, sp - data->value) &&
+           strncmp("output", data->value, sp - data->value)))
        {
-               char *sp = strchr(data->value, ' ');
-               char type;
-               int rate;
-
-               if (!sp || sp - data->value < 4 ||
-                   strncmp("service-policy", data->value, sp - data->value))
-                       return PLUGIN_RET_OK;
-
-               while (*sp == ' ') sp++;
-               data->value = sp;
-
-               if (!(sp = strchr(data->value, ' ')) ||
-                   (strncmp("input", data->value, sp - data->value) &&
-                   strncmp("output", data->value, sp - data->value)))
-               {
-                       p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
-                               "         Not throttling user (invalid type %.*s)\n",
-                               sp - data->value, data->value);
-
-                       return PLUGIN_RET_OK;
-               }
-
-               type = *data->value;
-
-               while (*sp == ' ') sp++;
-               data->value = sp;
-
-               if ((rate = strtol(data->value, &sp, 10)) < 0 || *sp)
-               {
-                       p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
-                               "         Not throttling user (invalid rate %s)\n",
-                               data->value);
-
-                       return PLUGIN_RET_OK;
-               }
-
-               if (type == 'i')
-               {
-                       data->s->throttle_in = rate;
-                       p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
-                               "         Throttling user input to %dkb/s\n",
-                               rate);
-               }
-               else
-               {
-                       data->s->throttle_out = rate;
-                       p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
-                               "         Throttling user output to %dkb/s\n",
-                               rate);
-               }
+           f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+               "         Not throttling user (invalid type %.*s)\n",
+               sp - data->value, data->value);
+
+           return PLUGIN_RET_OK;
+       }
+
+       type = *data->value;
+
+       while (*sp == ' ') sp++;
+       data->value = sp;
+
+       if ((rate = strtol(data->value, &sp, 10)) < 0 || *sp)
+       {
+           f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+               "         Not throttling user (invalid rate %s)\n",
+               data->value);
+
+           return PLUGIN_RET_OK;
        }
 
-       if (!strcmp(data->key, "throttle"))
+       if (type == 'i')
        {
-               char *e;
-               int rate;
-
-               if ((rate = strtol(data->value, &e, 10)) < 0 || *e)
-               {
-                       rate = -1;
-                       if (!strcmp(data->value, "yes"))
-                       {
-                               unsigned long *ts = p->getconfig("throttle_speed", UNSIGNED_LONG);
-                               if (ts)
-                                       rate = *ts;
-                       }
-                       else if (!strcmp(data->value, "no"))
-                               rate = 0;
-               }
-
-               if (rate < 0)
-                       return PLUGIN_RET_OK;
-
-               if (rate)
-                       p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
-                               "         Throttling user to %dkb/s\n", rate);
-               else
-                       p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
-                               "         Not throttling user\n");
-
-               data->s->throttle_in = data->s->throttle_out = rate;
+           data->s->throttle_in = rate;
+           f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+               "         Throttling user input to %dkb/s\n", rate);
        }
+       else
+       {
+           data->s->throttle_out = rate;
+           f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+                   "         Throttling user output to %dkb/s\n", rate);
+       }
+    }
+    else if (!strcmp(data->key, "throttle"))
+    {
+       char *e;
+       int rate;
+
+       if ((rate = strtol(data->value, &e, 10)) < 0 || *e)
+       {
+           rate = -1;
+           if (!strcmp(data->value, "yes"))
+           {
+               unsigned long *ts = f->getconfig("throttle_speed", UNSIGNED_LONG);
+               if (ts)
+                   rate = *ts;
+           }
+           else if (!strcmp(data->value, "no"))
+               rate = 0;
+       }
+
+       if (rate < 0)
+           return PLUGIN_RET_OK;
 
-       return PLUGIN_RET_OK;
+       if (rate)
+           f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+               "         Throttling user to %dkb/s\n", rate);
+       else
+           f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+               "         Not throttling user\n");
+
+       data->s->throttle_in = data->s->throttle_out = rate;
+    }
+
+    return PLUGIN_RET_OK;
 }
 
 int plugin_radius_reset(struct param_radius_reset *data)
 {
-       p->throttle(p->get_id_by_session(data->s), 0, 0);
-       return PLUGIN_RET_OK;
+    f->throttle(f->get_id_by_session(data->s), 0, 0);
+    return PLUGIN_RET_OK;
+}
+
+int plugin_radius_account(struct param_radius_account *data)
+{
+    if (data->s->throttle_in || data->s->throttle_out)
+    {
+       uint8_t *p = *data->packet;
+       int i = 1;
+
+       if (data->s->throttle_in)
+       {
+           *p = 26;                            // vendor-specific
+           *(uint32_t *) (p + 2) = htonl(9);   // Cisco
+           p[6] = 1;                           // Cisco-AVPair
+           p[7] = 2 + sprintf((char *) p + 8,
+               "lcp:interface-config#%d=service-policy input %d", i++,
+               data->s->throttle_in);
+
+           p[1] = p[7] + 6;
+           p += p[1];
+       }
+
+       if (data->s->throttle_out)
+       {
+           *p = 26;                            // vendor-specific
+           *(uint32_t *) (p + 2) = htonl(9);   // Cisco
+           p[6] = 1;                           // Cisco-AVPair
+           p[7] = 2 + sprintf((char *) p + 8,
+               "lcp:interface-config#%d=service-policy output %d", i++,
+               data->s->throttle_out);
+
+           p[1] = p[7] + 6;
+           p += p[1];
+       }
+
+       *data->packet = p;
+    }
+
+    return PLUGIN_RET_OK;
 }
 
 int plugin_init(struct pluginfuncs *funcs)
 {
-       return ((p = funcs)) ? 1 : 0;
+    return ((f = funcs)) ? 1 : 0;
 }
index 07f1f41..a023399 100644 (file)
--- a/garden.c
+++ b/garden.c
@@ -9,35 +9,35 @@
 
 /* walled garden */
 
-char const *cvs_id = "$Id: garden.c,v 1.23 2005-06-02 11:32:30 bodea Exp $";
+char const *cvs_id = "$Id: garden.c,v 1.24 2005-10-11 09:04:53 bodea Exp $";
 
 int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
 
 static int iam_master = 0;     // We're all slaves! Slaves I tell you!
 
 char *up_commands[] = {
-       "iptables -t nat -N garden >/dev/null 2>&1",                    // Create a chain that all gardened users will go through
-       "iptables -t nat -F garden",
-       ". " PLUGINCONF "/build-garden",                                // Populate with site-specific DNAT rules
-       "iptables -t nat -N garden_users >/dev/null 2>&1",              // Empty chain, users added/removed by garden_session
-       "iptables -t nat -F garden_users",
-       "iptables -t nat -A PREROUTING -j garden_users",                // DNAT any users on the garden_users chain
-       "sysctl -w net.ipv4.ip_conntrack_max=512000 >/dev/null",        // lots of entries
-       NULL,
+    "iptables -t nat -N garden >/dev/null 2>&1",               // Create a chain that all gardened users will go through
+    "iptables -t nat -F garden",
+    ". " PLUGINCONF "/build-garden",                           // Populate with site-specific DNAT rules
+    "iptables -t nat -N garden_users >/dev/null 2>&1",         // Empty chain, users added/removed by garden_session
+    "iptables -t nat -F garden_users",
+    "iptables -t nat -A PREROUTING -j garden_users",           // DNAT any users on the garden_users chain
+    "sysctl -w net.ipv4.ip_conntrack_max=512000 >/dev/null",   // lots of entries
+    NULL,
 };
 
 char *down_commands[] = {
-       "iptables -t nat -F PREROUTING",
-       "iptables -t nat -F garden_users",
-       "iptables -t nat -X garden_users",
-       "iptables -t nat -F garden",
-       "iptables -t nat -X garden",
-       "rmmod iptable_nat",    // Should also remove ip_conntrack, but
+    "iptables -t nat -F PREROUTING",
+    "iptables -t nat -F garden_users",
+    "iptables -t nat -X garden_users",
+    "iptables -t nat -F garden",
+    "iptables -t nat -X garden",
+    "rmmod iptable_nat",       // Should also remove ip_conntrack, but
                                // doing so can take hours...  literally.
                                // If a master is re-started as a slave,
                                // either rmmod manually, or reboot.
-       NULL,
+    NULL,
 };
 
 #define F_UNGARDEN     0
@@ -48,234 +48,249 @@ int garden_session(sessiont *s, int flag, char *newuser);
 
 int plugin_post_auth(struct param_post_auth *data)
 {
-       // Ignore if user authentication was successful
-       if (data->auth_allowed) return PLUGIN_RET_OK;
-
-       p->log(3, p->get_id_by_session(data->s), data->s->tunnel, "Walled Garden allowing login\n");
-       data->auth_allowed = 1;
-       data->s->walled_garden = 1;
+    // Ignore if user authentication was successful
+    if (data->auth_allowed)
        return PLUGIN_RET_OK;
+
+    f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+       "Walled Garden allowing login\n");
+
+    data->auth_allowed = 1;
+    data->s->walled_garden = 1;
+    return PLUGIN_RET_OK;
 }
 
 int plugin_new_session(struct param_new_session *data)
 {
-       if (!iam_master)
-               return PLUGIN_RET_OK;   // Slaves don't do walled garden processing.
+    if (!iam_master)
+       return PLUGIN_RET_OK;   // Slaves don't do walled garden processing.
 
-       if (data->s->walled_garden)
-               garden_session(data->s, F_GARDEN, 0);
+    if (data->s->walled_garden)
+       garden_session(data->s, F_GARDEN, 0);
 
-       return PLUGIN_RET_OK;
+    return PLUGIN_RET_OK;
 }
 
 int plugin_kill_session(struct param_new_session *data)
 {
-       if (!iam_master)
-               return PLUGIN_RET_OK;   // Slaves don't do walled garden processing.
+    if (!iam_master)
+       return PLUGIN_RET_OK;   // Slaves don't do walled garden processing.
 
-       if (data->s->walled_garden)
-               garden_session(data->s, F_CLEANUP, 0);
+    if (data->s->walled_garden)
+       garden_session(data->s, F_CLEANUP, 0);
 
-       return PLUGIN_RET_OK;
+    return PLUGIN_RET_OK;
 }
 
 char *plugin_control_help[] = {
-       "  garden USER|SID                             Put user into the walled garden",
-       "  ungarden SID [USER]                         Release session from garden",
-       0
+    "  garden USER|SID                             Put user into the walled garden",
+    "  ungarden SID [USER]                         Release session from garden",
+    0
 };
 
 int plugin_control(struct param_control *data)
 {
-       sessionidt session;
-       sessiont *s = 0;
-       int flag;
-       char *end;
+    sessionidt session;
+    sessiont *s = 0;
+    int flag;
+    char *end;
 
-       if (data->argc < 1)
-               return PLUGIN_RET_OK;
+    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
+    if (strcmp(data->argv[0], "garden") && strcmp(data->argv[0], "ungarden"))
+       return PLUGIN_RET_OK; // not for us
 
-       if (!iam_master)
-               return PLUGIN_RET_NOTMASTER;
+    if (!iam_master)
+       return PLUGIN_RET_NOTMASTER;
 
-       flag = data->argv[0][0] == 'g' ? F_GARDEN : F_UNGARDEN;
+    flag = data->argv[0][0] == 'g' ? F_GARDEN : F_UNGARDEN;
 
-       if (data->argc < 2 || data->argc > 3 || (data->argc > 2 && flag == F_GARDEN))
-       {
-               data->response = NSCTL_RES_ERR;
-               data->additional = flag == F_GARDEN
-                   ? "requires username or session id"
-                   : "requires session id and optional username";
+    if (data->argc < 2 || data->argc > 3 || (data->argc > 2 && flag == F_GARDEN))
+    {
+       data->response = NSCTL_RES_ERR;
+       data->additional = flag == F_GARDEN
+           ? "requires username or session id"
+           : "requires session id and optional username";
 
-               return PLUGIN_RET_STOP;
-       }
+       return PLUGIN_RET_STOP;
+    }
 
-       if (!(session = strtol(data->argv[1], &end, 10)) || *end)
-       {
-               if (flag)
-                       session = p->get_session_by_username(data->argv[1]);
-               else
-                       session = 0; // can't ungarden by username
-       }
+    if (!(session = strtol(data->argv[1], &end, 10)) || *end)
+    {
+       if (flag)
+           session = f->get_session_by_username(data->argv[1]);
+       else
+           session = 0; // can't ungarden by username
+    }
 
-       if (session)
-               s = p->get_session_by_id(session);
+    if (session)
+       s = f->get_session_by_id(session);
 
-       if (!s || !s->ip)
-       {
-               data->response = NSCTL_RES_ERR;
-               data->additional = "session not found";
-               return PLUGIN_RET_STOP;
-       }
+    if (!s || !s->ip)
+    {
+       data->response = NSCTL_RES_ERR;
+       data->additional = "session not found";
+       return PLUGIN_RET_STOP;
+    }
 
-       if (s->walled_garden == flag)
-       {
-               data->response = NSCTL_RES_ERR;
-               data->additional = flag ? "already in walled garden" : "not in walled garden";
-               return PLUGIN_RET_STOP;
-       }
+    if (s->walled_garden == flag)
+    {
+       data->response = NSCTL_RES_ERR;
+       data->additional = flag ? "already in walled garden" : "not in walled garden";
+       return PLUGIN_RET_STOP;
+    }
 
-       garden_session(s, flag, data->argc > 2 ? data->argv[2] : 0);
-       p->session_changed(session);
+    garden_session(s, flag, data->argc > 2 ? data->argv[2] : 0);
+    f->session_changed(session);
 
-       data->response = NSCTL_RES_OK;
-       data->additional = 0;
+    data->response = NSCTL_RES_OK;
+    data->additional = 0;
 
-       return PLUGIN_RET_STOP;
+    return PLUGIN_RET_STOP;
 }
 
 int plugin_become_master(void)
 {
-       int i;
-       iam_master = 1; // We just became the master. Wow!
+    int i;
+    iam_master = 1;    // We just became the master. Wow!
 
-       for (i = 0; up_commands[i] && *up_commands[i]; i++)
-       {
-               p->log(3, 0, 0, "Running %s\n", up_commands[i]);
-               system(up_commands[i]);
-       }
+    for (i = 0; up_commands[i] && *up_commands[i]; i++)
+    {
+       f->log(3, 0, 0, "Running %s\n", up_commands[i]);
+       system(up_commands[i]);
+    }
 
-       return PLUGIN_RET_OK;
+    return PLUGIN_RET_OK;
 }
 
 // Called for each active session after becoming master
 int plugin_new_session_master(sessiont *s)
 {      
-       if (s->walled_garden)
-               garden_session(s, F_GARDEN, 0);
+    if (s->walled_garden)
+       garden_session(s, F_GARDEN, 0);
 
-       return PLUGIN_RET_OK;
+    return PLUGIN_RET_OK;
 }
 
 int garden_session(sessiont *s, int flag, char *newuser)
 {
-       char cmd[2048];
-       sessionidt sess;
+    char cmd[2048];
+    sessionidt sess;
+
+    if (!s) return 0;
+    if (!s->opened) return 0;
+
+    sess = f->get_id_by_session(s);
+    if (flag == F_GARDEN)
+    {
+       f->log(2, sess, s->tunnel, "Garden user %s (%s)\n", s->user,
+           f->fmtaddr(htonl(s->ip), 0));
+
+       snprintf(cmd, sizeof(cmd),
+           "iptables -t nat -A garden_users -s %s -j garden",
+           f->fmtaddr(htonl(s->ip), 0));
+
+       f->log(3, sess, s->tunnel, "%s\n", cmd);
+       system(cmd);
+       s->walled_garden = 1;
+    }
+    else
+    {
+       sessionidt other;
+       int count = 40;
+
+       // Normal User
+       f->log(2, sess, s->tunnel, "Un-Garden user %s (%s)\n", s->user, f->fmtaddr(htonl(s->ip), 0));
+       if (newuser)
+       {
+           snprintf(s->user, MAXUSER, "%s", newuser);
+           f->log(2, sess, s->tunnel, "  Setting username to %s\n", s->user);
+       }
 
-       if (!s) return 0;
-       if (!s->opened) return 0;
+       // Kick off any duplicate usernames
+       // but make sure not to kick off ourself
+       if (s->ip && !s->die && (other = f->get_session_by_username(s->user)) &&
+           s != f->get_session_by_id(other))
+       {
+           f->sessionkill(other,
+               "Duplicate session when user released from walled garden");
+       }
+
+       /* Clean up counters */
+       s->pin = s->pout = 0;
+       s->cin = s->cout = 0;
+       s->cin_delta = s->cout_delta = 0;
+       s->cin_wrap = s->cout_wrap = 0;
 
-       sess = p->get_id_by_session(s);
-       if (flag == F_GARDEN)
+       snprintf(cmd, sizeof(cmd),
+           "iptables -t nat -D garden_users -s %s -j garden",
+           f->fmtaddr(htonl(s->ip), 0));
+
+       f->log(3, sess, s->tunnel, "%s\n", cmd);
+       while (--count)
        {
-               p->log(2, sess, s->tunnel, "Garden user %s (%s)\n", s->user, p->fmtaddr(htonl(s->ip), 0));
-               snprintf(cmd, sizeof(cmd), "iptables -t nat -A garden_users -s %s -j garden", p->fmtaddr(htonl(s->ip), 0));
-               p->log(3, sess, s->tunnel, "%s\n", cmd);
-               system(cmd);
-               s->walled_garden = 1;
+           int status = system(cmd);
+           if (WEXITSTATUS(status) != 0) break;
        }
-       else
+
+       s->walled_garden = 0;
+
+       if (flag != F_CLEANUP)
        {
-               sessionidt other;
-               int count = 40;
-
-               // Normal User
-               p->log(2, sess, s->tunnel, "Un-Garden user %s (%s)\n", s->user, p->fmtaddr(htonl(s->ip), 0));
-               if (newuser)
-               {
-                       snprintf(s->user, MAXUSER, "%s", newuser);
-                       p->log(2, sess, s->tunnel, "  Setting username to %s\n", s->user);
-               }
-
-               // Kick off any duplicate usernames
-               // but make sure not to kick off ourself
-               if (s->ip && !s->die && (other = p->get_session_by_username(s->user)) && s != p->get_session_by_id(other)) {
-                       p->sessionkill(other, "Duplicate session when user released from walled garden");
-               }
-               /* Clean up counters */
-               s->pin = s->pout = 0;
-               s->cin = s->cout = 0;
-               s->cin_delta = s->cout_delta = 0;
-               s->cin_wrap = s->cout_wrap = 0;
-
-               snprintf(cmd, sizeof(cmd), "iptables -t nat -D garden_users -s %s -j garden", p->fmtaddr(htonl(s->ip), 0));
-               p->log(3, sess, s->tunnel, "%s\n", cmd);
-               while (--count)
-               {
-                       int status = system(cmd);
-                       if (WEXITSTATUS(status) != 0) break;
-               }
-
-               s->walled_garden = 0;
-
-               if (flag != F_CLEANUP)
-               {
-                       /* OK, we're up! */
-                       uint16_t r = p->radiusnew(p->get_id_by_session(s));
-                       if (r) p->radiussend(r, RADIUSSTART);
-               }
+           /* OK, we're up! */
+           uint16_t r = f->radiusnew(f->get_id_by_session(s));
+           if (r) f->radiussend(r, RADIUSSTART);
        }
+    }
 
-       return 1;
+    return 1;
 }
 
 int plugin_init(struct pluginfuncs *funcs)
 {
-       FILE *tables;
-       int found_nat = 0;
+    FILE *tables;
+    int found_nat = 0;
 
-       if (!funcs)
-               return 0;
+    if (!funcs)
+       return 0;
 
-       p = funcs;
+    f = funcs;
 
-       if ((tables = fopen("/proc/net/ip_tables_names", "r")))
-       {
-               char buf[1024];
-               while (fgets(buf, sizeof(buf), tables) && !found_nat)
-                       found_nat = !strcmp(buf, "nat\n");
+    if ((tables = fopen("/proc/net/ip_tables_names", "r")))
+    {
+       char buf[1024];
+       while (fgets(buf, sizeof(buf), tables) && !found_nat)
+           found_nat = !strcmp(buf, "nat\n");
 
-               fclose(tables);
-       }
+       fclose(tables);
+    }
 
-       /* master killed/crashed? */
-       if (found_nat)
+    /* master killed/crashed? */
+    if (found_nat)
+    {
+       int i;
+       for (i = 0; down_commands[i] && *down_commands[i]; i++)
        {
-               int i;
-               for (i = 0; down_commands[i] && *down_commands[i]; i++)
-               {
-                       p->log(3, 0, 0, "Running %s\n", down_commands[i]);
-                       system(down_commands[i]);
-               }
+           f->log(3, 0, 0, "Running %s\n", down_commands[i]);
+           system(down_commands[i]);
        }
+    }
 
-       return 1;
+    return 1;
 }
 
 void plugin_done()
 {
-       int i;
+    int i;
 
-       if (!iam_master)        // Never became master. nothing to do.
-               return;
+    if (!iam_master)   // Never became master. nothing to do.
+       return;
 
-       for (i = 0; down_commands[i] && *down_commands[i]; i++)
-       {
-               p->log(3, 0, 0, "Running %s\n", down_commands[i]);
-               system(down_commands[i]);
-       }
+    for (i = 0; down_commands[i] && *down_commands[i]; i++)
+    {
+       f->log(3, 0, 0, "Running %s\n", down_commands[i]);
+       system(down_commands[i]);
+    }
 }
 
index 81d6dcc..0f50b64 100644 (file)
--- a/l2tpns.c
+++ b/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.143 2005-10-11 07:06:56 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.144 2005-10-11 09:04:53 bodea Exp $";
 
 #include <arpa/inet.h>
 #include <assert.h>
@@ -162,6 +162,7 @@ static char *plugin_functions[] = {
        "plugin_control",
        "plugin_radius_response",
        "plugin_radius_reset",
+       "plugin_radius_account",
        "plugin_become_master",
        "plugin_new_session_master",
 };
index faf3a5e..a57d700 100644 (file)
--- a/plugin.h
+++ b/plugin.h
@@ -6,18 +6,19 @@
 
 enum
 {
-       PLUGIN_PRE_AUTH = 1,
-       PLUGIN_POST_AUTH,
-       PLUGIN_PACKET_RX,
-       PLUGIN_PACKET_TX,
-       PLUGIN_TIMER,
-       PLUGIN_NEW_SESSION,
-       PLUGIN_KILL_SESSION,
-       PLUGIN_CONTROL,
-       PLUGIN_RADIUS_RESPONSE,
-       PLUGIN_RADIUS_RESET,
-       PLUGIN_BECOME_MASTER,
-       PLUGIN_NEW_SESSION_MASTER,
+    PLUGIN_PRE_AUTH = 1,
+    PLUGIN_POST_AUTH,
+    PLUGIN_PACKET_RX,
+    PLUGIN_PACKET_TX,
+    PLUGIN_TIMER,
+    PLUGIN_NEW_SESSION,
+    PLUGIN_KILL_SESSION,
+    PLUGIN_CONTROL,
+    PLUGIN_RADIUS_RESPONSE,
+    PLUGIN_RADIUS_RESET,
+    PLUGIN_RADIUS_ACCOUNT,
+    PLUGIN_BECOME_MASTER,
+    PLUGIN_NEW_SESSION_MASTER,
 };
 
 #define PLUGIN_RET_ERROR       0
@@ -27,95 +28,102 @@ enum
 
 struct pluginfuncs
 {
-       void (*log)(int level, sessionidt s, tunnelidt t, const char *format, ...);
-       void (*log_hex)(int level, const char *title, const uint8_t *data, int maxsize);
-       char *(*fmtaddr)(in_addr_t addr, int n);
-       sessionidt (*get_session_by_username)(char *username);
-       sessiont *(*get_session_by_id)(sessionidt s);
-       sessionidt (*get_id_by_session)(sessiont *s);
-       uint16_t (*radiusnew)(sessionidt s);
-       void (*radiussend)(uint16_t r, uint8_t state);
-       void *(*getconfig)(char *key, enum config_typet type);
-       void (*sessionshutdown)(sessionidt s, char *reason, int result, int error);
-       void (*sessionkill)(sessionidt s, char *reason);
-       void (*throttle)(sessionidt s, int rate_in, int rate_out);
-       int (*session_changed)(int sid);
+    void (*log)(int level, sessionidt s, tunnelidt t, const char *format, ...);
+    void (*log_hex)(int level, const char *title, const uint8_t *data, int maxsize);
+    char *(*fmtaddr)(in_addr_t addr, int n);
+    sessionidt (*get_session_by_username)(char *username);
+    sessiont *(*get_session_by_id)(sessionidt s);
+    sessionidt (*get_id_by_session)(sessiont *s);
+    uint16_t (*radiusnew)(sessionidt s);
+    void (*radiussend)(uint16_t r, uint8_t state);
+    void *(*getconfig)(char *key, enum config_typet type);
+    void (*sessionshutdown)(sessionidt s, char *reason, int result, int error);
+    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
 {
-       tunnelt *t;
-       sessiont *s;
-       char *username;
-       char *password;
-       int protocol;
-       int continue_auth;
+    tunnelt *t;
+    sessiont *s;
+    char *username;
+    char *password;
+    int protocol;
+    int continue_auth;
 };
 
 struct param_post_auth
 {
-       tunnelt *t;
-       sessiont *s;
-       char *username;
-       short auth_allowed;
-       int protocol;
+    tunnelt *t;
+    sessiont *s;
+    char *username;
+    short auth_allowed;
+    int protocol;
 };
 
 struct param_packet_rx
 {
-       tunnelt *t;
-       sessiont *s;
-       char *buf;
-       int len;
+    tunnelt *t;
+    sessiont *s;
+    char *buf;
+    int len;
 };
 
 struct param_packet_tx
 {
-       tunnelt *t;
-       sessiont *s;
-       char *buf;
-       int len;
+    tunnelt *t;
+    sessiont *s;
+    char *buf;
+    int len;
 };
 
 struct param_timer
 {
-       time_t time_now;
+    time_t time_now;
 };
 
 struct param_control
 {
-       int iam_master;
-       int argc;
-       char **argv;
-       // output
-       int response;
-       char *additional;
+    int iam_master;
+    int argc;
+    char **argv;
+    // output
+    int response;
+    char *additional;
 };
 
 struct param_new_session
 {
-       tunnelt *t;
-       sessiont *s;
+    tunnelt *t;
+    sessiont *s;
 };
 
 struct param_kill_session
 {
-       tunnelt *t;
-       sessiont *s;
+    tunnelt *t;
+    sessiont *s;
 };
 
 struct param_radius_response
 {
-       tunnelt *t;
-       sessiont *s;
-       char *key;
-       char *value;
+    tunnelt *t;
+    sessiont *s;
+    char *key;
+    char *value;
 };
 
 struct param_radius_reset
 {
-       tunnelt *t;
-       sessiont *s;
+    tunnelt *t;
+    sessiont *s;
+};
+
+struct param_radius_account
+{
+    tunnelt *t;
+    sessiont *s;
+    uint8_t **packet;
 };
 
 #endif /* __PLUGIN_H__ */
index 61cbfd4..f2eebb8 100644 (file)
--- a/radius.c
+++ b/radius.c
@@ -1,6 +1,6 @@
 // L2TPNS Radius Stuff
 
-char const *cvs_id_radius = "$Id: radius.c,v 1.43 2005-10-11 02:27:40 foonly Exp $";
+char const *cvs_id_radius = "$Id: radius.c,v 1.44 2005-10-11 09:04:53 bodea Exp $";
 
 #include <time.h>
 #include <stdio.h>
@@ -304,18 +304,11 @@ void radiussend(uint16_t r, uint8_t state)
                                p[1] = 6;
                                *(uint32_t *) (p + 2) = htonl(session[s].cout_wrap);
                                p += p[1];
-                       }
-
-                       if (session[s].snoop_ip && session[s].snoop_port)
-                       {
-                               *p = 26;                                // vendor-specific
-                               *(uint32_t *) (p + 2) = htonl(9);       // Cisco
-                               p[6] = 1;                               // Cisco-AVPair
-                               p[7] = 2 + sprintf((char *) p + 8, "intercept=%s:%d",
-                                       fmtaddr(session[s].snoop_ip, 0), session[s].snoop_port);
 
-                               p[1] = p[7] + 6;
-                               p += p[1];
+                               {
+                                       struct param_radius_account acct = { &tunnel[session[s].tunnel], &session[s], &p };
+                                       run_plugins(PLUGIN_RADIUS_ACCOUNT, &acct);
+                               }
                        }
                }
        }
index 0aae1c9..635d202 100644 (file)
@@ -5,10 +5,10 @@
 
 /* session control */
 
-char const *cvs_id = "$Id: sessionctl.c,v 1.3 2005-06-28 14:48:28 bodea Exp $";
+char const *cvs_id = "$Id: sessionctl.c,v 1.4 2005-10-11 09:04:53 bodea Exp $";
 
 int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
 
 char *plugin_control_help[] = {
     "  drop USER|SID [REASON]                      Shutdown user session",
@@ -40,10 +40,10 @@ int plugin_control(struct param_control *data)
     }
 
     if (!(session = strtol(data->argv[1], &end, 10)) || *end)
-       session = p->get_session_by_username(data->argv[1]);
+       session = f->get_session_by_username(data->argv[1]);
 
     if (session)
-       s = p->get_session_by_id(session);
+       s = f->get_session_by_id(session);
 
     if (!s || !s->ip)
     {
@@ -58,9 +58,9 @@ int plugin_control(struct param_control *data)
        reason = "Requested by administrator.";
 
     if (data->argv[0][0] == 'd')
-       p->sessionshutdown(session, reason, 3, 0);
+       f->sessionshutdown(session, reason, 3, 0);
     else
-       p->sessionkill(session, reason);
+       f->sessionkill(session, reason);
 
     data->response = NSCTL_RES_OK;
     data->additional = 0;
@@ -70,5 +70,5 @@ int plugin_control(struct param_control *data)
 
 int plugin_init(struct pluginfuncs *funcs)
 {
-       return ((p = funcs)) ? 1 : 0;
+    return ((f = funcs)) ? 1 : 0;
 }
index 9842e78..7a5acd9 100644 (file)
@@ -4,34 +4,38 @@
 
 /* fudge up session rx speed if not set */
 
-char const *cvs_id = "$Id: setrxspeed.c,v 1.3 2004-11-17 08:23:35 bodea Exp $";
+char const *cvs_id = "$Id: setrxspeed.c,v 1.4 2005-10-11 09:04:53 bodea Exp $";
 
 int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
 
 int plugin_post_auth(struct param_post_auth *data)
 {
-       if (!data->auth_allowed) return PLUGIN_RET_OK;
-
-       if (!data->s->rx_connect_speed)
-       {
-               switch (data->s->tx_connect_speed)
-               {
-                       case 256 :
-                               data->s->rx_connect_speed = 64;
-                               break;
-                       case 512 :
-                               data->s->rx_connect_speed = 128;
-                               break;
-                       case 1500 :
-                               data->s->rx_connect_speed = 256;
-                               break;
-               }
-       }
-       return PLUGIN_RET_OK;
+    if (!data->auth_allowed)
+       return PLUGIN_RET_OK;
+
+    if (data->s->rx_connect_speed)
+       return PLUGIN_RET_OK;
+
+    switch (data->s->tx_connect_speed)
+    {
+    case 256:
+       data->s->rx_connect_speed = 64;
+       break;
+
+    case 512:
+       data->s->rx_connect_speed = 128;
+       break;
+
+    case 1500:
+       data->s->rx_connect_speed = 256;
+       break;
+    }
+
+    return PLUGIN_RET_OK;
 }
 
 int plugin_init(struct pluginfuncs *funcs)
 {
-       return ((p = funcs)) ? 1 : 0;
+    return ((f = funcs)) ? 1 : 0;
 }
index b935723..943294f 100644 (file)
 
 /* snoop control */
 
-char const *cvs_id = "$Id: snoopctl.c,v 1.6 2005-10-11 07:59:09 bodea Exp $";
+char const *cvs_id = "$Id: snoopctl.c,v 1.7 2005-10-11 09:04:53 bodea Exp $";
 
 int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
 
 char *plugin_control_help[] = {
-       "  snoop USER|SID IP PORT                      Intercept user traffic",
-       "  unsnoop USER|SID                            Stop intercepting user",
-       0
+    "  snoop USER|SID IP PORT                      Intercept user traffic",
+    "  unsnoop USER|SID                            Stop intercepting user",
+    0
 };
 
 int plugin_control(struct param_control *data)
 {
-       sessionidt session;
-       sessiont *s = 0;
-       int flag;
-       char *end;
+    sessionidt session;
+    sessiont *s = 0;
+    int flag;
+    char *end;
 
-       if (data->argc < 1)
-               return PLUGIN_RET_OK;
+    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
+    if (strcmp(data->argv[0], "snoop") && strcmp(data->argv[0], "unsnoop"))
+       return PLUGIN_RET_OK; // not for us
 
-       if (!data->iam_master)
-               return PLUGIN_RET_NOTMASTER;
+    if (!data->iam_master)
+       return PLUGIN_RET_NOTMASTER;
 
-       flag = data->argv[0][0] != 'u';
+    flag = data->argv[0][0] != 'u';
 
-       if (flag)
+    if (flag)
+    {
+       if (data->argc != 4)
        {
-               if (data->argc != 4)
-               {
-                       data->response = NSCTL_RES_ERR;
-                       data->additional = "requires username or session id and host, port";
-                       return PLUGIN_RET_STOP;
-               }
+           data->response = NSCTL_RES_ERR;
+           data->additional = "requires username or session id and host, port";
+           return PLUGIN_RET_STOP;
        }
-       else
+    }
+    else
+    {
+       if (data->argc != 2)
        {
-               if (data->argc != 2)
-               {
-                       data->response = NSCTL_RES_ERR;
-                       data->additional = "requires username or session id";
-                       return PLUGIN_RET_STOP;
-               }
+           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 = strtol(data->argv[1], &end, 10)) || *end)
+       session = f->get_session_by_username(data->argv[1]);
 
-       if (session)
-               s = p->get_session_by_id(session);
+    if (session)
+       s = f->get_session_by_id(session);
 
-       if (!s || !s->ip)
+    if (!s || !s->ip)
+    {
+       data->response = NSCTL_RES_ERR;
+       data->additional = "session not found";
+       return PLUGIN_RET_STOP;
+    }
+
+    if (flag)
+    {
+       in_addr_t ip = inet_addr(data->argv[2]);
+       uint16_t port = atoi(data->argv[3]);
+
+       if (!ip || ip == INADDR_NONE)
        {
-               data->response = NSCTL_RES_ERR;
-               data->additional = "session not found";
-               return PLUGIN_RET_STOP;
+           data->response = NSCTL_RES_ERR;
+           data->additional = "invalid ip address";
+           return PLUGIN_RET_STOP;
        }
 
-       if (flag)
+       if (!port)
        {
-               in_addr_t ip = inet_addr(data->argv[2]);
-               uint16_t 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;
+           data->response = NSCTL_RES_ERR;
+           data->additional = "invalid port";
+           return PLUGIN_RET_STOP;
        }
-       else
+
+       if (ip == s->snoop_ip && port == s->snoop_port)
        {
-               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;
+           data->response = NSCTL_RES_ERR;
+           data->additional = "already intercepted";
+           return PLUGIN_RET_STOP;
        }
 
-       p->session_changed(session);
+       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;
+       }
 
-       data->response = NSCTL_RES_OK;
-       data->additional = 0;
+       s->snoop_ip = 0;
+       s->snoop_port = 0;
+    }
 
-       return PLUGIN_RET_STOP;
+    f->session_changed(session);
+
+    data->response = NSCTL_RES_OK;
+    data->additional = 0;
+
+    return PLUGIN_RET_STOP;
 }
 
 int plugin_init(struct pluginfuncs *funcs)
 {
-       return ((p = funcs)) ? 1 : 0;
+    return ((f = funcs)) ? 1 : 0;
 }
index a7a3fb2..c1dcea0 100644 (file)
@@ -4,28 +4,28 @@
 
 /* strip domain part of username before sending RADIUS requests */
 
-char const *cvs_id = "$Id: stripdomain.c,v 1.7 2004-11-29 02:17:18 bodea Exp $";
+char const *cvs_id = "$Id: stripdomain.c,v 1.8 2005-10-11 09:04:53 bodea Exp $";
 
 int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
 
 int plugin_pre_auth(struct param_pre_auth *data)
 {
-       char *x;
+    char *p;
 
-       if (!data->continue_auth) return PLUGIN_RET_STOP;
+    if (!data->continue_auth) return PLUGIN_RET_STOP;
 
-       // Strip off @domain
-       if ((x = strchr(data->username, '@')))
-       {
-               p->log(3, 0, 0, "Stripping off trailing domain name \"%s\"\n", x);
-               *x = 0;
-       }
+    // Strip off @domain
+    if ((p = strchr(data->username, '@')))
+    {
+       f->log(3, 0, 0, "Stripping off trailing domain name \"%s\"\n", p);
+       *p = 0;
+    }
 
-       return PLUGIN_RET_OK;
+    return PLUGIN_RET_OK;
 }
 
 int plugin_init(struct pluginfuncs *funcs)
 {
-       return ((p = funcs)) ? 1 : 0;
+    return ((f = funcs)) ? 1 : 0;
 }
index bcdfd70..46ce824 100644 (file)
 
 /* throttle control */
 
-char const *cvs_id = "$Id: throttlectl.c,v 1.8 2005-10-11 07:59:09 bodea Exp $";
+char const *cvs_id = "$Id: throttlectl.c,v 1.9 2005-10-11 09:04:53 bodea Exp $";
 
 int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
 
 char *plugin_control_help[] = {
-       "  throttle USER|SID [RATE|[in|out] RATE ...]  Throttle user traffic",
-       "  unthrottle USER|SID                         Stop throttling user",
-       0
+    "  throttle USER|SID [RATE|[in|out] RATE ...]  Throttle user traffic",
+    "  unthrottle USER|SID                         Stop throttling user",
+    0
 };
 
 int plugin_control(struct param_control *data)
 {
-       sessionidt session;
-       sessiont *s = 0;
-       int flag;
-       char *end;
-       int rate_in = 0;
-       int rate_out = 0;
+    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 (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
+    if (strcmp(data->argv[0], "throttle") &&
+       strcmp(data->argv[0], "unthrottle"))
+       return PLUGIN_RET_OK; // not for us
 
-       if (!data->iam_master)
-               return PLUGIN_RET_NOTMASTER;
+    if (!data->iam_master)
+       return PLUGIN_RET_NOTMASTER;
 
-       flag = data->argv[0][0] == 't';
+    flag = data->argv[0][0] == 't';
 
-       if (flag)
+    if (flag)
+    {
+       if (data->argc < 2 || data->argc > 6)
        {
-               if (data->argc < 2 || data->argc > 6)
-               {
-                       data->response = NSCTL_RES_ERR;
-                       data->additional = "requires username or session id and optional rate(s)";
-                       return PLUGIN_RET_STOP;
-               }
+           data->response = NSCTL_RES_ERR;
+           data->additional = "requires username or session id and optional rate(s)";
+           return PLUGIN_RET_STOP;
        }
-       else
+    }
+    else
+    {
+       if (data->argc != 2)
        {
-               if (data->argc != 2)
-               {
-                       data->response = NSCTL_RES_ERR;
-                       data->additional = "requires username or session id";
-                       return PLUGIN_RET_STOP;
-               }
+           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 = strtol(data->argv[1], &end, 10)) || *end)
+       session = f->get_session_by_username(data->argv[1]);
 
-       if (session)
-               s = p->get_session_by_id(session);
+    if (session)
+       s = f->get_session_by_id(session);
 
-       if (!s || !s->ip)
+    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)
        {
-               data->response = NSCTL_RES_ERR;
-               data->additional = "session not found";
-               return PLUGIN_RET_STOP;
+           unsigned long *rate = f->getconfig("throttle_speed", UNSIGNED_LONG);
+           rate_in = rate_out = *rate;
        }
-
-       if (flag)
+       else if (data->argc == 3)
        {
-               rate_in = rate_out = -1;
-               if (data->argc == 2)
+           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))
                {
-                       unsigned long *rate = p->getconfig("throttle_speed", UNSIGNED_LONG);
-                       rate_in = rate_out = *rate;
+                   rate_in = atoi(data->argv[i+1]);
                }
-               else if (data->argc == 3)
+               else if (!strncmp(data->argv[i], "out", len))
                {
-                       rate_in = rate_out = atoi(data->argv[2]);
+                   rate_out = atoi(data->argv[i+1]);
                }
                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(data->argv[i+1]);
-                               }
-                               else if (!strncmp(data->argv[i], "out", len))
-                               {
-                                       rate_out = atoi(data->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;
+                   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)
+       if (!rate_in || !rate_out)
        {
-               data->response = NSCTL_RES_ERR;
-               data->additional = flag ? "already throttled" : "not throttled";
-               return PLUGIN_RET_STOP;
+           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->session_changed(session);
+    f->throttle(session, rate_in, rate_out);
+    f->session_changed(session);
 
-       data->response = NSCTL_RES_OK;
-       data->additional = 0;
+    data->response = NSCTL_RES_OK;
+    data->additional = 0;
 
-       return PLUGIN_RET_STOP;
+    return PLUGIN_RET_STOP;
 }
 
 int plugin_init(struct pluginfuncs *funcs)
 {
-       return ((p = funcs)) ? 1 : 0;
+    return ((f = funcs)) ? 1 : 0;
 }