X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FProtocols%2FINet%2FINet6Address.hh;h=436d5fe187b2e3c7373c09c54620b55bbcf47d90;hb=6f50bf49e282c0528f51faa0a245bbfa2b867399;hp=2b93f7b6a61dacc59f0650c95ae9c3e74eaa82ec;hpb=2452ac2af5863afb6cfb74e6d2c6e35fc75d1f9a;p=senf.git diff --git a/Socket/Protocols/INet/INet6Address.hh b/Socket/Protocols/INet/INet6Address.hh index 2b93f7b..436d5fe 100644 --- a/Socket/Protocols/INet/INet6Address.hh +++ b/Socket/Protocols/INet/INet6Address.hh @@ -1,6 +1,8 @@ +// $Id$ +// // Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify @@ -28,9 +30,10 @@ #include #include #include -#include #include -#include "Utils/SafeBool.hh" +#include +#include "../../../Utils/safe_bool.hh" +#include "../../../Utils/Tags.hh" #include "INet4Address.hh" //#include "INet6Address.mpp" @@ -39,30 +42,35 @@ namespace senf { - /** \brief IpV6 network address + /** \brief IPv6 network address - This implementation of an IpV6 address is based strictly on RFC 4291: Internet Protocol + This implementation of an IPv6 address is based strictly on + RFC 4291: Internet Protocol Version 6 (IPv6) Addressing Architecture. This class provides accessors to all the information fields defined in this document. - The IpV6 addressing architecture however has several other components defined in other + The IPv6 addressing architecture however has several other components defined in other RFC's. These RFC's should be implemented in additional modules: - \li RFC4193: Unique Local Addresses (ULA). Defines the fc00::/7 prefix - \li RFC3306: Unicast-Prefix-based IPv6 Multicast Addresses. Defines the ff30::/12 prefix - \li RFC3956: Embedding the Rendezvous Point (RP) Address in an IPv6 Multicast + \li RFC 4193: + Unique Local Addresses (ULA). Defines the fc00::/7 prefix + \li RFC 3306: + Unicast-Prefix-based IPv6 Multicast Addresses. Defines the ff30::/12 prefix + \li RFC 3956: + Embedding the Rendezvous Point (RP) Address in an IPv6 Multicast Address. Defines the ff70::/12 prefix - \li RFC3056: Connection of IPv6 Domains via IPv4 Clouds. Defines 6to4 tunneling and the + \li RFC 3056: + Connection of IPv6 Domains via IPv4 Clouds. Defines 6to4 tunneling and the 2002::/16 prefix - \li RFC3849: IPv6 Address Prefix Reserved for Documentation. Defines the 2001:db8::/32 - prefix + \li RFC 3849: + IPv6 Address Prefix Reserved for Documentation. Defines the 2001:db8::/32 prefix Here an overview of well-known prefixes: - - + + @@ -79,33 +87,36 @@ namespace senf { The INet6Address class is based on \c boost::array and is built as a fixed-size sequence of 16 bytes. - \see CheckINet6Network Helper to check address against an arbitrary fixed network prefix + \see CheckINet6Network \n INet6Network \ingroup addr_group + + \implementation We awkwardly need to use static named constructors (from_ members) + instead of ordinarily overloaded constructors for one simple reason: char * + doubles as string literal and as arbitrary data iterator. The iterator constructor can + therefore not be distinguished from initialization with a string literal. Therefore we + need to disambiguate using the named constructors. */ class INet6Address : public boost::array, - public ComparableSafeBool + public comparable_safe_bool { public: /////////////////////////////////////////////////////////////////////////// // Types - typedef boost::function Callback; - ///< Callback for asynchronous from_string call - static INet6Address const None; ///< The empty (::0) address static INet6Address const Loopback; ///< The loopback (::1) address static INet6Address const AllNodes; ///< The 'all nodes' link-local multicast address static INet6Address const AllRouters; ///< The 'all routers' link-local multicast address - enum NoInit_t { noinit }; enum Resolve_t { ResolveINet6, ResolveINet4 }; /** \brief Possible scope values List of all possible scope values. This list includes all scope values defined for - multicast addresses in RFC4291. The values \ref LinkScope, \ref SiteScope and \ref - GlobalScope are also used with unicast addresses. + multicast addresses in RFC 4291. + The values \ref LinkScope, \ref SiteScope and \ref GlobalScope are also used with + unicast addresses. */ enum ScopeId { InterfaceScope = 1 /**< Interface only scope */ @@ -123,7 +134,7 @@ namespace senf { ///\name Structors and default members ///@{ - explicit INet6Address(NoInit_t); ///< Construct uninitialized (!) address + explicit INet6Address(senf::NoInit_t); ///< Construct uninitialized (!) address INet6Address(boost::uint16_t a0=0u, boost::uint16_t a1=0u, boost::uint16_t a2=0u, boost::uint16_t a3=0u, boost::uint16_t a4=0u, boost::uint16_t a5=0u, boost::uint16_t a6=0u, boost::uint16_t a7=0u); @@ -142,30 +153,10 @@ namespace senf { \param[in] s Address literal or hostname \param[in] resolve If this is set to \c ResolveINet4, the call will additionally try to interpret \a s as - an IpV4 address if no valid IpV6 address is - found. The address will be returned as mapped IpV6 + an IPv4 address if no valid IPv6 address is + found. The address will be returned as mapped IPv6 address. */ - static void from_string(std::string const & s, Callback const & cb, - Resolve_t resolve = ResolveINet6); - ///< Convert string to address (async/non-blocking) - /**< This member works like - from_string(std::string const &). However unlike - from_string(std::string const &), this call will not - block. Instead it will call \a cb passing the - INet6Address instance as soon as the address has been - resolved (which may be immediate if the address - represents an IP literal). \par - On error, the address passed to \a cb will be empty. - \param[in] s Address literal or hostname - \param[in] cb Callback to pass the address to - \param[in] resolve If this is set to \c ResolveINet4, - the call will additionally try to interpret \a s as - an IpV4 address if no valid IpV6 address is - found. The address will be returned as mapped IpV6 - address. - \fixme Implement */ - template static INet6Address from_data(InputIterator i); ///< Construct address from 16 bytes of raw data @@ -174,12 +165,14 @@ namespace senf { network byte order. */ static INet6Address from_inet4address(INet4Address addr); - ///< Construct an IpV6-mapped IpV4 address + ///< Construct an IPv6-mapped IPv4 address /**< This will construct an address of the form ::FFFF::w.x.y.z where w.x.y.z is the INet4Address value. This kind of address is called - an IpV6-mapped IpV4 address (see RFC4291). \par - IpV4 compatible IpV6 addresses are not directly + an IPv6-mapped IPv4 address (see + RFC 4291). + \par + IPv4 compatible IPv6 addresses are not directly supported, they are deprecated in the RFC. */ ///@} /////////////////////////////////////////////////////////////////////////// @@ -206,27 +199,31 @@ namespace senf { bool globalScope() const; ///< \c true, if address is global unicast or multicast bool linkScope() const; ///< \c true, if address is link-local unicast or multicast - INet4Address inet4address() const; ///< Return embedded IpV4 address - /**< Returns the IpV4 address embedded within an IpV4 - compatible or IpV4 mapped unicast address. This address - is given by the last 32 bits of the IpV6 address. \par - The value returned is only a valid IpV4 address if + INet4Address inet4address() const; ///< Return embedded IPv4 address + /**< Returns the IPv4 address embedded within an IPv4 + compatible or IPv4 mapped unicast address. This address + is given by the last 32 bits of the IPv6 address. \par + The value returned is only a valid IPv4 address if either ipv4Compatible() or ipv4Mapped() return \c true. */ - bool ipv4Compatible() const; ///< \c true, if address is IpV4 compatible - /**< IpV4 compatible IpV6 addresses are deprecated. */ - bool ipv4Mapped() const; ///< \c true, if address is IpV4 mapped + bool ipv4Compatible() const; ///< \c true, if address is IPv4 compatible + /**< IPv4 compatible IPv6 addresses are deprecated. */ + bool ipv4Mapped() const; ///< \c true, if address is IPv4 mapped bool globalMulticastAddr() const; ///< \c true, if T bit is \e not set /**< Any multicast address with a cleared T bit must be - globally assigned. See RFC4291. */ + globally assigned. See + RFC 4291. */ bool prefixMulticastAddr() const; ///< \c true, if P bit is set - /**< In RFC4291, the P bit is specified as defining a - unicast prefix based multicast address. See RFC3306. */ + /**< In RFC 4291, + the P bit is specified as defining a + unicast prefix based multicast address. See + RFC 3306. */ bool embeddedRpAddr() const; ///< \c true, if R bit is set - /** In RFC4291, the R bit is specified as defining a - multicast address with embedded rendezvous point. See - RFC3956. */ + /**< In RFC 4291, + the R bit is specified as defining a multicast address + with embedded rendezvous point. See + RFC 3956. */ bool boolean_test() const; ///< \c true, if address != '::' (None) @@ -239,9 +236,18 @@ namespace senf { ///@} - /** \brief Invalid IpV6 address syntax */ - struct SyntaxException : public std::exception - { virtual char const * what() const throw() { return "Invalid IpV6 address syntax"; } }; + /** \brief Base-class for INet6Address exceptions */ + struct AddressException : public std::exception {}; + + /** \brief Invalid INet4 address syntax */ + struct SyntaxException : public AddressException + { virtual char const * what() const throw() + { return "invalid INet6 address syntax"; } }; + + /** \brief Resolver failure */ + struct UnknownHostnameException : public AddressException + { virtual char const * what() const throw() + { return "failed to resolve INet6 hostname"; } }; }; /** \brief Output INet6Address instance as it's string representation @@ -249,10 +255,24 @@ namespace senf { */ std::ostream & operator<<(std::ostream & os, INet6Address const & addr); - /** \brief Check address against a fixed network prefix + /** \brief Check INet6Address against a fixed network prefix + + This helper allows to easily and efficiently check an INet6Address against an arbitrary but + constant network prefix. It takes from 1 to 8 arguments for the network address and an + additional last argument providing the prefix length. So + + \par "" + senf::CheckINet6Network< addr_1 , addr_2 , + ... , prefix_len > + + represents the network + + \par "" + addr_1 : addr_2 : ... ::/ prefix_len . + + The class exposes a single static member match( addr ) which + matches the INet6Address \a addr against the prefix: - This helper allows to easily and efficiently check an address against an arbitrary network - prefix: \code if (senf::CheckINet6Network<0x2000u,0xDB8u,32u>::match(addr)) { // 'addr' is within in the 2001:db8::/32 documentation-only network @@ -260,10 +280,7 @@ namespace senf { } \endcode - The code generated by this call is highly optimized and as probably as efficient as it can - get. - - \related INet6Address + The code generated by this call is highly optimized and probably as efficient as it can get. */ template @@ -271,6 +288,66 @@ namespace senf { : public detail::CheckINet6Network_impl {}; + /** \brief IPv6 network prefix + + This class represents an IPv6 network prefix in CIDR notation. + */ + class INet6Network + : public boost::equality_comparable, + public comparable_safe_bool + { + public: + /////////////////////////////////////////////////////////////////////////// + ///\name Structors and default members + ///@{ + + INet6Network(); ///< Construct empty (::/0) network + INet6Network(INet6Address address, unsigned prefix_len); + ///< Construct network from given address and prefix length + explicit INet6Network(std::string s); ///< Construct network from CIDR notation + + ///@} + /////////////////////////////////////////////////////////////////////////// + + INet6Address const & address() const; ///< Get the network address + unsigned prefix_len() const; ///< Get the network prefix length + + bool boolean_test() const; ///< \c true, if INet6Network is non-empty + bool operator==(INet6Network const & other) const; + ///< Compare two networks for equality + + bool match(INet6Address addr) const; ///< \c true, if the network includes \a addr + bool match(INet6Network 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. */ + INet6Address host(boost::uint64_t id); ///< Return the host with the given id + /**< Returns the host with the given number within the + network. This call replaces the lower 64 bits of the + network address with the given id. */ + + INet6Network subnet(boost::uint64_t net, unsigned prefix_len); + ///< Return the given subnet of \c this + /**< The returned INet6Network will be a subnet of \c this + with the given network number. The network number is + comprised by the bits above \a prefix_len: + \code + INet6Network("2001:db8::/32").subnet(0x12u,40u) == INet6Network("2001:db8:1200::/40") + INet6Network("2001:db8:1200::/40").subnet(0x2345,64u) == INet6Network("2001:db8:1200:2345::/64") + \endcode + \param[in] net network number + \param[in] prefix_len length of subnet prefix */ + + protected: + + private: + unsigned prefix_len_; + INet6Address address_; + }; + + /** \brief Output INet6Network instance as it's string representation + \related INet6Network + */ + std::ostream & operator<<(std::ostream & os, INet6Network const & addr); } ///////////////////////////////hh.e////////////////////////////////////////
Prefix Description Definition Note
::/96 IpV4 compatible IpV6 address RFC4291 deprecated
::ffff:0:0/96 IpV6 mapped IpV4 address RFC4291
::/96 IPv4 compatible IPv6 address RFC4291 deprecated
::ffff:0:0/96 IPv6 mapped IPv4 address RFC4291
2000::/3 Global unicast addresses RFC3587 only noted, not defined
2001:db8::/32 Documentation-only prefix RFC3849
2002::/16 6to4 addressing RFC3056