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 };
102 enum Resolve_t { ResolveINet6, ResolveINet4 };
104 /** \brief Possible scope values
106 List of all possible scope values. This list includes all scope values defined for
107 multicast addresses in RFC4291. The values \ref LinkScope, \ref SiteScope and \ref
108 GlobalScope are also used with unicast addresses.
111 InterfaceScope = 1 /**< Interface only scope */
112 , LinkScope = 2 /**< Link-local scope */
113 , AdminScope = 4 /**< Administration defined local scope */
114 , SiteScope = 5 /**< Site-local scope */
115 , OrganizationScope = 8 /**< Scope covering multiple sites of an organization */
116 , GlobalScope = 14 /**< Global Internet scope */
118 , ReservedScope = 0 /**< Reserved scope value */
119 , UnassignedScope = 6 /**< Unassigned scope, may be defined locally */
122 ///////////////////////////////////////////////////////////////////////////
123 ///\name Structors and default members
126 explicit INet6Address(NoInit_t); ///< Construct uninitialized (!) address
127 INet6Address(boost::uint16_t a0=0u, boost::uint16_t a1=0u, boost::uint16_t a2=0u,
128 boost::uint16_t a3=0u, boost::uint16_t a4=0u, boost::uint16_t a5=0u,
129 boost::uint16_t a6=0u, boost::uint16_t a7=0u);
130 ///< Construct an address constant
132 static INet6Address from_string(std::string const & s, Resolve_t resolve = ResolveINet6);
133 ///< Convert string to address
134 /**< This member will try to convert the given string into
135 an IP address. from_string() supports all standard IP
136 literal representations as well es hostnames.
137 \attention This call may block if \a s represents a
138 hostname which must be looked up via some network
139 protocol like DNS or NIS
140 \throws SyntaxException if the address cannot be
141 converted for some reason
142 \param[in] s Address literal or hostname
143 \param[in] resolve If this is set to \c ResolveINet4,
144 the call will additionally try to interpret \a s as
145 an IpV4 address if no valid IpV6 address is
146 found. The address will be returned as mapped IpV6
149 static void from_string(std::string const & s, Callback const & cb,
150 Resolve_t resolve = ResolveINet6);
151 ///< Convert string to address (async/non-blocking)
152 /**< This member works like
153 from_string(std::string const &). However unlike
154 from_string(std::string const &), this call will not
155 block. Instead it will call \a cb passing the
156 INet6Address instance as soon as the address has been
157 resolved (which may be immediate if the address
158 represents an IP literal). \par
159 On error, the address passed to \a cb will be empty.
160 \param[in] s Address literal or hostname
161 \param[in] cb Callback to pass the address to
162 \param[in] resolve If this is set to \c ResolveINet4,
163 the call will additionally try to interpret \a s as
164 an IpV4 address if no valid IpV6 address is
165 found. The address will be returned as mapped IpV6
169 template <class InputIterator>
170 static INet6Address from_data(InputIterator i);
171 ///< Construct address from 16 bytes of raw data
172 /**< from_data will build an address from 16 bytes of raw
173 data as accessed by the iterator. The data must be in
174 network byte order. */
176 static INet6Address from_inet4address(INet4Address addr);
177 ///< Construct an IpV6-mapped IpV4 address
178 /**< This will construct an address of the form
179 <tt>::FFFF::w.x.y.z</tt> where <tt>w.x.y.z</tt> is
180 the INet4Address value. This kind of address is called
181 an IpV6-mapped IpV4 address (see RFC4291). \par
182 IpV4 compatible IpV6 addresses are not directly
183 supported, they are deprecated in the RFC. */
185 ///////////////////////////////////////////////////////////////////////////
189 boost::uint64_t network() const; ///< Return 64bit network part
190 bool hasEuid64() const; ///< \c true, if address is based on an EUID-64
191 boost::uint64_t id() const; ///< Return interface id (EUID-64)
192 bool universalId() const; ///< \c true, if the id() is universally assigned
193 bool groupId() const; ///< \c true, if the id()'s \a group bit is set
195 bool unicast() const; ///< \c true, if address is unicast
196 bool multicast() const; ///< \c true, if address is multicast
198 ScopeId scope() const; ///< Get address's scope
199 /**< The scope of an address is one of the \ref ScopeId
200 values. We need to differentiate between unicast and
201 multicast addresses: unicast addresses only have local,
202 site or global scope (where site scope is deprecated),
203 multicast address can have a number of scope values of
204 which local, site and global are a few. See the \ref
205 ScopeId enumerators. */
206 bool globalScope() const; ///< \c true, if address is global unicast or multicast
207 bool linkScope() const; ///< \c true, if address is link-local unicast or multicast
209 INet4Address inet4address() const; ///< Return embedded IpV4 address
210 /**< Returns the IpV4 address embedded within an IpV4
211 compatible or IpV4 mapped unicast address. This address
212 is given by the last 32 bits of the IpV6 address. \par
213 The value returned is only a valid IpV4 address if
214 either ipv4Compatible() or ipv4Mapped() return \c
216 bool ipv4Compatible() const; ///< \c true, if address is IpV4 compatible
217 /**< IpV4 compatible IpV6 addresses are deprecated. */
218 bool ipv4Mapped() const; ///< \c true, if address is IpV4 mapped
220 bool globalMulticastAddr() const; ///< \c true, if T bit is \e not set
221 /**< Any multicast address with a cleared T bit must be
222 globally assigned. See RFC4291. */
223 bool prefixMulticastAddr() const; ///< \c true, if P bit is set
224 /**< In RFC4291, the P bit is specified as defining a
225 unicast prefix based multicast address. See RFC3306. */
226 bool embeddedRpAddr() const; ///< \c true, if R bit is set
227 /** In RFC4291, the R bit is specified as defining a
228 multicast address with embedded rendezvous point. See
231 bool boolean_test() const; ///< \c true, if address != '::' (None)
237 void network(boost::uint64_t net); ///< Set network part of address
238 void id(boost::uint64_t id); ///< Set interface id part of address
242 /** \brief Invalid IpV6 address syntax */
243 struct SyntaxException : public std::exception
244 { virtual char const * what() const throw() { return "Invalid IpV6 address syntax"; } };
247 /** \brief Output INet6Address instance as it's string representation
248 \related INet6Address
250 std::ostream & operator<<(std::ostream & os, INet6Address const & addr);
252 /** \brief Check address against a fixed network prefix
254 This helper allows to easily and efficiently check an address against an arbitrary network
257 if (senf::CheckINet6Network<0x2000u,0xDB8u,32u>::match(addr)) {
258 // 'addr' is within in the 2001:db8::/32 documentation-only network
263 The code generated by this call is highly optimized and as probably as efficient as it can
266 \related INet6Address
268 template <unsigned a0, unsigned a1, unsigned a2=0u, unsigned a3=0u, unsigned a4=0u,
269 unsigned a5=0u, unsigned a6=0u, unsigned a7=0u, unsigned a8=0u>
270 struct CheckINet6Network
271 : public detail::CheckINet6Network_impl<a0,a1,a2,a3,a4,a5,a6,a7,a8>
276 ///////////////////////////////hh.e////////////////////////////////////////
277 #include "INet6Address.cci"
278 #include "INet6Address.ct"
279 #include "INet6Address.cti"
286 // comment-column: 40
287 // c-file-style: "senf"
288 // indent-tabs-mode: nil
289 // ispell-local-dictionary: "american"
290 // compile-command: "scons -u test"