Skip to content
Snippets Groups Projects
Commit 37ffe176 authored by g0dil's avatar g0dil
Browse files

Socket/Protocols/INet: Implemented INet4Network

parent 94c321f1
No related branches found
No related tags found
No related merge requests found
......@@ -30,6 +30,7 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <boost/lexical_cast.hpp>
#ifdef _REENTRANT
#include <boost/thread/mutex.hpp>
#endif
......@@ -118,6 +119,21 @@ senf::INet4Address const senf::INet4Address::None;
senf::INet4Address const senf::INet4Address::Loopback (0x7F000001u);
senf::INet4Address const senf::INet4Address::Broadcast (0xFFFFFFFFu);
///////////////////////////////////////////////////////////////////////////
// senf::INet4Network
prefix_ senf::INet4Network::INet4Network(std::string s)
{
std::string::size_type i (s.find('/'));
if (i == std::string::npos)
throw INet4Address::SyntaxException();
try {
prefix_len_ = boost::lexical_cast<unsigned>(std::string(s,i+1));
} catch (boost::bad_lexical_cast const &) {
throw INet4Address::SyntaxException();
}
address_ = INet4Address(INet4Address::from_string(std::string(s, 0, i)).address() & mask());
}
///////////////////////////////////////////////////////////////////////////
// namespace members
......
......@@ -78,6 +78,73 @@ prefix_ senf::INet4Address::inaddr_type senf::INet4Address::iref()
return *reinterpret_cast<inaddr_type const *>(&(*this)[0]);
}
///////////////////////////////////////////////////////////////////////////
// senf::INet4Network
prefix_ senf::INet4Network::INet4Network()
: prefix_len_(), address_()
{}
prefix_ senf::INet4Network::INet4Network(INet4Address address, unsigned prefix_len)
: prefix_len_(prefix_len), address_(INet4Address(address.address() & mask()))
{}
prefix_ senf::INet4Address const & senf::INet4Network::address()
const
{
return address_;
}
prefix_ unsigned senf::INet4Network::prefix_len()
const
{
return prefix_len_;
}
prefix_ bool senf::INet4Network::boolean_test()
const
{
return address() || prefix_len();
}
prefix_ bool senf::INet4Network::operator==(INet4Network const & other)
const
{
return address() == other.address() && prefix_len() == other.prefix_len();
}
prefix_ bool senf::INet4Network::match(INet4Address addr)
const
{
return (addr.address() & mask()) == address_.address();
}
prefix_ bool senf::INet4Network::match(INet4Network net)
const
{
return net.prefix_len() >= prefix_len() &&
(net.address().address() & mask()) == address_.address();
}
////////////////////////////////////////
// private members
prefix_ boost::uint32_t senf::INet4Network::mask()
const
{
// This is correct as long as the system is using 2-complement arithmetic ...
return (~((boost::uint32_t(1u)<<(32u-prefix_len()))-1u)) & 0xFFFFFFFFu;
}
///////////////////////////////////////////////////////////////////////////
// namespace members
prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4Network const & addr)
{
os << addr.address() << '/' << addr.prefix_len();
return os;
}
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
......
......@@ -32,6 +32,7 @@
#include <boost/cstdint.hpp>
#include <boost/function.hpp>
#include <boost/array.hpp>
#include <boost/operators.hpp>
#include "Utils/SafeBool.hh"
//#include "INet4Address.mpp"
......@@ -58,7 +59,6 @@ namespace senf {
class INet4Address
: public boost::array<boost::uint8_t,4>,
public ComparableSafeBool<INet4Address>
{
public:
///////////////////////////////////////////////////////////////////////////
......@@ -195,6 +195,56 @@ namespace senf {
static bool match(INet4Address const & addr);
};
/** \brief IpV4 network prefix
This class represents an IpV4 network prefix in CIDR notation.
*/
class INet4Network
: public boost::equality_comparable<INet4Network>,
public ComparableSafeBool<INet4Network>
{
public:
///////////////////////////////////////////////////////////////////////////
// Types
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
INet4Network(); ///< Construct empty (0.0.0.0/0) network
INet4Network(INet4Address address, unsigned prefix_len);
///< Construct network from given address and prefix length
explicit INet4Network(std::string s); ///< Construct network from CIDR notation
///@}
///////////////////////////////////////////////////////////////////////////
INet4Address const & address() const; ///< Get the networks address
unsigned prefix_len() const; ///< Get the networks prefix length
bool boolean_test() const; ///< \c true, if INet4Network is non-empty
bool operator==(INet4Network const & other) const;
///< Compare to networks for equality
bool match(INet4Address addr) const; ///< \c true, if the network includes \a addr
bool match(INet4Network net) const; ///< \c true, if the network includes \a net
/**< The is true, if \a net is sub-network (or the same as)
\c this. */
protected:
private:
boost::uint32_t mask() const;
unsigned prefix_len_;
INet4Address address_;
};
/** \brief Output INet4Network instance as it's string representation
\related INet4Network
*/
std::ostream & operator<<(std::ostream & os, INet4Network const & addr);
}
///////////////////////////////hh.e////////////////////////////////////////
......
......@@ -28,6 +28,7 @@
// Custom includes
#include <arpa/inet.h>
#include <boost/lexical_cast.hpp>
#include <sstream>
#include "INet4Address.hh"
......@@ -68,6 +69,28 @@ BOOST_AUTO_UNIT_TEST(inet4Address)
BOOST_CHECK_EQUAL( str.str(), "128.129.130.131" );
}
BOOST_AUTO_UNIT_TEST(inet4Network)
{
senf::INet4Network net (senf::INet4Address::Loopback,8);
BOOST_CHECK_EQUAL( net.address().address(), 0x7F000000u );
BOOST_CHECK_EQUAL( net.prefix_len(), 8u );
BOOST_CHECK( net );
BOOST_CHECK( ! senf::INet4Network() );
senf::INet4Network net2 ("192.0.111.222/16");
BOOST_CHECK_EQUAL( net2.address(), senf::INet4Address::from_string("192.0.0.0") );
BOOST_CHECK_EQUAL( net2.prefix_len(), 16u );
BOOST_CHECK( net != net2 );
BOOST_CHECK( net.match(senf::INet4Address::from_string("127.0.0.1")) );
BOOST_CHECK( ! net2.match(senf::INet4Address::from_string("127.0.0.1")) );
BOOST_CHECK( ! net.match(net2) );
BOOST_CHECK( net2.match(senf::INet4Network("192.0.111.0/24")) );
BOOST_CHECK( ! net2.match(senf::INet4Network("192.0.0.0/15")) );
BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(net2), "192.0.0.0/16" );
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
......
......@@ -45,7 +45,7 @@ BOOST_AUTO_UNIT_TEST(inet4SocketAddress)
BOOST_CHECK( ! addr );
addr = INet4SocketAddress("127.0.0.1:12345");
BOOST_CHECK ( addr != INet4SocketAddress() );
BOOST_CHECK ( addr != INet4SocketAddress("127.0.0.2:12345") );
}
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment