IPv6 load-balancing
[l2tpns.git] / radius.c
index 4ee1bfc..134afe2 100644 (file)
--- a/radius.c
+++ b/radius.c
@@ -15,6 +15,7 @@
 
 #include "md5.h"
 #include "constants.h"
+#include "dhcp6.h"
 #include "l2tpns.h"
 #include "plugin.h"
 #include "util.h"
@@ -533,7 +534,8 @@ void processrad(uint8_t *buf, int len, char socket_index)
        sessionidt s;
        tunnelidt t = 0;
        hasht hash;
-       uint8_t routes = 0;
+       int routes = 0;
+       int routes6 = 0;
        int r_code;
        int r_id;
        int OpentunnelReq = 0;
@@ -782,7 +784,7 @@ void processrad(uint8_t *buf, int len, char socket_index)
                                                int prefixlen;
                                                uint8_t *n = p + 2;
                                                uint8_t *e = p + p[1];
-                                               uint8_t *m = memchr(n, '/', e - p);
+                                               uint8_t *m = memchr(n, '/', e - n);
 
                                                *m++ = 0;
                                                inet_pton(AF_INET6, (char *) n, &r6);
@@ -794,11 +796,48 @@ void processrad(uint8_t *buf, int len, char socket_index)
 
                                                if (prefixlen)
                                                {
-                                                       LOG(3, s, session[s].tunnel,
-                                                               "   Radius reply contains route for %s/%d\n",
-                                                               n, prefixlen);
-                                                       session[s].ipv6route = r6;
-                                                       session[s].ipv6prefixlen = prefixlen;
+                                                       if (routes6 == MAXROUTE6)
+                                                       {
+                                                               LOG(1, s, session[s].tunnel, "   Too many IPv6 routes\n");
+                                                       }
+                                                       else
+                                                       {
+                                                               LOG(3, s, session[s].tunnel, "   Radius reply contains route for %s/%d\n", n, prefixlen);
+                                                               session[s].route6[routes6].ipv6route = r6;
+                                                               session[s].route6[routes6].ipv6prefixlen = prefixlen;
+                                                               routes6++;
+                                                       }
+                                               }
+                                       }
+                                       else if (*p == 123)
+                                       {
+                                               // Delegated-IPv6-Prefix
+                                               if ((p[1] > 4) && (p[3] > 0) && (p[3] <= 128))
+                                               {
+                                                       char ipv6addr[INET6_ADDRSTRLEN];
+
+                                                       if (routes6 == MAXROUTE6)
+                                                       {
+                                                               LOG(1, s, session[s].tunnel, "   Too many IPv6 routes\n");
+                                                       }
+                                                       else
+                                                       {
+                                                               memcpy(&session[s].route6[routes6].ipv6route, &p[4], p[1] - 4);
+                                                               session[s].route6[routes6].ipv6prefixlen = p[3];
+                                                               LOG(3, s, session[s].tunnel, "   Radius reply contains Delegated IPv6 Prefix %s/%d\n",
+                                                                       inet_ntop(AF_INET6, &session[s].route6[routes6].ipv6route, ipv6addr, INET6_ADDRSTRLEN), session[s].route6[routes6].ipv6prefixlen);
+                                                               routes6++;
+                                                       }
+                                               }
+                                       }
+                                       else if (*p == 168)
+                                       {
+                                               // Framed-IPv6-Address
+                                               if (p[1] == 18)
+                                               {
+                                                       char ipv6addr[INET6_ADDRSTRLEN];
+                                                       memcpy(&session[s].ipv6address, &p[2], 16);
+                                                       LOG(3, s, session[s].tunnel, "   Radius reply contains Framed-IPv6-Address %s\n", inet_ntop(AF_INET6, &session[s].ipv6address, ipv6addr, INET6_ADDRSTRLEN));
                                                }
                                        }
                                        else if (*p == 25)