X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FProtocols%2FINet%2FINet6Address.hh;h=953bc491fa04d7936441a16412cfd5a71c6b9416;hb=d001b1fe2a8fb121145d2a111d737219abae20d7;hp=436d5fe187b2e3c7373c09c54620b55bbcf47d90;hpb=66293acca094b2f29e26e70208691db4af274efb;p=senf.git diff --git a/Socket/Protocols/INet/INet6Address.hh b/Socket/Protocols/INet/INet6Address.hh index 436d5fe..953bc49 100644 --- a/Socket/Protocols/INet/INet6Address.hh +++ b/Socket/Protocols/INet/INet6Address.hh @@ -1,8 +1,8 @@ // $Id$ // -// Copyright (C) 2007 -// Fraunhofer Institute for Open Communication Systems (FOKUS) -// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Copyright (C) 2007 +// 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 @@ -23,18 +23,20 @@ /** \file \brief INet6Address public header */ -#ifndef HH_INet6Address_ -#define HH_INet6Address_ 1 +#ifndef HH_SENF_Socket_Protocols_INet_INet6Address_ +#define HH_SENF_Socket_Protocols_INet_INet6Address_ 1 // Custom includes #include #include +#include #include #include #include #include "../../../Utils/safe_bool.hh" #include "../../../Utils/Tags.hh" #include "INet4Address.hh" +#include "../AddressExceptions.hh" //#include "INet6Address.mpp" #include "INet6Address.ih" @@ -42,50 +44,75 @@ namespace senf { - /** \brief IPv6 network address + /** \brief INet6 network address - This implementation of an IPv6 address is based strictly on + This implementation of an INet6 address is based strictly on RFC 4291: Internet Protocol - Version 6 (IPv6) Addressing Architecture. This class provides accessors to all the + Version 6 (INet6) 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 INet6 addressing architecture however has several other components defined in other RFC's. These RFC's should be implemented in additional modules: \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 + Unicast-Prefix-based INet6 Multicast Addresses. Defines the ff30::/12 prefix \li RFC 3956: - Embedding the Rendezvous Point (RP) Address in an IPv6 Multicast + Embedding the Rendezvous Point (RP) Address in an INet6 Multicast Address. Defines the ff70::/12 prefix \li RFC 3056: - Connection of IPv6 Domains via IPv4 Clouds. Defines 6to4 tunneling and the + Connection of INet6 Domains via INet4 Clouds. Defines 6to4 tunneling and the 2002::/16 prefix \li RFC 3849: - IPv6 Address Prefix Reserved for Documentation. Defines the 2001:db8::/32 prefix - + INet6 Address Prefix Reserved for Documentation. Defines the 2001:db8::/32 prefix + Here an overview of well-known prefixes: + \htmlonly - - - - - - - - - - - - - - + + + + + + + + + + + + + +
Prefix Description Definition Note
::/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
fc00::/7 ULA RFC4193
fe80::/64 Link-local addresses RFC4291
fec0::/10 Site-local addresses RFC4291 deprecated
ff00::/8 Multicast RFC4291
ff00::/12 Globally allocated multicast RFC4291
ff10::/12 Locally allocated multicast RFC4291
ff30::/12 Unicast prefic based multicast RFC3306
ff70::/12 Multicast address with embedded RP RFC3956
Prefix Description Definition Note
::/96 INet4 compatible INet6 address RFC4291 deprecated
::ffff:0:0/96 INet6 mapped INet4 address RFC4291
2000::/3 Global unicast addresses RFC3587 only noted, not defined
2001:db8::/32 Documentation-only prefix RFC3849
2002::/16 6to4 addressing RFC3056
fc00::/7 ULA RFC4193
fe80::/64 Link-local addresses RFC4291
fec0::/10 Site-local addresses RFC4291 deprecated
ff00::/8 Multicast RFC4291
ff00::/12 Globally allocated multicast RFC4291
ff10::/12 Locally allocated multicast RFC4291
ff30::/12 Unicast prefic based multicast RFC3306
ff70::/12 Multicast address with embedded RP RFC3956
+ \endhtmlonly - The INet6Address class is based on \c boost::array and is built as a fixed-size sequence of - 16 bytes. + The following statements all create the same INet6 address + 2001:db8::a0b1:1a2b:3dff:fe4e:5f00: + \code + // Used to construct constant INet6 addresses + INet6Address(0x2001u,0xDB8u,0x0u,0xA0B1u 0x1A2Bu,0x3DFFu,0xFE4Eu,0x5F00u) + + // Construct INet6 address from it's string representation + INet6Address::from_string("2001:db8::a0b1:1a2b:3dff:fe4e:5f00") + + // Construct an INet6 address from raw data. 'from_data' takes an arbitrary iterator (e.g. a + // pointer) as argument. Here we use a fixed array but normally you will need this to build + // an INet6 address in a packet parser + char rawBytes[] = { 0x20, 0x01, 0x0D, 0xB8, 0x00, 0x00, 0xA0, 0xB1, + 0x1a, 0x2b, 0x3d, 0xff, 0xfe, 0x4e, 0xff, 0x00 }; + INet6Address::from_data(rawBytes) + \endcode + + Since INet6Address class is based on \c boost::array and is built as a fixed-size sequence + of 16 bytes, you can access the raw data bytes of the address (in network byte order) using + \c begin(), \c end() or \c operator[] + \code + INet6Address ina = ...; + Packet::iterator i = ...; + std::copy(ina.begin(), ina.end(), i); // Copies 16 bytes + \endcode \see CheckINet6Network \n INet6Network \ingroup addr_group @@ -114,8 +141,8 @@ namespace senf { /** \brief Possible scope values List of all possible scope values. This list includes all scope values defined for - multicast addresses in RFC 4291. - The values \ref LinkScope, \ref SiteScope and \ref GlobalScope are also used with + multicast addresses in RFC 4291. + The values \ref LinkScope, \ref SiteScope and \ref GlobalScope are also used with unicast addresses. */ enum ScopeId { @@ -128,18 +155,20 @@ namespace senf { , ReservedScope = 0 /**< Reserved scope value */ , UnassignedScope = 6 /**< Unassigned scope, may be defined locally */ - }; + }; /////////////////////////////////////////////////////////////////////////// ///\name Structors and default members ///@{ 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); + explicit 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); ///< Construct an address constant + static INet6Address from_in6addr(in6_addr const & in6addr); ///< Construct from std C struct + static INet6Address from_string(std::string const & s, Resolve_t resolve = ResolveINet6); ///< Convert string to address /**< This member will try to convert the given string into @@ -148,32 +177,34 @@ namespace senf { \attention This call may block if \a s represents a hostname which must be looked up via some network protocol like DNS or NIS - \throws SyntaxException if the address cannot be + \throws AddressSyntaxException if the address cannot be converted for some reason - \param[in] s Address literal or hostname + \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 INet4 address if no valid INet6 address is + found. The address will be returned as mapped INet6 address. */ - template + template static INet6Address from_data(InputIterator i); ///< Construct address from 16 bytes of raw data /**< from_data will build an address from 16 bytes of raw data as accessed by the iterator. The data must be in network byte order. */ - static INet6Address from_inet4address(INet4Address addr); - ///< Construct an IPv6-mapped IPv4 address + static INet6Address from_inet4address(INet4Address const & addr); + ///< Construct an INet6-mapped INet4 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 + an INet6-mapped INet4 address (see RFC 4291). - \par - IPv4 compatible IPv6 addresses are not directly + \par + INet4 compatible INet6 addresses are not directly supported, they are deprecated in the RFC. */ + in6_addr toin6_addr() const; ///< get the linux in6_addr struct (convinience only) + ///@} /////////////////////////////////////////////////////////////////////////// ///\name Accessors @@ -187,6 +218,12 @@ namespace senf { bool unicast() const; ///< \c true, if address is unicast bool multicast() const; ///< \c true, if address is multicast + /**< To support a linux specific extension, INet4 multicast + addressed mapped to INet6 are also interpreted as + multicast addresses. This is NOT part of the standard, + however the standard officially only allows unicast v4 + addresses to be mapped to v6 so this does not collide + with any standard conforming use. */ ScopeId scope() const; ///< Get address's scope /**< The scope of an address is one of the \ref ScopeId @@ -195,33 +232,33 @@ namespace senf { site or global scope (where site scope is deprecated), multicast address can have a number of scope values of which local, site and global are a few. See the \ref - ScopeId enumerators. */ + ScopeId enumerators. */ 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 - 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 + INet4Address inet4address() const; ///< Return embedded INet4 address + /**< Returns the INet4 address embedded within an INet4 + compatible or INet4 mapped unicast address. This address + is given by the last 32 bits of the INet6 address. \par + The value returned is only a valid INet4 address if + either inet4Compatible() or inet4Mapped() return \c + true. */ + bool inet4Compatible() const; ///< \c true, if address is INet4 compatible + /**< INet4 compatible INet6 addresses are deprecated. */ + bool inet4Mapped() const; ///< \c true, if address is INet4 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 + globally assigned. See RFC 4291. */ bool prefixMulticastAddr() const; ///< \c true, if P bit is set /**< In RFC 4291, the P bit is specified as defining a - unicast prefix based multicast address. See - RFC 3306. */ + unicast prefix based multicast address. See + RFC 3306. */ bool embeddedRpAddr() const; ///< \c true, if R bit is set /**< In RFC 4291, - the R bit is specified as defining a multicast address + the R bit is specified as defining a multicast address with embedded rendezvous point. See RFC 3956. */ @@ -230,33 +267,27 @@ namespace senf { ///@} ///\name Mutators ///@{ - + void network(boost::uint64_t net); ///< Set network part of address void id(boost::uint64_t id); ///< Set interface id part of address ///@} - /** \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 \related INet6Address */ std::ostream & operator<<(std::ostream & os, INet6Address const & addr); + /** \brief Try to initialize INet6Address instance from a string representation + sets std::ios::failbit on the stream if an error occurred + \see INet6Address from_string() + \related INet6Address + */ + std::istream & operator>>(std::istream & is, INet6Address & addr); /** \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 @@ -266,13 +297,13 @@ namespace senf { ... , 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: - + \code if (senf::CheckINet6Network<0x2000u,0xDB8u,32u>::match(addr)) { // 'addr' is within in the 2001:db8::/32 documentation-only network @@ -285,15 +316,17 @@ namespace senf { template struct CheckINet6Network +#ifndef DOXYGEN : public detail::CheckINet6Network_impl +#endif {}; - /** \brief IPv6 network prefix + /** \brief INet6 network prefix - This class represents an IPv6 network prefix in CIDR notation. + This class represents an INet6 network prefix in CIDR notation. */ class INet6Network - : public boost::equality_comparable, + : public boost::equality_comparable, public comparable_safe_bool { public: @@ -302,9 +335,9 @@ namespace senf { ///@{ INet6Network(); ///< Construct empty (::/0) network - INet6Network(INet6Address address, unsigned prefix_len); + INet6Network(INet6Address const & address, unsigned prefix_len); ///< Construct network from given address and prefix length - explicit INet6Network(std::string s); ///< Construct network from CIDR notation + explicit INet6Network(std::string const & s); ///< Construct network from CIDR notation ///@} /////////////////////////////////////////////////////////////////////////// @@ -315,9 +348,9 @@ namespace senf { 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 + + bool match(INet6Address const & addr) const; ///< \c true, if the network includes \a addr + bool match(INet6Network const & 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 @@ -333,7 +366,7 @@ namespace senf { \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 + \endcode \param[in] net network number \param[in] prefix_len length of subnet prefix */ @@ -356,7 +389,7 @@ namespace senf { #include "INet6Address.cti" #endif - + // Local Variables: // mode: c++ // fill-column: 100