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