feat: Add support for IPv6 in AddressRange

This commit is contained in:
Sirius Bakke 2018-05-09 22:17:31 +02:00
parent 824a7c93ca
commit 9ac12168f0
6 changed files with 169 additions and 26 deletions

View File

@ -214,6 +214,16 @@ void invalidIPv6(string s)
}
}
void invalidIPv4Orv6(string s)
{
if (!testIPv4(s) && !testIPv6(s))
{
cout << "\"" << s << "\" - invalid IP address." << endl;
exit(0);
}
}
bool testPlatform(const string &pl, const string &os)
{
vector<string> platforms = Resources::getListOfPlatforms();
@ -382,19 +392,32 @@ void _modObject(FWObject *nobj, const string &comment_txt, operands ops)
{
try
{
addr1 = getNextOpt(ops); invalidIPv4(addr1);
addr2 = getNextOpt(ops); invalidIPv4(addr2);
addr1 = getNextOpt(ops); invalidIPv4Orv6(addr1);
addr2 = getNextOpt(ops); invalidIPv4Orv6(addr2);
} catch (OperandsError &e)
{
notEnoughAttributesError();
}
InetAddr range_start(AF_UNSPEC, addr1);
InetAddr range_end(AF_UNSPEC, addr2);
if (range_start.addressFamily() != range_end.addressFamily()) {
cout << "AddressRange start and end address must be of same IP address family: ";
cout << "start_address: " << range_start.toString() << ", ";
cout << "end_address: " << range_end.toString();
cout << endl;
exit(1);
}
cout << "Range start: " << addr1 << endl
<< "Range end: " << addr2 << endl;
AddressRange *o=AddressRange::cast(nobj);
o->setRangeStart(InetAddr(addr1));
o->setRangeEnd(InetAddr(addr2));
o->setRangeStart(range_start);
o->setRangeEnd(range_end);
}
else if (objtype==ObjectGroup::TYPENAME)
{

View File

@ -2343,10 +2343,16 @@ bool PolicyCompiler_ipt::specialCaseAddressRangeInRE::processNext()
if (addr_obj && !addr_obj->isAny() && AddressRange::isA(addr_obj) &&
addr_obj->dimension() == 1)
{
Address *new_addr = compiler->dbcopy->createIPv4();
bool IPv4 = AddressRange::cast(addr_obj)->isV4();
int address_family = IPv4 ? AF_INET : AF_INET6;
Address *new_addr = IPv4
? static_cast<Address*>(compiler->dbcopy->createIPv4())
: static_cast<Address*>(compiler->dbcopy->createIPv6());
new_addr->setName(addr_obj->getName() + "_addr");
new_addr->setAddress(AddressRange::cast(addr_obj)->getRangeStart());
new_addr->setNetmask(InetAddr(InetAddr::getAllOnes()));
new_addr->setNetmask(InetAddr(InetAddr::getAllOnes(address_family)));
compiler->persistent_objects->add(new_addr);
new_children.push_back(new_addr);
} else

View File

@ -116,13 +116,23 @@ void AddressRange::fromXML(xmlNodePtr root)
const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("start_address")));
assert(n!=NULL);
start_address = InetAddr(n);
start_address = InetAddr(AF_UNSPEC, n);
FREEXMLBUFF(n);
n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("end_address")));
assert(n!=NULL);
end_address = InetAddr(n);
end_address = InetAddr(AF_UNSPEC, n);
FREEXMLBUFF(n);
if (start_address.addressFamily() != end_address.addressFamily()) {
std::ostringstream s;
s << "AddressRange start and end address must be of same IP address family: ";
s << "start_address: " << start_address.toString() << ", ";
s << "end_address: " << end_address.toString();
throw(FWException(s.str()));
}
}
xmlNodePtr AddressRange::toXML(xmlNodePtr xml_parent_node)

View File

@ -52,6 +52,16 @@ class AddressRange : public Address
void setRangeStart(const InetAddr &o) { start_address = o; }
void setRangeEnd(const InetAddr &o) { end_address = o; }
bool isV4() const {
return start_address.addressFamily() == AF_INET
&& end_address.addressFamily() == AF_INET;
}
bool isV6() const {
return start_address.addressFamily() == AF_INET6
&& end_address.addressFamily() == AF_INET6;
}
/**
* virtual methods inherited from Address
*/

View File

@ -96,11 +96,29 @@ void InetAddr::init_from_string(const char* data)
if (inet_net_pton(AF_INET, data, &ipv4, sizeof(ipv4)) < 0)
throw FWException(string("Invalid IP address: '") +
string(data)+"'");
} else
} else if (address_family == AF_INET6)
{
if (inet_net_pton(AF_INET6, data, &ipv6, sizeof(ipv6)) < 0)
throw FWException(string("Invalid IPv6 address: '") +
string(data)+"'");
} else if (address_family == AF_UNSPEC)
{
if (inet_net_pton(AF_INET, data, &ipv4, sizeof(ipv4)) >= 0) {
address_family = AF_INET;
return;
}
if (inet_net_pton(AF_INET6, data, &ipv6, sizeof(ipv6)) >= 0) {
address_family = AF_INET6;
return;
}
throw FWException(string("Invalid IP address: '") + string(data)+"'");
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
}
@ -123,7 +141,7 @@ void InetAddr::init_from_int(unsigned int len)
i--;
}
ipv4.s_addr = htonl(nm_bits);
} else
} else if (address_family == AF_INET6)
{
if (len > addressLengthBits())
{
@ -154,6 +172,11 @@ void InetAddr::init_from_int(unsigned int len)
((uint32_t*)(&ipv6))[i] = htonl(t);
break;
}
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -264,9 +287,14 @@ InetAddr& InetAddr::operator=(const InetAddr &addr)
if ((address_family = addr.address_family)==AF_INET)
{
ipv4.s_addr = addr.ipv4.s_addr;
} else
} else if ((address_family = addr.address_family)==AF_INET6)
{
InetAddr::_copy_in6_addr(&ipv6, &(addr.ipv6) );
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
return *this;
}
@ -288,7 +316,7 @@ int InetAddr::getLength() const
}
return i;
} else
} else if (address_family==AF_INET6)
{
int bits = 0;
for (int i=3; i>=0; --i)
@ -308,6 +336,11 @@ int InetAddr::getLength() const
break;
}
return bits;
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -316,7 +349,7 @@ string InetAddr::toString() const
if (address_family==AF_INET)
{
return std::string(inet_ntoa(ipv4));
} else
} else if (address_family==AF_INET6)
{
char ntop_buf[sizeof
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"];
@ -358,6 +391,11 @@ string InetAddr::toString() const
char *slash_p = strchr(ntop_buf, '/');
if (slash_p!=NULL) *slash_p = '\0';
return std::string(ntop_buf);
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -371,13 +409,18 @@ InetAddr InetAddr::opAnd(const InetAddr &mask) const
struct in_addr res;
res.s_addr = htonl(ntohl(ipv4.s_addr) & ntohl(mask.ipv4.s_addr));
return InetAddr(&res);
} else {
} else if (address_family==AF_INET6) {
struct in6_addr res;
for (int i=0; i<4; ++i)
((uint32_t*)(&res))[i] =
htonl(ntohl(((uint32_t*)(&(ipv6)))[i]) &
ntohl(((uint32_t*)(&(mask.ipv6)))[i]));
return InetAddr(&res);
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -389,7 +432,7 @@ InetAddr InetAddr::opOr(const InetAddr &mask) const
struct in_addr res;
res.s_addr = htonl(ntohl(ipv4.s_addr) | ntohl(mask.ipv4.s_addr));
return InetAddr(&res);
} else
} else if (address_family==AF_INET6)
{
struct in6_addr res;
for (int i=0; i<4; ++i)
@ -397,6 +440,11 @@ InetAddr InetAddr::opOr(const InetAddr &mask) const
htonl(ntohl(((uint32_t*)(&(ipv6)))[i]) |
ntohl(((uint32_t*)(&(mask.ipv6)))[i]));
return InetAddr(&res);
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -407,7 +455,7 @@ InetAddr InetAddr::opPlus(int increment) const
struct in_addr res;
res.s_addr = htonl(ntohl(ipv4.s_addr) + increment);
return InetAddr(&res);
} else
} else if (address_family==AF_INET6)
{
uint128 x = to_uint128();
x += increment;
@ -420,6 +468,11 @@ InetAddr InetAddr::opPlus(int increment) const
// ((uint32_t*)(&res))[3] =
// htonl(ntohl( ((uint32_t*)(&(ipv6)))[3]) + increment);
// return InetAddr(&res);
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -430,7 +483,7 @@ InetAddr InetAddr::opMinus(int decrement) const
struct in_addr res;
res.s_addr = htonl(ntohl(ipv4.s_addr) - decrement);
return InetAddr(&res);
} else
} else if (address_family==AF_INET6)
{
uint128 x = to_uint128();
x -= decrement;
@ -443,6 +496,11 @@ InetAddr InetAddr::opMinus(int decrement) const
// ((uint32_t*)(&res))[3] =
// htonl(ntohl( ((uint32_t*)(&(ipv6)))[3]) - decrement);
// return InetAddr(&res);
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -452,7 +510,7 @@ bool InetAddr::opLT(const InetAddr &other) const
if (address_family==AF_INET)
{
return (ntohl( ipv4.s_addr ) < ntohl( other.ipv4.s_addr ));
} else
} else if (address_family==AF_INET6)
{
uint128 a = to_uint128();
uint128 b = other.to_uint128();
@ -460,6 +518,11 @@ bool InetAddr::opLT(const InetAddr &other) const
// return (ntohl(((uint32_t*)(&(ipv6)))[3]) <
// ntohl(((uint32_t*)(&(other.ipv6)))[3]));
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -469,7 +532,7 @@ bool InetAddr::opGT(const InetAddr &other) const
if (address_family==AF_INET)
{
return (ntohl( ipv4.s_addr ) > ntohl( other.ipv4.s_addr ));
} else
} else if (address_family==AF_INET6)
{
uint128 a = to_uint128();
uint128 b = other.to_uint128();
@ -477,6 +540,11 @@ bool InetAddr::opGT(const InetAddr &other) const
// return (ntohl(((uint32_t*)(&(ipv6)))[3]) >
// ntohl(((uint32_t*)(&(other.ipv6)))[3]));
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -486,9 +554,14 @@ bool InetAddr::opEQ(const InetAddr &other) const
if (address_family==AF_INET)
{
return ipv4.s_addr == other.ipv4.s_addr;
} else
} else if (address_family==AF_INET6)
{
return (IN6_ARE_ADDR_EQUAL(&(ipv6), &(other.ipv6)));
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -498,9 +571,14 @@ bool InetAddr::opNEQ(const InetAddr &other) const
if (address_family==AF_INET)
{
return ipv4.s_addr != other.ipv4.s_addr;
} else
} else if (address_family==AF_INET6)
{
return (!(IN6_ARE_ADDR_EQUAL(&(ipv6), &(other.ipv6))));
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}
@ -511,7 +589,7 @@ InetAddr InetAddr::opCompl() const
struct in_addr res;
res.s_addr = htonl(~(ntohl(ipv4.s_addr)));
return InetAddr(&res);
} else
} else if (address_family==AF_INET6)
{
struct in6_addr res;
((uint32_t *) (&res))[0] = htonl(~(ntohl(((uint32_t *) (&ipv6))[0])));
@ -519,6 +597,11 @@ InetAddr InetAddr::opCompl() const
((uint32_t *) (&res))[2] = htonl(~(ntohl(((uint32_t *) (&ipv6))[2])));
((uint32_t *) (&res))[3] = htonl(~(ntohl(((uint32_t *) (&ipv6))[3])));
return InetAddr(&res);
} else
{
std::ostringstream s;
s << "Invalid IP address family: '" << addressFamily() << "'";
throw FWException(s.str());
}
}

View File

@ -47,6 +47,7 @@
#include <QUndoStack>
#include <memory>
#include <sstream>
using namespace std;
using namespace libfwbuilder;
@ -102,8 +103,18 @@ void AddressRangeDialog::validate(bool *res)
assert(s!=NULL);
try
{
InetAddr(m_dialog->rangeStart->text().toLatin1().constData());
InetAddr(m_dialog->rangeEnd->text().toLatin1().constData());
InetAddr range_start(AF_UNSPEC, m_dialog->rangeStart->text().toLatin1().constData());
InetAddr range_end(AF_UNSPEC, m_dialog->rangeEnd->text().toLatin1().constData());
if (range_start.addressFamily() != range_end.addressFamily()) {
std::ostringstream s;
s << "AddressRange start and end address must be of same IP address family: ";
s << "start_address: " << m_dialog->rangeStart->text().toStdString() << ", ";
s << "end_address: " << m_dialog->rangeEnd->text().toStdString();
throw(FWException(s.str()));
}
} catch (FWException &ex)
{
*res = false;
@ -136,8 +147,8 @@ void AddressRangeDialog::applyChanges()
try
{
InetAddr addr_start(m_dialog->rangeStart->text().toStdString());
InetAddr addr_end(m_dialog->rangeEnd->text().toStdString());
InetAddr addr_start(AF_UNSPEC, m_dialog->rangeStart->text().toStdString());
InetAddr addr_end(AF_UNSPEC, m_dialog->rangeEnd->text().toStdString());
if (addr_end < addr_start)
{
addr_end = addr_start;