mirror of
https://github.com/fwbuilder/fwbuilder
synced 2026-06-25 02:19:37 +02:00
refactored InetAddr class, removed Inet6Addr class; all address manipulation operators now work with both address families
This commit is contained in:
@@ -1,3 +1,14 @@
|
||||
2008-05-23 Vadim Kurland <vadim@vk.crocodile.org>
|
||||
|
||||
* InetAddr.h (libfwbuilder): Class InetAddr represents both IPv4
|
||||
and IPv6 addresses (depending on its member variable
|
||||
address_family). This simplifies design of the operators that
|
||||
perform address manipulations. The reason is that these operators
|
||||
should not modify object they are called with but rather return
|
||||
temporary object. The address family of this temporary object
|
||||
depends on address family of arguments, which makes it hard to
|
||||
use virtual operators.
|
||||
|
||||
2008-05-22 Vadim Kurland <vadim@vk.crocodile.org>
|
||||
|
||||
* Changes for IPv6 support. All compilers and OSConfigurator
|
||||
|
||||
@@ -92,7 +92,7 @@ void IPv6::fromXML(xmlNodePtr root) throw(FWException)
|
||||
|
||||
n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("address")));
|
||||
assert(n!=NULL);
|
||||
setAddress(Inet6Addr(n));
|
||||
setAddress(InetAddr(AF_INET6, n));
|
||||
FREEXMLBUFF(n);
|
||||
|
||||
n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("netmask")));
|
||||
@@ -101,15 +101,15 @@ void IPv6::fromXML(xmlNodePtr root) throw(FWException)
|
||||
{
|
||||
if (string(n).find(":")!=string::npos)
|
||||
{
|
||||
setNetmask(Inet6Addr(n));
|
||||
setNetmask(InetAddr(AF_INET6, n));
|
||||
} else
|
||||
{
|
||||
istringstream str(n);
|
||||
int netm;
|
||||
str >> netm;
|
||||
setNetmask(Inet6Addr(netm));
|
||||
setNetmask(InetAddr(AF_INET6, netm));
|
||||
}
|
||||
} else setNetmask(Inet6Addr(0));
|
||||
} else setNetmask(InetAddr(AF_INET6, 0));
|
||||
FREEXMLBUFF(n);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
|
||||
Firewall Builder
|
||||
|
||||
Copyright (C) 2008 NetCitadel, LLC
|
||||
|
||||
Author: Vadim Kurland vadim@vk.crocodile.org
|
||||
|
||||
$Id$
|
||||
|
||||
|
||||
This program is free software which we release under the GNU General Public
|
||||
License. You may redistribute and/or modify this program under the terms
|
||||
of that license as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
To get a copy of the GNU General Public License, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <fwbuilder/libfwbuilder-config.h>
|
||||
|
||||
#include <fwbuilder/Inet6Addr.h>
|
||||
#include <fwbuilder/Interface.h>
|
||||
#include <fwbuilder/inet_net.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <sys/types.h>
|
||||
# include <netinet/in.h>
|
||||
#else
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
namespace libfwbuilder
|
||||
{
|
||||
|
||||
Inet6Addr::Inet6Addr(const string &s)
|
||||
throw(FWException, FWNotSupportedException)
|
||||
{
|
||||
|
||||
if (inet_net_pton(PGSQL_AF_INET6, s.c_str(), &ipv6, sizeof(ipv6)) < 0)
|
||||
throw FWException(string("Invalid IPv6 address: '")+s+"'");
|
||||
}
|
||||
|
||||
Inet6Addr::Inet6Addr(const Inet6Addr &o) : InetAddr()
|
||||
{
|
||||
*this = o;
|
||||
}
|
||||
|
||||
Inet6Addr::Inet6Addr(const char *data) throw(FWException) : InetAddr()
|
||||
{
|
||||
if(!data)
|
||||
throw FWException("NULL IP address data..");
|
||||
if (inet_net_pton(PGSQL_AF_INET6, data, &ipv6, sizeof(ipv6)) < 0)
|
||||
throw FWException(string("Invalid IP address: '")+string(data)+"'");
|
||||
}
|
||||
|
||||
Inet6Addr::Inet6Addr(const struct in6_addr *na) throw(FWException) : InetAddr()
|
||||
{
|
||||
_copy_in6_addr(&ipv6, na);
|
||||
}
|
||||
|
||||
// Set netmask to 'n' bits
|
||||
Inet6Addr::Inet6Addr(int len) throw(FWException)
|
||||
{
|
||||
if (len<0 || len>128) throw FWException(string("Invalid netmask length"));
|
||||
|
||||
((uint32_t *) (&ipv6))[0] = 0xffffffff;
|
||||
((uint32_t *) (&ipv6))[1] = 0xffffffff;
|
||||
((uint32_t *) (&ipv6))[2] = 0xffffffff;
|
||||
((uint32_t *) (&ipv6))[3] = 0xffffffff;
|
||||
|
||||
// bits is number of zeros counting from the right end
|
||||
int nbits = 128 - len;
|
||||
for (int i=3; i>=0; --i)
|
||||
{
|
||||
if (nbits >= 32)
|
||||
{
|
||||
((uint32_t*)(&ipv6))[i] = 0;
|
||||
nbits -= 32;
|
||||
continue;
|
||||
}
|
||||
uint32_t t = 0xffffffff;
|
||||
for (int k = nbits % 32; k; --k)
|
||||
{
|
||||
t <<= 1;
|
||||
t &= 0xfffffffe;
|
||||
}
|
||||
((uint32_t*)(&ipv6))[i] = htonl(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Inet6Addr& Inet6Addr::operator=(const Inet6Addr &addr)
|
||||
{
|
||||
Inet6Addr::_copy_in6_addr(&ipv6, &(addr.ipv6) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
std::string Inet6Addr::toString() const
|
||||
{
|
||||
char ntop_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"];
|
||||
char *cp;
|
||||
cp = inet_net_ntop(PGSQL_AF_INET6, (const void*)(&ipv6), -1, ntop_buf, sizeof(ntop_buf));
|
||||
if (cp==NULL)
|
||||
{
|
||||
ostringstream err;
|
||||
switch (errno)
|
||||
{
|
||||
case EINVAL:
|
||||
err << "Inet6Addr::toString() Invalid bit length 0";
|
||||
throw FWException(err.str());
|
||||
;;
|
||||
case EMSGSIZE:
|
||||
err << "Inet6Addr::toString() EMSGSIZE error";
|
||||
throw FWException(err.str());
|
||||
;;
|
||||
case EAFNOSUPPORT:
|
||||
err << "Inet6Addr::toString() EAFNOSUPPORT error";
|
||||
throw FWException(err.str());
|
||||
;;
|
||||
default:
|
||||
err << "Inet6Addr::toString() other error: " << errno;
|
||||
throw FWException(err.str());
|
||||
;;
|
||||
}
|
||||
}
|
||||
return std::string(strdup(cp));
|
||||
}
|
||||
|
||||
|
||||
int Inet6Addr::getLength() const
|
||||
{
|
||||
int bits = 0;
|
||||
for (int i=3; i>=0; --i)
|
||||
{
|
||||
uint32_t n = ntohl(((uint32_t*)(&ipv6))[i]);
|
||||
if (n==0)
|
||||
{
|
||||
bits += 32;
|
||||
continue;
|
||||
}
|
||||
while ((n & 1) == 0)
|
||||
{
|
||||
bits++;
|
||||
n = n >> 1;
|
||||
}
|
||||
bits = 128 - bits;
|
||||
break;
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
|
||||
Inet6Addr operator~(const Inet6Addr &a)
|
||||
{
|
||||
struct in6_addr res;
|
||||
((uint32_t *) (&res))[0] = htonl(~(ntohl(((uint32_t *) (&a.ipv6))[0])));
|
||||
((uint32_t *) (&res))[1] = htonl(~(ntohl(((uint32_t *) (&a.ipv6))[1])));
|
||||
((uint32_t *) (&res))[2] = htonl(~(ntohl(((uint32_t *) (&a.ipv6))[2])));
|
||||
((uint32_t *) (&res))[3] = htonl(~(ntohl(((uint32_t *) (&a.ipv6))[3])));
|
||||
return Inet6Addr(&res);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
/*
|
||||
|
||||
Firewall Builder
|
||||
|
||||
Copyright (C) 2008 NetCitadel, LLC
|
||||
|
||||
Author: Vadim Kurland vadim@vk.crocodile.org
|
||||
|
||||
$Id$
|
||||
|
||||
|
||||
This program is free software which we release under the GNU General Public
|
||||
License. You may redistribute and/or modify this program under the terms
|
||||
of that license as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
To get a copy of the GNU General Public License, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __INET6ADDR_HH_FLAG__
|
||||
#define __INET6ADDR_HH_FLAG__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
#else
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include <fwbuilder/InetAddr.h>
|
||||
|
||||
namespace libfwbuilder
|
||||
{
|
||||
|
||||
/**
|
||||
* Class Inet6Addr is a wrapper for struct in6_addr
|
||||
*
|
||||
*/
|
||||
class Inet6Addr : public InetAddr
|
||||
{
|
||||
protected:
|
||||
|
||||
friend class IPv6Network;
|
||||
friend class Inet6AddrMask;
|
||||
|
||||
// Address in network order
|
||||
struct in6_addr ipv6;
|
||||
|
||||
// copy in6_addr from sa to da
|
||||
static inline void _copy_in6_addr(struct in6_addr* da,
|
||||
const struct in6_addr* sa)
|
||||
{
|
||||
((uint32_t*)(da))[0] = ((uint32_t*)(sa))[0];
|
||||
((uint32_t*)(da))[1] = ((uint32_t*)(sa))[1];
|
||||
((uint32_t*)(da))[2] = ((uint32_t*)(sa))[2];
|
||||
((uint32_t*)(da))[3] = ((uint32_t*)(sa))[3];
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
explicit Inet6Addr()
|
||||
{
|
||||
((uint32_t *) (&ipv6))[0] = 0;
|
||||
((uint32_t *) (&ipv6))[1] = 0;
|
||||
((uint32_t *) (&ipv6))[2] = 0;
|
||||
((uint32_t *) (&ipv6))[3] = 0;
|
||||
}
|
||||
|
||||
virtual ~Inet6Addr() {}
|
||||
|
||||
Inet6Addr(const char *data) throw(FWException);
|
||||
Inet6Addr(const struct in6_addr*) throw(FWException);
|
||||
explicit Inet6Addr(const std::string&)
|
||||
throw(FWException, FWNotSupportedException);
|
||||
Inet6Addr(const Inet6Addr &);
|
||||
Inet6Addr(int n) throw(FWException); // creates netmask 'n' bits long
|
||||
|
||||
Inet6Addr& operator=(const Inet6Addr &addr);
|
||||
|
||||
virtual bool isV4() const { return false; }
|
||||
virtual bool isV6() const { return true; }
|
||||
|
||||
static inline Inet6Addr getAny()
|
||||
{
|
||||
return Inet6Addr();
|
||||
}
|
||||
|
||||
static inline Inet6Addr getAllOnes()
|
||||
{
|
||||
struct in6_addr a;
|
||||
((uint32_t *) (&a))[0] = 0xffffffff;
|
||||
((uint32_t *) (&a))[1] = 0xffffffff;
|
||||
((uint32_t *) (&a))[2] = 0xffffffff;
|
||||
((uint32_t *) (&a))[3] = 0xffffffff;
|
||||
return Inet6Addr(&a);
|
||||
}
|
||||
|
||||
static inline Inet6Addr getLoopbackAddr()
|
||||
{
|
||||
struct in6_addr a;
|
||||
((uint32_t *) (&a))[0] = 0;
|
||||
((uint32_t *) (&a))[1] = 0;
|
||||
((uint32_t *) (&a))[2] = 0;
|
||||
((uint32_t *) (&a))[3] = htonl (1);
|
||||
return Inet6Addr(&a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast : there are no broadcast addresses in ipv6
|
||||
* However some multicast addresses serve similar purpose. For example
|
||||
* "link-scope all-hosts multicast" address ff02::1 corresponds to
|
||||
* the ipv4 broadcast 255.255.255.255
|
||||
*/
|
||||
inline virtual bool isBroadcast() const
|
||||
{
|
||||
return IN6_IS_ADDR_MC_LINKLOCAL(&ipv6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multicast
|
||||
*/
|
||||
inline virtual bool isMulticast() const
|
||||
{
|
||||
return IN6_IS_ADDR_MULTICAST(&ipv6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unspecified ipv6 address
|
||||
*/
|
||||
inline virtual bool isAny() const
|
||||
{
|
||||
return (IN6_IS_ADDR_UNSPECIFIED(&ipv6));
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate distance between _this_ address and address a2 and return
|
||||
* it as int.
|
||||
* This method is limited, it only calculates distance that fit in 32 bit
|
||||
* number
|
||||
*/
|
||||
inline virtual int distance(const Inet6Addr &a2)
|
||||
{
|
||||
uint32_t *d1 = (uint32_t *)(&ipv6);
|
||||
uint32_t *d2 = (uint32_t *)(&(a2.ipv6));
|
||||
return *d2 - *d1 + 1;
|
||||
}
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
/**
|
||||
* returns the "length" of the netmask, that is number of bits set to '1'
|
||||
* counting from left to right
|
||||
*/
|
||||
virtual int getLength() const;
|
||||
|
||||
/**
|
||||
* for netmasks: return true if this is host mask, i.e. all '1'
|
||||
*/
|
||||
inline bool isHostMask() const
|
||||
{
|
||||
return (((uint32_t*)(&ipv6))[0] == 0xffffffff &&
|
||||
((uint32_t*)(&ipv6))[1] == 0xffffffff &&
|
||||
((uint32_t*)(&ipv6))[2] == 0xffffffff &&
|
||||
((uint32_t*)(&ipv6))[3] == 0xffffffff);
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
inline friend Inet6Addr operator&(const Inet6Addr &addr,
|
||||
const Inet6Addr &mask)
|
||||
{
|
||||
struct in6_addr res;
|
||||
for (int i=0; i<4; ++i)
|
||||
((uint32_t*)(&res))[i] =
|
||||
htonl(ntohl(((uint32_t*)(&(addr.ipv6)))[i]) &
|
||||
ntohl(((uint32_t*)(&(mask.ipv6)))[i]));
|
||||
return Inet6Addr(&res);
|
||||
}
|
||||
|
||||
inline friend Inet6Addr operator|(const Inet6Addr &addr,
|
||||
const Inet6Addr &mask)
|
||||
{
|
||||
struct in6_addr res;
|
||||
for (int i=0; i<4; ++i)
|
||||
((uint32_t*)(&res))[i] =
|
||||
htonl(ntohl(((uint32_t*)(&(addr.ipv6)))[i]) |
|
||||
ntohl(((uint32_t*)(&(mask.ipv6)))[i]));
|
||||
return Inet6Addr(&res);
|
||||
}
|
||||
|
||||
inline friend Inet6Addr operator+(const Inet6Addr &addr, int increment)
|
||||
{
|
||||
struct in6_addr res;
|
||||
Inet6Addr::_copy_in6_addr(&res, &(addr.ipv6) );
|
||||
((uint32_t*)(&res))[3] =
|
||||
htonl(ntohl( ((uint32_t*)(&(addr.ipv6)))[3] + increment));
|
||||
return Inet6Addr(&res);
|
||||
}
|
||||
|
||||
inline friend Inet6Addr operator-(const Inet6Addr &addr,int decrement)
|
||||
{
|
||||
struct in6_addr res;
|
||||
Inet6Addr::_copy_in6_addr(&res, &(addr.ipv6) );
|
||||
((uint32_t*)(&res))[3] =
|
||||
htonl(ntohl( ((uint32_t*)(&(addr.ipv6)))[3] - decrement));
|
||||
return Inet6Addr(&res);
|
||||
}
|
||||
|
||||
inline friend bool operator<(const Inet6Addr &a, const Inet6Addr &b)
|
||||
{
|
||||
return (ntohl(((uint32_t*)(&(a.ipv6)))[3]) <
|
||||
ntohl(((uint32_t*)(&(b.ipv6)))[3]));
|
||||
}
|
||||
|
||||
inline friend bool operator>(const Inet6Addr &a, const Inet6Addr &b)
|
||||
{
|
||||
return (ntohl(((uint32_t*)(&(a.ipv6)))[3]) >
|
||||
ntohl(((uint32_t*)(&(b.ipv6)))[3]));
|
||||
}
|
||||
|
||||
inline friend bool operator==(const Inet6Addr &a, const Inet6Addr &b)
|
||||
{
|
||||
return (IN6_ARE_ADDR_EQUAL(&(a.ipv6), &(b.ipv6)));
|
||||
}
|
||||
|
||||
inline friend bool operator!=(const Inet6Addr &a, const Inet6Addr &b)
|
||||
{
|
||||
return (!(IN6_ARE_ADDR_EQUAL(&(a.ipv6), &(b.ipv6))));
|
||||
}
|
||||
|
||||
friend Inet6Addr operator~(const Inet6Addr &a);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -46,49 +46,15 @@
|
||||
using namespace std;
|
||||
using namespace libfwbuilder;
|
||||
|
||||
void Inet6AddrMask::setNetworkAndBroadcastAddress()
|
||||
Inet6AddrMask::Inet6AddrMask() : InetAddrMask()
|
||||
{
|
||||
delete network_address;
|
||||
network_address = new Inet6Addr(
|
||||
dynamic_cast<const Inet6Addr&>(*address) & dynamic_cast<const Inet6Addr&>(*netmask));
|
||||
delete broadcast_address;
|
||||
broadcast_address = new Inet6Addr(
|
||||
dynamic_cast<const Inet6Addr&>(*address) | (~(dynamic_cast<const Inet6Addr&>(*netmask))));
|
||||
address->address_family = AF_INET6;
|
||||
netmask->address_family = AF_INET6;
|
||||
setNetworkAndBroadcastAddress();
|
||||
}
|
||||
|
||||
Inet6AddrMask::Inet6AddrMask() : InetAddrMask(true)
|
||||
{
|
||||
address = new Inet6Addr();
|
||||
netmask = new Inet6Addr();
|
||||
broadcast_address = new Inet6Addr();
|
||||
network_address = new Inet6Addr();
|
||||
}
|
||||
|
||||
Inet6AddrMask::Inet6AddrMask(const Inet6Addr &a, const Inet6Addr &n) :
|
||||
Inet6AddrMask::Inet6AddrMask(const string &s) throw(FWException) :
|
||||
InetAddrMask(true)
|
||||
{
|
||||
address = new Inet6Addr(a & n);
|
||||
netmask = new Inet6Addr(n);
|
||||
broadcast_address = new Inet6Addr();
|
||||
network_address = new Inet6Addr();
|
||||
setNetworkAndBroadcastAddress();
|
||||
}
|
||||
|
||||
Inet6AddrMask::Inet6AddrMask(const Inet6AddrMask& other) : InetAddrMask(true)
|
||||
{
|
||||
Inet6Addr *i6_addr = dynamic_cast<Inet6Addr*>(other.address);
|
||||
assert(i6_addr);
|
||||
Inet6Addr *i6_nm = dynamic_cast<Inet6Addr*>(other.netmask);
|
||||
assert(i6_nm);
|
||||
|
||||
address = new Inet6Addr(*i6_addr);
|
||||
netmask = new Inet6Addr(*i6_nm);
|
||||
broadcast_address = new Inet6Addr();
|
||||
network_address = new Inet6Addr();
|
||||
setNetworkAndBroadcastAddress();
|
||||
}
|
||||
|
||||
Inet6AddrMask::Inet6AddrMask(const string &s) throw(FWException) : InetAddrMask(true)
|
||||
{
|
||||
struct in6_addr a_ipv6;
|
||||
int nbits;
|
||||
@@ -96,43 +62,30 @@ Inet6AddrMask::Inet6AddrMask(const string &s) throw(FWException) : InetAddrMask(
|
||||
if (nbits < 0)
|
||||
throw FWException(string("Invalid IP address: '") + s + "'");
|
||||
|
||||
address = new Inet6Addr(&a_ipv6);
|
||||
netmask = new Inet6Addr(nbits);
|
||||
address = new InetAddr(&a_ipv6);
|
||||
netmask = new InetAddr(AF_INET6, nbits);
|
||||
|
||||
broadcast_address = new Inet6Addr();
|
||||
network_address = new Inet6Addr();
|
||||
broadcast_address = new InetAddr();
|
||||
network_address = new InetAddr();
|
||||
setNetworkAndBroadcastAddress();
|
||||
}
|
||||
|
||||
Inet6AddrMask::Inet6AddrMask(const InetAddr &a, const InetAddr &n) :
|
||||
InetAddrMask(a, n)
|
||||
{
|
||||
}
|
||||
|
||||
Inet6AddrMask::~Inet6AddrMask()
|
||||
{
|
||||
// destructor of InetAddrMask deletes address, netmask
|
||||
// and other member variables
|
||||
}
|
||||
|
||||
void Inet6AddrMask::setAddress(const InetAddr &a)
|
||||
{
|
||||
assert(a.isV6());
|
||||
delete address;
|
||||
address = new Inet6Addr(dynamic_cast<const Inet6Addr&>(a));
|
||||
setNetworkAndBroadcastAddress();
|
||||
}
|
||||
|
||||
void Inet6AddrMask::setNetmask(const InetAddr &nm)
|
||||
{
|
||||
assert(nm.isV6());
|
||||
delete netmask;
|
||||
netmask = new Inet6Addr(dynamic_cast<const Inet6Addr&>(nm));
|
||||
setNetworkAndBroadcastAddress();
|
||||
}
|
||||
|
||||
|
||||
std::string Inet6AddrMask::toString() const
|
||||
{
|
||||
char ntop_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"];
|
||||
char *cp;
|
||||
cp = inet_net_ntop(PGSQL_AF_INET6,
|
||||
(const void*)(&(dynamic_cast<Inet6Addr*>(address)->ipv6)),
|
||||
cp = inet_net_ntop(PGSQL_AF_INET6, (const void*)(&(address->ipv6)),
|
||||
netmask->getLength(),
|
||||
ntop_buf, sizeof(ntop_buf));
|
||||
if (cp==NULL)
|
||||
|
||||
@@ -48,27 +48,20 @@
|
||||
|
||||
#include <fwbuilder/FWException.h>
|
||||
#include <fwbuilder/InetAddrMask.h>
|
||||
#include <fwbuilder/Inet6Addr.h>
|
||||
|
||||
namespace libfwbuilder
|
||||
{
|
||||
|
||||
class Inet6AddrMask : public InetAddrMask
|
||||
{
|
||||
private:
|
||||
void setNetworkAndBroadcastAddress();
|
||||
|
||||
public:
|
||||
|
||||
Inet6AddrMask();
|
||||
Inet6AddrMask(const Inet6Addr&, const Inet6Addr&);
|
||||
Inet6AddrMask(const std::string &s) throw(FWException);
|
||||
Inet6AddrMask(const Inet6AddrMask&);
|
||||
Inet6AddrMask(const InetAddr&, const InetAddr&);
|
||||
virtual ~Inet6AddrMask();
|
||||
|
||||
virtual void setAddress(const InetAddr &a);
|
||||
virtual void setNetmask(const InetAddr &nm);
|
||||
|
||||
virtual std::string toString() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -29,8 +29,11 @@
|
||||
#include <fwbuilder/InetAddr.h>
|
||||
#include <fwbuilder/Interface.h>
|
||||
|
||||
#include <fwbuilder/inet_net.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -41,18 +44,92 @@
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace libfwbuilder;
|
||||
|
||||
|
||||
namespace libfwbuilder
|
||||
void InetAddr::init_from_string(const char* data)
|
||||
{
|
||||
if(!data) throw FWException("NULL IP address data..");
|
||||
if (address_family == AF_INET)
|
||||
{
|
||||
if (inet_aton(data, &ipv4)==0)
|
||||
throw FWException(string("Invalid IP address: '")+string(data)+"'");
|
||||
} else
|
||||
{
|
||||
if (inet_net_pton(PGSQL_AF_INET6, data, &ipv6, sizeof(ipv6)) < 0)
|
||||
throw FWException(string("Invalid IPv6 address: '")+string(data)+"'");
|
||||
}
|
||||
}
|
||||
|
||||
void InetAddr::init_from_int(int len)
|
||||
{
|
||||
if (address_family == AF_INET)
|
||||
{
|
||||
if (len<0 || len>32) throw FWException(string("Invalid netmask length"));
|
||||
unsigned long nm_bits = 0;
|
||||
int i = len;
|
||||
while (i>0)
|
||||
{
|
||||
nm_bits >>= 1;
|
||||
nm_bits |= 0x80000000;
|
||||
i--;
|
||||
}
|
||||
ipv4.s_addr = htonl(nm_bits);
|
||||
} else
|
||||
{
|
||||
if (len<0 || len>128)
|
||||
throw FWException(string("Invalid netmask length"));
|
||||
|
||||
((uint32_t *) (&ipv6))[0] = 0xffffffff;
|
||||
((uint32_t *) (&ipv6))[1] = 0xffffffff;
|
||||
((uint32_t *) (&ipv6))[2] = 0xffffffff;
|
||||
((uint32_t *) (&ipv6))[3] = 0xffffffff;
|
||||
|
||||
// bits is number of zeros counting from the right end
|
||||
int nbits = 128 - len;
|
||||
for (int i=3; i>=0; --i)
|
||||
{
|
||||
if (nbits >= 32)
|
||||
{
|
||||
((uint32_t*)(&ipv6))[i] = 0;
|
||||
nbits -= 32;
|
||||
continue;
|
||||
}
|
||||
uint32_t t = 0xffffffff;
|
||||
for (int k = nbits % 32; k; --k)
|
||||
{
|
||||
t <<= 1;
|
||||
t &= 0xfffffffe;
|
||||
}
|
||||
((uint32_t*)(&ipv6))[i] = htonl(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
InetAddr::InetAddr(const string &s)
|
||||
throw(FWException, FWNotSupportedException)
|
||||
{
|
||||
address_family = AF_INET;
|
||||
if (inet_aton(s.c_str(), &ipv4)==0)
|
||||
throw FWException(string("Invalid IP address: '")+s+"'");
|
||||
}
|
||||
|
||||
InetAddr::InetAddr(int af, const string &s)
|
||||
throw(FWException, FWNotSupportedException)
|
||||
{
|
||||
address_family = af;
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
if (inet_aton(s.c_str(), &ipv4)==0)
|
||||
throw FWException(string("Invalid IP address: '")+s+"'");
|
||||
} else
|
||||
{
|
||||
if (inet_net_pton(PGSQL_AF_INET6, s.c_str(), &ipv6, sizeof(ipv6)) < 0)
|
||||
throw FWException(string("Invalid IPv6 address: '")+s+"'");
|
||||
}
|
||||
}
|
||||
|
||||
InetAddr::InetAddr(const InetAddr &o)
|
||||
{
|
||||
*this = o;
|
||||
@@ -60,54 +137,268 @@ InetAddr::InetAddr(const InetAddr &o)
|
||||
|
||||
InetAddr::InetAddr(const char *data) throw(FWException)
|
||||
{
|
||||
if(!data)
|
||||
throw FWException("NULL IP address data..");
|
||||
if (inet_aton(data, &ipv4)==0)
|
||||
throw FWException(string("Invalid IP address: '")+string(data)+"'");
|
||||
address_family = AF_INET;
|
||||
init_from_string(data);
|
||||
}
|
||||
|
||||
InetAddr::InetAddr(int af, const char *data) throw(FWException)
|
||||
{
|
||||
address_family = af;
|
||||
init_from_string(data);
|
||||
}
|
||||
|
||||
InetAddr::InetAddr(const struct in_addr *na) throw(FWException)
|
||||
{
|
||||
address_family = AF_INET;
|
||||
ipv4.s_addr = na->s_addr;
|
||||
}
|
||||
|
||||
InetAddr::InetAddr(const struct in6_addr *na) throw(FWException)
|
||||
{
|
||||
address_family = AF_INET6;
|
||||
_copy_in6_addr(&ipv6, na);
|
||||
}
|
||||
|
||||
// Set netmask to 'n' bits
|
||||
InetAddr::InetAddr(int n) throw(FWException)
|
||||
{
|
||||
if (n<0 || n>32) throw FWException(string("Invalid netmask length"));
|
||||
unsigned long nm_bits = 0;
|
||||
int i = n;
|
||||
while (i>0)
|
||||
{
|
||||
nm_bits >>= 1;
|
||||
nm_bits |= 0x80000000;
|
||||
i--;
|
||||
}
|
||||
ipv4.s_addr = htonl(nm_bits);
|
||||
address_family = AF_INET;
|
||||
init_from_int(n);
|
||||
}
|
||||
|
||||
InetAddr::InetAddr(int af, int n) throw(FWException)
|
||||
{
|
||||
address_family = af;
|
||||
init_from_int(n);
|
||||
}
|
||||
|
||||
InetAddr& InetAddr::operator=(const InetAddr &addr)
|
||||
{
|
||||
ipv4.s_addr = addr.ipv4.s_addr;
|
||||
if ((address_family = addr.address_family)==AF_INET)
|
||||
{
|
||||
ipv4.s_addr = addr.ipv4.s_addr;
|
||||
} else
|
||||
{
|
||||
InetAddr::_copy_in6_addr(&ipv6, &(addr.ipv6) );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
int InetAddr::getLength() const
|
||||
{
|
||||
if (ipv4.s_addr == INADDR_BROADCAST) return 32;
|
||||
if (ipv4.s_addr == 0) return 0;
|
||||
|
||||
unsigned int n = ntohl(ipv4.s_addr);
|
||||
|
||||
int i=0;
|
||||
while (n)
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
n=n<<1;
|
||||
i++;
|
||||
if (ipv4.s_addr == INADDR_BROADCAST) return 32;
|
||||
if (ipv4.s_addr == 0) return 0;
|
||||
|
||||
unsigned int n = ntohl(ipv4.s_addr);
|
||||
|
||||
int i=0;
|
||||
while (n)
|
||||
{
|
||||
n=n<<1;
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
} else
|
||||
{
|
||||
int bits = 0;
|
||||
for (int i=3; i>=0; --i)
|
||||
{
|
||||
uint32_t n = ntohl(((uint32_t*)(&ipv6))[i]);
|
||||
if (n==0)
|
||||
{
|
||||
bits += 32;
|
||||
continue;
|
||||
}
|
||||
while ((n & 1) == 0)
|
||||
{
|
||||
bits++;
|
||||
n = n >> 1;
|
||||
}
|
||||
bits = 128 - bits;
|
||||
break;
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
string InetAddr::toString() const
|
||||
{
|
||||
if (address_family==AF_INET) return std::string(strdup(inet_ntoa(ipv4)));
|
||||
else
|
||||
{
|
||||
char ntop_buf[sizeof
|
||||
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"];
|
||||
char *cp;
|
||||
cp = inet_net_ntop(PGSQL_AF_INET6, (const void*)(&ipv6),
|
||||
-1, ntop_buf, sizeof(ntop_buf));
|
||||
if (cp==NULL)
|
||||
{
|
||||
ostringstream err;
|
||||
switch (errno)
|
||||
{
|
||||
case EINVAL:
|
||||
err << "InetAddr::toString() Invalid bit length 0";
|
||||
throw FWException(err.str());
|
||||
;;
|
||||
case EMSGSIZE:
|
||||
err << "InetAddr::toString() EMSGSIZE error";
|
||||
throw FWException(err.str());
|
||||
;;
|
||||
case EAFNOSUPPORT:
|
||||
err << "InetAddr::toString() EAFNOSUPPORT error";
|
||||
throw FWException(err.str());
|
||||
;;
|
||||
default:
|
||||
err << "InetAddr::toString() other error: " << errno;
|
||||
throw FWException(err.str());
|
||||
;;
|
||||
}
|
||||
}
|
||||
return std::string(strdup(cp));
|
||||
}
|
||||
}
|
||||
|
||||
// note that address family of the result is dictated by the address family of
|
||||
// "this". Address family of mask must be the same.
|
||||
InetAddr InetAddr::opAnd(const InetAddr &mask) const
|
||||
{
|
||||
assert(address_family==mask.address_family);
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
struct in_addr res;
|
||||
res.s_addr = htonl(ntohl(ipv4.s_addr) & ntohl(mask.ipv4.s_addr));
|
||||
return InetAddr(&res);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
InetAddr InetAddr::opOr(const InetAddr &mask) const
|
||||
{
|
||||
assert(address_family==mask.address_family);
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
struct in_addr res;
|
||||
res.s_addr = htonl(ntohl(ipv4.s_addr) | ntohl(mask.ipv4.s_addr));
|
||||
return InetAddr(&res);
|
||||
} else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
InetAddr InetAddr::opPlus(int increment) const
|
||||
{
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
struct in_addr res;
|
||||
res.s_addr = htonl(ntohl(ipv4.s_addr) + increment);
|
||||
return InetAddr(&res);
|
||||
} else
|
||||
{
|
||||
struct in6_addr res;
|
||||
InetAddr::_copy_in6_addr(&res, &(ipv6) );
|
||||
((uint32_t*)(&res))[3] =
|
||||
htonl(ntohl( ((uint32_t*)(&(ipv6)))[3] + increment));
|
||||
return InetAddr(&res);
|
||||
}
|
||||
}
|
||||
|
||||
InetAddr InetAddr::opMinus(int decrement) const
|
||||
{
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
struct in_addr res;
|
||||
res.s_addr = htonl(ntohl(ipv4.s_addr) - decrement);
|
||||
return InetAddr(&res);
|
||||
} else
|
||||
{
|
||||
struct in6_addr res;
|
||||
InetAddr::_copy_in6_addr(&res, &(ipv6) );
|
||||
((uint32_t*)(&res))[3] =
|
||||
htonl(ntohl( ((uint32_t*)(&(ipv6)))[3] - decrement));
|
||||
return InetAddr(&res);
|
||||
}
|
||||
}
|
||||
|
||||
bool InetAddr::opLT(const InetAddr &other) const
|
||||
{
|
||||
assert(address_family==other.address_family);
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
return (ntohl( ipv4.s_addr ) < ntohl( other.ipv4.s_addr ));
|
||||
} else
|
||||
{
|
||||
return (ntohl(((uint32_t*)(&(ipv6)))[3]) <
|
||||
ntohl(((uint32_t*)(&(other.ipv6)))[3]));
|
||||
}
|
||||
}
|
||||
|
||||
bool InetAddr::opGT(const InetAddr &other) const
|
||||
{
|
||||
assert(address_family==other.address_family);
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
return (ntohl( ipv4.s_addr ) > ntohl( other.ipv4.s_addr ));
|
||||
} else
|
||||
{
|
||||
return (ntohl(((uint32_t*)(&(ipv6)))[3]) >
|
||||
ntohl(((uint32_t*)(&(other.ipv6)))[3]));
|
||||
}
|
||||
}
|
||||
|
||||
bool InetAddr::opEQ(const InetAddr &other) const
|
||||
{
|
||||
assert(address_family==other.address_family);
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
return ipv4.s_addr == other.ipv4.s_addr;
|
||||
} else
|
||||
{
|
||||
return (IN6_ARE_ADDR_EQUAL(&(ipv6), &(other.ipv6)));
|
||||
}
|
||||
}
|
||||
|
||||
bool InetAddr::opNEQ(const InetAddr &other) const
|
||||
{
|
||||
assert(address_family==other.address_family);
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
return ipv4.s_addr != other.ipv4.s_addr;
|
||||
} else
|
||||
{
|
||||
return (!(IN6_ARE_ADDR_EQUAL(&(ipv6), &(other.ipv6))));
|
||||
}
|
||||
}
|
||||
|
||||
InetAddr InetAddr::opCompl() const
|
||||
{
|
||||
if (address_family==AF_INET)
|
||||
{
|
||||
struct in_addr res;
|
||||
res.s_addr = htonl(~(ntohl(ipv4.s_addr)));
|
||||
return InetAddr(&res);
|
||||
} else
|
||||
{
|
||||
struct in6_addr res;
|
||||
((uint32_t *) (&res))[0] = htonl(~(ntohl(((uint32_t *) (&ipv6))[0])));
|
||||
((uint32_t *) (&res))[1] = htonl(~(ntohl(((uint32_t *) (&ipv6))[1])));
|
||||
((uint32_t *) (&res))[2] = htonl(~(ntohl(((uint32_t *) (&ipv6))[2])));
|
||||
((uint32_t *) (&res))[3] = htonl(~(ntohl(((uint32_t *) (&ipv6))[3])));
|
||||
return InetAddr(&res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <typeinfo>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <sys/types.h>
|
||||
@@ -45,7 +47,15 @@ namespace libfwbuilder
|
||||
{
|
||||
|
||||
/**
|
||||
* Class InetAddr is a wrapper for struct inet_addr
|
||||
* Class InetAddr is a wrapper for struct inet_addr and in6_addr
|
||||
*
|
||||
* Why both address families are implemented as the same class ? Mostly
|
||||
* because I need to have a family of two-argument operators such as
|
||||
* operator&, operator| etc which return new object of the class that
|
||||
* represent the same address family as the arguments. These operators
|
||||
* should be "friends" of class InetAddr since they return new object
|
||||
* by value rather than modify "this". But how to do it if returned
|
||||
* type should be different depending on the types of arguments ?
|
||||
*
|
||||
*/
|
||||
class InetAddr
|
||||
@@ -53,158 +63,250 @@ class InetAddr
|
||||
protected:
|
||||
|
||||
friend class InetAddrMask;
|
||||
friend class Inet6AddrMask;
|
||||
|
||||
int address_family;
|
||||
// Address in network order
|
||||
struct in_addr ipv4;
|
||||
struct in_addr ipv4;
|
||||
struct in6_addr ipv6;
|
||||
|
||||
// copy in6_addr from sa to da
|
||||
static inline void _copy_in6_addr(struct in6_addr* da,
|
||||
const struct in6_addr* sa)
|
||||
{
|
||||
((uint32_t*)(da))[0] = ((uint32_t*)(sa))[0];
|
||||
((uint32_t*)(da))[1] = ((uint32_t*)(sa))[1];
|
||||
((uint32_t*)(da))[2] = ((uint32_t*)(sa))[2];
|
||||
((uint32_t*)(da))[3] = ((uint32_t*)(sa))[3];
|
||||
}
|
||||
|
||||
void init_from_string(const char* data);
|
||||
void init_from_int(int n);
|
||||
|
||||
public:
|
||||
|
||||
explicit InetAddr() { ipv4.s_addr = 0; }
|
||||
explicit InetAddr()
|
||||
{
|
||||
address_family = AF_INET;
|
||||
ipv4.s_addr = 0;
|
||||
((uint32_t *) (&ipv6))[0] = 0;
|
||||
((uint32_t *) (&ipv6))[1] = 0;
|
||||
((uint32_t *) (&ipv6))[2] = 0;
|
||||
((uint32_t *) (&ipv6))[3] = 0;
|
||||
}
|
||||
|
||||
virtual ~InetAddr() {}
|
||||
|
||||
InetAddr(const char *data) throw(FWException);
|
||||
InetAddr(int af, const char *data) throw(FWException);
|
||||
InetAddr(const struct in_addr*) throw(FWException);
|
||||
InetAddr(const struct in6_addr*) throw(FWException);
|
||||
explicit InetAddr(const std::string&)
|
||||
throw(FWException, FWNotSupportedException);
|
||||
explicit InetAddr(int af, const std::string&)
|
||||
throw(FWException, FWNotSupportedException);
|
||||
InetAddr(const InetAddr &);
|
||||
|
||||
// creates netmask 'n' bits long
|
||||
explicit InetAddr(int n) throw(FWException);
|
||||
explicit InetAddr(int af, int n) throw(FWException);
|
||||
|
||||
InetAddr& operator=(const InetAddr &addr);
|
||||
|
||||
virtual bool isV4() const { return true; }
|
||||
virtual bool isV6() const { return false; }
|
||||
bool isV4() const { return (address_family==AF_INET); }
|
||||
bool isV6() const { return (address_family==AF_INET6); }
|
||||
|
||||
static inline InetAddr getAny()
|
||||
{
|
||||
return InetAddr();
|
||||
}
|
||||
|
||||
static inline InetAddr getAllOnes()
|
||||
static inline InetAddr getAllOnes(int af=AF_INET)
|
||||
{
|
||||
struct in_addr allones;
|
||||
allones.s_addr = 0xffffffff;
|
||||
return InetAddr(&allones);
|
||||
if (af==AF_INET)
|
||||
{
|
||||
struct in_addr allones;
|
||||
allones.s_addr = 0xffffffff;
|
||||
return InetAddr(&allones);
|
||||
} else
|
||||
{
|
||||
struct in6_addr a;
|
||||
((uint32_t *) (&a))[0] = 0xffffffff;
|
||||
((uint32_t *) (&a))[1] = 0xffffffff;
|
||||
((uint32_t *) (&a))[2] = 0xffffffff;
|
||||
((uint32_t *) (&a))[3] = 0xffffffff;
|
||||
return InetAddr(&a);
|
||||
}
|
||||
}
|
||||
|
||||
static inline InetAddr getLoopbackAddr()
|
||||
static inline InetAddr getLoopbackAddr(int af=AF_INET)
|
||||
{
|
||||
struct in_addr loopback;
|
||||
loopback.s_addr = htonl(INADDR_LOOPBACK);
|
||||
return InetAddr(&loopback);
|
||||
if (af==AF_INET)
|
||||
{
|
||||
struct in_addr loopback;
|
||||
loopback.s_addr = htonl(INADDR_LOOPBACK);
|
||||
return InetAddr(&loopback);
|
||||
} else
|
||||
{
|
||||
struct in6_addr a;
|
||||
((uint32_t *) (&a))[0] = 0;
|
||||
((uint32_t *) (&a))[1] = 0;
|
||||
((uint32_t *) (&a))[2] = 0;
|
||||
((uint32_t *) (&a))[3] = htonl (1);
|
||||
return InetAddr(&a);
|
||||
}
|
||||
}
|
||||
|
||||
inline virtual std::string toString() const
|
||||
{
|
||||
return std::string(strdup(inet_ntoa(ipv4)));
|
||||
}
|
||||
std::string toString() const;
|
||||
|
||||
/**
|
||||
* Broadcast : 255.255.255.255
|
||||
*
|
||||
* there are no broadcast addresses in ipv6. However some multicast
|
||||
* addresses serve similar purpose. For example "link-scope
|
||||
* all-hosts multicast" address ff02::1 corresponds to the ipv4
|
||||
* broadcast 255.255.255.255
|
||||
*/
|
||||
inline virtual bool isBroadcast() const
|
||||
inline bool isBroadcast() const
|
||||
{
|
||||
return ipv4.s_addr == INADDR_BROADCAST;
|
||||
if (address_family==AF_INET)
|
||||
return ipv4.s_addr == INADDR_BROADCAST;
|
||||
else
|
||||
return IN6_IS_ADDR_MC_LINKLOCAL(&ipv6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multicast : 224.0.0.0 - 239.0.0.0
|
||||
*/
|
||||
inline virtual bool isMulticast() const
|
||||
inline bool isMulticast() const
|
||||
{
|
||||
return IN_MULTICAST(ntohl(ipv4.s_addr));
|
||||
if (address_family==AF_INET)
|
||||
return IN_MULTICAST(ntohl(ipv4.s_addr));
|
||||
else
|
||||
return IN6_IS_ADDR_MULTICAST(&ipv6);
|
||||
}
|
||||
|
||||
/**
|
||||
* INADDR_ANY: 0
|
||||
*/
|
||||
inline virtual bool isAny() const
|
||||
inline bool isAny() const
|
||||
{
|
||||
return ipv4.s_addr == INADDR_ANY;
|
||||
if (address_family==AF_INET)
|
||||
return ipv4.s_addr == INADDR_ANY;
|
||||
else
|
||||
return (IN6_IS_ADDR_UNSPECIFIED(&ipv6));
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate distance between _this_ address and address a2 and return
|
||||
* it as int
|
||||
* This method is limited, it only calculates distance that fit in 32 bit
|
||||
* number
|
||||
*/
|
||||
inline virtual int distance(const InetAddr &a2) const
|
||||
inline int distance(const InetAddr &a2) const
|
||||
{
|
||||
return ntohl(a2.ipv4.s_addr) - ntohl(ipv4.s_addr) + 1;
|
||||
if (address_family==AF_INET)
|
||||
return ntohl(a2.ipv4.s_addr) - ntohl(ipv4.s_addr) + 1;
|
||||
else
|
||||
{
|
||||
uint32_t *d1 = (uint32_t *)(&ipv6);
|
||||
uint32_t *d2 = (uint32_t *)(&(a2.ipv6));
|
||||
return *d2 - *d1 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the "length" of the netmask, that is number of bits set to '1'
|
||||
* counting from left to right
|
||||
*/
|
||||
virtual int getLength() const;
|
||||
int getLength() const;
|
||||
|
||||
/**
|
||||
* for netmasks: return true if this is host mask, i.e. all '1'
|
||||
*/
|
||||
inline bool isHostMask() const
|
||||
{
|
||||
return ipv4.s_addr == INADDR_BROADCAST;
|
||||
if (address_family==AF_INET)
|
||||
return ipv4.s_addr == INADDR_BROADCAST;
|
||||
else
|
||||
return (((uint32_t*)(&ipv6))[0] == 0xffffffff &&
|
||||
((uint32_t*)(&ipv6))[1] == 0xffffffff &&
|
||||
((uint32_t*)(&ipv6))[2] == 0xffffffff &&
|
||||
((uint32_t*)(&ipv6))[3] == 0xffffffff);
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
InetAddr opAnd(const InetAddr &mask) const;
|
||||
|
||||
InetAddr opOr(const InetAddr &mask) const;
|
||||
|
||||
InetAddr opPlus(int increment) const;
|
||||
|
||||
InetAddr opMinus(int decrement) const;
|
||||
|
||||
bool opLT(const InetAddr &other) const;
|
||||
|
||||
bool opGT(const InetAddr &other) const;
|
||||
|
||||
bool opEQ(const InetAddr &other) const;
|
||||
|
||||
bool opNEQ(const InetAddr &other) const;
|
||||
|
||||
InetAddr opCompl() const;
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
inline friend InetAddr operator&(const InetAddr &addr,
|
||||
const InetAddr &mask)
|
||||
{
|
||||
struct in_addr res;
|
||||
res.s_addr = htonl(ntohl(addr.ipv4.s_addr) & ntohl(mask.ipv4.s_addr));
|
||||
return InetAddr(&res);
|
||||
assert (typeid(addr) == typeid(mask));
|
||||
return addr.opAnd(mask);
|
||||
}
|
||||
|
||||
inline friend InetAddr operator|(const InetAddr &addr,
|
||||
const InetAddr &mask)
|
||||
{
|
||||
struct in_addr res;
|
||||
res.s_addr = htonl(ntohl(addr.ipv4.s_addr) | ntohl(mask.ipv4.s_addr));
|
||||
return InetAddr(&res);
|
||||
assert (typeid(addr) == typeid(mask));
|
||||
return addr.opOr(mask);
|
||||
}
|
||||
|
||||
inline friend InetAddr operator+(const InetAddr &addr, int increment)
|
||||
{
|
||||
struct in_addr res;
|
||||
res.s_addr = htonl(ntohl(addr.ipv4.s_addr) + increment);
|
||||
return InetAddr(&res);
|
||||
return addr.opPlus(increment);
|
||||
}
|
||||
|
||||
inline friend InetAddr operator-(const InetAddr &addr,int decrement)
|
||||
inline friend InetAddr operator-(const InetAddr &addr, int decrement)
|
||||
{
|
||||
struct in_addr res;
|
||||
res.s_addr = htonl(ntohl(addr.ipv4.s_addr) - decrement);
|
||||
return InetAddr(&res);
|
||||
return addr.opMinus(decrement);
|
||||
}
|
||||
|
||||
inline friend bool operator<(const InetAddr &a, const InetAddr &b)
|
||||
{
|
||||
return (ntohl( a.ipv4.s_addr ) < ntohl( b.ipv4.s_addr ));
|
||||
assert (typeid(a) == typeid(b));
|
||||
return a.opLT(b);
|
||||
}
|
||||
|
||||
inline friend bool operator>(const InetAddr &a, const InetAddr &b)
|
||||
{
|
||||
return (ntohl( a.ipv4.s_addr ) > ntohl( b.ipv4.s_addr ));
|
||||
assert (typeid(a) == typeid(b));
|
||||
return a.opGT(b);
|
||||
}
|
||||
|
||||
inline friend bool operator==(const InetAddr &a, const InetAddr &b)
|
||||
{
|
||||
return a.ipv4.s_addr == b.ipv4.s_addr;
|
||||
assert (typeid(a) == typeid(b));
|
||||
return a.opEQ(b);
|
||||
}
|
||||
|
||||
inline friend bool operator!=(const InetAddr &a, const InetAddr &b)
|
||||
{
|
||||
return a.ipv4.s_addr != b.ipv4.s_addr;
|
||||
assert (typeid(a) == typeid(b));
|
||||
return a.opNEQ(b);
|
||||
}
|
||||
|
||||
inline friend InetAddr operator~(const InetAddr &a)
|
||||
{
|
||||
struct in_addr res;
|
||||
res.s_addr = htonl(~(ntohl(a.ipv4.s_addr)));
|
||||
return InetAddr(&res);
|
||||
return a.opCompl();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -135,14 +135,12 @@ InetAddrMask::~InetAddrMask()
|
||||
|
||||
void InetAddrMask::setAddress(const InetAddr &a)
|
||||
{
|
||||
assert(a.isV4());
|
||||
*address = a;
|
||||
setNetworkAndBroadcastAddress();
|
||||
}
|
||||
|
||||
void InetAddrMask::setNetmask(const InetAddr &nm)
|
||||
{
|
||||
assert(nm.isV4());
|
||||
*netmask = nm;
|
||||
setNetworkAndBroadcastAddress();
|
||||
}
|
||||
|
||||
@@ -67,8 +67,6 @@ namespace libfwbuilder
|
||||
|
||||
class InetAddrMask
|
||||
{
|
||||
private:
|
||||
void setNetworkAndBroadcastAddress();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -86,6 +84,7 @@ public:
|
||||
InetAddrMask(const std::string &s) throw(FWException);
|
||||
InetAddrMask(const InetAddrMask&);
|
||||
virtual ~InetAddrMask();
|
||||
void setNetworkAndBroadcastAddress();
|
||||
|
||||
virtual const InetAddr* getAddressPtr() const { return address; }
|
||||
virtual const InetAddr* getNetmaskPtr() const { return netmask; }
|
||||
|
||||
@@ -84,7 +84,7 @@ void NetworkIPv6::fromXML(xmlNodePtr root) throw(FWException)
|
||||
|
||||
const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("address")));
|
||||
assert(n!=NULL);
|
||||
setAddress(Inet6Addr(n));
|
||||
setAddress(InetAddr(AF_INET6, n));
|
||||
FREEXMLBUFF(n);
|
||||
|
||||
n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("netmask")));
|
||||
@@ -93,15 +93,15 @@ void NetworkIPv6::fromXML(xmlNodePtr root) throw(FWException)
|
||||
{
|
||||
if (string(n).find(":")!=string::npos)
|
||||
{
|
||||
setNetmask(Inet6Addr(n));
|
||||
setNetmask(InetAddr(AF_INET6, n));
|
||||
} else
|
||||
{
|
||||
istringstream str(n);
|
||||
int netm;
|
||||
str >> netm;
|
||||
setNetmask(Inet6Addr(netm));
|
||||
setNetmask(InetAddr(AF_INET6, netm));
|
||||
}
|
||||
} else setNetmask(Inet6Addr(0));
|
||||
} else setNetmask(InetAddr(AF_INET6, 0));
|
||||
FREEXMLBUFF(n);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ VERSION = $$SO_VERSION
|
||||
SOURCES = inet_net_ntop.c \
|
||||
inet_net_pton.c \
|
||||
InetAddr.cpp \
|
||||
Inet6Addr.cpp \
|
||||
InetAddrMask.cpp \
|
||||
Inet6AddrMask.cpp \
|
||||
IPRoute.cpp \
|
||||
@@ -68,7 +67,6 @@ SOURCES = inet_net_ntop.c \
|
||||
|
||||
HEADERS = inet_net.h \
|
||||
InetAddr.h \
|
||||
Inet6Addr.h \
|
||||
InetAddrMask.h \
|
||||
Inet6AddrMask.h \
|
||||
IPRoute.h \
|
||||
|
||||
@@ -80,30 +80,30 @@ int main(int, char * const *)
|
||||
cout << endl;
|
||||
cout << "Start test for Inet6AddrMask" << endl;
|
||||
|
||||
Inet6Addr x1(0);
|
||||
InetAddr x1(AF_INET6, 0);
|
||||
cout << "Inet6Addr::Inet6Addr(0) "
|
||||
<< x1.toString() << " length=" << x1.getLength() << endl;
|
||||
|
||||
Inet6Addr x2(8);
|
||||
InetAddr x2(AF_INET6, 8);
|
||||
cout << "Inet6Addr::Inet6Addr(8) "
|
||||
<< x2.toString() << " length=" << x2.getLength() << endl;
|
||||
|
||||
Inet6Addr x3(16);
|
||||
InetAddr x3(AF_INET6, 16);
|
||||
cout << "Inet6Addr::Inet6Addr(16) "
|
||||
<< x3.toString() << " length=" << x3.getLength() << endl;
|
||||
|
||||
Inet6Addr x4(64);
|
||||
InetAddr x4(AF_INET6, 64);
|
||||
cout << "Inet6Addr::Inet6Addr(64) "
|
||||
<< x4.toString() << " length=" << x4.getLength() << endl;
|
||||
|
||||
Inet6Addr x5(128);
|
||||
InetAddr x5(AF_INET6, 128);
|
||||
cout << "Inet6Addr::Inet6Addr(128) "
|
||||
<< x5.toString() << " length=" << x5.getLength() << endl;
|
||||
|
||||
|
||||
Inet6Addr x6("fe80::21d:9ff:fe8b:8e94");
|
||||
Inet6Addr y6(64);
|
||||
Inet6Addr z = x6 & y6;
|
||||
InetAddr x6(AF_INET6, "fe80::21d:9ff:fe8b:8e94");
|
||||
InetAddr y6(AF_INET6, 64);
|
||||
InetAddr z = x6 & y6;
|
||||
|
||||
cout << "z=" << z.toString() << endl;
|
||||
assert(z.toString()=="fe80::");
|
||||
@@ -115,7 +115,7 @@ int main(int, char * const *)
|
||||
cout << endl;
|
||||
|
||||
Inet6AddrMask *a1 = new Inet6AddrMask();
|
||||
sa = a1->getAddress().toString();
|
||||
sa = a1->getAddressPtr()->toString();
|
||||
cout << "a1=" << sa << endl;
|
||||
assert(sa=="::");
|
||||
// assert(a1->dimension()==0);
|
||||
@@ -123,16 +123,18 @@ int main(int, char * const *)
|
||||
|
||||
cout << endl;
|
||||
|
||||
Inet6AddrMask *a2 = new Inet6AddrMask(Inet6Addr("fe80::21d:9ff:fe8b:8e94"),
|
||||
Inet6Addr(128));
|
||||
sa = a2->getAddress().toString();
|
||||
Inet6AddrMask *a2 = new Inet6AddrMask(
|
||||
InetAddr(AF_INET6, "fe80::21d:9ff:fe8b:8e94"),
|
||||
InetAddr(AF_INET6, 128));
|
||||
|
||||
sa = a2->getAddressPtr()->toString();
|
||||
cout << "a2.address=" << sa << endl;
|
||||
assert(sa=="fe80::21d:9ff:fe8b:8e94");
|
||||
sa = a2->getNetmask().toString();
|
||||
sa = a2->getNetmaskPtr()->toString();
|
||||
cout << "a2.netmask=" << sa
|
||||
<< " length=" << a2->getNetmask().getLength() << endl;
|
||||
<< " length=" << a2->getNetmaskPtr()->getLength() << endl;
|
||||
assert(sa=="ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
|
||||
assert(a2->getNetmask().getLength()==128);
|
||||
assert(a2->getNetmaskPtr()->getLength()==128);
|
||||
|
||||
// assert(a2->dimension()==18446744073709551616);
|
||||
|
||||
@@ -142,17 +144,19 @@ int main(int, char * const *)
|
||||
|
||||
cout << endl;
|
||||
|
||||
Inet6AddrMask *a3 = new Inet6AddrMask(Inet6Addr("fe80::21d:9ff:fe8b:8e94"),
|
||||
Inet6Addr(128));
|
||||
a3->setNetmask(Inet6Addr(64));
|
||||
sa = a3->getAddress().toString();
|
||||
Inet6AddrMask *a3 = new Inet6AddrMask(
|
||||
InetAddr(AF_INET6, "fe80::21d:9ff:fe8b:8e94"),
|
||||
InetAddr(AF_INET6, 128));
|
||||
|
||||
a3->setNetmask(InetAddr(AF_INET6, 64));
|
||||
sa = a3->getAddressPtr()->toString();
|
||||
cout << "a3.address=" << sa << endl;
|
||||
assert(sa=="fe80::21d:9ff:fe8b:8e94");
|
||||
sa = a3->getNetmask().toString();
|
||||
sa = a3->getNetmaskPtr()->toString();
|
||||
cout << "a3.netmask=" << sa
|
||||
<< " length=" << a3->getNetmask().getLength() << endl;
|
||||
<< " length=" << a3->getNetmaskPtr()->getLength() << endl;
|
||||
assert(sa=="ffff:ffff:ffff:ffff::");
|
||||
assert(a3->getNetmask().getLength()==64);
|
||||
assert(a3->getNetmaskPtr()->getLength()==64);
|
||||
// assert(a3->dimension()==18446744073709551616);
|
||||
assert(a3->toString()=="fe80::21d:9ff:fe8b:8e94/64");
|
||||
|
||||
@@ -161,32 +165,32 @@ int main(int, char * const *)
|
||||
|
||||
Inet6AddrMask *a4 = new Inet6AddrMask(
|
||||
string("fe80::21d:9ff:fe8b:8e94/64"));
|
||||
sa = a4->getAddress().toString();
|
||||
sa = a4->getAddressPtr()->toString();
|
||||
cout << "a4.address=" << sa << endl;
|
||||
assert(sa=="fe80::21d:9ff:fe8b:8e94");
|
||||
sa = a4->getNetmask().toString();
|
||||
sa = a4->getNetmaskPtr()->toString();
|
||||
cout << "a4.netmask=" << sa << endl;
|
||||
assert(sa=="ffff:ffff:ffff:ffff::");
|
||||
// assert(a4->dimension()==1);
|
||||
|
||||
cout << "Checking Inet6AddrMask::belongs()" << endl;
|
||||
assert(a4->belongs(a2->getAddress()));
|
||||
assert(a4->belongs( *(a2->getAddressPtr()) ));
|
||||
|
||||
cout << endl;
|
||||
|
||||
Inet6AddrMask *a5 = new Inet6AddrMask(*a3);
|
||||
sa = a5->getAddress().toString();
|
||||
sa = a5->getAddressPtr()->toString();
|
||||
assert(sa=="fe80::21d:9ff:fe8b:8e94");
|
||||
sa = a5->getNetmask().toString();
|
||||
sa = a5->getNetmaskPtr()->toString();
|
||||
assert(sa=="ffff:ffff:ffff:ffff::");
|
||||
// assert(a5->dimension()==1);
|
||||
|
||||
cout << "Checking Inet6AddrMask::setAddress()" << endl;
|
||||
a5->setAddress(Inet6Addr("3ffe:1200:2001:1:8000::1"));
|
||||
sa = a5->getAddress().toString();
|
||||
a5->setAddress(InetAddr(AF_INET6, "3ffe:1200:2001:1:8000::1"));
|
||||
sa = a5->getAddressPtr()->toString();
|
||||
cout << "a5.address=" << sa << endl;
|
||||
assert(sa=="3ffe:1200:2001:1:8000::1");
|
||||
sa = a5->getNetmask().toString();
|
||||
sa = a5->getNetmaskPtr()->toString();
|
||||
assert(sa=="ffff:ffff:ffff:ffff::");
|
||||
// assert(a5->dimension()==1);
|
||||
|
||||
|
||||
@@ -81,46 +81,46 @@ int main(int, char * const *)
|
||||
cout << "Start test for InetAddrMask" << endl;
|
||||
|
||||
InetAddrMask *a1 = new InetAddrMask();
|
||||
sa = a1->getAddress().toString();
|
||||
sa = a1->getAddressPtr()->toString();
|
||||
assert(sa=="0.0.0.0");
|
||||
assert(a1->dimension()==0);
|
||||
|
||||
InetAddrMask *a2 = new InetAddrMask(InetAddr("1.1.1.1"), InetAddr("255.255.255.0"));
|
||||
sa = a2->getAddress().toString();
|
||||
sa = a2->getAddressPtr()->toString();
|
||||
assert(sa=="1.1.1.0");
|
||||
sa = a2->getNetmask().toString();
|
||||
sa = a2->getNetmaskPtr()->toString();
|
||||
assert(sa=="255.255.255.0");
|
||||
assert(a2->dimension()==256);
|
||||
assert(a2->toString()=="1.1.1.0/255.255.255.0");
|
||||
|
||||
InetAddrMask *a3 = new InetAddrMask(string("1.1.1.1"));
|
||||
sa = a3->getAddress().toString();
|
||||
sa = a3->getAddressPtr()->toString();
|
||||
assert(sa=="1.1.1.1");
|
||||
sa = a3->getNetmask().toString();
|
||||
sa = a3->getNetmaskPtr()->toString();
|
||||
assert(sa=="255.255.255.255");
|
||||
assert(a3->dimension()==1);
|
||||
|
||||
assert(a2->belongs(a3->getAddress()));
|
||||
assert(a2->belongs( *(a3->getAddressPtr()) ));
|
||||
|
||||
|
||||
InetAddrMask *a4 = new InetAddrMask(*a3);
|
||||
sa = a4->getAddress().toString();
|
||||
sa = a4->getAddressPtr()->toString();
|
||||
assert(sa=="1.1.1.1");
|
||||
sa = a4->getNetmask().toString();
|
||||
sa = a4->getNetmaskPtr()->toString();
|
||||
assert(sa=="255.255.255.255");
|
||||
assert(a4->dimension()==1);
|
||||
|
||||
a4->setAddress(InetAddr("2.2.2.2"));
|
||||
sa = a4->getAddress().toString();
|
||||
sa = a4->getAddressPtr()->toString();
|
||||
assert(sa=="2.2.2.2");
|
||||
sa = a4->getNetmask().toString();
|
||||
sa = a4->getNetmaskPtr()->toString();
|
||||
assert(sa=="255.255.255.255");
|
||||
assert(a4->dimension()==1);
|
||||
|
||||
a4->setNetmask(InetAddr("255.255.0.0"));
|
||||
sa = a4->getAddress().toString();
|
||||
sa = a4->getAddressPtr()->toString();
|
||||
assert(sa=="2.2.2.2");
|
||||
sa = a4->getNetmask().toString();
|
||||
sa = a4->getNetmaskPtr()->toString();
|
||||
assert(sa=="255.255.0.0");
|
||||
assert(a4->dimension()==256*256);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user