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