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