Source: openvpn-auth-radius
Version: 2.1-6
Severity: normal
Tags: patch ipv6

Hello,

Here are patches to add IPv6 support to openvpn-auth-radius:

- support for Framed-IPv6-Route
- support optional gateway parameter
- support for announcing routes to bird
- support for Framed-IPv6-Address

I had already reported them upstream ([email protected]) on
2013 Apr 1st, but upstream is not really responsive, so if the patches
would at least be applied in Debian, that would allow ISPs interested in
it to avoid having to apply them by hand.

Samuel

-- System Information:
Debian Release: jessie/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable'), (500, 'stable'), (1, 
'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.14.0 (SMP w/8 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

-- 
Samuel
"And the next time you consider complaining that running Lucid Emacs
19.05 via NFS from a remote Linux machine in Paraguay doesn't seem to
get the background colors right, you'll know who to thank."
(By Matt Welsh)
This adds support for Framed-IPv6-Route, which is recorded in
user->framedroutes6, which is used to add IPv6 framed routes just like IPv4 are.

--- a/AccountingProcess.cpp
+++ b/AccountingProcess.cpp
@@ -107,6 +107,7 @@ void AccountingProcess::Accounting(Plugi
                     user->setCommonname(context->acctsocketforegr.recvStr());
                     
user->setAcctInterimInterval(context->acctsocketforegr.recvInt());
                     user->setFramedRoutes(context->acctsocketforegr.recvStr());
+                    
user->setFramedRoutes6(context->acctsocketforegr.recvStr());
                     user->setKey(context->acctsocketforegr.recvStr());
                     
user->setStatusFileKey(context->acctsocketforegr.recvStr());
                     
user->setUntrustedPort(context->acctsocketforegr.recvStr());
--- a/AuthenticationProcess.cpp
+++ b/AuthenticationProcess.cpp
@@ -105,6 +105,9 @@ void AuthenticationProcess::Authenticati
                                //send the framed ip to the parent process
                                
context->authsocketforegr.send(user->getFramedIp());
                                                                                
+                               //send the IPv6 routes to the parent process
+                               
context->authsocketforegr.send(user->getFramedRoutes6());
+                                       
                                        //send the interval to the parent 
process
                                
context->authsocketforegr.send(user->getAcctInterimInterval());
                                
--- a/User.cpp
+++ b/User.cpp
@@ -26,6 +26,7 @@ User::User()
 {
        this->framedip="";
        this->framedroutes="";
+       this->framedroutes6="";
        this->key="";
         this->statusfilekey="";
        this->untrustedport="";
@@ -43,6 +44,7 @@ User::User()
 {
        this->framedip="";
        this->framedroutes="";
+       this->framedroutes6="";
        this->key="";
        this->untrustedport="";
        this->acctinteriminterval=0;
@@ -70,6 +72,7 @@ User & User::operator=(const User & u)
        this->commonname=u.commonname;
        this->framedroutes=u.framedroutes;
        this->framedip=u.framedip;
+       this->framedroutes6=u.framedroutes6;
        this->key=u.key;
         this->statusfilekey=u.statusfilekey;
        this->callingstationid=u.callingstationid;
@@ -110,6 +113,7 @@ User::User(const User & u)
        this->commonname=u.commonname;
        this->framedroutes=u.framedroutes;
        this->framedip=u.framedip;
+       this->framedroutes6=u.framedroutes6;
        this->key=u.key;
         this->statusfilekey=u.statusfilekey;
        this->callingstationid=u.callingstationid;
@@ -171,7 +175,7 @@ string User::getFramedRoutes(void)
 }
 /** The setter method for the framedroutes.
  * @param froutes The framedroutes, if there are more 
- * routes they are diveded through a ';'.*/
+ * routes they are divided through a ';'.*/
 void User::setFramedRoutes(string froutes)
 {
        this->framedroutes=froutes;
@@ -190,6 +194,20 @@ void User::setFramedIp(string ip)
        this->framedip=ip;
 }
 
+/** The getter method for the framed IPv6 routes.
+ *  @return The framed IPv6 routes as a string.*/
+string User::getFramedRoutes6(void)
+{
+       return this->framedroutes6;
+}
+/** The setter method for the framed IPv6 routes.
+ * @param froutes6 The framed IPv6 routes, if there are more 
+ * routes they are divided through a ';'.*/
+void User::setFramedRoutes6(string froutes6)
+{
+       this->framedroutes6=froutes6;
+}
+
 /** The getter method for the fkey.
  *  @return The unique key as a string.*/
 string User::getKey(void)
--- a/User.h
+++ b/User.h
@@ -47,6 +47,7 @@ protected:
        string commonname;              /**<The commonname.*/
        string framedroutes;            /**<The framedroutes, they are stored 
as a string. If there are more routes, they must be delimited by an ';'*/
        string framedip;                /**<The framed ip.*/
+       string framedroutes6;           /**<The framed IPv6 routes, they are 
stored as a string. If there are more routes, they must be delimited by an ';'*/
        string callingstationid;        /**<The calling station id, in this 
case the real ip address of the client.*/
        string key;                     /**<A unique key to find the user in a 
map. */
        string statusfilekey;           /**<Unique identifier in the status log 
file (version 1) "commonname,untrusted_ip:untrusted_port"*/
@@ -80,6 +81,9 @@ public:
        string getFramedIp(void);
        void setFramedIp(string);
        
+       string getFramedRoutes6(void);
+       void setFramedRoutes6(string);
+       
        string getKey(void);
        void setKey(string);
 
--- a/UserAcct.cpp
+++ b/UserAcct.cpp
@@ -599,13 +599,13 @@ int UserAcct::sendStopPacket(PluginConte
 void UserAcct::delSystemRoutes(PluginContext * context)
 {
        char * route;
-       char framedip[16];
+       char framedip[40];
        
-       char routestring[100];
-       char framednetmask_cidr[3]; 
-       char framedgw[16];
+       char routestring[200];
+       char framednetmask_cidr[4]; 
+       char framedgw[40];
        char framedmetric[5];  
-       char * framedroutes;
+       char * framedroutes, * framedroutes6;
        int j=0,k=0,len=0;
        
        //copy the framed route string to an char array, it is easier to
@@ -750,6 +750,141 @@ void UserAcct::delSystemRoutes(PluginCon
        delete [] framedroutes;
                
 
+       //copy the framed route string to an char array, it is easier to
+       //analyse
+       framedroutes6=new char[this->getFramedRoutes6().size()+1];
+       memset(framedroutes6,0,this->getFramedRoutes6().size()+1);
+       
+       // copy in a temp-string, because strtok deletes the delimiter, if it 
used anywhere
+       
strncpy(framedroutes6,this->getFramedRoutes6().c_str(),this->getFramedRoutes6().size());
+       
+       //are there framed routes
+       if (framedroutes6[0]!='\0')
+       {
+               //get the first route
+               route=strtok(framedroutes6,";");
+               len=strlen(route);
+               if (len > 150) //this is too big!! but the length is variable
+               {
+                       cerr << getTime() <<"RADIUS-PLUGIN: BACKGROUND-ACCT:  
Argument for Framed Route is too long (>150 Characters).\n";
+               }
+               else
+               {
+                       while (route!=NULL)
+                       {               
+                               //set the arrays to 0
+                               memset(routestring,0,200);
+                               memset(framednetmask_cidr,0,4);
+                               memset(framedip,0,40);
+                               memset(framedgw,0,40);
+                               memset(framedmetric,0,5);
+                                                       
+                               j=0;k=0;
+                               //get ip address and add it to framedip
+                               while(route[j]!='/' && j<len)
+                               {
+                                       if (route[j]!=' ')
+                                       {
+                                               framedip[k]=route[j];
+                                               k++;
+                                       }
+                                       j++;
+                               }
+                               k=0;
+                               j++;
+                               //get the framednetmask and add it to 
framednetmack_cidr
+                               while(route[j]!=' ' && j<=len)
+                               {
+                                       framednetmask_cidr[k]=route[j];
+                                       k++;
+                                       j++;
+                               }
+                               k=0;
+                               //jump spaces
+                               while(route[j]==' ' && j<=len)
+                               {
+                                       j++;
+                               }
+                               //get the gateway
+                               while(route[j]!='/' && j<=len)
+                               {
+                                       if (route[j]!=' ')
+                                       {
+                                               framedgw[k]=route[j];
+                                               k++;
+                                       }
+                                       j++;
+                               }
+                               j++;
+                               //find gateway netmask (this isn't used
+                               //at the command route under linux)
+                               while(route[j]!=' ' && j<=len)
+                               {
+                                       j++;
+                               }
+                               //jump spaces
+                               while(route[j]==' ' && j<=len)
+                               {
+                                       j++;
+                               }
+                               k=0;
+                               if (j<=len) //is there a metric (optional)
+                               {
+                                       k=0;
+                                       //find the metric
+                                       while(route[j]!=' ' && j<=len)
+                                       {
+                                                       
framedmetric[k]=route[j];
+                                                       k++;
+                                                       j++;
+                                       }
+                               }
+                                                                               
                                        
+                               //create system call
+                               strncat(routestring, "route -6 del ",13);
+                               strncat(routestring, framedip ,40);
+                               strncat(routestring, "/" ,1);
+                               strncat(routestring, framednetmask_cidr, 3);
+                               strncat(routestring, " gw ", 4);
+                               strncat(routestring, framedgw, 40);
+                               if (framedmetric[0]!='\0')
+                               {
+                                       strncat(routestring, " metric ", 8);
+                                       strncat(routestring, framedmetric , 5);
+                               }
+                               //redirect the output stderr to /dev/null
+                               strncat(routestring," 2> /dev/null",13);
+                               
+                                               
+                               if (DEBUG (context->getVerbosity()))
+                               cerr << getTime() << "RADIUS-PLUGIN: 
BACKGROUND-ACCT:  Create IPv6 route string "<< routestring <<".\n";
+                               
+                               //system call
+                               if(system(routestring)!=0) 
+                               //if(1)//-> the debugg can't context system()
+                               {
+                                       cerr << getTime() << "RADIUS-PLUGIN: 
BACKGROUND-ACCT:  Route " << routestring << " could not set. Route already set 
or bad route string.\n";
+                               }
+                               else
+                               {
+                                       if (DEBUG (context->getVerbosity()))
+                                       cerr << getTime() << "RADIUS-PLUGIN: 
BACKGROUND-ACCT:  Add route to system routing table.\n";
+                                       
+                               }
+                               //get the next route
+                               route=strtok(NULL,";"); 
+                       }
+               }
+               
+       }
+       else
+       {
+               if (DEBUG (context->getVerbosity()))
+               cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT:  No IPv6 
routes for user in AccessAcceptPacket.\n";
+       }
+       //free the char array
+       delete [] framedroutes6;
+               
 }
 
 /** The method adds ths routes of the user to the system routing table.
@@ -758,13 +893,13 @@ void UserAcct::delSystemRoutes(PluginCon
 void UserAcct::addSystemRoutes(PluginContext * context)
 {
        char * route;
-       char framedip[16];
+       char framedip[40];
        
-       char routestring[100];
-       char framednetmask_cidr[3]; 
-       char framedgw[16];
+       char routestring[200];
+       char framednetmask_cidr[4]; 
+       char framedgw[40];
        char framedmetric[5];  
-       char * framedroutes;
+       char * framedroutes, * framedroutes6;
        int j=0,k=0,len=0;
        
        //copy the framed route string to an char array, it is easier to
@@ -905,9 +1040,144 @@ void UserAcct::addSystemRoutes(PluginCon
                if (DEBUG (context->getVerbosity()))
                cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT:  No 
routes for user.\n";
        }
-       //fre the chat array
+       //free the char array
        delete [] framedroutes;
        
+       //copy the framed route string to an char array, it is easier to
+       //analyse
+       framedroutes6=new char[this->getFramedRoutes6().size()+1];
+       memset(framedroutes6,0,this->getFramedRoutes6().size()+1);
+       
+       // copy in a temp-string, becaue strtok deletes the delimiter, if it 
used anywhere
+       
strncpy(framedroutes6,this->getFramedRoutes6().c_str(),this->getFramedRoutes6().size());
+       
+       //are there framed routes
+       if (framedroutes6[0]!='\0')
+       {
+               //get the first route
+               route=strtok(framedroutes6,";");
+               len=strlen(route);
+               if (len > 150) //this is to big!! but the length is variable
+               {
+                       cerr << getTime() <<"RADIUS-PLUGIN: BACKGROUND-ACCT:  
Argument for Framed Route is to long (>150 Characters).\n";
+               }
+               else
+               {
+                       while (route!=NULL)
+                       {               
+                               //set the arrays to 0
+                               memset(routestring,0,200);
+                               memset(framednetmask_cidr,0,4);
+                               memset(framedip,0,40);
+                               memset(framedgw,0,40);
+                               memset(framedmetric,0,5);
+                                                       
+                               j=0;k=0;
+                               //get ip address and add it to framedip
+                               while(route[j]!='/' && j<len)
+                               {
+                                       if (route[j]!=' ')
+                                       {
+                                               framedip[k]=route[j];
+                                               k++;
+                                       }
+                                       j++;
+                               }
+                               k=0;
+                               j++;
+                               //get the framednetmask and add it to 
framednetmask_cidr
+                               while(route[j]!=' ' && j<=len)
+                               {
+                                       framednetmask_cidr[k]=route[j];
+                                       k++;
+                                       j++;
+                               }
+                               k=0;
+                               //jump spaces
+                               while(route[j]==' ' && j<=len)
+                               {
+                                       j++;
+                               }
+                               //get the gateway
+                               while(route[j]!='/' && j<=len)
+                               {
+                                       if (route[j]!=' ')
+                                       {
+                                               framedgw[k]=route[j];
+                                               k++;
+                                       }
+                                       j++;
+                               }
+                               j++;
+                               //find gateway netmask (this isn't used
+                               //at the command route under linux)
+                               while(route[j]!=' ' && j<=len)
+                               {
+                                       j++;
+                               }
+                               //jump spaces
+                               while(route[j]==' ' && j<=len)
+                               {
+                                       j++;
+                               }
+                               k=0;
+                               if (j<=len) //is there a metric (optional)
+                               {
+                                       k=0;
+                                       //find the metric
+                                       while(route[j]!=' ' && j<=len)
+                                       {
+                                                       
framedmetric[k]=route[j];
+                                                       k++;
+                                                       j++;
+                                       }
+                               }
+                                                                               
                                        
+                                                                               
                                
+                               //create system call
+                               strncat(routestring, "route -6 add ",13);
+                               strncat(routestring, framedip ,40);
+                               strncat(routestring, "/" ,1);
+                               strncat(routestring, framednetmask_cidr, 3);
+                               strncat(routestring, " gw ", 4);
+                               strncat(routestring, framedgw, 40);
+                               if (framedmetric[0]!='\0')
+                               {
+                                       strncat(routestring, " metric ", 8);
+                                       strncat(routestring, framedmetric , 5);
+                               }
+                               //redirect the output stderr to /dev/null
+                               strncat(routestring," 2> /dev/null",13);
+                               
+                                               
+                               if (DEBUG (context->getVerbosity()))
+                               cerr << getTime() << "RADIUS-PLUGIN: 
BACKGROUND-ACCT:  Create IPv6 route string "<< routestring << " dev " << 
this->getDev() << ".\n";
+                               
+                               //system call route
+                               if(system(routestring)!=0) 
+                               //if(1)//-> the debugg can't context system()
+                               {
+                                       cerr << getTime() << "RADIUS-PLUGIN: 
BACKGROUND-ACCT:  Route " << routestring << " could not set. Route already set 
or bad route string.\n";
+                               }
+                               else
+                               {
+                                       if (DEBUG (context->getVerbosity()))
+                                       cerr << getTime() << "RADIUS-PLUGIN: 
BACKGROUND-ACCT:  Add route to system routing table.\n";
+                                                                               
                
+                               }
+                               //get the next route
+                               route=strtok(NULL,";"); 
+                       }
+               }
+       }
+       else
+       {
+               if (DEBUG (context->getVerbosity()))
+               cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT:  No IPv6 
routes for user.\n";
+       }
+       //free the char array
+       delete [] framedroutes6;
+       
 }
 
 
@@ -995,7 +1265,7 @@ int UserAcct::deleteCcdFile(PluginContex
 {
        string filename;
        filename = context->conf.getCcdPath()+ this->getCommonname();
-       if(context->conf.getOverWriteCCFiles()==true && 
(this->getFramedIp().length() > 0 || this->getFramedRoutes().length() > 0))
+       if(context->conf.getOverWriteCCFiles()==true && 
(this->getFramedIp().length() > 0 || this->getFramedRoutes().length() > 0 || 
this->getFramedRoutes6().length() > 0))
        {
                remove(filename.c_str());
        }
--- a/UserAuth.cpp
+++ b/UserAuth.cpp
@@ -251,6 +251,25 @@ void UserAuth::parseResponsePacket(Radiu
        
        
        
+       range=packet->findAttributes(99);
+       iter1=range.first;
+       iter2=range.second;     
+       string froutes6;
+       
+       while (iter1!=iter2)
+       {
+               
+               froutes6.append((char *) iter1->second.getValue(), 
iter1->second.getLength()-2);
+               froutes6.append(";");
+               iter1++;
+       }
+       this->setFramedRoutes6(froutes6);
+       
+       if (DEBUG (context->getVerbosity()))
+       cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: framed ipv6 
route: " << this->getFramedRoutes6() <<".\n";
+       
+       
+       
        range=packet->findAttributes(85);
        iter1=range.first;
        iter2=range.second;             
@@ -1485,16 +1504,17 @@ int UserAuth::createCcdFile(PluginContex
        ofstream ccdfile;
        
        char * route;
-       char framedip[16];
+       char framedip[40];
        char ipstring[100];
        in_addr_t ip2;
        in_addr ip3;
        string filename;
        char framedroutes[4096];
-       char framednetmask_cidr[3]; // ->/24
+       char framedroutes6[4096];
+       char framednetmask_cidr[4]; // ->/128
        char framednetmask[16]; // ->255.255.255.0
        char mask_part[6];
-       char framedgw[16];
+       char framedgw[40];
        char framedmetric[5]; //what is the biggest metric? 
        
        double d1,d2;
@@ -1503,11 +1523,12 @@ int UserAuth::createCcdFile(PluginContex
        int len=0;
        
        
-       if(context->conf.getOverWriteCCFiles()==true && 
(this->getFramedIp().length() > 0 || this->getFramedRoutes().length() > 0))
+       if(context->conf.getOverWriteCCFiles()==true && 
(this->getFramedIp().length() > 0 || this->getFramedRoutes().length() > 0 || 
this->getFramedRoutes6().length() > 0))
        {
                memset(ipstring,0,100);
                memset(framedip,0,16);
                memset(framedroutes,0,4096);
+               memset(framedroutes6,0,4096);
                        
                //create the filename, ccd-path + commonname
                filename=context->conf.getCcdPath()+this->getCommonname();
@@ -1526,6 +1547,9 @@ int UserAuth::createCcdFile(PluginContex
                // copy in a temp-string, becaue strtok deletes the delimiter, 
if it is used anywhere
                strncpy(framedroutes,this->getFramedRoutes().c_str(),4095);
                
+               // copy in a temp-string, becaue strtok deletes the delimiter, 
if it is used anywhere
+               strncpy(framedroutes6,this->getFramedRoutes6().c_str(),4095);
+               
                
                if (ccdfile.is_open())
                {
@@ -1756,6 +1780,106 @@ int UserAuth::createCcdFile(PluginContex
                                                
                                                        route=strtok(NULL,";");
                                        }
+                               }
+                       }
+                       
+                       //set the IPv6 framed routes in the file for the 
openvpn process
+                       if (framedroutes6[0]!='\0')
+                       {
+                               if (DEBUG (context->getVerbosity()))
+                                       cerr << getTime() << "RADIUS-PLUGIN: 
BACKGROUND AUTH: Write framed routes to ccd-file.\n";
+                       
+                               route=strtok(framedroutes6,";");
+                               len=strlen(route);
+                               if (len > 150) //this is too big! but the 
length is variable
+                               {
+                                       cerr << getTime() <<"RADIUS-PLUGIN: 
Argument for Framed Route is to long (>50 Characters).\n";
+                                       return 1;
+                               }
+                               else
+                               {
+                                       while (route!=NULL)
+                                       {
+                                               j=0;k=0;
+                                               //set everything back for the 
next route entry
+                                               memset(mask_part,0,6);
+                                               memset(framednetmask_cidr,0,4);
+                                               memset(framedip,0,40);
+                                               memset(framednetmask,0,40);
+                                               memset(framedgw,0,40);
+                                               memset(framedmetric,0,5);
+                                               
+                                               //add ip address to string
+                                               while(route[j]!='/' && j<len)
+                                                       {
+                                                               if (route[j]!=' 
')
+                                                               {
+                                                                       
framedip[k]=route[j];
+                                                                       k++;
+                                                               }
+                                                               j++;
+                                                       }
+                                                       k=0;
+                                                       j++;
+                                                       //add netmask
+                                                       while(route[j]!=' ' && 
j<=len)
+                                                       {
+                                                               
framednetmask_cidr[k]=route[j];
+                                                               k++;
+                                                               j++;
+                                                       }
+                                                       k=0;
+                                                       //jump spaces
+                                                       while(route[j]==' ' && 
j<len)
+                                                       {
+                                                               j++;
+                                                       }
+                                                       //find gateway
+                                                       while(route[j]!='/' && 
j<len)
+                                                       {
+                                                               if (route[j]!=' 
')
+                                                               {
+                                                                       
framedgw[k]=route[j];
+                                                                       k++;
+                                                               }
+                                                               j++;
+                                                       }
+                                                       j++;
+                                                       
+                                                       //find gateway netmask 
(this isn't used
+                                                       //at the command route 
under linux)
+                                                       while(route[j]!=' ' && 
j<len)
+                                                       {
+                                                               j++;
+                                                       }
+                                                       //jump spaces
+                                                       
+                                                       while(route[j]==' ' && 
j<len )
+                                                       {
+                                                               j++;
+                                                       }
+                                                       k=0;
+                                                       if (j<=len)
+                                                       {
+                                                       
+                                                               k=0;
+                                                               //find the 
metric
+                                                               
while(route[j]!=' ' && j<len)
+                                                               {
+                                                                       
framedmetric[k]=route[j];
+                                                                       k++;
+                                                                       j++;
+                                                               }
+                                                       }
+                                                                               
                                                                                
                                
+                                                       if (DEBUG 
(context->getVerbosity()))
+                                                               cerr << 
getTime() << "RADIUS-PLUGIN: Write route string: iroute-ipv6 " << framedip << 
"/" << framednetmask_cidr << " " << framedgw << " " << framedmetric << " to 
ccd-file.\n";
+                       
+                                                       //write iroute to 
client file
+                                                       ccdfile << "iroute-ipv6 
" << framedip << "/"<< framednetmask_cidr << "\n";
+                                               
+                                                       route=strtok(NULL,";");
+                                       }
                                }
                        }
                
--- a/radiusplugin.cpp
+++ b/radiusplugin.cpp
@@ -494,6 +494,7 @@ error:
                     context->acctsocketbackgr.send ( newuser->getCommonname() 
);
                     context->acctsocketbackgr.send ( 
newuser->getAcctInterimInterval() );
                     context->acctsocketbackgr.send ( 
newuser->getFramedRoutes() );
+                    context->acctsocketbackgr.send ( 
newuser->getFramedRoutes6() );
                     context->acctsocketbackgr.send ( newuser->getKey() );
                     context->acctsocketbackgr.send ( 
newuser->getStatusFileKey());
                     context->acctsocketbackgr.send ( 
newuser->getUntrustedPort() );
@@ -988,6 +989,10 @@ void  * auth_user_pass_verify(void * c)
                 newuser->setFramedIp ( context->authsocketbackgr.recvStr() );
                 if ( DEBUG ( context->getVerbosity() ) )
                     cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: 
Received framed ip for user: "<< newuser->getFramedIp() << "." << endl;
+                //get the routes from background process
+                newuser->setFramedRoutes6 ( 
context->authsocketbackgr.recvStr() );
+                if ( DEBUG ( context->getVerbosity() ) )
+                    cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: 
Received IPv6 routes for user: "<< newuser->getFramedRoutes6() << ".\n";
 
 
                 // get the interval from the background process
This records the the network device in user->dev, which is used to permit the
gateway to be omited, and just route to the device without a specific gateway
(since it's point to point from the point of view of the kernel, and openvpn
knows which actual connection it will have to go to)

--- a/AccountingProcess.cpp
+++ b/AccountingProcess.cpp
@@ -101,6 +101,7 @@ void AccountingProcess::Accounting(Plugi
                     //get the information from the foreground process
                     user->setUsername(context->acctsocketforegr.recvStr());
                     user->setSessionId(context->acctsocketforegr.recvStr()) ;
+                    user->setDev(context->acctsocketforegr.recvStr()) ;
                     user->setPortnumber(context->acctsocketforegr.recvInt());
                     
user->setCallingStationId(context->acctsocketforegr.recvStr());
                     user->setFramedIp(context->acctsocketforegr.recvStr());
--- a/AuthenticationProcess.cpp
+++ b/AuthenticationProcess.cpp
@@ -72,6 +72,7 @@ void AuthenticationProcess::Authenticati
                            //get the user informations
                            
user->setUsername(context->authsocketforegr.recvStr());
                            
user->setPassword(context->authsocketforegr.recvStr());
+                           user->setDev(context->authsocketforegr.recvStr());
                            
user->setPortnumber(context->authsocketforegr.recvInt());
                            
user->setSessionId(context->authsocketforegr.recvStr());
                            
user->setCallingStationId(context->authsocketforegr.recvStr());
--- a/User.cpp
+++ b/User.cpp
@@ -24,6 +24,7 @@
 /** The constructor sets the acctinteriminterval and the portnumber to 0.*/
 User::User()
 {
+       this->dev="";
        this->framedip="";
        this->framedroutes="";
        this->framedroutes6="";
@@ -42,6 +43,7 @@ User::User()
  * @param num  The portnumber.*/
 /*User::User(int num)
 {
+       this->dev="";
        this->framedip="";
        this->framedroutes="";
        this->framedroutes6="";
@@ -70,6 +72,7 @@ User & User::operator=(const User & u)
 {
        this->username=u.username;
        this->commonname=u.commonname;
+       this->dev=u.dev;
        this->framedroutes=u.framedroutes;
        this->framedip=u.framedip;
        this->framedroutes6=u.framedroutes6;
@@ -111,6 +114,7 @@ User::User(const User & u)
 {
        this->username=u.username;
        this->commonname=u.commonname;
+       this->dev=u.dev;
        this->framedroutes=u.framedroutes;
        this->framedip=u.framedip;
        this->framedroutes6=u.framedroutes6;
@@ -167,6 +171,19 @@ void User::setCommonname(string cn)
        this->commonname=cn;
 }
 
+/** The getter method for the device.
+ *  @return The device as a string.*/
+string User::getDev(void)
+{
+       return this->dev;
+}
+/** The setter method for the device.
+ * @param dev The device.*/
+void User::setDev(string dev)
+{
+       this->dev=dev;
+}
+
 /** The getter method for the framed routes.
  *  @return The framed routes as a string.*/   
 string User::getFramedRoutes(void)
--- a/User.h
+++ b/User.h
@@ -45,6 +45,7 @@ class User
 protected:
        string username;                /**<The username.*/
        string commonname;              /**<The commonname.*/
+       string dev;                     /**<The device.*/
        string framedroutes;            /**<The framedroutes, they are stored 
as a string. If there are more routes, they must be delimited by an ';'*/
        string framedip;                /**<The framed ip.*/
        string framedroutes6;           /**<The framed IPv6 routes, they are 
stored as a string. If there are more routes, they must be delimited by an ';'*/
@@ -74,6 +75,8 @@ public:
        string getCommonname(void);
        void setCommonname(string);
                
+       string getDev(void);
+       void setDev(string);
        
        string getFramedRoutes(void);
        void setFramedRoutes(string);
--- a/UserAcct.cpp
+++ b/UserAcct.cpp
@@ -709,13 +709,18 @@ void UserAcct::delSystemRoutes(PluginCon
                                strncat(routestring, framedip ,16);
                                strncat(routestring, "/" ,1);
                                strncat(routestring, framednetmask_cidr, 2);
-                               strncat(routestring, " gw ", 4);
-                               strncat(routestring, framedgw, 16);
+                               if (framedgw[0]!='\0')
+                               {
+                                       strncat(routestring, " gw ", 4);
+                                       strncat(routestring, framedgw, 16);
+                               }
                                if (framedmetric[0]!='\0')
                                {
                                        strncat(routestring, " metric ", 8);
                                        strncat(routestring, framedmetric , 5);
                                }
+                               strncat(routestring," dev ",5);
+                               strcat(routestring,this->getDev().c_str());
                                //redirect the output stderr to /dev/null
                                strncat(routestring," 2> /dev/null",13);
                                
@@ -845,13 +850,18 @@ void UserAcct::delSystemRoutes(PluginCon
                                strncat(routestring, framedip ,40);
                                strncat(routestring, "/" ,1);
                                strncat(routestring, framednetmask_cidr, 3);
-                               strncat(routestring, " gw ", 4);
-                               strncat(routestring, framedgw, 40);
+                               if (framedgw[0]!='\0')
+                               {
+                                       strncat(routestring, " gw ", 4);
+                                       strncat(routestring, framedgw, 40);
+                               }
                                if (framedmetric[0]!='\0')
                                {
                                        strncat(routestring, " metric ", 8);
                                        strncat(routestring, framedmetric , 5);
                                }
+                               strncat(routestring," dev ",5);
+                               strcat(routestring,this->getDev().c_str());
                                //redirect the output stderr to /dev/null
                                strncat(routestring," 2> /dev/null",13);
                                
@@ -1004,13 +1014,18 @@ void UserAcct::addSystemRoutes(PluginCon
                                strncat(routestring, framedip ,16);
                                strncat(routestring, "/" ,1);
                                strncat(routestring, framednetmask_cidr, 2);
-                               strncat(routestring, " gw ", 4);
-                               strncat(routestring, framedgw, 16);
+                               if (framedgw[0]!='\0')
+                               {
+                                       strncat(routestring, " gw ", 4);
+                                       strncat(routestring, framedgw, 16);
+                               }
                                if (framedmetric[0]!='\0')
                                {
                                        strncat(routestring, " metric ", 8);
                                        strncat(routestring, framedmetric , 5);
                                }
+                               strncat(routestring," dev ",5);
+                               strcat(routestring,this->getDev().c_str());
                                //redirect the output stderr to /dev/null
                                strncat(routestring," 2> /dev/null",13);
                                
@@ -1139,13 +1154,18 @@ void UserAcct::addSystemRoutes(PluginCon
                                strncat(routestring, framedip ,40);
                                strncat(routestring, "/" ,1);
                                strncat(routestring, framednetmask_cidr, 3);
-                               strncat(routestring, " gw ", 4);
-                               strncat(routestring, framedgw, 40);
+                               if (framedgw[0]!='\0')
+                               {
+                                       strncat(routestring, " gw ", 4);
+                                       strncat(routestring, framedgw, 40);
+                               }
                                if (framedmetric[0]!='\0')
                                {
                                        strncat(routestring, " metric ", 8);
                                        strncat(routestring, framedmetric , 5);
                                }
+                               strncat(routestring," dev ",5);
+                               strcat(routestring,this->getDev().c_str());
                                //redirect the output stderr to /dev/null
                                strncat(routestring," 2> /dev/null",13);
                                
--- a/radiusplugin.cpp
+++ b/radiusplugin.cpp
@@ -488,6 +488,7 @@ error:
                     context->acctsocketbackgr.send ( ADD_USER );
                     context->acctsocketbackgr.send ( newuser->getUsername() );
                     context->acctsocketbackgr.send ( newuser->getSessionId() );
+                    context->acctsocketbackgr.send ( newuser->getDev() );
                     context->acctsocketbackgr.send ( newuser->getPortnumber() 
);
                     context->acctsocketbackgr.send ( 
newuser->getCallingStationId() );
                     context->acctsocketbackgr.send ( newuser->getFramedIp() );
@@ -968,6 +969,7 @@ void  * auth_user_pass_verify(void * c)
             context->authsocketbackgr.send ( COMMAND_VERIFY );
             context->authsocketbackgr.send ( newuser->getUsername() );
             context->authsocketbackgr.send ( newuser->getPassword() );
+            context->authsocketbackgr.send ( newuser->getDev() );
             context->authsocketbackgr.send ( newuser->getPortnumber() );
             context->authsocketbackgr.send ( newuser->getSessionId() );
             context->authsocketbackgr.send ( newuser->getCallingStationId() );
@@ -1214,6 +1216,8 @@ void get_user_env(PluginContext * contex
         user->setCommonname ( get_env ( "username", envp ) );
     }
 
+    user->setDev ( get_env ( "dev", envp ) );
+
     string untrusted_ip;
     // it's ipv4
     if ( get_env ( "untrusted_ip", envp ) !=NULL )
This migrates to the use of the "ip" command instead of "route", in order to
be able to append "proto static", since this is really a static route entry
that routing daemons should follow; it's neither an ICMP redirection, nor an
autoconfed kernel route, nor a bootup route, nor an RA route.

--- a/UserAcct.cpp
+++ b/UserAcct.cpp
@@ -705,13 +705,13 @@ void UserAcct::delSystemRoutes(PluginCon
                                }
                                                                                
                                        
                                //create system call
-                               strncat(routestring, "route del -net ",15);
+                               strncat(routestring, "ip route del ",13);
                                strncat(routestring, framedip ,16);
                                strncat(routestring, "/" ,1);
                                strncat(routestring, framednetmask_cidr, 2);
                                if (framedgw[0]!='\0')
                                {
-                                       strncat(routestring, " gw ", 4);
+                                       strncat(routestring, " via ", 5);
                                        strncat(routestring, framedgw, 16);
                                }
                                if (framedmetric[0]!='\0')
@@ -721,6 +721,7 @@ void UserAcct::delSystemRoutes(PluginCon
                                }
                                strncat(routestring," dev ",5);
                                strcat(routestring,this->getDev().c_str());
+                               strncat(routestring," proto static",13);
                                //redirect the output stderr to /dev/null
                                strncat(routestring," 2> /dev/null",13);
                                
@@ -846,13 +847,13 @@ void UserAcct::delSystemRoutes(PluginCon
                                }
                                                                                
                                        
                                //create system call
-                               strncat(routestring, "route -6 del ",13);
+                               strncat(routestring, "ip -6 route del ",16);
                                strncat(routestring, framedip ,40);
                                strncat(routestring, "/" ,1);
                                strncat(routestring, framednetmask_cidr, 3);
                                if (framedgw[0]!='\0')
                                {
-                                       strncat(routestring, " gw ", 4);
+                                       strncat(routestring, " via ", 5);
                                        strncat(routestring, framedgw, 40);
                                }
                                if (framedmetric[0]!='\0')
@@ -862,6 +863,7 @@ void UserAcct::delSystemRoutes(PluginCon
                                }
                                strncat(routestring," dev ",5);
                                strcat(routestring,this->getDev().c_str());
+                               strncat(routestring," proto static",13);
                                //redirect the output stderr to /dev/null
                                strncat(routestring," 2> /dev/null",13);
                                
@@ -1010,13 +1012,13 @@ void UserAcct::addSystemRoutes(PluginCon
                                                                                
                                        
                                                                                
                                
                                //create system call
-                               strncat(routestring, "route add -net ",15);
+                               strncat(routestring, "ip route add ",13);
                                strncat(routestring, framedip ,16);
                                strncat(routestring, "/" ,1);
                                strncat(routestring, framednetmask_cidr, 2);
                                if (framedgw[0]!='\0')
                                {
-                                       strncat(routestring, " gw ", 4);
+                                       strncat(routestring, " via ", 5);
                                        strncat(routestring, framedgw, 16);
                                }
                                if (framedmetric[0]!='\0')
@@ -1026,6 +1028,7 @@ void UserAcct::addSystemRoutes(PluginCon
                                }
                                strncat(routestring," dev ",5);
                                strcat(routestring,this->getDev().c_str());
+                               strncat(routestring," proto static",13);
                                //redirect the output stderr to /dev/null
                                strncat(routestring," 2> /dev/null",13);
                                
@@ -1150,13 +1153,13 @@ void UserAcct::addSystemRoutes(PluginCon
                                                                                
                                        
                                                                                
                                
                                //create system call
-                               strncat(routestring, "route -6 add ",13);
+                               strncat(routestring, "ip -6 route add ",21);
                                strncat(routestring, framedip ,40);
                                strncat(routestring, "/" ,1);
                                strncat(routestring, framednetmask_cidr, 3);
                                if (framedgw[0]!='\0')
                                {
-                                       strncat(routestring, " gw ", 4);
+                                       strncat(routestring, " via ", 5);
                                        strncat(routestring, framedgw, 40);
                                }
                                if (framedmetric[0]!='\0')
@@ -1166,6 +1169,7 @@ void UserAcct::addSystemRoutes(PluginCon
                                }
                                strncat(routestring," dev ",5);
                                strcat(routestring,this->getDev().c_str());
+                               strncat(routestring," proto static",13);
                                //redirect the output stderr to /dev/null
                                strncat(routestring," 2> /dev/null",13);
                                
@@ -1285,7 +1289,7 @@ int UserAcct::deleteCcdFile(PluginContex
 {
        string filename;
        filename = context->conf.getCcdPath()+ this->getCommonname();
-       if(context->conf.getOverWriteCCFiles()==true && 
(this->getFramedIp().length() > 0 || this->getFramedRoutes().length() > 0 || 
this->getFramedRoutes6().length() > 0))
+       if(context->conf.getOverWriteCCFiles()==true && 
(this->getFramedIp().length() > 0 || this->getFramedRoutes().length() > 0 || 
this->getFramedIp6().length() > 0 || this->getFramedRoutes6().length() > 0))
        {
                remove(filename.c_str());
        }
This adds support for Framed-IPv6-Address, as drafted in
RFC-ietf-radext-ipv6-access-16, recorded in user->framedip6 and used as in IPv4.

--- a/AccountingProcess.cpp
+++ b/AccountingProcess.cpp
@@ -105,6 +105,7 @@ void AccountingProcess::Accounting(Plugi
                     user->setPortnumber(context->acctsocketforegr.recvInt());
                     
user->setCallingStationId(context->acctsocketforegr.recvStr());
                     user->setFramedIp(context->acctsocketforegr.recvStr());
+                    user->setFramedIp6(context->acctsocketforegr.recvStr());
                     user->setCommonname(context->acctsocketforegr.recvStr());
                     
user->setAcctInterimInterval(context->acctsocketforegr.recvInt());
                     user->setFramedRoutes(context->acctsocketforegr.recvStr());
@@ -114,7 +115,7 @@ void AccountingProcess::Accounting(Plugi
                     
user->setUntrustedPort(context->acctsocketforegr.recvStr());
                     context->acctsocketforegr.recvBuf(user);
                     if (DEBUG (context->getVerbosity()))
-                        cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: 
New user acct: username: " << user->getUsername() << ", interval: " << 
user->getAcctInterimInterval() << ", calling station: " << 
user->getCallingStationId() << ", commonname: " << user->getCommonname() << ", 
framed ip: " << user->getFramedIp() <<".\n";
+                        cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: 
New user acct: username: " << user->getUsername() << ", interval: " << 
user->getAcctInterimInterval() << ", calling station: " << 
user->getCallingStationId() << ", commonname: " << user->getCommonname() << ", 
framed ip: " << user->getFramedIp() << ", framed ipv6: " << 
user->getFramedIp6() <<".\n";
 
 
                     //set the starttime
--- a/AuthenticationProcess.cpp
+++ b/AuthenticationProcess.cpp
@@ -109,6 +109,9 @@ void AuthenticationProcess::Authenticati
                                //send the IPv6 routes to the parent process
                                
context->authsocketforegr.send(user->getFramedRoutes6());
                                        
+                               //send the framed IPv6 to the parent process
+                               
context->authsocketforegr.send(user->getFramedIp6());
+                                                                               
                                        //send the interval to the parent 
process
                                
context->authsocketforegr.send(user->getAcctInterimInterval());
                                
--- a/RadiusClass/utilities/dictionary
+++ b/RadiusClass/utilities/dictionary
@@ -123,6 +123,8 @@ ATTRIBUTE   NAS-IPv6-Address                95      ipaddr6
 ATTRIBUTE      Login-IPv6-Host                 98      ipaddr6 
 ATTRIBUTE      Framed-IPv6-Route               99      string  
 ATTRIBUTE      Framed-IPv6-Pool                100     string  
+ATTRIBUTE      Framed-IPv6-Address             168     ipaddr6
+
 ATTRIBUTE      X-Ascend-FCP-Parameter          119     string  
 ATTRIBUTE      Ascend-Modem-PortNo             120     integer 
 ATTRIBUTE      Ascend-Modem-SlotNo             121     integer 
--- a/RadiusClass/utilities/vsa.h
+++ b/RadiusClass/utilities/vsa.h
@@ -161,6 +161,8 @@
        //ATTRIBUTE     Login-IPv6-Host                 98      ipaddr6 
        //ATTRIBUTE     Framed-IPv6-Route               99      string  
        //ATTRIBUTE     Framed-IPv6-Pool                100     string  
+       //ATTRIBUTE     Framed-IPv6-Address             168     ipaddr6 
+       //
        //ATTRIBUTE     X-Ascend-FCP-Parameter          119     string  
        //ATTRIBUTE     Ascend-Modem-PortNo             120     integer 
        //ATTRIBUTE     Ascend-Modem-SlotNo             121     integer 
--- a/RadiusClass/vsa.h
+++ b/RadiusClass/vsa.h
@@ -161,6 +161,8 @@
        //ATTRIBUTE     Login-IPv6-Host                 98      ipaddr6 
        //ATTRIBUTE     Framed-IPv6-Route               99      string  
        //ATTRIBUTE     Framed-IPv6-Pool                100     string  
+       //ATTRIBUTE     Framed-IPv6-Address             168     ipaddr6 
+       //
        //ATTRIBUTE     X-Ascend-FCP-Parameter          119     string  
        //ATTRIBUTE     Ascend-Modem-PortNo             120     integer 
        //ATTRIBUTE     Ascend-Modem-SlotNo             121     integer 
--- a/User.cpp
+++ b/User.cpp
@@ -27,6 +27,7 @@ User::User()
        this->dev="";
        this->framedip="";
        this->framedroutes="";
+       this->framedip6="";
        this->framedroutes6="";
        this->key="";
         this->statusfilekey="";
@@ -46,6 +47,7 @@ User::User()
        this->dev="";
        this->framedip="";
        this->framedroutes="";
+       this->framedip6="";
        this->framedroutes6="";
        this->key="";
        this->untrustedport="";
@@ -73,8 +75,9 @@ User & User::operator=(const User & u)
        this->username=u.username;
        this->commonname=u.commonname;
        this->dev=u.dev;
-       this->framedroutes=u.framedroutes;
        this->framedip=u.framedip;
+       this->framedroutes=u.framedroutes;
+       this->framedip6=u.framedip6;
        this->framedroutes6=u.framedroutes6;
        this->key=u.key;
         this->statusfilekey=u.statusfilekey;
@@ -115,8 +118,9 @@ User::User(const User & u)
        this->username=u.username;
        this->commonname=u.commonname;
        this->dev=u.dev;
-       this->framedroutes=u.framedroutes;
        this->framedip=u.framedip;
+       this->framedroutes=u.framedroutes;
+       this->framedip6=u.framedip6;
        this->framedroutes6=u.framedroutes6;
        this->key=u.key;
         this->statusfilekey=u.statusfilekey;
@@ -225,6 +229,19 @@ void User::setFramedRoutes6(string frout
        this->framedroutes6=froutes6;
 }
 
+/** The getter method for the framed IPv6.
+ *  @return The framed IPv6 as a string.*/
+string User::getFramedIp6(void)
+{
+       return this->framedip6;
+}
+/** The setter method for the framedip6.
+ * @param ip The framedip.*/
+void User::setFramedIp6(string ip)
+{
+       this->framedip6=ip;
+}
+
 /** The getter method for the fkey.
  *  @return The unique key as a string.*/
 string User::getKey(void)
--- a/User.h
+++ b/User.h
@@ -49,6 +49,7 @@ protected:
        string framedroutes;            /**<The framedroutes, they are stored 
as a string. If there are more routes, they must be delimited by an ';'*/
        string framedip;                /**<The framed ip.*/
        string framedroutes6;           /**<The framed IPv6 routes, they are 
stored as a string. If there are more routes, they must be delimited by an ';'*/
+       string framedip6;               /**<The framed ipv6.*/
        string callingstationid;        /**<The calling station id, in this 
case the real ip address of the client.*/
        string key;                     /**<A unique key to find the user in a 
map. */
        string statusfilekey;           /**<Unique identifier in the status log 
file (version 1) "commonname,untrusted_ip:untrusted_port"*/
@@ -87,6 +88,9 @@ public:
        string getFramedRoutes6(void);
        void setFramedRoutes6(string);
        
+       string getFramedIp6(void);
+       void setFramedIp6(string);
+       
        string getKey(void);
        void setKey(string);
 
--- a/UserAuth.cpp
+++ b/UserAuth.cpp
@@ -269,6 +269,19 @@ void UserAuth::parseResponsePacket(Radiu
        cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: framed ipv6 
route: " << this->getFramedRoutes6() <<".\n";
        
        
+       range=packet->findAttributes(168);
+       iter1=range.first;
+       iter2=range.second;     
+       
+       
+       if (iter1!=iter2)
+       {
+               this->setFramedIp6(iter1->second.ip6FromBuf());
+       }
+       
+       if (DEBUG (context->getVerbosity()))
+       cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: framed IPv6: " << 
this->getFramedIp6() <<".\n";
+       
        
        range=packet->findAttributes(85);
        iter1=range.first;
@@ -1523,7 +1536,7 @@ int UserAuth::createCcdFile(PluginContex
        int len=0;
        
        
-       if(context->conf.getOverWriteCCFiles()==true && 
(this->getFramedIp().length() > 0 || this->getFramedRoutes().length() > 0 || 
this->getFramedRoutes6().length() > 0))
+       if(context->conf.getOverWriteCCFiles()==true && 
(this->getFramedIp().length() > 0 || this->getFramedRoutes().length() > 0 || 
this->getFramedIp6().length() > 0 || this->getFramedRoutes6().length() > 0))
        {
                memset(ipstring,0,100);
                memset(framedip,0,16);
@@ -1783,6 +1796,32 @@ int UserAuth::createCcdFile(PluginContex
                                }
                        }
                        
+                       //set the IPv6 address in the file
+                       if (this->framedip6[0]!='\0')
+                       {
+                               if (DEBUG (context->getVerbosity()))
+                                       cerr << getTime() << "RADIUS-PLUGIN: 
BACKGROUND AUTH: Write framed IPv6 to ccd-file.\n";
+                       
+                               //build the ifconfig
+                               ipstring[0] = 0;
+                               strncat(ipstring, "ifconfig-ipv6-push ",19);
+                               strncat(ipstring, this->getFramedIp6().c_str() 
, 39);
+                               strncat(ipstring, " ", 1);
+                               
+                               if(context->conf.getP2p6()[0]!='\0')
+                               {
+                                       strncat(ipstring, 
context->conf.getP2p6() , 39);
+                                       if (DEBUG (context->getVerbosity()))
+                                               cerr << getTime() << 
"RADIUS-PLUGIN: BACKGROUND AUTH: Create ifconfig-ipv6-push for topology p2p.\n";
+                               }
+                               
+                               if (DEBUG (context->getVerbosity()))
+                                       cerr << getTime() << "RADIUS-PLUGIN: 
Write " << ipstring << " ccd-file.\n";
+                               
+                               
+                               ccdfile << ipstring <<"\n";
+                       }
+                       
                        //set the IPv6 framed routes in the file for the 
openvpn process
                        if (framedroutes6[0]!='\0')
                        {
--- a/radiusplugin.cpp
+++ b/radiusplugin.cpp
@@ -492,6 +492,7 @@ error:
                     context->acctsocketbackgr.send ( newuser->getPortnumber() 
);
                     context->acctsocketbackgr.send ( 
newuser->getCallingStationId() );
                     context->acctsocketbackgr.send ( newuser->getFramedIp() );
+                    context->acctsocketbackgr.send ( newuser->getFramedIp6() );
                     context->acctsocketbackgr.send ( newuser->getCommonname() 
);
                     context->acctsocketbackgr.send ( 
newuser->getAcctInterimInterval() );
                     context->acctsocketbackgr.send ( 
newuser->getFramedRoutes() );
@@ -995,6 +996,10 @@ void  * auth_user_pass_verify(void * c)
                 newuser->setFramedRoutes6 ( 
context->authsocketbackgr.recvStr() );
                 if ( DEBUG ( context->getVerbosity() ) )
                     cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: 
Received IPv6 routes for user: "<< newuser->getFramedRoutes6() << ".\n";
+                //get the framed IPv6
+                newuser->setFramedIp6 ( context->authsocketbackgr.recvStr() );
+                if ( DEBUG ( context->getVerbosity() ) )
+                    cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: 
Received framed IPv6 for user: "<< newuser->getFramedIp6() << "." << endl;
 
 
                 // get the interval from the background process
--- a/Config.cpp
+++ b/Config.cpp
@@ -41,6 +41,7 @@ Config::Config(void)
        this->vsascript="";
        memset(this->subnet,0,16);
        memset(this->p2p,0,16);
+       memset(this->p2p6,0,40);
 }
 
 /** The constructor initializes all char arrays with 0. After the 
initialization
@@ -53,6 +54,7 @@ Config::Config(char * configfile)
 {
        memset(this->subnet,0,16);
        memset(this->p2p,0,16);
+       memset(this->p2p6,0,40);
        this->ccdPath="";
        this->openvpnconfig="";
        this->vsanamedpipe="";
@@ -114,6 +116,14 @@ int Config::parseConfigFile(const char *
                                        }
                                        line.copy(this->p2p,line.size()-4,4);
                                }
+                               if (strncmp(line.c_str(),"p2p6=",5)==0)
+                               {
+                                       if((line.size()-5)>39)
+                                       {
+                                               return BAD_FILE;
+                                       }
+                                       line.copy(this->p2p6,line.size()-5,5);
+                               }
                                if (strncmp(line.c_str(),"vsascript=",10)==0)
                                {
                                        
this->vsascript=line.substr(10,line.size()-10);
@@ -399,6 +409,23 @@ char * Config::getP2p(void)
        return this->p2p;
 }
 
+/** The setter method for the p2p6 address.
+ * @param ip A string with p2p6 address.
+ */    
+void Config::setP2p6(char * ip)
+{
+       strncpy(this->p2p6,ip, 40);
+}
+
+
+/** The getter method for the p2p6 address.
+ * @return A pointer to the p2p6 address.
+ */
+char * Config::getP2p6(void)
+{
+       return this->p2p6;
+}
+
 /** The setter method for the vsascript.
  * @param script A path of the script.
  */    
--- a/Config.h
+++ b/Config.h
@@ -43,6 +43,7 @@ private:
     string statusfile;                                 /**< The path and 
filename of the status file, where openvpn writes the status information.*/ 
        char subnet[16];                                /**<The subnet which is 
assigned to the client in topology option.*/
        char p2p[16];                                   /**<The OpenVPN server 
address which is assigned to the client in topology p2p.*/
+       char p2p6[40];                                  /**<The OpenVPN server 
IPv6 address which is assigned to the client in topology p2p.*/
        string vsascript;                               /**<A script which 
handles vendor specific attributes.*/
        string vsanamedpipe;            /**<The named pipe to the vsascript.*/
        bool usernameascommonname;              /**<Use the username as 
commonname in the plugin (for OpenVPN option username-as-common-name (no 
commonname in the enviroment!)).*/
@@ -77,6 +78,9 @@ public:
        char * getP2p(void);
        void setP2p(char * );
        
+       char * getP2p6(void);
+       void setP2p6(char * );
+       
        string getVsaScript(void);
        void setVsaScript(string);
        
--- a/radiusplugin.cnf
+++ b/radiusplugin.cnf
@@ -30,6 +30,9 @@ subnet=255.255.255.0
 # If you use topology option "p2p", fill in the right network, e.g. from 
OpenVPN option "--server NETWORK NETMASK"
 # p2p=10.8.0.1
 
+# If using Framed-IPv6-Address, fill in the gateway, e.g. from OpenVPN option 
"--server-ipv6 ADDRESS"
+# p2p6=fc00::1
+
 
 # Allows the plugin to overwrite the client config in client config file 
directory,
 # default is true
--- a/RadiusClass/RadiusAttribute.cpp
+++ b/RadiusClass/RadiusAttribute.cpp
@@ -568,3 +568,26 @@ string RadiusAttribute::ipFromBuf(void)
        }
        return string(ip3);                      
 }  
+
+/** The method converts the value into an IPv6.
+ * The attribute must have the right datatype IPADDRESS6.
+ * @return The ip address as a string.
+ */
+string RadiusAttribute::ip6FromBuf(void)
+{
+       int num,i,len;
+       char ip2[3],ip3[40];
+       memset(ip3,0,40);
+       len=(this->length-2);
+       if(len>16)
+               len=16;
+       for (i=0;i<len;i++)
+       {
+               num=(int)this->value[i];
+               sprintf(ip2,"%02x",num);
+               strcat(ip3,ip2);
+               if((i%2)==1 && i<len-1)
+                       strcat(ip3,":");
+       }
+       return string(ip3);
+}  
--- a/RadiusClass/RadiusAttribute.h
+++ b/RadiusClass/RadiusAttribute.h
@@ -68,6 +68,7 @@ public:
        int                             intFromBuf(void);
         
        string                  ipFromBuf(void); 
+       string                  ip6FromBuf(void); 
                
        void                    dumpRadiusAttrib(void);
        

Reply via email to