libtins 4.5
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>
44public:
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 }
123private:
124 Address address_;
125 bool reached_end_;
126};
127
166template<typename Address>
168public:
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
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 }
287private:
288 address_type first_, last_;
289 bool only_hosts_;
290};
291
296
301
307template<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
328IPv6Range operator/(const IPv6Address& addr, int mask);
329
335IPv4Range 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
const value_type & operator*() const
Definition address_range.h:78
bool operator!=(const AddressRangeIterator &rhs) const
Definition address_range.h:103
const value_type * operator->() const
Definition address_range.h:85
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
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
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
AddressRangeIterator< address_type > const_iterator
Definition address_range.h:177
bool is_iterable() const
Indicates whether this range is iterable.
Definition address_range.h:271
Address address_type
Definition address_range.h:172
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 resolve_utils.h:43
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< IPv6Address > IPv6Range
Definition address_range.h:300
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
Definition address_range.h:51