libtins 4.4
Loading...
Searching...
No Matches
address_range.h
1/*
2 * Copyright (c) 2017, Matias Fontanini
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef TINS_ADDRESS_RANGE
31#define TINS_ADDRESS_RANGE
32
33#include <iterator>
34#include <tins/endianness.h>
35#include <tins/exceptions.h>
36#include <tins/detail/address_helpers.h>
37
38namespace Tins {
42template<typename Address>
43class AddressRangeIterator : public std::iterator<std::forward_iterator_tag, const Address> {
44public:
45 typedef typename std::iterator<std::forward_iterator_tag, const Address>::value_type value_type;
46
47 struct end_iterator {
48
49 };
50
56 AddressRangeIterator(const value_type& address)
57 : address_(address), reached_end_(false) {
58
59 }
60
66 AddressRangeIterator(const value_type& address, end_iterator)
67 : address_(address) {
68 reached_end_ = Internals::increment(address_);
69 }
70
74 const value_type& operator*() const {
75 return address_;
76 }
77
81 const value_type* operator->() const {
82 return& address_;
83 }
84
90 bool operator==(const AddressRangeIterator& rhs) const {
91 return reached_end_ == rhs.reached_end_ && address_ == rhs.address_;
92 }
93
99 bool operator!=(const AddressRangeIterator& rhs) const {
100 return !(*this == rhs);
101 }
102
107 reached_end_ = Internals::increment(address_);
108 return* this;
109 }
110
115 AddressRangeIterator copy(*this);
116 (*this)++;
117 return copy;
118 }
119private:
120 Address address_;
121 bool reached_end_;
122};
123
162template<typename Address>
164public:
168 typedef Address address_type;
169
174
182
198 AddressRange(const address_type& first, const address_type& last, bool only_hosts = false)
199 : first_(first), last_(last), only_hosts_(only_hosts){
200 if (last_ < first_) {
201 throw exception_base("Invalid address range");
202 }
203 }
204
212 static AddressRange from_mask(const address_type& first, const address_type& mask) {
214 first & mask,
215 Internals::last_address_from_mask(first, mask),
216 true
217 );
218 }
219
225 bool contains(const address_type& addr) const {
226 return (first_ < addr && addr < last_) || addr == first_ || addr == last_;
227 }
228
234 address_type addr = first_;
235 if (only_hosts_) {
236 Internals::increment(addr);
237 }
238 return const_iterator(addr);
239 }
240
246 address_type addr = last_;
247 if (only_hosts_) {
248 Internals::decrement(addr);
249 }
250 return const_iterator(addr, typename const_iterator::end_iterator());
251 }
252
267 bool is_iterable() const {
268 // Since first < last, it's iterable
269 if (!only_hosts_) {
270 return true;
271 }
272 // We need that distance(first, last) >= 4
273 address_type addr(first_);
274 for (int i = 0; i < 3; ++i) {
275 // If there's overflow before the last iteration, we're done
276 if (Internals::increment(addr) && i != 2) {
277 return false;
278 }
279 }
280 // If addr <= last, it's OK.
281 return addr < last_ || addr == last_;
282 }
283private:
284 address_type first_, last_;
285 bool only_hosts_;
286};
287
292
297
303template<size_t n>
305 if (mask > 48) {
306 throw std::logic_error("Prefix length cannot exceed 48");
307 }
308 HWAddress<n> last_addr;
309 typename HWAddress<n>::iterator it = last_addr.begin();
310 while (mask > 8) {
311 *it = 0xff;
312 ++it;
313 mask -= 8;
314 }
315 *it = 0xff << (8 - mask);
316 return AddressRange<HWAddress<6> >::from_mask(addr, last_addr);
317}
318
324IPv6Range operator/(const IPv6Address& addr, int mask);
325
331IPv4Range operator/(const IPv4Address& addr, int mask);
332} // namespace Tins
333
334#endif // TINS_ADDRESS_RANGE
AddressRange iterator class.
Definition: address_range.h:43
AddressRangeIterator operator++(int)
Definition: address_range.h:114
const value_type & operator*() const
Definition: address_range.h:74
bool operator!=(const AddressRangeIterator &rhs) const
Definition: address_range.h:99
const value_type * operator->() const
Definition: address_range.h:81
AddressRangeIterator & operator++()
Definition: address_range.h:106
AddressRangeIterator(const value_type &address, end_iterator)
Definition: address_range.h:66
bool operator==(const AddressRangeIterator &rhs) const
Definition: address_range.h:90
AddressRangeIterator(const value_type &address)
Definition: address_range.h:56
Represents a range of addresses.
Definition: address_range.h:163
const_iterator end() const
Returns an interator to the end of this range.
Definition: address_range.h:245
const_iterator begin() const
Returns an interator to the beginning of this range.
Definition: address_range.h:233
const_iterator iterator
The iterator type.
Definition: address_range.h:181
bool contains(const address_type &addr) const
Indicates whether an address is included in this range.
Definition: address_range.h:225
AddressRangeIterator< address_type > const_iterator
Definition: address_range.h:173
static AddressRange from_mask(const address_type &first, const address_type &mask)
Creates an address range from a base address and a network mask.
Definition: address_range.h:212
Address address_type
Definition: address_range.h:168
bool is_iterable() const
Indicates whether this range is iterable.
Definition: address_range.h:267
AddressRange(const address_type &first, const address_type &last, bool only_hosts=false)
Constructs an address range from two addresses.
Definition: address_range.h:198
Represents a hardware address.
Definition: hw_address.h:91
storage_type * iterator
The random access iterator type.
Definition: hw_address.h:101
iterator begin()
Retrieves an iterator pointing to the begining of the address.
Definition: hw_address.h:207
Base class for all libtins exceptions.
Definition: exceptions.h:41
The Tins namespace.
Definition: address_range.h:38
AddressRange< IPv4Address > IPv4Range
Definition: address_range.h:291
AddressRange< IPv6Address > IPv6Range
Definition: address_range.h:296
AddressRange< HWAddress< n > > operator/(const HWAddress< n > &addr, int mask)
Constructs an AddressRange from a base address and a mask.
Definition: address_range.h:304
Definition: address_range.h:47