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