ipaddress 1.2.0
Loading...
Searching...
No Matches
ip-networks.hpp
Go to the documentation of this file.
1/**
2 * @file ip-networks.hpp
3 * @brief Defines constants for various reserved IP networks
4 * @author Vladimir Shaleev
5 * @copyright MIT License
6 *
7 * This file contains arrays of ipv4_network and ipv6_network objects representing
8 * reserved IP address ranges, such as private networks and multicast addresses.
9 * These constants are used to facilitate the identification and handling of these
10 * special address ranges in network-related operations.
11 */
12
13#ifndef IPADDRESS_IP_NETWORKS_HPP
14#define IPADDRESS_IP_NETWORKS_HPP
15
16#include "ipv4-network.hpp"
17#include "ipv6-network.hpp"
18
19namespace IPADDRESS_NAMESPACE {
20
21namespace internal {
22
23template <typename>
24struct networks {
25#if __cpp_constexpr < 201304L
26 static const ipv4_network ipv4_private_networks[];
27 static const ipv6_network ipv6_private_networks[];
28
29 static const ipv4_network ipv4_private_networks_exceptions[];
30 static const ipv6_network ipv6_private_networks_exceptions[];
31
32 static const ipv4_network ipv4_is_public_network;
33
34 static const ipv4_network ipv4_reserved_network;
35 static const ipv6_network ipv6_reserved_networks[];
36
37 static const ipv4_network ipv4_is_multicast;
38 static const ipv6_network ipv6_is_multicast;
39
40 static const ipv4_network ipv4_is_loopback;
41
42 static const ipv4_network ipv4_is_link_local;
43 static const ipv6_network ipv6_is_link_local;
44
45 static const ipv6_network ipv6_is_site_local;
46};
47#endif
48
49// Private networks
50#if __cpp_constexpr >= 201304L
51static constexpr ipv4_network
52#else
53template <typename T> const ipv4_network networks<T>::
54#endif
55 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
56 ipv4_private_networks[] = {
57 ipv4_network::parse("0.0.0.0/8"),
58 ipv4_network::parse("10.0.0.0/8"),
59 ipv4_network::parse("127.0.0.0/8"),
60 ipv4_network::parse("169.254.0.0/16"),
61 ipv4_network::parse("172.16.0.0/12"),
62 ipv4_network::parse("192.0.0.0/24"),
63 ipv4_network::parse("192.0.0.170/31"),
64 ipv4_network::parse("192.0.2.0/24"),
65 ipv4_network::parse("192.168.0.0/16"),
66 ipv4_network::parse("198.18.0.0/15"),
67 ipv4_network::parse("198.51.100.0/24"),
68 ipv4_network::parse("203.0.113.0/24"),
69 ipv4_network::parse("240.0.0.0/4"),
70 ipv4_network::parse("255.255.255.255/32")
71 };
72
73#if __cpp_constexpr >= 201304L
74static constexpr ipv6_network
75#else
76template <typename T> const ipv6_network networks<T>::
77#endif
78 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
79 ipv6_private_networks[] = {
80 ipv6_network::parse("::1/128"),
81 ipv6_network::parse("::/128"),
82 ipv6_network::parse("::ffff:0:0/96"),
83 ipv6_network::parse("64:ff9b:1::/48"),
84 ipv6_network::parse("100::/64"),
85 ipv6_network::parse("2001::/23"),
86 ipv6_network::parse("2001:db8::/32"),
87 ipv6_network::parse("2002::/16"),
88 ipv6_network::parse("fc00::/7"),
89 ipv6_network::parse("fe80::/10")
90 };
91
92// Private networks exceptions
93#if __cpp_constexpr >= 201304L
94static constexpr ipv4_network
95#else
96template <typename T> const ipv4_network networks<T>::
97#endif
98 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
99 ipv4_private_networks_exceptions[] = {
100 ipv4_network::parse("192.0.0.9/32"),
101 ipv4_network::parse("192.0.0.10/32")
102 };
103
104#if __cpp_constexpr >= 201304L
105static constexpr ipv6_network
106#else
107template <typename T> const ipv6_network networks<T>::
108#endif
109 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
110 ipv6_private_networks_exceptions[] = {
111 ipv6_network::parse("2001:1::1/128"),
112 ipv6_network::parse("2001:1::2/128"),
113 ipv6_network::parse("2001:3::/32"),
114 ipv6_network::parse("2001:4:112::/48"),
115 ipv6_network::parse("2001:20::/28"),
116 ipv6_network::parse("2001:30::/28")
117 };
118
119// Global networks
120#if __cpp_constexpr >= 201304L
121static constexpr ipv4_network
122#else
123template <typename T> const ipv4_network networks<T>::
124#endif
125 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
126 ipv4_is_public_network = ipv4_network::parse("100.64.0.0/10");
127
128// Reserved networks
129#if __cpp_constexpr >= 201304L
130static constexpr ipv4_network
131#else
132template <typename T> const ipv4_network networks<T>::
133#endif
134 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
135 ipv4_reserved_network = ipv4_network::parse("240.0.0.0/4");
136
137#if __cpp_constexpr >= 201304L
138static constexpr ipv6_network
139#else
140template <typename T> const ipv6_network networks<T>::
141#endif
142 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
143 ipv6_reserved_networks[] = {
144 ipv6_network::parse("::/8"),
145 ipv6_network::parse("100::/8"),
146 ipv6_network::parse("200::/7"),
147 ipv6_network::parse("400::/6"),
148 ipv6_network::parse("800::/5"),
149 ipv6_network::parse("1000::/4"),
150 ipv6_network::parse("4000::/3"),
151 ipv6_network::parse("6000::/3"),
152 ipv6_network::parse("8000::/3"),
153 ipv6_network::parse("A000::/3"),
154 ipv6_network::parse("C000::/3"),
155 ipv6_network::parse("E000::/4"),
156 ipv6_network::parse("F000::/5"),
157 ipv6_network::parse("F800::/6"),
158 ipv6_network::parse("FE00::/9")
159 };
160
161// Multicast networks
162#if __cpp_constexpr >= 201304L
163static constexpr ipv4_network
164#else
165template <typename T> const ipv4_network networks<T>::
166#endif
167 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
168 ipv4_is_multicast = ipv4_network::parse("224.0.0.0/4");
169
170#if __cpp_constexpr >= 201304L
171static constexpr ipv6_network
172#else
173template <typename T> const ipv6_network networks<T>::
174#endif
175 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
176 ipv6_is_multicast = ipv6_network::parse("ff00::/8");
177
178// Loopback networks
179#if __cpp_constexpr >= 201304L
180static constexpr ipv4_network
181#else
182template <typename T> const ipv4_network networks<T>::
183#endif
184 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
185 ipv4_is_loopback = ipv4_network::parse("127.0.0.0/8");
186
187// Link local networks
188#if __cpp_constexpr >= 201304L
189static constexpr ipv4_network
190#else
191template <typename T> const ipv4_network networks<T>::
192#endif
193 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
194 ipv4_is_link_local = ipv4_network::parse("169.254.0.0/16");
195
196#if __cpp_constexpr >= 201304L
197static constexpr ipv6_network
198#else
199template <typename T> const ipv6_network networks<T>::
200#endif
201 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
202 ipv6_is_link_local = ipv6_network::parse("fe80::/10");
203
204// Site local networks
205#if __cpp_constexpr >= 201304L
206static constexpr ipv6_network
207#else
208template <typename T> const ipv6_network networks<T>::
209#endif
210 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
211 ipv6_is_site_local = ipv6_network::parse("fec0::/10");
212
213#if __cpp_constexpr >= 201304L
214};
215
216template <typename T>
217constexpr ipv4_network networks<T>::ipv4_private_networks[];
218
219template <typename T>
220constexpr ipv6_network networks<T>::ipv6_private_networks[];
221
222template <typename T>
223constexpr ipv4_network networks<T>::ipv4_private_networks_exceptions[];
224
225template <typename T>
226constexpr ipv6_network networks<T>::ipv6_private_networks_exceptions[];
227
228template <typename T>
229constexpr ipv4_network networks<T>::ipv4_is_public_network;
230
231template <typename T>
232constexpr ipv4_network networks<T>::ipv4_reserved_network;
233
234template <typename T>
235constexpr ipv6_network networks<T>::ipv6_reserved_networks[];
236
237template <typename T>
238constexpr ipv4_network networks<T>::ipv4_is_multicast;
239
240template <typename T>
241constexpr ipv6_network networks<T>::ipv6_is_multicast;
242
243template <typename T>
244constexpr ipv4_network networks<T>::ipv4_is_loopback;
245
246template <typename T>
247constexpr ipv4_network networks<T>::ipv4_is_link_local;
248
249template <typename T>
250constexpr ipv6_network networks<T>::ipv6_is_link_local;
251
252template <typename T>
253constexpr ipv6_network networks<T>::ipv6_is_site_local;
254
255#endif
256
257using nets = networks<int>;
258
259template <typename T, int N>
260IPADDRESS_NODISCARD constexpr IPADDRESS_FORCE_INLINE int array_size(const T (&)[N]) IPADDRESS_NOEXCEPT {
261 return N;
262}
263
264template <typename>
265struct props;
266
267template <>
268struct props<ipv4_network> {
269 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv4_network& net) IPADDRESS_NOEXCEPT {
270 auto ip_private = false;
271 const auto& address = net.network_address();
272 const auto broadcast = net.broadcast_address();
273 constexpr auto count = array_size(nets::ipv4_private_networks);
274 for (int i = 0; i < count; ++i) {
275 if (nets::ipv4_private_networks[i].contains(address) && nets::ipv4_private_networks[i].contains(broadcast)) {
276 ip_private = true;
277 break;
278 }
279 }
280 if (ip_private) {
281 constexpr auto countExceptions = array_size(nets::ipv4_private_networks_exceptions);
282 for (int i = 0; i < countExceptions; ++i) {
283 if (nets::ipv4_private_networks_exceptions[i].contains(address) || nets::ipv4_private_networks_exceptions[i].contains(broadcast)) {
284 ip_private = false;
285 break;
286 }
287 }
288 }
289 return ip_private;
290 }
291
292 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv4_network& net) IPADDRESS_NOEXCEPT {
293 const auto& network = nets::ipv4_is_public_network;
294 const auto& address = net.network_address();
295 const auto broadcast = net.broadcast_address();
296 return !(network.contains(address) && network.contains(broadcast)) && !is_private(net);
297 }
298};
299
300template <>
301struct props<ipv6_network> {
302 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv6_network& net) IPADDRESS_NOEXCEPT {
303 auto ip_private = false;
304 const auto& address = net.network_address();
305 const auto broadcast = net.broadcast_address();
306 constexpr auto count = array_size(nets::ipv6_private_networks);
307 for (int i = 0; i < count; ++i) {
308 if (nets::ipv6_private_networks[i].contains(address) && nets::ipv6_private_networks[i].contains(broadcast)) {
309 ip_private = true;
310 break;
311 }
312 }
313 if (ip_private) {
314 constexpr auto countExceptions = array_size(nets::ipv6_private_networks_exceptions);
315 for (int i = 0; i < countExceptions; ++i) {
316 if (nets::ipv6_private_networks_exceptions[i].contains(address) || nets::ipv6_private_networks_exceptions[i].contains(broadcast)) {
317 ip_private = false;
318 break;
319 }
320 }
321 }
322 return ip_private;
323 }
324
325 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv6_network& net) IPADDRESS_NOEXCEPT {
326 return !is_private(net);
327 }
328};
329
330template <>
331struct props<ipv4_address> {
332 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
333 auto ip_private = false;
334 constexpr auto count = array_size(nets::ipv4_private_networks);
335 for (int i = 0; i < count; ++i) {
336 if (nets::ipv4_private_networks[i].contains(ip)) {
337 ip_private = true;
338 break;
339 }
340 }
341 if (ip_private) {
342 constexpr auto countExceptions = array_size(nets::ipv4_private_networks_exceptions);
343 for (int i = 0; i < countExceptions; ++i) {
344 if (nets::ipv4_private_networks_exceptions[i].contains(ip)) {
345 ip_private = false;
346 break;
347 }
348 }
349 }
350 return ip_private;
351 }
352
353 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
354 return !nets::ipv4_is_public_network.contains(ip) && !is_private(ip);
355 }
356
357 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_multicast(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
358 return nets::ipv4_is_multicast.contains(ip);
359 }
360
361 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_reserved(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
362 return nets::ipv4_reserved_network.contains(ip);
363 }
364
365 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_loopback(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
366 return nets::ipv4_is_loopback.contains(ip);
367 }
368
369 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_link_local(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
370 return nets::ipv4_is_link_local.contains(ip);
371 }
372};
373
374template <>
375struct props<ipv6_address> {
376 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
377 const auto ipv4 = ip.ipv4_mapped();
378 if (ipv4) {
379 return ipv4->is_private();
380 }
381
382 auto ip_private = false;
383 constexpr auto count = array_size(nets::ipv6_private_networks);
384 for (int i = 0; i < count; ++i) {
385 if (nets::ipv6_private_networks[i].contains(ip)) {
386 ip_private = true;
387 break;
388 }
389 }
390 if (ip_private) {
391 constexpr auto countExceptions = array_size(nets::ipv6_private_networks_exceptions);
392 for (int i = 0; i < countExceptions; ++i) {
393 if (nets::ipv6_private_networks_exceptions[i].contains(ip)) {
394 ip_private = false;
395 break;
396 }
397 }
398 }
399 return ip_private;
400 }
401
402 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
403 const auto ipv4 = ip.ipv4_mapped();
404 if (ipv4) {
405 return ipv4->is_global();
406 }
407 return !is_private(ip);
408 }
409
410 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_multicast(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
411 return nets::ipv6_is_multicast.contains(ip);
412 }
413
414 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_reserved(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
415 constexpr auto count = array_size(nets::ipv6_reserved_networks);
416 for (int i = 0; i < count; ++i) {
417 if (nets::ipv6_reserved_networks[i].contains(ip)) {
418 return true;
419 }
420 }
421 return false;
422 }
423
424 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_loopback(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
425 const auto& b = ip.bytes();
426 return b[0] == 0 && b[1] == 0 && b[2] == 0 && b[3] == 0
427 && b[4] == 0 && b[5] == 0 && b[6] == 0 && b[7] == 0
428 && b[8] == 0 && b[9] == 0 && b[10] == 0 && b[11] == 0
429 && b[12] == 0 && b[13] == 0 && b[14] == 0 && b[15] == 1;
430 }
431
432 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_link_local(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
433 return nets::ipv6_is_link_local.contains(ip);
434 }
435};
436
437} // namespace IPADDRESS_NAMESPACE::internal
438
439template <typename Base>
441 return internal::props<ip_network_base<Base>>::is_private(*this);
442}
443
444template <typename Base>
446 return internal::props<ip_network_base<Base>>::is_global(*this);
447}
448
449template <typename Base>
451 return internal::props<ip_address_base<Base>>::is_private(*this);
453
454template <typename Base>
456 return internal::props<ip_address_base<Base>>::is_global(*this);
457}
458
459template <typename Base>
461 return internal::props<ip_address_base<Base>>::is_multicast(*this);
462}
463
464template <typename Base>
466 return internal::props<ip_address_base<Base>>::is_reserved(*this);
467}
468
469template <typename Base>
471 return internal::props<ip_address_base<Base>>::is_loopback(*this);
472}
473
474template <typename Base>
476 return internal::props<ip_address_base<Base>>::is_link_local(*this);
478
480 ipv6_address address(bytes());
481 return internal::nets::ipv6_is_site_local.contains(address);
482}
483
484} // namespace IPADDRESS_NAMESPACE
485
486#endif // IPADDRESS_IP_NETWORKS_HPP
A template base class for IP address representations.
Definition ip-address-base.hpp:56
constexpr inline bool is_multicast() const noexcept
Checks if the IP address is a multicast address.
Definition ip-networks.hpp:460
constexpr inline bool is_private() const noexcept
Checks if the IP address is a private address.
Definition ip-networks.hpp:450
constexpr inline bool is_reserved() const noexcept
Checks if the IP address is a reserved address.
Definition ip-networks.hpp:465
constexpr inline bool is_link_local() const noexcept
Checks if the IP address is a link-local address.
Definition ip-networks.hpp:475
constexpr inline bool is_global() const noexcept
Checks if the IP address is a global address.
Definition ip-networks.hpp:455
constexpr inline bool is_loopback() const noexcept
Checks if the IP address is a loopback address.
Definition ip-networks.hpp:470
Template base class for representing a network of IP addresses.
Definition ip-network-base.hpp:32
constexpr inline bool is_private() const noexcept
Checks if the network is a private network.
Definition ip-networks.hpp:440
constexpr inline bool is_global() const noexcept
Checks if the network is a global network.
Definition ip-networks.hpp:445
Represents the base class for IPv6 address manipulation.
Definition ipv6-address.hpp:274
constexpr inline bool is_site_local() const noexcept
Checks if the IPv6 address is a site-local address.
Definition ip-networks.hpp:479
#define IPADDRESS_NODISCARD
Definition config.hpp:101
#define IPADDRESS_FORCE_INLINE
Definition config.hpp:115
#define IPADDRESS_NAMESPACE
Definition config.hpp:41
#define IPADDRESS_NOEXCEPT
Definition config.hpp:92