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