Line data Source code
1 : // Network Address -- classes functions to ease handling IP addresses
2 : // Copyright (C) 2012-2017 Made to Order Software Corp.
3 : //
4 : // http://snapwebsites.org/project/libaddr
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program; if not, write to the Free Software
18 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 :
20 : // self
21 : //
22 : #include "libaddr/addr.h"
23 :
24 : // C++ lib
25 : //
26 : #include <algorithm>
27 : #include <sstream>
28 : #include <iostream>
29 :
30 : // C lib
31 : //
32 : #include <ifaddrs.h>
33 : #include <netdb.h>
34 :
35 :
36 :
37 : namespace addr
38 : {
39 :
40 :
41 :
42 :
43 :
44 :
45 : /** \brief Return true if the range has a 'from' address defined.
46 : *
47 : * By default the 'from' and 'to' addresses of an addr_range are legal
48 : * but considered undefined. After you called the set_from() function
49 : * once, this function will always return true.
50 : *
51 : * \return false until 'set_from()' is called at least once.
52 : */
53 277 : bool addr_range::has_from() const
54 : {
55 277 : return f_has_from;
56 : }
57 :
58 :
59 : /** \brief Return true if the range has a 'to' address defined.
60 : *
61 : * By default the 'from' and 'to' addresses of an addr_range are legal
62 : * but considered undefined. After you called the set_to() function
63 : * once, this function will always return true.
64 : *
65 : * \return false until 'set_to()' is called at least once.
66 : */
67 277 : bool addr_range::has_to() const
68 : {
69 277 : return f_has_to;
70 : }
71 :
72 :
73 : /** \brief Determine whether an addr_range object is considered a range.
74 : *
75 : * This function returns false until both, set_from() and set_to(),
76 : * were called.
77 : *
78 : * Note that the order in which the two functions get called is not
79 : * important, although we generally expect set_from() to be called
80 : * first, it does not matter.
81 : *
82 : * \return true if both, 'from' and 'to', were set.
83 : */
84 974 : bool addr_range::is_range() const
85 : {
86 974 : return f_has_from && f_has_to;
87 : }
88 :
89 :
90 : /** \brief Check whether this range is empty.
91 : *
92 : * If you defined the 'from' and 'to' addresses of the range, then you
93 : * can check whether the range is empty or not.
94 : *
95 : * A range is considered empty if 'from' is larger than 'to' because
96 : * in that case nothing can appear in between (no IP can at the same
97 : * time be larger than 'from' and smaller than 'to' if 'from > to'
98 : * is true.)
99 : *
100 : * \return true if 'from > to' and is_range() returns true.
101 : *
102 : * \sa is_range()
103 : * \sa has_from()
104 : * \sa has_to()
105 : */
106 283 : bool addr_range::is_empty() const
107 : {
108 283 : if(!is_range())
109 : {
110 275 : return false;
111 : }
112 8 : return f_from > f_to;
113 : }
114 :
115 :
116 : /** \brief Check whether \p rhs is part of this range.
117 : *
118 : * If the address specified in rhs is part of this range, then the function
119 : * returns true. The 'from' and 'to' addresses are considered inclusive,
120 : * so if rhs is equal to 'from' or 'to', then the function returns true.
121 : *
122 : * If 'from' is larger than 'to' then the function already returns false
123 : * since the range represents an empty range.
124 : *
125 : * \exception addr_invalid_state_exception
126 : * The addr_range object must be a range or this function throws this
127 : * exception. To test whether you can call this function, first call
128 : * the is_range() function. If it returns true, then is_in() is available.
129 : *
130 : * \param[in] rhs The address to check for inclusion.
131 : *
132 : * \return true if rhs is considered part of this range.
133 : */
134 408 : bool addr_range::is_in(addr const & rhs) const
135 : {
136 408 : if(!is_range())
137 : {
138 10 : throw addr_invalid_state_exception("addr_range::is_in(): range is not complete (from or to missing.)");
139 : }
140 :
141 398 : if(f_from <= f_to)
142 : {
143 : //
144 276 : return rhs >= f_from && rhs <= f_to;
145 : }
146 : //else -- from/to are swapped... this represents an empty range
147 :
148 122 : return false;
149 : }
150 :
151 :
152 : /** \brief Set 'from' address.
153 : *
154 : * This function saves the 'from' address in this range object.
155 : *
156 : * Once this function was called at least once, the has_from() returns true.
157 : *
158 : * \param[in] from The address to save as the 'from' address.
159 : */
160 131826 : void addr_range::set_from(addr const & from)
161 : {
162 131826 : f_has_from = true;
163 131826 : f_from = from;
164 131826 : }
165 :
166 :
167 : /** \brief Get 'from' address.
168 : *
169 : * This function return the 'from' address as set by the set_from()
170 : * functions.
171 : *
172 : * The get_from() function can be called even if the has_from()
173 : * function returns false. It will return a default address
174 : * (a new 'addr' object.)
175 : *
176 : * \return The address saved as the 'from' address.
177 : */
178 545 : addr & addr_range::get_from()
179 : {
180 545 : return f_from;
181 : }
182 :
183 :
184 : /** \brief Get the 'from' address when addr_range is constant.
185 : *
186 : * This function return the 'from' address as set by the set_from()
187 : * functions.
188 : *
189 : * The get_from() function can be called even if the has_from()
190 : * function returns false. It will return a default address
191 : * (a new 'addr' object.)
192 : *
193 : * \return The address saved as the 'from' address.
194 : */
195 131770 : addr const & addr_range::get_from() const
196 : {
197 131770 : return f_from;
198 : }
199 :
200 :
201 : /** \brief Set 'to' address.
202 : *
203 : * This function saves the 'to' address in this range object.
204 : *
205 : * Once this function was called at least once, the has_to() returns true.
206 : *
207 : * \param[in] to The address to save as the 'to' address.
208 : */
209 8 : void addr_range::set_to(addr const & to)
210 : {
211 8 : f_has_to = true;
212 8 : f_to = to;
213 8 : }
214 :
215 :
216 : /** \brief Get the 'to' address.
217 : *
218 : * This function return the 'to' address as set by the set_to()
219 : * function.
220 : *
221 : * The get_from() function can be called even if the has_from()
222 : * function returns false. It will return a default address
223 : * (a new 'addr' object.)
224 : *
225 : * \return The address saved as the 'to' address.
226 : */
227 9 : addr & addr_range::get_to()
228 : {
229 9 : return f_to;
230 : }
231 :
232 :
233 : /** \brief Get the 'to' address when addr_range is constant.
234 : *
235 : * This function return the 'to' address as set by the set_to()
236 : * function.
237 : *
238 : * The get_to() function can be called even if the has_to()
239 : * function returns false. It will return a default address
240 : * (a new 'addr' object.)
241 : *
242 : * \return The address saved as the 'to' address.
243 : */
244 7 : addr const & addr_range::get_to() const
245 : {
246 7 : return f_to;
247 : }
248 :
249 :
250 : /** \brief Compute a new range with the part that is shared between both inputs.
251 : *
252 : * This function computers a range which encompasses all the addresses found
253 : * in \p this range and \p rhs range.
254 : *
255 : * If the two range do not intersect, then the resulting range will be an
256 : * empty range (see is_empty() for details).
257 : *
258 : * The new range receives the largest 'from' address from both inputs and
259 : * the smallest 'to' address from both inputs.
260 : *
261 : * \param[in] rhs The other range to compute the intersection with.
262 : *
263 : * \return The resulting intersection range.
264 : */
265 2 : addr_range addr_range::intersection(addr_range const & rhs) const
266 : {
267 2 : addr_range result;
268 :
269 2 : result.set_from(f_from > rhs.f_from ? f_from : rhs.f_from);
270 2 : result.set_to (f_to < rhs.f_to ? f_to : rhs.f_to);
271 :
272 2 : return result;
273 : }
274 :
275 :
276 :
277 :
278 :
279 :
280 :
281 6 : }
282 : // snap_addr namespace
283 : // vim: ts=4 sw=4 et
|