Termlib: fixed endian bug while reading terminfo file
[senf.git] / senf / Socket / Protocols / INet / INet4Address.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 INet4Address public header */
30
31 #ifndef HH_SENF_Socket_Protocols_INet_INet4Address_
32 #define HH_SENF_Socket_Protocols_INet_INet4Address_ 1
33
34 // Custom includes
35 #include <iostream>
36 #include <string>
37 #include <boost/cstdint.hpp>
38 #include <boost/array.hpp>
39 #include <boost/operators.hpp>
40 #include <senf/Utils/safe_bool.hh>
41 #include <senf/Utils/Tags.hh>
42
43 //#include "INet4Address.mpp"
44 //-/////////////////////////////////////////////////////////////////////////////////////////////////
45
46 namespace senf {
47
48     /** \brief IPv4 Internet address
49
50         INet4Address represents a simple IP address. It is modelled as a fixed-size
51         container/sequence of 4 bytes.
52
53         The following statements all create the same INet4 address <code>211.194.177.160</code>
54         \code
55         // Used to construct constant INet4 addresses
56         INet4Address(0xD3C2B1A0)
57
58         // Construct an INet4 address from it's string representation. All the standard address
59         // representations are supported
60         INet4Address::from_string("211.194.177.160")
61         INet4Address::from_string("211.12759456")
62
63         // Construct an INet4 address from raw data. 'from_data' takes an arbitrary iterator (e.g. a
64         // pointer) as argument. Here we use a fixed array but normally you will need this to build
65         // an INet4 address in a packet parser
66         char rawBytes[] = { 0xD3, 0xC2, 0xB1, 0xA0 };
67         INet4Address::from_data(rawBytes)
68
69         // Construct an INet4 address from the standard POSIX representation: a 32-bit integer in
70         // network byte oder. This is used to interface with POSIX routines
71         struct sockaddr_in saddr = ...;
72         INet4Address::from_inaddr(saddr.sin_addr.s_addr)
73         \endcode
74
75         Since INet4Address is based on \c boost::array, you can access the raw data bytes of the
76         address (in network byte order) using \c begin(), \c end() or \c operator[]
77         \code
78         INet4Address ina = ...;
79         Packet::iterator i = ...;
80         std::copy(ina.begin(), ina.end(), i); // Copies 4 bytes
81         \endcode
82
83         \see CheckINet4Network \n INet4Network
84
85         \implementation We awkwardly need to use static named constructors (<tt>from_</tt> members)
86             instead of ordinarily overloaded constructors for one simple reason: <tt>char *</tt>
87             doubles as string literal and as arbitrary data iterator. The iterator constructor can
88             therefore not be distinguished from initialization with a string literal. Therefore we
89             need to disambiguate using the named constructors.
90
91         \ingroup addr_group
92       */
93     class INet4Address
94         : public boost::array<boost::uint8_t,4>,
95           public comparable_safe_bool<INet4Address>
96     {
97     public:
98         //-////////////////////////////////////////////////////////////////////////
99         // Types
100
101         typedef uint32_t address_type;  ///< Address representation as number in host byte order
102         typedef uint32_t inaddr_type;   ///< Legacy address representation in network byte order
103
104         static INet4Address const None; ///< The empty (0) address
105         static INet4Address const Loopback; ///< The loopback (127.0.0.1) address
106         static INet4Address const Broadcast; ////< The global broadcast (255.255.255.255) address
107
108         //-////////////////////////////////////////////////////////////////////////
109         ///\name Structors and default members
110         //\{
111
112         INet4Address();                 ///< Construct an empty address
113         explicit INet4Address(senf::NoInit_t); ///< Construct uninitialized (!) address
114         explicit INet4Address(address_type value);
115                                         ///< Construct an address constant
116
117         static INet4Address from_string(std::string const & s);
118                                         ///< Convert string to address
119                                         /**< This member will try to convert the given string into
120                                              an IP address. from_string() supports all standard IP
121                                              literal representations as well as hostnames.
122                                              \attention This call may block if \a s represents a
123                                                  hostname which must be looked up via some network
124                                                  protocol like DNS or NIS
125                                              \throws AddressSyntaxException if the address cannot be
126                                                  converted for some reason
127                                              \throws UnknownHostnameException if the hostname cannot
128                                                  be resolved
129                                              \param[in] s Address literal or hostname */
130
131         template <class InputIterator>
132         static INet4Address from_data(InputIterator i);
133                                         ///< Construct address from 4 bytes of raw data
134                                         /**< from_data will build an address from 4 bytes of raw
135                                              data as accessed by the iterator. The data must be in
136                                              network byte order. */
137         static INet4Address from_inaddr(inaddr_type v);
138                                         ///< Construct address from integer in network byte order
139                                         /**< This call is used when interfacing with other legacy
140                                              code to convert a network byte order address in an
141                                              integer number into an INet4Address. */
142
143         //\}
144         //-////////////////////////////////////////////////////////////////////////
145         ///\name Accessors
146         //\{
147
148         bool local() const;             ///< \c true, if address is locally administered
149                                         /**< This call checks, if the address is within one of the
150                                              IANA private ranges. */
151         bool loopback() const;          ///< \c true, if address is within the loopback network
152                                         /**< Checks, whether the address is in the IANA loopback
153                                              network 10.0.0.0/8 */
154         bool multicast() const;         ///< \c true, if address is a multicast address
155                                         /**< Checks, whether the address is in the 224.0.0.0/4
156                                              network reserved for multicast addresses by the
157                                              IANA. */
158         bool broadcast() const;         ///< \c true, if address is 255.255.255.255
159         bool boolean_test() const;      ///< \c true, if address is non-empty (!= 0.0.0.0)
160
161         inaddr_type inaddr() const;     ///< Return the raw network byte order address
162                                         /**< This member is used to interact with legacy code.
163                                              \return */
164         address_type address() const;   ///< Return address represented as integer number
165                                         /**< This member returns the address as an integer number in
166                                              host byte order. This representation allows simple
167                                              network math operations. */
168         //-/////////////////////////////////////////////////////////////////////////////////////////
169
170     private:
171         enum InAddr_t { IsInAddr };
172         INet4Address(inaddr_type addr, InAddr_t);
173         inaddr_type & iref();
174         inaddr_type iref() const;
175     };
176
177     /** \brief Output INet4Address instance as it's string representation
178         \related INet4Address
179      */
180     std::ostream & operator<<(std::ostream & os, INet4Address const & addr);
181
182     /** \brief Initialize INet4Address instance from a string representation
183         sets std::ios::failbit on the stream if an error occurred
184         \see INet4Address from_string()
185         \related INet4Address
186      */
187     std::istream & operator>>(std::istream & os, INet4Address & addr);
188
189     /** \brief Check INet4Address against a fixed network prefix
190
191         This helper allows to easily and efficiently check an INet4Address against an arbitrary but
192         constant network prefix. The network prefix is represented by
193
194         \par ""
195             <tt>senf::CheckINet4Network<</tt> <i>addr</i> <tt>,</tt> <i>prefix-len</i> <tt>></tt>
196
197         Where \a addr is the v4 Internet address as a 32-bit unsigned integer number in host byte
198         order and \a prefix_len is the length of the network prefix. The class exposes a single
199         static member <tt>match(</tt> <i>addr</i> <tt>)</tt> which matches the INet4Address \a addr
200         against the prefix:
201
202         \code
203         if (senf::CheckINet4Network<0x7F000000u,8u>::match(addr)) {
204             // 'addr' is within the 127.0.0.0/8 loopback network
205             ...
206         }
207         \endcode
208
209         \implementation This is implemented the way it is so the syntax is identical to the
210             CheckINet6Network syntax.
211      */
212     template <boost::uint32_t address, unsigned prefix_len>
213     class CheckINet4Network
214     {
215     public:
216         static bool match(INet4Address const & addr);
217     };
218
219     /** \brief IPv4 network prefix
220
221         This class represents an IPv4 network prefix in CIDR notation.
222       */
223     class INet4Network
224         : public boost::equality_comparable<INet4Network>,
225           public comparable_safe_bool<INet4Network>
226     {
227     public:
228         //-////////////////////////////////////////////////////////////////////////
229         ///\name Structors and default members
230         //\{
231
232         INet4Network();                 ///< Construct empty (0.0.0.0/0) network
233         INet4Network(INet4Address const & address, unsigned prefix_len);
234                                         ///< Construct network from given address and prefix length
235         explicit INet4Network(std::string const & s); ///< Construct network from CIDR notation
236
237         //\}
238         //-////////////////////////////////////////////////////////////////////////
239
240         INet4Address const & address() const; ///< Get the networks address
241         unsigned prefix_len() const;    ///< Get the networks prefix length
242
243         bool boolean_test() const;      ///< \c true, if INet4Network is non-empty
244         bool operator==(INet4Network const & other) const;
245                                         ///< Compare to networks for equality
246
247         bool match(INet4Address const & addr) const; ///< \c true, if the network includes \a addr
248         bool match(INet4Network const & net) const; ///< \c true, if the network includes \a net
249                                         /**< The is true, if \a net is sub-network (or the same as)
250                                              \c this. */
251
252         INet4Address host(boost::uint32_t number); ///< Return the host with the given number
253                                         /**< Returns the host with the given number within the
254                                              network. If the number is larger than the maximum
255                                              host number in the network, it is truncated. So \c
256                                              host(0) is the networks own address, \c host(1)
257                                              customarily is the default router and \c host(-1) is
258                                              the broadcast address. */
259
260         INet4Network subnet(boost::uint32_t net, unsigned prefix_len);
261                                         ///< Return the given subnet of \c this
262                                         /**< The returned INet4Network will be a subnet of \c this
263                                              with the given network number. The network number is
264                                              comprised by the bits above \a prefix_len:
265                                              \code
266                                              INet4Network("192.168.0.0/16").subnet(111u,24u) == INet4Network("192.168.111.0/24")
267                                              INet4Network("192.168.111.0/24").subnet(1u,28u) == INet4Network("192.168.111.16/28")
268                                              \endcode
269                                              \param[in] net network number
270                                              \param[in] prefix_len length of subnet prefix */
271
272     protected:
273
274     private:
275         boost::uint32_t mask() const;
276         unsigned prefix_len_checked(unsigned prefix_len) const;
277
278         unsigned prefix_len_;
279         INet4Address address_;
280     };
281
282     /** \brief Output INet4Network instance as it's string representation
283         \related INet4Network
284      */
285     std::ostream & operator<<(std::ostream & os, INet4Network const & addr);
286
287     /** \brief Initialize INet4Address instance from a string representation
288
289         sets std::ios::failbit on the stream if an error occurred
290         \see INet4Address from_string()
291         \related INet4Network
292      */
293     std::istream & operator>>(std::istream & is, INet4Network & addr);
294
295 }
296
297 //-/////////////////////////////////////////////////////////////////////////////////////////////////
298 #include "INet4Address.cci"
299 #include "INet4Address.ct"
300 #include "INet4Address.cti"
301 #endif
302
303
304 // Local Variables:
305 // mode: c++
306 // fill-column: 100
307 // comment-column: 40
308 // c-file-style: "senf"
309 // indent-tabs-mode: nil
310 // ispell-local-dictionary: "american"
311 // compile-command: "scons -u test"
312 // End: