4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief INet6Address public header */
26 #ifndef HH_INet6Address_
27 #define HH_INet6Address_ 1
32 #include <boost/cstdint.hpp>
33 #include <boost/array.hpp>
34 #include <boost/operators.hpp>
35 #include "../../../Utils/safe_bool.hh"
36 #include "../../../Utils/Tags.hh"
37 #include "INet4Address.hh"
38 #include "../AddressExceptions.hh"
40 //#include "INet6Address.mpp"
41 #include "INet6Address.ih"
42 ///////////////////////////////hh.p////////////////////////////////////////
46 /** \brief IPv6 network address
48 This implementation of an IPv6 address is based strictly on
49 <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>: Internet Protocol
50 Version 6 (IPv6) Addressing Architecture. This class provides accessors to all the
51 information fields defined in this document.
53 The IPv6 addressing architecture however has several other components defined in other
54 RFC's. These RFC's should be implemented in additional modules:
56 \li <a href="http://tools.ietf.org/html/rfc4193">RFC 4193</a>:
57 Unique Local Addresses (ULA). Defines the fc00::/7 prefix
58 \li <a href="http://tools.ietf.org/html/rfc3306">RFC 3306</a>:
59 Unicast-Prefix-based IPv6 Multicast Addresses. Defines the ff30::/12 prefix
60 \li <a href="http://tools.ietf.org/html/rfc3956">RFC 3956</a>:
61 Embedding the Rendezvous Point (RP) Address in an IPv6 Multicast
62 Address. Defines the ff70::/12 prefix
63 \li <a href="http://tools.ietf.org/html/rfc3056">RFC 3056</a>:
64 Connection of IPv6 Domains via IPv4 Clouds. Defines 6to4 tunneling and the
66 \li <a href="http://tools.ietf.org/html/rfc3849">RFC 3849</a>:
67 IPv6 Address Prefix Reserved for Documentation. Defines the 2001:db8::/32 prefix
69 Here an overview of well-known prefixes:
72 <tr><th>Prefix</th> <th>Description</th> <th>Definition</th> <th>Note</th></tr>
73 <tr><td><tt>::/96</tt></td> <td>IPv4 compatible IPv6 address</td> <td>RFC4291</td> <td>deprecated</td></tr>
74 <tr><td><tt>::ffff:0:0/96</tt></td> <td>IPv6 mapped IPv4 address</td> <td>RFC4291</td> <td></td></tr>
75 <tr><td><tt>2000::/3</tt></td> <td>Global unicast addresses</td> <td>RFC3587</td> <td>only noted, not defined</td></tr>
76 <tr><td><tt>2001:db8::/32</tt></td> <td>Documentation-only prefix</td> <td>RFC3849</td> <td></td></tr>
77 <tr><td><tt>2002::/16</tt></td> <td>6to4 addressing</td> <td>RFC3056</td> <td></td></tr>
78 <tr><td><tt>fc00::/7</tt></td> <td>ULA</td> <td>RFC4193</td> <td></td></tr>
79 <tr><td><tt>fe80::/64</tt></td> <td>Link-local addresses</td> <td>RFC4291</td> <td></td></tr>
80 <tr><td><tt>fec0::/10</tt></td> <td>Site-local addresses </td> <td>RFC4291</td> <td>deprecated</td></tr>
81 <tr><td><tt>ff00::/8</tt></td> <td>Multicast</td> <td>RFC4291</td> <td></td></tr>
82 <tr><td><tt>ff00::/12</tt></td> <td>Globally allocated multicast</td> <td>RFC4291</td> <td></td></tr>
83 <tr><td><tt>ff10::/12</tt></td> <td>Locally allocated multicast</td> <td>RFC4291</td> <td></td></tr>
84 <tr><td><tt>ff30::/12</tt></td> <td>Unicast prefic based multicast</td> <td>RFC3306</td> <td></td></tr>
85 <tr><td><tt>ff70::/12</tt></td> <td>Multicast address with embedded RP</td> <td>RFC3956</td> <td></td></tr>
88 The INet6Address class is based on \c boost::array and is built as a fixed-size sequence of
91 \see CheckINet6Network \n INet6Network
94 \implementation We awkwardly need to use static named constructors (<tt>from_</tt> members)
95 instead of ordinarily overloaded constructors for one simple reason: <tt>char *</tt>
96 doubles as string literal and as arbitrary data iterator. The iterator constructor can
97 therefore not be distinguished from initialization with a string literal. Therefore we
98 need to disambiguate using the named constructors.
101 : public boost::array<boost::uint8_t,16>,
102 public comparable_safe_bool<INet6Address>
105 ///////////////////////////////////////////////////////////////////////////
108 static INet6Address const None; ///< The empty (::0) address
109 static INet6Address const Loopback; ///< The loopback (::1) address
110 static INet6Address const AllNodes; ///< The 'all nodes' link-local multicast address
111 static INet6Address const AllRouters; ///< The 'all routers' link-local multicast address
113 enum Resolve_t { ResolveINet6, ResolveINet4 };
115 /** \brief Possible scope values
117 List of all possible scope values. This list includes all scope values defined for
118 multicast addresses in <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>.
119 The values \ref LinkScope, \ref SiteScope and \ref GlobalScope are also used with
123 InterfaceScope = 1 /**< Interface only scope */
124 , LinkScope = 2 /**< Link-local scope */
125 , AdminScope = 4 /**< Administration defined local scope */
126 , SiteScope = 5 /**< Site-local scope */
127 , OrganizationScope = 8 /**< Scope covering multiple sites of an organization */
128 , GlobalScope = 14 /**< Global Internet scope */
130 , ReservedScope = 0 /**< Reserved scope value */
131 , UnassignedScope = 6 /**< Unassigned scope, may be defined locally */
134 ///////////////////////////////////////////////////////////////////////////
135 ///\name Structors and default members
138 explicit INet6Address(senf::NoInit_t); ///< Construct uninitialized (!) address
139 INet6Address(boost::uint16_t a0=0u, boost::uint16_t a1=0u, boost::uint16_t a2=0u,
140 boost::uint16_t a3=0u, boost::uint16_t a4=0u, boost::uint16_t a5=0u,
141 boost::uint16_t a6=0u, boost::uint16_t a7=0u);
142 ///< Construct an address constant
144 static INet6Address from_string(std::string const & s, Resolve_t resolve = ResolveINet6);
145 ///< Convert string to address
146 /**< This member will try to convert the given string into
147 an IP address. from_string() supports all standard IP
148 literal representations as well es hostnames.
149 \attention This call may block if \a s represents a
150 hostname which must be looked up via some network
151 protocol like DNS or NIS
152 \throws AddressSyntaxException if the address cannot be
153 converted for some reason
154 \param[in] s Address literal or hostname
155 \param[in] resolve If this is set to \c ResolveINet4,
156 the call will additionally try to interpret \a s as
157 an IPv4 address if no valid IPv6 address is
158 found. The address will be returned as mapped IPv6
161 template <class InputIterator>
162 static INet6Address from_data(InputIterator i);
163 ///< Construct address from 16 bytes of raw data
164 /**< from_data will build an address from 16 bytes of raw
165 data as accessed by the iterator. The data must be in
166 network byte order. */
168 static INet6Address from_inet4address(INet4Address addr);
169 ///< Construct an IPv6-mapped IPv4 address
170 /**< This will construct an address of the form
171 <tt>::FFFF::w.x.y.z</tt> where <tt>w.x.y.z</tt> is
172 the INet4Address value. This kind of address is called
173 an IPv6-mapped IPv4 address (see
174 <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>).
176 IPv4 compatible IPv6 addresses are not directly
177 supported, they are deprecated in the RFC. */
179 ///////////////////////////////////////////////////////////////////////////
183 boost::uint64_t network() const; ///< Return 64bit network part
184 bool hasEuid64() const; ///< \c true, if address is based on an EUID-64
185 boost::uint64_t id() const; ///< Return interface id (EUID-64)
186 bool universalId() const; ///< \c true, if the id() is universally assigned
187 bool groupId() const; ///< \c true, if the id()'s \a group bit is set
189 bool unicast() const; ///< \c true, if address is unicast
190 bool multicast() const; ///< \c true, if address is multicast
192 ScopeId scope() const; ///< Get address's scope
193 /**< The scope of an address is one of the \ref ScopeId
194 values. We need to differentiate between unicast and
195 multicast addresses: unicast addresses only have local,
196 site or global scope (where site scope is deprecated),
197 multicast address can have a number of scope values of
198 which local, site and global are a few. See the \ref
199 ScopeId enumerators. */
200 bool globalScope() const; ///< \c true, if address is global unicast or multicast
201 bool linkScope() const; ///< \c true, if address is link-local unicast or multicast
203 INet4Address inet4address() const; ///< Return embedded IPv4 address
204 /**< Returns the IPv4 address embedded within an IPv4
205 compatible or IPv4 mapped unicast address. This address
206 is given by the last 32 bits of the IPv6 address. \par
207 The value returned is only a valid IPv4 address if
208 either ipv4Compatible() or ipv4Mapped() return \c
210 bool ipv4Compatible() const; ///< \c true, if address is IPv4 compatible
211 /**< IPv4 compatible IPv6 addresses are deprecated. */
212 bool ipv4Mapped() const; ///< \c true, if address is IPv4 mapped
214 bool globalMulticastAddr() const; ///< \c true, if T bit is \e not set
215 /**< Any multicast address with a cleared T bit must be
216 globally assigned. See
217 <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>. */
218 bool prefixMulticastAddr() const; ///< \c true, if P bit is set
219 /**< In <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>,
220 the P bit is specified as defining a
221 unicast prefix based multicast address. See
222 <a href="http://tools.ietf.org/html/rfc3306">RFC 3306</a>. */
223 bool embeddedRpAddr() const; ///< \c true, if R bit is set
224 /**< In <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>,
225 the R bit is specified as defining a multicast address
226 with embedded rendezvous point. See
227 <a href="http://tools.ietf.org/html/rfc3956">RFC 3956</a>. */
229 bool boolean_test() const; ///< \c true, if address != '::' (None)
235 void network(boost::uint64_t net); ///< Set network part of address
236 void id(boost::uint64_t id); ///< Set interface id part of address
242 /** \brief Output INet6Address instance as it's string representation
243 \related INet6Address
245 std::ostream & operator<<(std::ostream & os, INet6Address const & addr);
247 /** \brief Check INet6Address against a fixed network prefix
249 This helper allows to easily and efficiently check an INet6Address against an arbitrary but
250 constant network prefix. It takes from 1 to 8 arguments for the network address and an
251 additional last argument providing the prefix length. So
254 <tt>senf::CheckINet6Network<</tt> <i>addr_1</i> <tt>,</tt> <i>addr_2</i> <tt>,</tt>
255 ... <tt>,</tt> <i>prefix_len</i> <tt>></tt>
257 represents the network
260 <i>addr_1</i> <tt>:</tt> <i>addr_2</i> <tt>:</tt> ... <tt>::/</tt> <i>prefix_len</i> .
262 The class exposes a single static member <tt>match(</tt> <i>addr</i> <tt>)</tt> which
263 matches the INet6Address \a addr against the prefix:
266 if (senf::CheckINet6Network<0x2000u,0xDB8u,32u>::match(addr)) {
267 // 'addr' is within in the 2001:db8::/32 documentation-only network
272 The code generated by this call is highly optimized and probably as efficient as it can get.
274 template <unsigned a0, unsigned a1, unsigned a2=0u, unsigned a3=0u, unsigned a4=0u,
275 unsigned a5=0u, unsigned a6=0u, unsigned a7=0u, unsigned a8=0u>
276 struct CheckINet6Network
277 : public detail::CheckINet6Network_impl<a0,a1,a2,a3,a4,a5,a6,a7,a8>
280 /** \brief IPv6 network prefix
282 This class represents an IPv6 network prefix in CIDR notation.
285 : public boost::equality_comparable<INet6Network>,
286 public comparable_safe_bool<INet6Network>
289 ///////////////////////////////////////////////////////////////////////////
290 ///\name Structors and default members
293 INet6Network(); ///< Construct empty (::/0) network
294 INet6Network(INet6Address address, unsigned prefix_len);
295 ///< Construct network from given address and prefix length
296 explicit INet6Network(std::string s); ///< Construct network from CIDR notation
299 ///////////////////////////////////////////////////////////////////////////
301 INet6Address const & address() const; ///< Get the network address
302 unsigned prefix_len() const; ///< Get the network prefix length
304 bool boolean_test() const; ///< \c true, if INet6Network is non-empty
305 bool operator==(INet6Network const & other) const;
306 ///< Compare two networks for equality
308 bool match(INet6Address addr) const; ///< \c true, if the network includes \a addr
309 bool match(INet6Network net) const; ///< \c true, if the network includes \a net
310 /**< The is true, if \a net is sub-network (or the same as)
312 INet6Address host(boost::uint64_t id); ///< Return the host with the given id
313 /**< Returns the host with the given number within the
314 network. This call replaces the lower 64 bits of the
315 network address with the given id. */
317 INet6Network subnet(boost::uint64_t net, unsigned prefix_len);
318 ///< Return the given subnet of \c this
319 /**< The returned INet6Network will be a subnet of \c this
320 with the given network number. The network number is
321 comprised by the bits above \a prefix_len:
323 INet6Network("2001:db8::/32").subnet(0x12u,40u) == INet6Network("2001:db8:1200::/40")
324 INet6Network("2001:db8:1200::/40").subnet(0x2345,64u) == INet6Network("2001:db8:1200:2345::/64")
326 \param[in] net network number
327 \param[in] prefix_len length of subnet prefix */
332 unsigned prefix_len_;
333 INet6Address address_;
336 /** \brief Output INet6Network instance as it's string representation
337 \related INet6Network
339 std::ostream & operator<<(std::ostream & os, INet6Network const & addr);
342 ///////////////////////////////hh.e////////////////////////////////////////
343 #include "INet6Address.cci"
344 #include "INet6Address.ct"
345 #include "INet6Address.cti"
352 // comment-column: 40
353 // c-file-style: "senf"
354 // indent-tabs-mode: nil
355 // ispell-local-dictionary: "american"
356 // compile-command: "scons -u test"