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