libtins  4.0
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 
38 namespace Tins {
42 template<typename Address>
43 class AddressRangeIterator : public std::iterator<std::forward_iterator_tag, const Address> {
44 public:
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  }
119 private:
120  Address address_;
121  bool reached_end_;
122 };
123 
162 template<typename Address>
164 public:
168  typedef Address address_type;
169 
174 
181  typedef const_iterator iterator;
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 
233  const_iterator begin() const {
234  address_type addr = first_;
235  if (only_hosts_) {
236  Internals::increment(addr);
237  }
238  return const_iterator(addr);
239  }
240 
245  const_iterator end() const {
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  }
283 private:
284  address_type first_, last_;
285  bool only_hosts_;
286 };
287 
292 
297 
303 template<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 
324 IPv6Range operator/(const IPv6Address& addr, int mask);
325 
331 IPv4Range operator/(const IPv4Address& addr, int mask);
332 } // namespace Tins
333 
334 #endif // TINS_ADDRESS_RANGE
const_iterator begin() const
Returns an interator to the beginning of this range.
Definition: address_range.h:233
AddressRange iterator class.
Definition: address_range.h:43
bool is_iterable() const
Indicates whether this range is iterable.
Definition: address_range.h:267
AddressRangeIterator & operator++()
Definition: address_range.h:106
bool operator==(const AddressRangeIterator &rhs) const
Definition: address_range.h:90
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
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
bool operator!=(const AddressRangeIterator &rhs) const
Definition: address_range.h:99
iterator begin()
Retrieves an iterator pointing to the begining of the address.
Definition: hw_address.h:207
AddressRange< IPv4Address > IPv4Range
Definition: address_range.h:291
Address address_type
Definition: address_range.h:168
bool contains(const address_type &addr) const
Indicates whether an address is included in this range.
Definition: address_range.h:225
Represents a hardware address.
Definition: hw_address.h:91
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
AddressRangeIterator(const value_type &address, end_iterator)
Definition: address_range.h:66
Definition: address_range.h:47
Base class for all libtins exceptions.
Definition: exceptions.h:41
The Tins namespace.
Definition: address_range.h:38
AddressRange< IPv6Address > IPv6Range
Definition: address_range.h:296
const value_type & operator*() const
Definition: address_range.h:74
const_iterator iterator
The iterator type.
Definition: address_range.h:181
AddressRangeIterator< address_type > const_iterator
Definition: address_range.h:173
Abstraction of an IPv4 address.
Definition: ip_address.h:45
AddressRangeIterator(const value_type &address)
Definition: address_range.h:56
Represents a range of addresses.
Definition: address_range.h:163
storage_type * iterator
The random access iterator type.
Definition: hw_address.h:101
Definition: ipv6_address.h:45
const_iterator end() const
Returns an interator to the end of this range.
Definition: address_range.h:245
AddressRangeIterator operator++(int)
Definition: address_range.h:114
const value_type * operator->() const
Definition: address_range.h:81