ipaddress 1.1.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_is_public_network;
30
31 static const ipv4_network ipv4_reserved_network;
32 static const ipv6_network ipv6_reserved_networks[];
33
34 static const ipv4_network ipv4_is_multicast;
35 static const ipv6_network ipv6_is_multicast;
36
37 static const ipv4_network ipv4_is_loopback;
38
39 static const ipv4_network ipv4_is_link_local;
40 static const ipv6_network ipv6_is_link_local;
41
42 static const ipv6_network ipv6_is_site_local;
43};
44#endif
45
46// Private networks
47#if __cpp_constexpr >= 201304L
48static constexpr ipv4_network
49#else
50template <typename T> const ipv4_network networks<T>::
51#endif
52 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
53 ipv4_private_networks[] = {
54 ipv4_network::parse("0.0.0.0/8"),
55 ipv4_network::parse("10.0.0.0/8"),
56 ipv4_network::parse("127.0.0.0/8"),
57 ipv4_network::parse("169.254.0.0/16"),
58 ipv4_network::parse("172.16.0.0/12"),
59 ipv4_network::parse("192.0.0.0/29"),
60 ipv4_network::parse("192.0.0.170/31"),
61 ipv4_network::parse("192.0.2.0/24"),
62 ipv4_network::parse("192.168.0.0/16"),
63 ipv4_network::parse("198.18.0.0/15"),
64 ipv4_network::parse("198.51.100.0/24"),
65 ipv4_network::parse("203.0.113.0/24"),
66 ipv4_network::parse("240.0.0.0/4"),
67 ipv4_network::parse("255.255.255.255/32")
68 };
69
70#if __cpp_constexpr >= 201304L
71static constexpr ipv6_network
72#else
73template <typename T> const ipv6_network networks<T>::
74#endif
75 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
76 ipv6_private_networks[] = {
77 ipv6_network::parse("::1/128"),
78 ipv6_network::parse("::/128"),
79 ipv6_network::parse("::ffff:0:0/96"),
80 ipv6_network::parse("100::/64"),
81 ipv6_network::parse("2001::/23"),
82 ipv6_network::parse("2001:2::/48"),
83 ipv6_network::parse("2001:db8::/32"),
84 ipv6_network::parse("2001:10::/28"),
85 ipv6_network::parse("fc00::/7"),
86 ipv6_network::parse("fe80::/10")
87 };
88
89// Global networks
90#if __cpp_constexpr >= 201304L
91static constexpr ipv4_network
92#else
93template <typename T> const ipv4_network networks<T>::
94#endif
95 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
96 ipv4_is_public_network = ipv4_network::parse("100.64.0.0/10");
97
98// Reserved networks
99#if __cpp_constexpr >= 201304L
100static constexpr ipv4_network
101#else
102template <typename T> const ipv4_network networks<T>::
103#endif
104 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
105 ipv4_reserved_network = ipv4_network::parse("240.0.0.0/4");
106
107#if __cpp_constexpr >= 201304L
108static constexpr ipv6_network
109#else
110template <typename T> const ipv6_network networks<T>::
111#endif
112 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
113 ipv6_reserved_networks[] = {
114 ipv6_network::parse("::/8"),
115 ipv6_network::parse("100::/8"),
116 ipv6_network::parse("200::/7"),
117 ipv6_network::parse("400::/6"),
118 ipv6_network::parse("800::/5"),
119 ipv6_network::parse("1000::/4"),
120 ipv6_network::parse("4000::/3"),
121 ipv6_network::parse("6000::/3"),
122 ipv6_network::parse("8000::/3"),
123 ipv6_network::parse("A000::/3"),
124 ipv6_network::parse("C000::/3"),
125 ipv6_network::parse("E000::/4"),
126 ipv6_network::parse("F000::/5"),
127 ipv6_network::parse("F800::/6"),
128 ipv6_network::parse("FE00::/9")
129 };
130
131// Multicast networks
132#if __cpp_constexpr >= 201304L
133static constexpr ipv4_network
134#else
135template <typename T> const ipv4_network networks<T>::
136#endif
137 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
138 ipv4_is_multicast = ipv4_network::parse("224.0.0.0/4");
139
140#if __cpp_constexpr >= 201304L
141static constexpr ipv6_network
142#else
143template <typename T> const ipv6_network networks<T>::
144#endif
145 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
146 ipv6_is_multicast = ipv6_network::parse("ff00::/8");
147
148// Loopback networks
149#if __cpp_constexpr >= 201304L
150static constexpr ipv4_network
151#else
152template <typename T> const ipv4_network networks<T>::
153#endif
154 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
155 ipv4_is_loopback = ipv4_network::parse("127.0.0.0/8");
156
157// Link local networks
158#if __cpp_constexpr >= 201304L
159static constexpr ipv4_network
160#else
161template <typename T> const ipv4_network networks<T>::
162#endif
163 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
164 ipv4_is_link_local = ipv4_network::parse("169.254.0.0/16");
165
166#if __cpp_constexpr >= 201304L
167static constexpr ipv6_network
168#else
169template <typename T> const ipv6_network networks<T>::
170#endif
171 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
172 ipv6_is_link_local = ipv6_network::parse("fe80::/10");
173
174// Site local networks
175#if __cpp_constexpr >= 201304L
176static constexpr ipv6_network
177#else
178template <typename T> const ipv6_network networks<T>::
179#endif
180 // NOLINTNEXTLINE(cert-err58-cpp): for C++11
181 ipv6_is_site_local = ipv6_network::parse("fec0::/10");
182
183#if __cpp_constexpr >= 201304L
184};
185
186template <typename T>
187constexpr ipv4_network networks<T>::ipv4_private_networks[];
188
189template <typename T>
190constexpr ipv6_network networks<T>::ipv6_private_networks[];
191
192template <typename T>
193constexpr ipv4_network networks<T>::ipv4_is_public_network;
194
195template <typename T>
196constexpr ipv4_network networks<T>::ipv4_reserved_network;
197
198template <typename T>
199constexpr ipv6_network networks<T>::ipv6_reserved_networks[];
200
201template <typename T>
202constexpr ipv4_network networks<T>::ipv4_is_multicast;
203
204template <typename T>
205constexpr ipv6_network networks<T>::ipv6_is_multicast;
206
207template <typename T>
208constexpr ipv4_network networks<T>::ipv4_is_loopback;
209
210template <typename T>
211constexpr ipv4_network networks<T>::ipv4_is_link_local;
212
213template <typename T>
214constexpr ipv6_network networks<T>::ipv6_is_link_local;
215
216template <typename T>
217constexpr ipv6_network networks<T>::ipv6_is_site_local;
218
219#endif
220
221using nets = networks<int>;
222
223template <typename T, int N>
224IPADDRESS_NODISCARD constexpr IPADDRESS_FORCE_INLINE int array_size(const T (&)[N]) IPADDRESS_NOEXCEPT {
225 return N;
226}
227
228template <typename>
229struct props;
230
231template <>
232struct props<ipv4_network> {
233 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv4_network& net) IPADDRESS_NOEXCEPT {
234 const auto& address = net.network_address();
235 const auto broadcast = net.broadcast_address();
236 constexpr auto count = array_size(nets::ipv4_private_networks);
237 for (int i = 0; i < count; ++i) {
238 if (nets::ipv4_private_networks[i].contains(address) && nets::ipv4_private_networks[i].contains(broadcast)) {
239 return true;
240 }
241 }
242 return false;
243 }
244
245 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv4_network& net) IPADDRESS_NOEXCEPT {
246 const auto& network = nets::ipv4_is_public_network;
247 const auto& address = net.network_address();
248 const auto broadcast = net.broadcast_address();
249 return !(network.contains(address) && network.contains(broadcast)) && !is_private(net);
250 }
251};
252
253template <>
254struct props<ipv6_network> {
255 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv6_network& net) IPADDRESS_NOEXCEPT {
256 const auto& address = net.network_address();
257 const auto broadcast = net.broadcast_address();
258 constexpr auto count = array_size(nets::ipv6_private_networks);
259 for (int i = 0; i < count; ++i) {
260 if (nets::ipv6_private_networks[i].contains(address) && nets::ipv6_private_networks[i].contains(broadcast)) {
261 return true;
262 }
263 }
264 return false;
265 }
266
267 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv6_network& net) IPADDRESS_NOEXCEPT {
268 return !is_private(net);
269 }
270};
271
272template <>
273struct props<ipv4_address> {
274 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
275 constexpr auto count = array_size(nets::ipv4_private_networks);
276 for (int i = 0; i < count; ++i) {
277 if (nets::ipv4_private_networks[i].contains(ip)) {
278 return true;
279 }
280 }
281 return false;
282 }
283
284 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
285 return !nets::ipv4_is_public_network.contains(ip) && !is_private(ip);
286 }
287
288 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_multicast(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
289 return nets::ipv4_is_multicast.contains(ip);
290 }
291
292 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_reserved(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
293 return nets::ipv4_reserved_network.contains(ip);
294 }
295
296 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_loopback(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
297 return nets::ipv4_is_loopback.contains(ip);
298 }
299
300 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_link_local(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
301 return nets::ipv4_is_link_local.contains(ip);
302 }
303};
304
305template <>
306struct props<ipv6_address> {
307 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
308 const auto ipv4 = ip.ipv4_mapped();
309
310 if (ipv4) {
311 return ipv4->is_private();
312 }
313
314 constexpr auto count = array_size(nets::ipv6_private_networks);
315 for (int i = 0; i < count; ++i) {
316 if (nets::ipv6_private_networks[i].contains(ip)) {
317 return true;
318 }
319 }
320
321 return false;
322 }
323
324 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
325 return !is_private(ip);
326 }
327
328 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_multicast(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
329 return nets::ipv6_is_multicast.contains(ip);
330 }
331
332 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_reserved(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
333 constexpr auto count = array_size(nets::ipv6_reserved_networks);
334 for (int i = 0; i < count; ++i) {
335 if (nets::ipv6_reserved_networks[i].contains(ip)) {
336 return true;
337 }
338 }
339 return false;
340 }
341
342 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_loopback(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
343 const auto& b = ip.bytes();
344 return b[0] == 0 && b[1] == 0 && b[2] == 0 && b[3] == 0
345 && b[4] == 0 && b[5] == 0 && b[6] == 0 && b[7] == 0
346 && b[8] == 0 && b[9] == 0 && b[10] == 0 && b[11] == 0
347 && b[12] == 0 && b[13] == 0 && b[14] == 0 && b[15] == 1;
348 }
349
350 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_link_local(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
351 return nets::ipv6_is_link_local.contains(ip);
352 }
353};
354
355} // namespace IPADDRESS_NAMESPACE::internal
356
357template <typename Base>
359 return internal::props<ip_network_base<Base>>::is_private(*this);
360}
361
362template <typename Base>
364 return internal::props<ip_network_base<Base>>::is_global(*this);
365}
366
367template <typename Base>
369 return internal::props<ip_address_base<Base>>::is_private(*this);
370}
371
372template <typename Base>
374 return internal::props<ip_address_base<Base>>::is_global(*this);
375}
376
377template <typename Base>
379 return internal::props<ip_address_base<Base>>::is_multicast(*this);
380}
381
382template <typename Base>
384 return internal::props<ip_address_base<Base>>::is_reserved(*this);
385}
386
387template <typename Base>
389 return internal::props<ip_address_base<Base>>::is_loopback(*this);
390}
391
392template <typename Base>
394 return internal::props<ip_address_base<Base>>::is_link_local(*this);
395}
396
398 ipv6_address address(bytes());
399 return internal::nets::ipv6_is_site_local.contains(address);
400}
401
402} // namespace IPADDRESS_NAMESPACE
403
404#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:378
constexpr inline bool is_private() const noexcept
Checks if the IP address is a private address.
Definition ip-networks.hpp:368
constexpr inline bool is_reserved() const noexcept
Checks if the IP address is a reserved address.
Definition ip-networks.hpp:383
constexpr inline bool is_link_local() const noexcept
Checks if the IP address is a link-local address.
Definition ip-networks.hpp:393
constexpr inline bool is_global() const noexcept
Checks if the IP address is a global address.
Definition ip-networks.hpp:373
constexpr inline bool is_loopback() const noexcept
Checks if the IP address is a loopback address.
Definition ip-networks.hpp:388
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:358
constexpr inline bool is_global() const noexcept
Checks if the network is a global network.
Definition ip-networks.hpp:363
Represents the base class for IPv6 address manipulation.
Definition ipv6-address.hpp:272
constexpr inline bool is_site_local() const noexcept
Checks if the IPv6 address is a site-local address.
Definition ip-networks.hpp:397
#define IPADDRESS_NODISCARD
Definition config.hpp:98
#define IPADDRESS_FORCE_INLINE
Definition config.hpp:112
#define IPADDRESS_NAMESPACE
Definition config.hpp:38
#define IPADDRESS_NOEXCEPT
Definition config.hpp:89