some documentation updates
[senf.git] / Socket / Protocols / INet / INet6Address.hh
1 // $Id$
2 //
3 // Copyright (C) 2007 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief INet6Address public header */
25
26 #ifndef HH_INet6Address_
27 #define HH_INet6Address_ 1
28
29 // Custom includes
30 #include <iostream>
31 #include <string>
32 #include <boost/cstdint.hpp>
33 #include <boost/function.hpp>
34 #include <boost/array.hpp>
35 #include "Utils/SafeBool.hh"
36 #include "INet4Address.hh"
37
38 //#include "INet6Address.mpp"
39 #include "INet6Address.ih"
40 ///////////////////////////////hh.p////////////////////////////////////////
41
42 namespace senf {
43
44     /** \brief IpV6 network address
45
46         This implementation of an IpV6 address is based strictly on 
47         <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>: Internet Protocol
48         Version 6 (IPv6) Addressing Architecture. This class provides accessors to all the
49         information fields defined in this document.
50
51         The IpV6 addressing architecture however has several other components defined in other
52         RFC's. These RFC's should be implemented in additional modules:
53
54         \li <a href="http://tools.ietf.org/html/rfc4193">RFC 4193</a>:
55             Unique Local Addresses (ULA). Defines the fc00::/7 prefix
56         \li <a href="http://tools.ietf.org/html/rfc3306">RFC 3306</a>:
57             Unicast-Prefix-based IPv6 Multicast Addresses. Defines the ff30::/12 prefix
58         \li <a href="http://tools.ietf.org/html/rfc3956">RFC 3956</a>:
59             Embedding the Rendezvous Point (RP) Address in an IPv6 Multicast
60             Address. Defines the ff70::/12 prefix
61         \li <a href="http://tools.ietf.org/html/rfc3056">RFC 3056</a>:
62             Connection of IPv6 Domains via IPv4 Clouds. Defines 6to4 tunneling and the
63             2002::/16 prefix
64         \li <a href="http://tools.ietf.org/html/rfc3849">RFC 3849</a>:
65             IPv6 Address Prefix Reserved for Documentation. Defines the 2001:db8::/32 prefix
66         
67         Here an overview of well-known prefixes:
68
69         <table class="senf">
70         <tr><th>Prefix</th>                  <th>Description</th>                        <th>Definition</th> <th>Note</th></tr>
71         <tr><td><tt>::/96</tt></td>          <td>IpV4 compatible IpV6 address</td>       <td>RFC4291</td>    <td>deprecated</td></tr>
72         <tr><td><tt>::ffff:0:0/96</tt></td>  <td>IpV6 mapped IpV4 address</td>           <td>RFC4291</td>    <td></td></tr>
73         <tr><td><tt>2000::/3</tt></td>       <td>Global unicast addresses</td>           <td>RFC3587</td>    <td>only noted, not defined</td></tr>
74         <tr><td><tt>2001:db8::/32</tt></td>  <td>Documentation-only prefix</td>          <td>RFC3849</td>    <td></td></tr>
75         <tr><td><tt>2002::/16</tt></td>      <td>6to4 addressing</td>                    <td>RFC3056</td>    <td></td></tr>
76         <tr><td><tt>fc00::/7</tt></td>       <td>ULA</td>                                <td>RFC4193</td>    <td></td></tr>
77         <tr><td><tt>fe80::/64</tt></td>      <td>Link-local addresses</td>               <td>RFC4291</td>    <td></td></tr>
78         <tr><td><tt>fec0::/10</tt></td>      <td>Site-local addresses </td>              <td>RFC4291</td>    <td>deprecated</td></tr>
79         <tr><td><tt>ff00::/8</tt></td>       <td>Multicast</td>                          <td>RFC4291</td>    <td></td></tr>
80         <tr><td><tt>ff00::/12</tt></td>      <td>Globally allocated multicast</td>       <td>RFC4291</td>    <td></td></tr>
81         <tr><td><tt>ff10::/12</tt></td>      <td>Locally allocated multicast</td>        <td>RFC4291</td>    <td></td></tr>
82         <tr><td><tt>ff30::/12</tt></td>      <td>Unicast prefic based multicast</td>     <td>RFC3306</td>    <td></td></tr>
83         <tr><td><tt>ff70::/12</tt></td>      <td>Multicast address with embedded RP</td> <td>RFC3956</td>    <td></td></tr>
84         </table>
85
86         The INet6Address class is based on \c boost::array and is built as a fixed-size sequence of
87         16 bytes.
88
89         \see CheckINet6Network Helper to check address against an arbitrary fixed network prefix
90         \ingroup addr_group
91
92         \implementation We awkwardly need to use static named constructors (<tt>from_</tt> members)
93             instead of ordinarily overloaded constructors for one simple reason: <tt>char *</tt>
94             doubles as string literal and as arbitrary data iterator. The iterator constructor can
95             therefore not be distinguished from initialization with a string literal. Therefore we
96             need to disambiguate using the named constructors.
97      */
98     class INet6Address
99         : public boost::array<boost::uint8_t,16>,
100           public ComparableSafeBool<INet6Address>
101     {
102     public:
103         ///////////////////////////////////////////////////////////////////////////
104         // Types
105
106         typedef boost::function<void (INet6Address const &)> Callback;
107                                         ///< Callback for asynchronous from_string call
108
109         static INet6Address const None;        ///< The empty (::0) address
110         static INet6Address const Loopback;    ///< The loopback (::1) address
111         static INet6Address const AllNodes;    ///< The 'all nodes' link-local multicast address
112         static INet6Address const AllRouters;  ///< The 'all routers' link-local multicast address
113
114         enum NoInit_t { noinit };
115         enum Resolve_t { ResolveINet6, ResolveINet4 };
116
117         /** \brief Possible scope values
118
119             List of all possible scope values. This list includes all scope values defined for
120             multicast addresses in <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>. 
121             The values \ref LinkScope, \ref SiteScope and \ref GlobalScope are also used with 
122             unicast addresses.
123          */
124         enum ScopeId {
125               InterfaceScope    =  1    /**< Interface only scope */
126             , LinkScope         =  2    /**< Link-local scope */
127             , AdminScope        =  4    /**< Administration defined local scope */
128             , SiteScope         =  5    /**< Site-local scope */
129             , OrganizationScope =  8    /**< Scope covering multiple sites of an organization */
130             , GlobalScope       = 14    /**< Global Internet scope */
131
132             , ReservedScope     =  0    /**< Reserved scope value */
133             , UnassignedScope   =  6    /**< Unassigned scope, may be defined locally */
134         }; 
135
136         ///////////////////////////////////////////////////////////////////////////
137         ///\name Structors and default members
138         ///@{
139
140         explicit INet6Address(NoInit_t); ///< Construct uninitialized (!) address
141         INet6Address(boost::uint16_t a0=0u, boost::uint16_t a1=0u, boost::uint16_t a2=0u,
142                      boost::uint16_t a3=0u, boost::uint16_t a4=0u, boost::uint16_t a5=0u,
143                      boost::uint16_t a6=0u, boost::uint16_t a7=0u);
144                                         ///< Construct an address constant
145
146         static INet6Address from_string(std::string const & s, Resolve_t resolve = ResolveINet6);
147                                         ///< Convert string to address
148                                         /**< This member will try to convert the given string into
149                                              an IP address. from_string() supports all standard IP
150                                              literal representations as well es hostnames.
151                                              \attention This call may block if \a s represents a
152                                                  hostname which must be looked up via some network
153                                                  protocol like DNS or NIS
154                                              \throws SyntaxException if the address cannot be
155                                                  converted for some reason
156                                              \param[in] s Address literal or hostname 
157                                              \param[in] resolve If this is set to \c ResolveINet4,
158                                                  the call will additionally try to interpret \a s as
159                                                  an IpV4 address if no valid IpV6 address is
160                                                  found. The address will be returned as mapped IpV6
161                                                  address. */
162
163         static void from_string(std::string const & s, Callback const & cb, 
164                                 Resolve_t resolve = ResolveINet6);
165                                         ///< Convert string to address (async/non-blocking)
166                                         /**< This member works like
167                                              from_string(std::string const &). However unlike
168                                              from_string(std::string const &), this call will not
169                                              block. Instead it will call \a cb passing the
170                                              INet6Address instance as soon as the address has been
171                                              resolved (which may be immediate if the address
172                                              represents an IP literal). \par
173                                              On error, the address passed to \a cb will be empty.
174                                              \param[in] s Address literal or hostname
175                                              \param[in] cb Callback to pass the address to 
176                                              \param[in] resolve If this is set to \c ResolveINet4,
177                                                  the call will additionally try to interpret \a s as
178                                                  an IpV4 address if no valid IpV6 address is
179                                                  found. The address will be returned as mapped IpV6
180                                                  address.
181                                              \fixme Implement */
182
183         template <class InputIterator> 
184         static INet6Address from_data(InputIterator i);
185                                         ///< Construct address from 16 bytes of raw data
186                                         /**< from_data will build an address from 16 bytes of raw
187                                              data as accessed by the iterator. The data must be in
188                                              network byte order. */
189
190         static INet6Address from_inet4address(INet4Address addr);
191                                         ///< Construct an IpV6-mapped IpV4 address
192                                         /**< This will construct an address of the form
193                                              <tt>::FFFF::w.x.y.z</tt> where <tt>w.x.y.z</tt> is
194                                              the INet4Address value. This kind of address is called
195                                              an IpV6-mapped IpV4 address (see 
196                                              <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>).
197                                              \par 
198                                              IpV4 compatible IpV6 addresses are not directly
199                                              supported, they are deprecated in the RFC. */
200         ///@}
201         ///////////////////////////////////////////////////////////////////////////
202         ///\name Accessors
203         ///@{
204
205         boost::uint64_t network() const; ///< Return 64bit network part
206         bool hasEuid64() const;         ///< \c true, if address is based on an EUID-64
207         boost::uint64_t id() const;     ///< Return interface id (EUID-64)
208         bool universalId() const;       ///< \c true, if the id() is universally assigned
209         bool groupId() const;           ///< \c true, if the id()'s \a group bit is set
210
211         bool unicast() const;           ///< \c true, if address is unicast
212         bool multicast() const;         ///< \c true, if address is multicast
213
214         ScopeId scope() const;          ///< Get address's scope
215                                         /**< The scope of an address is one of the \ref ScopeId
216                                              values. We need to differentiate between unicast and
217                                              multicast addresses: unicast addresses only have local,
218                                              site or global scope (where site scope is deprecated),
219                                              multicast address can have a number of scope values of
220                                              which local, site and global are a few. See the \ref
221                                              ScopeId enumerators. */ 
222         bool globalScope() const;       ///< \c true, if address is global unicast or multicast
223         bool linkScope() const;         ///< \c true, if address is link-local unicast or multicast
224
225         INet4Address inet4address() const; ///< Return embedded IpV4 address
226                                         /**< Returns the IpV4 address embedded within an IpV4
227                                              compatible or IpV4 mapped unicast address. This address
228                                              is given by the last 32 bits of the IpV6 address. \par
229                                              The value returned is only a valid IpV4 address if
230                                              either ipv4Compatible() or ipv4Mapped() return \c
231                                              true. */ 
232         bool ipv4Compatible() const;    ///< \c true, if address is IpV4 compatible
233                                         /**< IpV4 compatible IpV6 addresses are deprecated. */
234         bool ipv4Mapped() const;        ///< \c true, if address is IpV4 mapped
235
236         bool globalMulticastAddr() const; ///< \c true, if T bit is \e not set
237                                         /**< Any multicast address with a cleared T bit must be
238                                              globally assigned. See 
239                                              <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>. */
240         bool prefixMulticastAddr() const; ///< \c true, if P bit is set
241                                         /**< In <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>,
242                                              the P bit is specified as defining a
243                                              unicast prefix based multicast address. See 
244                                              <a href="http://tools.ietf.org/html/rfc3306">RFC 3306</a>. */ 
245         bool embeddedRpAddr() const;    ///< \c true, if R bit is set
246                                         /**< In <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>,
247                                              the R bit is specified as defining a multicast address 
248                                              with embedded rendezvous point. See
249                                              <a href="http://tools.ietf.org/html/rfc3956">RFC 3956</a>. */
250
251         bool boolean_test() const;      ///< \c true, if address != '::' (None)
252
253         ///@}
254         ///\name Mutators
255         ///@{
256         
257         void network(boost::uint64_t net); ///< Set network part of address
258         void id(boost::uint64_t id);    ///< Set interface id part of address
259
260         ///@}
261
262         /** \brief Invalid IpV6 address syntax */
263         struct SyntaxException : public std::exception
264         { virtual char const * what() const throw() { return "Invalid IpV6 address syntax"; } };
265     };
266
267     /** \brief Output INet6Address instance as it's string representation
268         \related INet6Address
269      */
270     std::ostream & operator<<(std::ostream & os, INet6Address const & addr);
271
272     /** \brief Check address against a fixed network prefix
273         
274         This helper allows to easily and efficiently check an address against an arbitrary network
275         prefix:
276         \code
277         if (senf::CheckINet6Network<0x2000u,0xDB8u,32u>::match(addr)) {
278             // 'addr' is within in the 2001:db8::/32 documentation-only network
279             ...
280         }
281         \endcode
282
283         The code generated by this call is highly optimized and as probably as efficient as it can
284         get.
285
286         \related INet6Address
287      */
288     template <unsigned a0, unsigned a1, unsigned a2=0u, unsigned a3=0u, unsigned a4=0u,
289               unsigned a5=0u, unsigned a6=0u, unsigned a7=0u, unsigned a8=0u>
290     struct CheckINet6Network
291         : public detail::CheckINet6Network_impl<a0,a1,a2,a3,a4,a5,a6,a7,a8>
292     {};
293
294 }
295
296 ///////////////////////////////hh.e////////////////////////////////////////
297 #include "INet6Address.cci"
298 #include "INet6Address.ct"
299 #include "INet6Address.cti"
300 #endif
301
302 \f
303 // Local Variables:
304 // mode: c++
305 // fill-column: 100
306 // comment-column: 40
307 // c-file-style: "senf"
308 // indent-tabs-mode: nil
309 // ispell-local-dictionary: "american"
310 // compile-command: "scons -u test"
311 // End: