#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
+#include <boost/lexical_cast.hpp>
#ifdef _REENTRANT
#include <boost/thread/mutex.hpp>
#endif
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
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_
#include <boost/cstdint.hpp>
#include <boost/function.hpp>
#include <boost/array.hpp>
+#include <boost/operators.hpp>
#include "Utils/SafeBool.hh"
//#include "INet4Address.mpp"
class INet4Address
: public boost::array<boost::uint8_t,4>,
public ComparableSafeBool<INet4Address>
-
{
public:
///////////////////////////////////////////////////////////////////////////
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////////////////////////////////////////
// Custom includes
#include <arpa/inet.h>
+#include <boost/lexical_cast.hpp>
#include <sstream>
#include "INet4Address.hh"
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_
BOOST_CHECK( ! addr );
addr = INet4SocketAddress("127.0.0.1:12345");
- BOOST_CHECK ( addr != INet4SocketAddress() );
+ BOOST_CHECK ( addr != INet4SocketAddress("127.0.0.2:12345") );
}
{