add filtering
[l2tpns.git] / radius.c
index d2e2d3b..63aeec1 100644 (file)
--- a/radius.c
+++ b/radius.c
@@ -1,6 +1,6 @@
 // L2TPNS Radius Stuff
 
 // L2TPNS Radius Stuff
 
-char const *cvs_id_radius = "$Id: radius.c,v 1.11 2004-11-05 04:55:27 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>
 
 #include <time.h>
 #include <stdio.h>
@@ -22,10 +22,11 @@ extern radiust *radius;
 extern sessiont *session;
 extern tunnelt *tunnel;
 extern u32 sessionid;
 extern sessiont *session;
 extern tunnelt *tunnel;
 extern u32 sessionid;
-extern struct configt *config;
+extern configt *config;
 extern int *radfds;
 extern int *radfds;
+extern ip_filtert *ip_filters;
 
 
-const char *radius_state(int state)
+static const char *radius_state(int state)
 {
        static char *tmp = NULL;
        int i;
 {
        static char *tmp = NULL;
        int i;
@@ -46,7 +47,7 @@ void initrad(void)
        for (i = 0; i < config->num_radfds; i++)
        {
                int flags;
        for (i = 0; i < config->num_radfds; i++)
        {
                int flags;
-               if (!radfds[i]) radfds[i] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+               radfds[i] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
                flags = fcntl(radfds[i], F_GETFL, 0);
                fcntl(radfds[i], F_SETFL, flags | O_NONBLOCK);
        }
                flags = fcntl(radfds[i], F_GETFL, 0);
                fcntl(radfds[i], F_SETFL, flags | O_NONBLOCK);
        }
@@ -426,9 +427,8 @@ void processrad(u8 *buf, int len, char socket_index)
                        {
                                // CHAP
                                u8 *p = makeppp(b, sizeof(b), 0, 0, t, s, PPPCHAP);
                        {
                                // CHAP
                                u8 *p = makeppp(b, sizeof(b), 0, 0, t, s, PPPCHAP);
-                               if (!p) {
-                                       return; // Abort!
-                               }
+                               if (!p) return; // Abort!
+
                                {
                                        struct param_post_auth packet = { &tunnel[t], &session[s], session[s].user, (*buf == 2), PPPCHAP };
                                        run_plugins(PLUGIN_POST_AUTH, &packet);
                                {
                                        struct param_post_auth packet = { &tunnel[t], &session[s], session[s].user, (*buf == 2), PPPCHAP };
                                        run_plugins(PLUGIN_POST_AUTH, &packet);
@@ -446,8 +446,7 @@ void processrad(u8 *buf, int len, char socket_index)
                        {
                                // PAP
                                u8 *p = makeppp(b, sizeof(b), 0, 0, t, s, PPPPAP);
                        {
                                // PAP
                                u8 *p = makeppp(b, sizeof(b), 0, 0, t, s, PPPPAP);
-                               if (!p)
-                                       return;         // Abort!
+                               if (!p) return;         // Abort!
 
                                {
                                        struct param_post_auth packet = { &tunnel[t], &session[s], session[s].user, (*buf == 2), PPPPAP };
 
                                {
                                        struct param_post_auth packet = { &tunnel[t], &session[s], session[s].user, (*buf == 2), PPPPAP };
@@ -475,7 +474,7 @@ void processrad(u8 *buf, int len, char socket_index)
                                {
                                        if (*p == 8)
                                        {
                                {
                                        if (*p == 8)
                                        {
-                                               // Statically assigned address
+                                               // Framed-IP-Address
                                                LOG(3, 0, s, session[s].tunnel, "   Radius reply contains IP address %s\n", inet_toa(*(u32 *) (p + 2)));
                                                session[s].ip = ntohl(*(u32 *) (p + 2));
                                                session[s].ip_pool_index = -1;
                                                LOG(3, 0, s, session[s].tunnel, "   Radius reply contains IP address %s\n", inet_toa(*(u32 *) (p + 2)));
                                                session[s].ip = ntohl(*(u32 *) (p + 2));
                                                session[s].ip_pool_index = -1;
@@ -494,7 +493,7 @@ void processrad(u8 *buf, int len, char socket_index)
                                        }
                                        else if (*p == 22)
                                        {
                                        }
                                        else if (*p == 22)
                                        {
-                                               // framed-route
+                                               // Framed-Route
                                                ipt ip = 0, mask = 0;
                                                u8 u = 0;
                                                u8 bits = 0;
                                                ipt ip = 0, mask = 0;
                                                u8 u = 0;
                                                u8 bits = 0;
@@ -542,13 +541,51 @@ void processrad(u8 *buf, int len, char socket_index)
                                                        routes++;
                                                }
                                        }
                                                        routes++;
                                                }
                                        }
+                                       else if (*p == 11)
+                                       {
+                                               // Filter-Id
+                                               char *filter = p + 2;
+                                               int l = p[1] - 2;
+                                               char *suffix;
+                                               u8 *f = 0;
+                                               int i;
+
+                                               LOG(3, 0, s, session[s].tunnel, "   Radius reply contains Filter-Id \"%.*s\"\n", l, filter);
+                                               if ((suffix = memchr(filter, '.', l)))
+                                               {
+                                                       int b = suffix - filter;
+                                                       if (l - b == 3 && !memcmp("in", suffix+1, 2))
+                                                               f = &session[s].filter_in;
+                                                       else if (l - b == 4 && !memcmp("out", suffix+1, 3))
+                                                               f = &session[s].filter_out;
+
+                                                       l = b;
+                                               }
+
+                                               if (!f)
+                                               {
+                                                       LOG(3, 0, s, session[s].tunnel, "    Invalid filter\n");
+                                                       continue;
+                                               }
+
+                                               for (*f = 0, i = 0; !*f && i < MAXFILTER; i++)
+                                                       if (strlen(ip_filters[i].name) == l &&
+                                                           !strncmp(ip_filters[i].name, filter, l))
+                                                               *f = i + 1;
+
+                                               if (*f)
+                                                       ip_filters[*f - 1].used++;
+                                               else
+                                                       LOG(3, 0, s, session[s].tunnel, "    Unknown filter\n");
+
+                                       }
                                        else if (*p == 26)
                                        {
                                                // Vendor-Specific Attribute
                                                int vendor = ntohl(*(int *)(p + 2));
                                                char attrib = *(p + 6);
                                                char attrib_length = *(p + 7) - 2;
                                        else if (*p == 26)
                                        {
                                                // Vendor-Specific Attribute
                                                int vendor = ntohl(*(int *)(p + 2));
                                                char attrib = *(p + 6);
                                                char attrib_length = *(p + 7) - 2;
-                                               LOG(3, 0, s, session[s].tunnel, "   Radius reply contains Vendor-Specific. Vendor=%d Attrib=%d Length=%d\n", vendor, attrib, attrib_length);
+                                               LOG(3, 0, s, session[s].tunnel, "   Radius reply contains Vendor-Specific.  Vendor=%d Attrib=%d Length=%d\n", vendor, attrib, attrib_length);
                                                if (attrib_length == 0) continue;
                                                if (attrib != 1)
                                                        LOG(3, 0, s, session[s].tunnel, "      Unknown vendor-specific\n");
                                                if (attrib_length == 0) continue;
                                                if (attrib != 1)
                                                        LOG(3, 0, s, session[s].tunnel, "      Unknown vendor-specific\n");
@@ -658,19 +695,3 @@ void radiusretry(u16 r)
                        break;
        }
 }
                        break;
        }
 }
-
-void radius_clean()
-{
-       int i;
-
-       LOG(1, 0, 0, 0, "Cleaning radius session array\n");
-
-       for (i = 1; i < MAXRADIUS; i++)
-       {
-               if (radius[i].retry == 0
-                               || !session[radius[i].session].opened
-                               || session[radius[i].session].die
-                               || session[radius[i].session].tunnel == 0)
-                       radiusclear(i, radius[i].session);
-       }
-}