diff --git a/src/fwbedit/new_object.cpp b/src/fwbedit/new_object.cpp index 1096ab8f9..91f10598e 100644 --- a/src/fwbedit/new_object.cpp +++ b/src/fwbedit/new_object.cpp @@ -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 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) { diff --git a/src/iptlib/PolicyCompiler_ipt.cpp b/src/iptlib/PolicyCompiler_ipt.cpp index eedb8e513..63f24d6eb 100644 --- a/src/iptlib/PolicyCompiler_ipt.cpp +++ b/src/iptlib/PolicyCompiler_ipt.cpp @@ -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(compiler->dbcopy->createIPv4()) + : static_cast(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 diff --git a/src/libfwbuilder/src/fwbuilder/AddressRange.cpp b/src/libfwbuilder/src/fwbuilder/AddressRange.cpp index 037649090..af5f22c4a 100644 --- a/src/libfwbuilder/src/fwbuilder/AddressRange.cpp +++ b/src/libfwbuilder/src/fwbuilder/AddressRange.cpp @@ -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) diff --git a/src/libfwbuilder/src/fwbuilder/AddressRange.h b/src/libfwbuilder/src/fwbuilder/AddressRange.h index 5b45d97fc..031ce97f1 100644 --- a/src/libfwbuilder/src/fwbuilder/AddressRange.h +++ b/src/libfwbuilder/src/fwbuilder/AddressRange.h @@ -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 */ diff --git a/src/libfwbuilder/src/fwbuilder/InetAddr.cpp b/src/libfwbuilder/src/fwbuilder/InetAddr.cpp index c70a34f47..e2614ce75 100644 --- a/src/libfwbuilder/src/fwbuilder/InetAddr.cpp +++ b/src/libfwbuilder/src/fwbuilder/InetAddr.cpp @@ -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()); } } diff --git a/src/libgui/AddressRangeDialog.cpp b/src/libgui/AddressRangeDialog.cpp index 94d8519c8..cd1feed9d 100644 --- a/src/libgui/AddressRangeDialog.cpp +++ b/src/libgui/AddressRangeDialog.cpp @@ -47,6 +47,7 @@ #include #include +#include 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;