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 <netinet/in.h>
33 #include <boost/cstdint.hpp>
34 #include <boost/array.hpp>
35 #include <boost/operators.hpp>
36 #include "../../../Utils/safe_bool.hh"
37 #include "../../../Utils/Tags.hh"
38 #include "INet4Address.hh"
39 #include "../AddressExceptions.hh"
41 //#include "INet6Address.mpp"
42 #include "INet6Address.ih"
43 ///////////////////////////////hh.p////////////////////////////////////////
47 /** \brief INet6 network address
49 This implementation of an INet6 address is based strictly on
50 <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>: Internet Protocol
51 Version 6 (INet6) Addressing Architecture. This class provides accessors to all the
52 information fields defined in this document.
54 The INet6 addressing architecture however has several other components defined in other
55 RFC's. These RFC's should be implemented in additional modules:
57 \li <a href="http://tools.ietf.org/html/rfc4193">RFC 4193</a>:
58 Unique Local Addresses (ULA). Defines the fc00::/7 prefix
59 \li <a href="http://tools.ietf.org/html/rfc3306">RFC 3306</a>:
60 Unicast-Prefix-based INet6 Multicast Addresses. Defines the ff30::/12 prefix
61 \li <a href="http://tools.ietf.org/html/rfc3956">RFC 3956</a>:
62 Embedding the Rendezvous Point (RP) Address in an INet6 Multicast
63 Address. Defines the ff70::/12 prefix
64 \li <a href="http://tools.ietf.org/html/rfc3056">RFC 3056</a>:
65 Connection of INet6 Domains via INet4 Clouds. Defines 6to4 tunneling and the
67 \li <a href="http://tools.ietf.org/html/rfc3849">RFC 3849</a>:
68 INet6 Address Prefix Reserved for Documentation. Defines the 2001:db8::/32 prefix
70 Here an overview of well-known prefixes:
74 <tr><th>Prefix</th> <th>Description</th> <th>Definition</th> <th>Note</th></tr>
75 <tr><td><tt>::/96</tt></td> <td>INet4 compatible INet6 address</td> <td>RFC4291</td> <td>deprecated</td></tr>
76 <tr><td><tt>::ffff:0:0/96</tt></td> <td>INet6 mapped INet4 address</td> <td>RFC4291</td> <td></td></tr>
77 <tr><td><tt>2000::/3</tt></td> <td>Global unicast addresses</td> <td>RFC3587</td> <td>only noted, not defined</td></tr>
78 <tr><td><tt>2001:db8::/32</tt></td> <td>Documentation-only prefix</td> <td>RFC3849</td> <td></td></tr>
79 <tr><td><tt>2002::/16</tt></td> <td>6to4 addressing</td> <td>RFC3056</td> <td></td></tr>
80 <tr><td><tt>fc00::/7</tt></td> <td>ULA</td> <td>RFC4193</td> <td></td></tr>
81 <tr><td><tt>fe80::/64</tt></td> <td>Link-local addresses</td> <td>RFC4291</td> <td></td></tr>
82 <tr><td><tt>fec0::/10</tt></td> <td>Site-local addresses </td> <td>RFC4291</td> <td>deprecated</td></tr>
83 <tr><td><tt>ff00::/8</tt></td> <td>Multicast</td> <td>RFC4291</td> <td></td></tr>
84 <tr><td><tt>ff00::/12</tt></td> <td>Globally allocated multicast</td> <td>RFC4291</td> <td></td></tr>
85 <tr><td><tt>ff10::/12</tt></td> <td>Locally allocated multicast</td> <td>RFC4291</td> <td></td></tr>
86 <tr><td><tt>ff30::/12</tt></td> <td>Unicast prefic based multicast</td> <td>RFC3306</td> <td></td></tr>
87 <tr><td><tt>ff70::/12</tt></td> <td>Multicast address with embedded RP</td> <td>RFC3956</td> <td></td></tr>
91 The following statements all create the same INet6 address
92 <code>2001:db8::a0b1:1a2b:3dff:fe4e:5f00</code>:
94 // Used to construct constant INet6 addresses
95 INet6Address(0x2001u,0xDB8u,0x0u,0xA0B1u 0x1A2Bu,0x3DFFu,0xFE4Eu,0x5F00u)
97 // Construct INet6 address from it's string representation
98 INet6Address::from_string("2001:db8::a0b1:1a2b:3dff:fe4e:5f00")
100 // Construct an INet6 address from raw data. 'from_data' takes an arbitrary iterator (e.g. a
101 // pointer) as argument. Here we use a fixed array but normally you will need this to build
102 // an INet6 address in a packet parser
103 char rawBytes[] = { 0x20, 0x01, 0x0D, 0xB8, 0x00, 0x00, 0xA0, 0xB1,
104 0x1a, 0x2b, 0x3d, 0xff, 0xfe, 0x4e, 0xff, 0x00 };
105 INet6Address::from_data(rawBytes)
108 Since INet6Address class is based on \c boost::array and is built as a fixed-size sequence
109 of 16 bytes, you can access the raw data bytes of the address (in network byte order) using
110 \c begin(), \c end() or \c operator[]
112 INet6Address ina = ...;
113 Packet::iterator i = ...;
114 std::copy(ina.begin(), ina.end(), i); // Copies 16 bytes
117 \see CheckINet6Network \n INet6Network
120 \implementation We awkwardly need to use static named constructors (<tt>from_</tt> members)
121 instead of ordinarily overloaded constructors for one simple reason: <tt>char *</tt>
122 doubles as string literal and as arbitrary data iterator. The iterator constructor can
123 therefore not be distinguished from initialization with a string literal. Therefore we
124 need to disambiguate using the named constructors.
127 : public boost::array<boost::uint8_t,16>,
128 public comparable_safe_bool<INet6Address>
131 ///////////////////////////////////////////////////////////////////////////
134 static INet6Address const None; ///< The empty (::0) address
135 static INet6Address const Loopback; ///< The loopback (::1) address
136 static INet6Address const AllNodes; ///< The 'all nodes' link-local multicast address
137 static INet6Address const AllRouters; ///< The 'all routers' link-local multicast address
139 enum Resolve_t { ResolveINet6, ResolveINet4 };
141 /** \brief Possible scope values
143 List of all possible scope values. This list includes all scope values defined for
144 multicast addresses in <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>.
145 The values \ref LinkScope, \ref SiteScope and \ref GlobalScope are also used with
149 InterfaceScope = 1 /**< Interface only scope */
150 , LinkScope = 2 /**< Link-local scope */
151 , AdminScope = 4 /**< Administration defined local scope */
152 , SiteScope = 5 /**< Site-local scope */
153 , OrganizationScope = 8 /**< Scope covering multiple sites of an organization */
154 , GlobalScope = 14 /**< Global Internet scope */
156 , ReservedScope = 0 /**< Reserved scope value */
157 , UnassignedScope = 6 /**< Unassigned scope, may be defined locally */
160 ///////////////////////////////////////////////////////////////////////////
161 ///\name Structors and default members
164 explicit INet6Address(senf::NoInit_t); ///< Construct uninitialized (!) address
165 explicit INet6Address(boost::uint16_t a0=0u, boost::uint16_t a1=0u, boost::uint16_t a2=0u,
166 boost::uint16_t a3=0u, boost::uint16_t a4=0u, boost::uint16_t a5=0u,
167 boost::uint16_t a6=0u, boost::uint16_t a7=0u);
168 ///< Construct an address constant
170 static INet6Address from_in6addr(in6_addr const & in6addr); ///< Construct from std C struct
172 static INet6Address from_string(std::string const & s, Resolve_t resolve = ResolveINet6);
173 ///< Convert string to address
174 /**< This member will try to convert the given string into
175 an IP address. from_string() supports all standard IP
176 literal representations as well es hostnames.
177 \attention This call may block if \a s represents a
178 hostname which must be looked up via some network
179 protocol like DNS or NIS
180 \throws AddressSyntaxException if the address cannot be
181 converted for some reason
182 \param[in] s Address literal or hostname
183 \param[in] resolve If this is set to \c ResolveINet4,
184 the call will additionally try to interpret \a s as
185 an INet4 address if no valid INet6 address is
186 found. The address will be returned as mapped INet6
189 template <class InputIterator>
190 static INet6Address from_data(InputIterator i);
191 ///< Construct address from 16 bytes of raw data
192 /**< from_data will build an address from 16 bytes of raw
193 data as accessed by the iterator. The data must be in
194 network byte order. */
196 static INet6Address from_inet4address(INet4Address addr);
197 ///< Construct an INet6-mapped INet4 address
198 /**< This will construct an address of the form
199 <tt>::FFFF::w.x.y.z</tt> where <tt>w.x.y.z</tt> is
200 the INet4Address value. This kind of address is called
201 an INet6-mapped INet4 address (see
202 <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>).
204 INet4 compatible INet6 addresses are not directly
205 supported, they are deprecated in the RFC. */
207 ///////////////////////////////////////////////////////////////////////////
211 boost::uint64_t network() const; ///< Return 64bit network part
212 bool hasEuid64() const; ///< \c true, if address is based on an EUID-64
213 boost::uint64_t id() const; ///< Return interface id (EUID-64)
214 bool universalId() const; ///< \c true, if the id() is universally assigned
215 bool groupId() const; ///< \c true, if the id()'s \a group bit is set
217 bool unicast() const; ///< \c true, if address is unicast
218 bool multicast() const; ///< \c true, if address is multicast
219 /**< To support a linux specific extension, INet4 multicast
220 addressed mapped to INet6 are also interpreted as
221 multicast addresses. This is NOT part of the standard,
222 however the standard officially only allows unicast v4
223 addresses to be mapped to v6 so this does not collide
224 with any standard conforming use. */
226 ScopeId scope() const; ///< Get address's scope
227 /**< The scope of an address is one of the \ref ScopeId
228 values. We need to differentiate between unicast and
229 multicast addresses: unicast addresses only have local,
230 site or global scope (where site scope is deprecated),
231 multicast address can have a number of scope values of
232 which local, site and global are a few. See the \ref
233 ScopeId enumerators. */
234 bool globalScope() const; ///< \c true, if address is global unicast or multicast
235 bool linkScope() const; ///< \c true, if address is link-local unicast or multicast
237 INet4Address inet4address() const; ///< Return embedded INet4 address
238 /**< Returns the INet4 address embedded within an INet4
239 compatible or INet4 mapped unicast address. This address
240 is given by the last 32 bits of the INet6 address. \par
241 The value returned is only a valid INet4 address if
242 either inet4Compatible() or inet4Mapped() return \c
244 bool inet4Compatible() const; ///< \c true, if address is INet4 compatible
245 /**< INet4 compatible INet6 addresses are deprecated. */
246 bool inet4Mapped() const; ///< \c true, if address is INet4 mapped
248 bool globalMulticastAddr() const; ///< \c true, if T bit is \e not set
249 /**< Any multicast address with a cleared T bit must be
250 globally assigned. See
251 <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>. */
252 bool prefixMulticastAddr() const; ///< \c true, if P bit is set
253 /**< In <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>,
254 the P bit is specified as defining a
255 unicast prefix based multicast address. See
256 <a href="http://tools.ietf.org/html/rfc3306">RFC 3306</a>. */
257 bool embeddedRpAddr() const; ///< \c true, if R bit is set
258 /**< In <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>,
259 the R bit is specified as defining a multicast address
260 with embedded rendezvous point. See
261 <a href="http://tools.ietf.org/html/rfc3956">RFC 3956</a>. */
263 bool boolean_test() const; ///< \c true, if address != '::' (None)
269 void network(boost::uint64_t net); ///< Set network part of address
270 void id(boost::uint64_t id); ///< Set interface id part of address
276 /** \brief Output INet6Address instance as it's string representation
277 \related INet6Address
279 std::ostream & operator<<(std::ostream & os, INet6Address const & addr);
281 /** \brief Check INet6Address against a fixed network prefix
283 This helper allows to easily and efficiently check an INet6Address against an arbitrary but
284 constant network prefix. It takes from 1 to 8 arguments for the network address and an
285 additional last argument providing the prefix length. So
288 <tt>senf::CheckINet6Network<</tt> <i>addr_1</i> <tt>,</tt> <i>addr_2</i> <tt>,</tt>
289 ... <tt>,</tt> <i>prefix_len</i> <tt>></tt>
291 represents the network
294 <i>addr_1</i> <tt>:</tt> <i>addr_2</i> <tt>:</tt> ... <tt>::/</tt> <i>prefix_len</i> .
296 The class exposes a single static member <tt>match(</tt> <i>addr</i> <tt>)</tt> which
297 matches the INet6Address \a addr against the prefix:
300 if (senf::CheckINet6Network<0x2000u,0xDB8u,32u>::match(addr)) {
301 // 'addr' is within in the 2001:db8::/32 documentation-only network
306 The code generated by this call is highly optimized and probably as efficient as it can get.
308 template <unsigned a0, unsigned a1, unsigned a2=0u, unsigned a3=0u, unsigned a4=0u,
309 unsigned a5=0u, unsigned a6=0u, unsigned a7=0u, unsigned a8=0u>
310 struct CheckINet6Network
311 : public detail::CheckINet6Network_impl<a0,a1,a2,a3,a4,a5,a6,a7,a8>
314 /** \brief INet6 network prefix
316 This class represents an INet6 network prefix in CIDR notation.
319 : public boost::equality_comparable<INet6Network>,
320 public comparable_safe_bool<INet6Network>
323 ///////////////////////////////////////////////////////////////////////////
324 ///\name Structors and default members
327 INet6Network(); ///< Construct empty (::/0) network
328 INet6Network(INet6Address address, unsigned prefix_len);
329 ///< Construct network from given address and prefix length
330 explicit INet6Network(std::string s); ///< Construct network from CIDR notation
333 ///////////////////////////////////////////////////////////////////////////
335 INet6Address const & address() const; ///< Get the network address
336 unsigned prefix_len() const; ///< Get the network prefix length
338 bool boolean_test() const; ///< \c true, if INet6Network is non-empty
339 bool operator==(INet6Network const & other) const;
340 ///< Compare two networks for equality
342 bool match(INet6Address addr) const; ///< \c true, if the network includes \a addr
343 bool match(INet6Network net) const; ///< \c true, if the network includes \a net
344 /**< The is true, if \a net is sub-network (or the same as)
346 INet6Address host(boost::uint64_t id); ///< Return the host with the given id
347 /**< Returns the host with the given number within the
348 network. This call replaces the lower 64 bits of the
349 network address with the given id. */
351 INet6Network subnet(boost::uint64_t net, unsigned prefix_len);
352 ///< Return the given subnet of \c this
353 /**< The returned INet6Network will be a subnet of \c this
354 with the given network number. The network number is
355 comprised by the bits above \a prefix_len:
357 INet6Network("2001:db8::/32").subnet(0x12u,40u) == INet6Network("2001:db8:1200::/40")
358 INet6Network("2001:db8:1200::/40").subnet(0x2345,64u) == INet6Network("2001:db8:1200:2345::/64")
360 \param[in] net network number
361 \param[in] prefix_len length of subnet prefix */
366 unsigned prefix_len_;
367 INet6Address address_;
370 /** \brief Output INet6Network instance as it's string representation
371 \related INet6Network
373 std::ostream & operator<<(std::ostream & os, INet6Network const & addr);
376 ///////////////////////////////hh.e////////////////////////////////////////
377 #include "INet6Address.cci"
378 #include "INet6Address.ct"
379 #include "INet6Address.cti"
386 // comment-column: 40
387 // c-file-style: "senf"
388 // indent-tabs-mode: nil
389 // ispell-local-dictionary: "american"
390 // compile-command: "scons -u test"