Description: framed-ipv6-route.patch
   * Add Framed-IPv6-Route support.
Author: Samuel Thibault <sthibault@debian.org>
X-Dgit-Generated: 2.1-6+IP6.3 2370bab74632d6c8937cbc931970f0a8154b9d85

---

--- openvpn-auth-radius-2.1.orig/AccountingProcess.cpp
+++ openvpn-auth-radius-2.1/AccountingProcess.cpp
@@ -93,12 +93,14 @@ 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()); 
 					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());
--- openvpn-auth-radius-2.1.orig/AuthenticationProcess.cpp
+++ openvpn-auth-radius-2.1/AuthenticationProcess.cpp
@@ -73,6 +73,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());
@@ -106,6 +107,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());
 			     	
--- openvpn-auth-radius-2.1.orig/User.cpp
+++ openvpn-auth-radius-2.1/User.cpp
@@ -24,8 +24,10 @@
 /** The constructor sets the acctinteriminterval and the portnumber to 0.*/
 User::User()
 {
+	this->dev="";
 	this->framedip="";
 	this->framedroutes="";
+	this->framedroutes6="";
 	this->key="";
         this->statusfilekey="";
 	this->untrustedport="";
@@ -41,8 +43,10 @@ User::User()
  * @param num  The portnumber.*/
 /*User::User(int num)
 {
+	this->dev="";
 	this->framedip="";
 	this->framedroutes="";
+	this->framedroutes6="";
 	this->key="";
 	this->untrustedport="";
 	this->acctinteriminterval=0;
@@ -68,8 +72,10 @@ 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;
 	this->key=u.key;
         this->statusfilekey=u.statusfilekey;
 	this->callingstationid=u.callingstationid;
@@ -100,8 +106,10 @@ 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;
 	this->key=u.key;
         this->statusfilekey=u.statusfilekey;
 	this->callingstationid=u.callingstationid;
@@ -149,6 +157,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)
@@ -157,12 +178,26 @@ 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;
 }
 
+/** 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 framed ip.
  *  @return The framed ip as a string.*/
 string User::getFramedIp(void)
--- openvpn-auth-radius-2.1.orig/User.h
+++ openvpn-auth-radius-2.1/User.h
@@ -44,8 +44,10 @@ 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 delimted 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 addres 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"*/
@@ -73,9 +75,15 @@ public:
 	void setCommonname(string);
 		
 	
+	string getDev(void);
+	void setDev(string);
+	
 	string getFramedRoutes(void);
 	void setFramedRoutes(string);
 	
+	string getFramedRoutes6(void);
+	void setFramedRoutes6(string);
+	
 	string getFramedIp(void);
 	void setFramedIp(string);
 	
--- openvpn-auth-radius-2.1.orig/UserAcct.cpp
+++ openvpn-auth-radius-2.1/UserAcct.cpp
@@ -594,13 +594,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
@@ -694,17 +694,23 @@ 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);
-				strncat(routestring, " gw ", 4);
-				strncat(routestring, framedgw, 16);
+				if (framedgw[0]!='\0' && strncmp(framedgw, "0.0.0.0", 8) != 0)
+				{
+					strncat(routestring, " via ", 5);
+					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());
+				strncat(routestring," proto static",13);
 				//redirect the output stderr to /dev/null
 				strncat(routestring," 2> /dev/null",13);
 				
@@ -739,6 +745,147 @@ 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, "ip -6 route del ",16);
+				strncat(routestring, framedip ,40);
+				strncat(routestring, "/" ,1);
+				strncat(routestring, framednetmask_cidr, 3);
+				if (framedgw[0]!='\0')
+				{
+					strncat(routestring, " via ", 5);
+					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());
+				strncat(routestring," proto static",13);
+				//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.
@@ -747,13 +894,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
@@ -848,17 +995,23 @@ 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);
-				strncat(routestring, " gw ", 4);
-				strncat(routestring, framedgw, 16);
+				if (framedgw[0]!='\0' && strncmp(framedgw, "0.0.0.0", 8) != 0)
+				{
+					strncat(routestring, " via ", 5);
+					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());
+				strncat(routestring," proto static",13);
 				//redirect the output stderr to /dev/null
 				strncat(routestring," 2> /dev/null",13);
 				
@@ -888,9 +1041,150 @@ 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, "ip -6 route add ",21);
+				strncat(routestring, framedip ,40);
+				strncat(routestring, "/" ,1);
+				strncat(routestring, framednetmask_cidr, 3);
+				if (framedgw[0]!='\0')
+				{
+					strncat(routestring, " via ", 5);
+					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());
+				strncat(routestring," proto static",13);
+				//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;
+	
 }
 
 
--- openvpn-auth-radius-2.1.orig/UserAuth.cpp
+++ openvpn-auth-radius-2.1/UserAuth.cpp
@@ -250,6 +250,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;		
@@ -1484,15 +1503,16 @@ 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 framedgw[16];
+	char framedgw[40];
 	char framedmetric[5]; //what is the biggest metric? 
 	
 	unsigned long d1,d2;
@@ -1501,11 +1521,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();
@@ -1524,6 +1545,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())
 		{
@@ -1706,6 +1730,104 @@ 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(framednetmask_cidr,0,4);
+						memset(framedip,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,";");
+					}
 				}
 			}
 		
--- openvpn-auth-radius-2.1.orig/radiusplugin.cpp
+++ openvpn-auth-radius-2.1/radiusplugin.cpp
@@ -442,6 +442,8 @@ extern "C"
 				}
 
 
+				newuser->setDev ( get_env ( "dev", envp ) );
+
 				newuser->setUntrustedPort ( get_env ( "untrusted_port", envp ) );
 				newuser->setStatusFileKey(newuser->getCommonname() +string ( "," ) + untrusted_ip + string ( ":" ) + get_env ( "untrusted_port", envp ) );
                                 newuser->setKey(untrusted_ip + string ( ":" ) + get_env ( "untrusted_port", envp ) );
@@ -571,12 +573,14 @@ extern "C"
 					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() );
 					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() );
@@ -1055,6 +1059,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() );
@@ -1076,6 +1081,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() << ".\n";
+                          //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
