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