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);