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