2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 // Stefan Bund <g0dil@berlios.de>
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 \brief INet6Address public header */
24 #ifndef HH_INet6Address_
25 #define HH_INet6Address_ 1
30 #include <boost/cstdint.hpp>
31 #include <boost/function.hpp>
32 #include <boost/array.hpp>
33 #include "Utils/SafeBool.hh"
34 #include "INet4Address.hh"
36 //#include "INet6Address.mpp"
37 #include "INet6Address.ih"
38 ///////////////////////////////hh.p////////////////////////////////////////
42 /** \brief IpV6 network address
44 This implementation of an IpV6 address is based strictly on RFC 4291: Internet Protocol
45 Version 6 (IPv6) Addressing Architecture. This class provides accessors to all the
46 information fields defined in this document.
48 The IpV6 addressing architecture however has several other components defined in other
49 RFC's. These RFC's should be implemented in additional modules:
51 \li RFC4193: Unique Local Addresses (ULA). Defines the fc00::/7 prefix
52 \li RFC3306: Unicast-Prefix-based IPv6 Multicast Addresses. Defines the ff30::/12 prefix
53 \li RFC3956: Embedding the Rendezvous Point (RP) Address in an IPv6 Multicast
54 Address. Defines the ff70::/12 prefix
55 \li RFC3056: Connection of IPv6 Domains via IPv4 Clouds. Defines 6to4 tunneling and the
57 \li RFC3849: IPv6 Address Prefix Reserved for Documentation. Defines the 2001:db8::/32
60 Here an overview of well-known prefixes:
63 <tr><th>Prefix</th> <th>Description</th> <th>Definition</th> <th>Note</th></tr>
64 <tr><td><tt>::/96</tt></td> <td>IpV4 compatible IpV6 address</td> <td>RFC4291</td> <td>deprecated</td></tr>
65 <tr><td><tt>::ffff:0:0/96</tt></td> <td>IpV6 mapped IpV4 address</td> <td>RFC4291</td> <td></td></tr>
66 <tr><td><tt>2000::/3</tt></td> <td>Global unicast addresses</td> <td>RFC3587</td> <td>only noted, not defined</td></tr>
67 <tr><td><tt>2001:db8::/32</tt></td> <td>Documentation-only prefix</td> <td>RFC3849</td> <td></td></tr>
68 <tr><td><tt>2002::/16</tt></td> <td>6to4 addressing</td> <td>RFC3056</td> <td></td></tr>
69 <tr><td><tt>fc00::/7</tt></td> <td>ULA</td> <td>RFC4193</td> <td></td></tr>
70 <tr><td><tt>fe80::/64</tt></td> <td>Link-local addresses</td> <td>RFC4291</td> <td></td></tr>
71 <tr><td><tt>fec0::/10</tt></td> <td>Site-local addresses </td> <td>RFC4291</td> <td>deprecated</td></tr>
72 <tr><td><tt>ff00::/8</tt></td> <td>Multicast</td> <td>RFC4291</td> <td></td></tr>
73 <tr><td><tt>ff00::/12</tt></td> <td>Globally allocated multicast</td> <td>RFC4291</td> <td></td></tr>
74 <tr><td><tt>ff10::/12</tt></td> <td>Locally allocated multicast</td> <td>RFC4291</td> <td></td></tr>
75 <tr><td><tt>ff30::/12</tt></td> <td>Unicast prefic based multicast</td> <td>RFC3306</td> <td></td></tr>
76 <tr><td><tt>ff70::/12</tt></td> <td>Multicast address with embedded RP</td> <td>RFC3956</td> <td></td></tr>
79 The INet6Address class is based on \c boost::array and is built as a fixed-size sequence of
82 \see CheckINet6Network Helper to check address against an arbitrary fixed network prefix
86 : public boost::array<boost::uint8_t,16>,
87 public ComparableSafeBool<INet6Address>
90 ///////////////////////////////////////////////////////////////////////////
93 typedef boost::function<void (INet6Address const &)> Callback;
94 ///< Callback for asynchronous from_string call
96 static INet6Address const None; ///< The empty (::0) address
97 static INet6Address const Loopback; ///< The loopback (::1) address
98 static INet6Address const AllNodes; ///< The 'all nodes' link-local multicast address
99 static INet6Address const AllRouters; ///< The 'all routers' link-local multicast address
101 enum NoInit_t { noinit };
103 /** \brief Possible scope values
105 List of all possible scope values. This list includes all scope values defined for
106 multicast addresses in RFC4291. The values \ref LinkScope, \ref SiteScope and \ref
107 GlobalScope are also used with unicast addresses.
110 InterfaceScope = 1 /**< Interface only scope */
111 , LinkScope = 2 /**< Link-local scope */
112 , AdminScope = 4 /**< Administration defined local scope */
113 , SiteScope = 5 /**< Site-local scope */
114 , OrganizationScope = 8 /**< Scope covering multiple sites of an organization */
115 , GlobalScope = 14 /**< Global Internet scope */
117 , ReservedScope = 0 /**< Reserved scope value */
118 , UnassignedScope = 6 /**< Unassigned scope, may be defined locally */
121 ///////////////////////////////////////////////////////////////////////////
122 ///\name Structors and default members
125 explicit INet6Address(NoInit_t); ///< Construct uninitialized (!) address
126 INet6Address(boost::uint16_t a0=0u, boost::uint16_t a1=0u, boost::uint16_t a2=0u,
127 boost::uint16_t a3=0u, boost::uint16_t a4=0u, boost::uint16_t a5=0u,
128 boost::uint16_t a6=0u, boost::uint16_t a7=0u);
129 ///< Construct an address constant
131 static INet6Address from_string(std::string const & s);
132 ///< Convert string to address
133 /**< This member will try to convert the given string into
134 an IP address. from_string() supports all standard IP
135 literal representations as well es hostnames.
136 \attention This call may block if \a s represents a
137 hostname which must be looked up via some network
138 protocol like DNS or NIS
139 \throws SyntaxException if the address cannot be
140 converted for some reason
141 \param[in] s Address literal or hostname */
143 static void from_string(std::string const & s, Callback const & cb);
144 ///< Convert string to address (async/non-blocking)
145 /**< This member works like
146 from_string(std::string const &). However unlike
147 from_string(std::string const &), this call will not
148 block. Instead it will call \a cb passing the
149 INet6Address instance as soon as the address has been
150 resolved (which may be immediate if the address
151 represents an IP literal). \par
152 On error, the address passed to \a cb will be empty.
153 \param[in] s Address literal or hostname
154 \param[in] cb Callback to pass the address to
157 template <class InputIterator>
158 static INet6Address from_data(InputIterator i);
159 ///< Construct address from 16 bytes of raw data
160 /**< from_data will build an address from 16 bytes of raw
161 data as accessed by the iterator. The data must be in
162 network byte order. */
164 static INet6Address from_inet4address(INet4Address addr);
165 ///< Construct an IpV6-mapped IpV4 address
166 /**< This will construct an address of the form
167 <tt>::FFFF::w.x.y.z</tt> where <tt>w.x.y.z</tt> is
168 the INet4Address value. This kind of address is called
169 an IpV6-mapped IpV4 address (see RFC4291). \par
170 IpV4 compatible IpV6 addresses are not directly
171 supported, they are deprecated in the RFC. */
173 ///////////////////////////////////////////////////////////////////////////
177 boost::uint64_t network() const; ///< Return 64bit network part
178 bool hasEuid64() const; ///< \c true, if address is based on an EUID-64
179 boost::uint64_t id() const; ///< Return interface id (EUID-64)
180 bool universalId() const; ///< \c true, if the id() is universally assigned
181 bool groupId() const; ///< \c true, if the id()'s \a group bit is set
183 bool unicast() const; ///< \c true, if address is unicast
184 bool multicast() const; ///< \c true, if address is multicast
186 ScopeId scope() const; ///< Get address's scope
187 /**< The scope of an address is one of the \ref ScopeId
188 values. We need to differentiate between unicast and
189 multicast addresses: unicast addresses only have local,
190 site or global scope (where site scope is deprecated),
191 multicast address can have a number of scope values of
192 which local, site and global are a few. See the \ref
193 ScopeId enumerators. */
194 bool globalScope() const; ///< \c true, if address is global unicast or multicast
195 bool linkScope() const; ///< \c true, if address is link-local unicast or multicast
197 INet4Address inet4address() const; ///< Return embedded IpV4 address
198 /**< Returns the IpV4 address embedded within an IpV4
199 compatible or IpV4 mapped unicast address. This address
200 is given by the last 32 bits of the IpV6 address. \par
201 The value returned is only a valid IpV4 address if
202 either ipv4Compatible() or ipv4Mapped() return \c
204 bool ipv4Compatible() const; ///< \c true, if address is IpV4 compatible
205 /**< IpV4 compatible IpV6 addresses are deprecated. */
206 bool ipv4Mapped() const; ///< \c true, if address is IpV4 mapped
208 bool globalMulticastAddr() const; ///< \c true, if T bit is \e not set
209 /**< Any multicast address with a cleared T bit must be
210 globally assigned. See RFC4291. */
211 bool prefixMulticastAddr() const; ///< \c true, if P bit is set
212 /**< In RFC4291, the P bit is specified as defining a
213 unicast prefix based multicast address. See RFC3306. */
214 bool embeddedRpAddr() const; ///< \c true, if R bit is set
215 /** In RFC4291, the R bit is specified as defining a
216 multicast address with embedded rendezvous point. See
219 bool boolean_test() const; ///< \c true, if address != '::' (None)
225 void network(boost::uint64_t net); ///< Set network part of address
226 void id(boost::uint64_t id); ///< Set interface id part of address
230 /** \brief Invalid IpV6 address syntax */
231 struct SyntaxException : public std::exception
232 { virtual char const * what() const throw() { return "Invalid IpV6 address syntax"; } };
235 /** \brief Output INet6Address instance as it's string representation
236 \related INet6Address
238 std::ostream & operator<<(std::ostream & os, INet6Address const & addr);
240 /** \brief Check address against a fixed network prefix
242 This helper allows to easily and efficiently check an address against an arbitrary network
245 if (senf::CheckINet6Network<0x2000u,0xDB8u,32u>::match(addr)) {
246 // 'addr' is within in the 2001:db8::/32 documentation-only network
251 The code generated by this call is highly optimized and as probably as efficient as it can
254 \related INet6Address
256 template <unsigned a0, unsigned a1, unsigned a2=0u, unsigned a3=0u, unsigned a4=0u,
257 unsigned a5=0u, unsigned a6=0u, unsigned a7=0u, unsigned a8=0u>
258 struct CheckINet6Network
259 : public detail::CheckINet6Network_impl<a0,a1,a2,a3,a4,a5,a6,a7,a8>
264 ///////////////////////////////hh.e////////////////////////////////////////
265 #include "INet6Address.cci"
266 #include "INet6Address.ct"
267 #include "INet6Address.cti"
274 // comment-column: 40
275 // c-file-style: "senf"
276 // indent-tabs-mode: nil
277 // ispell-local-dictionary: "american"
278 // compile-command: "scons -u test"