libtins  4.5
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>
44 public:
45  typedef std::forward_iterator_tag iterator_category;
46  typedef const Address value_type;
47  typedef std::ptrdiff_t difference_type;
48  typedef const Address* pointer;
49  typedef const Address& reference;
50 
51  struct end_iterator {
52 
53  };
54 
60  AddressRangeIterator(const value_type& address)
61  : address_(address), reached_end_(false) {
62 
63  }
64 
70  AddressRangeIterator(const value_type& address, end_iterator)
71  : address_(address) {
72  reached_end_ = Internals::increment(address_);
73  }
74 
78  const value_type& operator*() const {
79  return address_;
80  }
81 
85  const value_type* operator->() const {
86  return& address_;
87  }
88 
94  bool operator==(const AddressRangeIterator& rhs) const {
95  return reached_end_ == rhs.reached_end_ && address_ == rhs.address_;
96  }
97 
103  bool operator!=(const AddressRangeIterator& rhs) const {
104  return !(*this == rhs);
105  }
106 
111  reached_end_ = Internals::increment(address_);
112  return* this;
113  }
114 
119  AddressRangeIterator copy(*this);
120  (*this)++;
121  return copy;
122  }
123 private:
124  Address address_;
125  bool reached_end_;
126 };
127 
166 template<typename Address>
168 public:
172  typedef Address address_type;
173 
178 
186 
202  AddressRange(const address_type& first, const address_type& last, bool only_hosts = false)
203  : first_(first), last_(last), only_hosts_(only_hosts){
204  if (last_ < first_) {
205  throw exception_base("Invalid address range");
206  }
207  }
208 
216  static AddressRange from_mask(const address_type& first, const address_type& mask) {
218  first & mask,
219  Internals::last_address_from_mask(first, mask),
220  true
221  );
222  }
223 
229  bool contains(const address_type& addr) const {
230  return (first_ < addr && addr < last_) || addr == first_ || addr == last_;
231  }
232 
238  address_type addr = first_;
239  if (only_hosts_) {
240  Internals::increment(addr);
241  }
242  return const_iterator(addr);
243  }
244 
249  const_iterator end() const {
250  address_type addr = last_;
251  if (only_hosts_) {
252  Internals::decrement(addr);
253  }
254  return const_iterator(addr, typename const_iterator::end_iterator());
255  }
256 
271  bool is_iterable() const {
272  // Since first < last, it's iterable
273  if (!only_hosts_) {
274  return true;
275  }
276  // We need that distance(first, last) >= 4
277  address_type addr(first_);
278  for (int i = 0; i < 3; ++i) {
279  // If there's overflow before the last iteration, we're done
280  if (Internals::increment(addr) && i != 2) {
281  return false;
282  }
283  }
284  // If addr <= last, it's OK.
285  return addr < last_ || addr == last_;
286  }
287 private:
288  address_type first_, last_;
289  bool only_hosts_;
290 };
291 
296 
301 
307 template<size_t n>
309  if (mask > 48) {
310  throw std::logic_error("Prefix length cannot exceed 48");
311  }
312  HWAddress<n> last_addr;
313  typename HWAddress<n>::iterator it = last_addr.begin();
314  while (mask > 8) {
315  *it = 0xff;
316  ++it;
317  mask -= 8;
318  }
319  *it = 0xff << (8 - mask);
320  return AddressRange<HWAddress<6> >::from_mask(addr, last_addr);
321 }
322 
328 IPv6Range operator/(const IPv6Address& addr, int mask);
329 
335 IPv4Range operator/(const IPv4Address& addr, int mask);
336 } // namespace Tins
337 
338 #endif // TINS_ADDRESS_RANGE
AddressRange iterator class.
Definition: address_range.h:43
AddressRangeIterator operator++(int)
Definition: address_range.h:118
bool operator!=(const AddressRangeIterator &rhs) const
Definition: address_range.h:103
const value_type & operator*() const
Definition: address_range.h:78
AddressRangeIterator & operator++()
Definition: address_range.h:110
AddressRangeIterator(const value_type &address, end_iterator)
Definition: address_range.h:70
bool operator==(const AddressRangeIterator &rhs) const
Definition: address_range.h:94
AddressRangeIterator(const value_type &address)
Definition: address_range.h:60
const value_type * operator->() const
Definition: address_range.h:85
Represents a range of addresses.
Definition: address_range.h:167
const_iterator end() const
Returns an interator to the end of this range.
Definition: address_range.h:249
const_iterator begin() const
Returns an interator to the beginning of this range.
Definition: address_range.h:237
const_iterator iterator
The iterator type.
Definition: address_range.h:185
bool contains(const address_type &addr) const
Indicates whether an address is included in this range.
Definition: address_range.h:229
AddressRangeIterator< address_type > const_iterator
Definition: address_range.h:177
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:216
Address address_type
Definition: address_range.h:172
bool is_iterable() const
Indicates whether this range is iterable.
Definition: address_range.h:271
AddressRange(const address_type &first, const address_type &last, bool only_hosts=false)
Constructs an address range from two addresses.
Definition: address_range.h:202
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:295
AddressRange< HWAddress< n > > operator/(const HWAddress< n > &addr, int mask)
Constructs an AddressRange from a base address and a mask.
Definition: address_range.h:308
AddressRange< IPv6Address > IPv6Range
Definition: address_range.h:300
Definition: address_range.h:51