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