1 | // |
2 | // IPAddress.h |
3 | // |
4 | // Library: Net |
5 | // Package: NetCore |
6 | // Module: IPAddress |
7 | // |
8 | // Definition of the IPAddress class. |
9 | // |
10 | // Copyright (c) 2005-2011, Applied Informatics Software Engineering GmbH. |
11 | // and Contributors. |
12 | // |
13 | // SPDX-License-Identifier: BSL-1.0 |
14 | // |
15 | |
16 | |
17 | #ifndef Net_IPAddress_INCLUDED |
18 | #define Net_IPAddress_INCLUDED |
19 | |
20 | |
21 | #include "Poco/Net/Net.h" |
22 | #include "Poco/Net/SocketDefs.h" |
23 | #include "Poco/Net/IPAddressImpl.h" |
24 | #include "Poco/AutoPtr.h" |
25 | #include "Poco/Exception.h" |
26 | #include <vector> |
27 | #include <ostream> |
28 | |
29 | |
30 | namespace Poco { |
31 | |
32 | class BinaryReader; |
33 | class BinaryWriter; |
34 | |
35 | namespace Net { |
36 | |
37 | |
38 | class Net_API IPAddress |
39 | /// This class represents an internet (IP) host |
40 | /// address. The address can belong either to the |
41 | /// IPv4 or the IPv6 address family. |
42 | /// |
43 | /// Relational operators (==, !=, <, <=, >, >=) are |
44 | /// supported. However, you must not interpret any |
45 | /// special meaning into the result of these |
46 | /// operations, other than that the results are |
47 | /// consistent. |
48 | /// |
49 | /// Especially, an IPv4 address is never equal to |
50 | /// an IPv6 address, even if the IPv6 address is |
51 | /// IPv4 compatible and the addresses are the same. |
52 | /// |
53 | /// IPv6 addresses are supported only if the target platform |
54 | /// supports IPv6. |
55 | { |
56 | public: |
57 | typedef std::vector<IPAddress> List; |
58 | |
59 | // The following declarations keep the Family type |
60 | // backwards compatible with the previously used |
61 | // enum declaration. |
62 | typedef AddressFamily::Family Family; |
63 | static const Family IPv4 = AddressFamily::IPv4; |
64 | #if defined(POCO_HAVE_IPv6) |
65 | static const Family IPv6 = AddressFamily::IPv6; |
66 | #endif |
67 | |
68 | IPAddress(); |
69 | /// Creates a wildcard (zero) IPv4 IPAddress. |
70 | |
71 | IPAddress(const IPAddress& addr); |
72 | /// Creates an IPAddress by copying another one. |
73 | |
74 | explicit IPAddress(Family family); |
75 | /// Creates a wildcard (zero) IPAddress for the |
76 | /// given address family. |
77 | |
78 | explicit IPAddress(const std::string& addr); |
79 | /// Creates an IPAddress from the string containing |
80 | /// an IP address in presentation format (dotted decimal |
81 | /// for IPv4, hex string for IPv6). |
82 | /// |
83 | /// Depending on the format of addr, either an IPv4 or |
84 | /// an IPv6 address is created. |
85 | /// |
86 | /// See toString() for details on the supported formats. |
87 | /// |
88 | /// Throws an InvalidAddressException if the address cannot be parsed. |
89 | |
90 | IPAddress(const std::string& addr, Family family); |
91 | /// Creates an IPAddress from the string containing |
92 | /// an IP address in presentation format (dotted decimal |
93 | /// for IPv4, hex string for IPv6). |
94 | |
95 | IPAddress(const void* addr, poco_socklen_t length); |
96 | /// Creates an IPAddress from a native internet address. |
97 | /// A pointer to a in_addr or a in6_addr structure may be |
98 | /// passed. |
99 | |
100 | IPAddress(const void* addr, poco_socklen_t length, Poco::UInt32 scope); |
101 | /// Creates an IPAddress from a native internet address. |
102 | /// A pointer to a in_addr or a in6_addr structure may be |
103 | /// passed. Additionally, for an IPv6 address, a scope ID |
104 | /// may be specified. The scope ID will be ignored if an IPv4 |
105 | /// address is specified. |
106 | |
107 | IPAddress(unsigned prefix, Family family); |
108 | /// Creates an IPAddress mask with the given length of prefix. |
109 | |
110 | #if defined(_WIN32) |
111 | IPAddress(const SOCKET_ADDRESS& socket_address); |
112 | /// Creates an IPAddress from Windows SOCKET_ADDRESS structure. |
113 | #endif |
114 | |
115 | IPAddress(const struct sockaddr& sockaddr); |
116 | /// Same for struct sock_addr on POSIX. |
117 | |
118 | |
119 | ~IPAddress(); |
120 | /// Destroys the IPAddress. |
121 | |
122 | IPAddress& operator = (const IPAddress& addr); |
123 | /// Assigns an IPAddress. |
124 | |
125 | Family family() const; |
126 | /// Returns the address family (IPv4 or IPv6) of the address. |
127 | |
128 | Poco::UInt32 scope() const; |
129 | /// Returns the IPv6 scope identifier of the address. Returns 0 if |
130 | /// the address is an IPv4 address, or the address is an |
131 | /// IPv6 address but does not have a scope identifier. |
132 | |
133 | std::string toString() const; |
134 | /// Returns a string containing a representation of the address |
135 | /// in presentation format. |
136 | /// |
137 | /// For IPv4 addresses the result will be in dotted-decimal |
138 | /// (d.d.d.d) notation. |
139 | /// |
140 | /// Textual representation of IPv6 address is one of the following forms: |
141 | /// |
142 | /// The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the hexadecimal |
143 | /// values of the eight 16-bit pieces of the address. This is the full form. |
144 | /// Example: 1080:0:0:0:8:600:200A:425C |
145 | /// |
146 | /// It is not necessary to write the leading zeros in an individual field. |
147 | /// However, there must be at least one numeral in every field, except as described below. |
148 | /// |
149 | /// It is common for IPv6 addresses to contain long strings of zero bits. |
150 | /// In order to make writing addresses containing zero bits easier, a special syntax is |
151 | /// available to compress the zeros. The use of "::" indicates multiple groups of 16-bits of zeros. |
152 | /// The "::" can only appear once in an address. The "::" can also be used to compress the leading |
153 | /// and/or trailing zeros in an address. Example: 1080::8:600:200A:425C |
154 | /// |
155 | /// For dealing with IPv4 compatible addresses in a mixed environment, |
156 | /// a special syntax is available: x:x:x:x:x:x:d.d.d.d, where the 'x's are the |
157 | /// hexadecimal values of the six high-order 16-bit pieces of the address, |
158 | /// and the 'd's are the decimal values of the four low-order 8-bit pieces of the |
159 | /// standard IPv4 representation address. Example: ::FFFF:192.168.1.120 |
160 | /// |
161 | /// If an IPv6 address contains a non-zero scope identifier, it is added |
162 | /// to the string, delimited by a percent character. On Windows platforms, |
163 | /// the numeric value (which specifies an interface index) is directly |
164 | /// appended. On Unix platforms, the name of the interface corresponding |
165 | /// to the index (interpretation of the scope identifier) is added. |
166 | |
167 | bool isWildcard() const; |
168 | /// Returns true iff the address is a wildcard (all zero) |
169 | /// address. |
170 | |
171 | bool isBroadcast() const; |
172 | /// Returns true iff the address is a broadcast address. |
173 | /// |
174 | /// Only IPv4 addresses can be broadcast addresses. In a broadcast |
175 | /// address, all bits are one. |
176 | /// |
177 | /// For an IPv6 address, returns always false. |
178 | |
179 | bool isLoopback() const; |
180 | /// Returns true iff the address is a loopback address. |
181 | /// |
182 | /// For IPv4, the loopback address is 127.0.0.1. |
183 | /// |
184 | /// For IPv6, the loopback address is ::1. |
185 | |
186 | bool isMulticast() const; |
187 | /// Returns true iff the address is a multicast address. |
188 | /// |
189 | /// IPv4 multicast addresses are in the |
190 | /// 224.0.0.0 to 239.255.255.255 range |
191 | /// (the first four bits have the value 1110). |
192 | /// |
193 | /// IPv6 multicast addresses are in the |
194 | /// FFxx:x:x:x:x:x:x:x range. |
195 | |
196 | bool isUnicast() const; |
197 | /// Returns true iff the address is a unicast address. |
198 | /// |
199 | /// An address is unicast if it is neither a wildcard, |
200 | /// broadcast or multicast address. |
201 | |
202 | bool isLinkLocal() const; |
203 | /// Returns true iff the address is a link local unicast address. |
204 | /// |
205 | /// IPv4 link local addresses are in the 169.254.0.0/16 range, |
206 | /// according to RFC 3927. |
207 | /// |
208 | /// IPv6 link local addresses have 1111 1110 10 as the first |
209 | /// 10 bits, followed by 54 zeros. |
210 | |
211 | bool isSiteLocal() const; |
212 | /// Returns true iff the address is a site local unicast address. |
213 | /// |
214 | /// IPv4 site local addresses are in on of the 10.0.0.0/24, |
215 | /// 192.168.0.0/16 or 172.16.0.0 to 172.31.255.255 ranges. |
216 | /// |
217 | /// Originally, IPv6 site-local addresses had FEC0/10 (1111 1110 11) |
218 | /// prefix (RFC 4291), followed by 38 zeros. Interfaces using |
219 | /// this mask are supported, but obsolete; RFC 4193 prescribes |
220 | /// fc00::/7 (1111 110) as local unicast prefix. |
221 | |
222 | bool isIPv4Compatible() const; |
223 | /// Returns true iff the address is IPv4 compatible. |
224 | /// |
225 | /// For IPv4 addresses, this is always true. |
226 | /// |
227 | /// For IPv6, the address must be in the ::x:x range (the |
228 | /// first 96 bits are zero). |
229 | |
230 | bool isIPv4Mapped() const; |
231 | /// Returns true iff the address is an IPv4 mapped IPv6 address. |
232 | /// |
233 | /// For IPv4 addresses, this is always true. |
234 | /// |
235 | /// For IPv6, the address must be in the ::FFFF:x:x range. |
236 | |
237 | bool isWellKnownMC() const; |
238 | /// Returns true iff the address is a well-known multicast address. |
239 | /// |
240 | /// For IPv4, well-known multicast addresses are in the |
241 | /// 224.0.0.0/8 range. |
242 | /// |
243 | /// For IPv6, well-known multicast addresses are in the |
244 | /// FF0x:x:x:x:x:x:x:x range. |
245 | |
246 | bool isNodeLocalMC() const; |
247 | /// Returns true iff the address is a node-local multicast address. |
248 | /// |
249 | /// IPv4 does not support node-local addresses, thus the result is |
250 | /// always false for an IPv4 address. |
251 | /// |
252 | /// For IPv6, node-local multicast addresses are in the |
253 | /// FFx1:x:x:x:x:x:x:x range. |
254 | |
255 | bool isLinkLocalMC() const; |
256 | /// Returns true iff the address is a link-local multicast address. |
257 | /// |
258 | /// For IPv4, link-local multicast addresses are in the |
259 | /// 224.0.0.0/24 range. Note that this overlaps with the range for well-known |
260 | /// multicast addresses. |
261 | /// |
262 | /// For IPv6, link-local multicast addresses are in the |
263 | /// FFx2:x:x:x:x:x:x:x range. |
264 | |
265 | bool isSiteLocalMC() const; |
266 | /// Returns true iff the address is a site-local multicast address. |
267 | /// |
268 | /// For IPv4, site local multicast addresses are in the |
269 | /// 239.255.0.0/16 range. |
270 | /// |
271 | /// For IPv6, site-local multicast addresses are in the |
272 | /// FFx5:x:x:x:x:x:x:x range. |
273 | |
274 | bool isOrgLocalMC() const; |
275 | /// Returns true iff the address is a organization-local multicast address. |
276 | /// |
277 | /// For IPv4, organization-local multicast addresses are in the |
278 | /// 239.192.0.0/16 range. |
279 | /// |
280 | /// For IPv6, organization-local multicast addresses are in the |
281 | /// FFx8:x:x:x:x:x:x:x range. |
282 | |
283 | bool isGlobalMC() const; |
284 | /// Returns true iff the address is a global multicast address. |
285 | /// |
286 | /// For IPv4, global multicast addresses are in the |
287 | /// 224.0.1.0 to 238.255.255.255 range. |
288 | /// |
289 | /// For IPv6, global multicast addresses are in the |
290 | /// FFxF:x:x:x:x:x:x:x range. |
291 | |
292 | bool operator == (const IPAddress& addr) const; |
293 | bool operator != (const IPAddress& addr) const; |
294 | bool operator < (const IPAddress& addr) const; |
295 | bool operator <= (const IPAddress& addr) const; |
296 | bool operator > (const IPAddress& addr) const; |
297 | bool operator >= (const IPAddress& addr) const; |
298 | IPAddress operator & (const IPAddress& addr) const; |
299 | IPAddress operator | (const IPAddress& addr) const; |
300 | IPAddress operator ^ (const IPAddress& addr) const; |
301 | IPAddress operator ~ () const; |
302 | |
303 | poco_socklen_t length() const; |
304 | /// Returns the length in bytes of the internal socket address structure. |
305 | |
306 | const void* addr() const; |
307 | /// Returns the internal address structure. |
308 | |
309 | int af() const; |
310 | /// Returns the address family (AF_INET or AF_INET6) of the address. |
311 | |
312 | unsigned prefixLength() const; |
313 | /// Returns the prefix length. |
314 | |
315 | void mask(const IPAddress& mask); |
316 | /// Masks the IP address using the given netmask, which is usually |
317 | /// a IPv4 subnet mask. Only supported for IPv4 addresses. |
318 | /// |
319 | /// The new address is (address & mask). |
320 | |
321 | void mask(const IPAddress& mask, const IPAddress& set); |
322 | /// Masks the IP address using the given netmask, which is usually |
323 | /// a IPv4 subnet mask. Only supported for IPv4 addresses. |
324 | /// |
325 | /// The new address is (address & mask) | (set & ~mask). |
326 | |
327 | static IPAddress parse(const std::string& addr); |
328 | /// Creates an IPAddress from the string containing |
329 | /// an IP address in presentation format (dotted decimal |
330 | /// for IPv4, hex string for IPv6). |
331 | /// |
332 | /// Depending on the format of addr, either an IPv4 or |
333 | /// an IPv6 address is created. |
334 | /// |
335 | /// See toString() for details on the supported formats. |
336 | /// |
337 | /// Throws an InvalidAddressException if the address cannot be parsed. |
338 | |
339 | static bool tryParse(const std::string& addr, IPAddress& result); |
340 | /// Tries to interpret the given address string as an |
341 | /// IP address in presentation format (dotted decimal |
342 | /// for IPv4, hex string for IPv6). |
343 | /// |
344 | /// Returns true and stores the IPAddress in result if the |
345 | /// string contains a valid address. |
346 | /// |
347 | /// Returns false and leaves result unchanged otherwise. |
348 | |
349 | static IPAddress wildcard(Family family = IPv4); |
350 | /// Returns a wildcard IPv4 or IPv6 address (0.0.0.0). |
351 | |
352 | static IPAddress broadcast(); |
353 | /// Returns a broadcast IPv4 address (255.255.255.255). |
354 | |
355 | enum |
356 | { |
357 | MAX_ADDRESS_LENGTH = |
358 | #if defined(POCO_HAVE_IPv6) |
359 | sizeof(struct in6_addr) |
360 | #else |
361 | sizeof(struct in_addr) |
362 | #endif |
363 | /// Maximum length in bytes of a socket address. |
364 | }; |
365 | |
366 | private: |
367 | typedef Poco::Net::Impl::IPAddressImpl Impl; |
368 | typedef Impl* Ptr; |
369 | |
370 | Ptr pImpl() const; |
371 | void newIPv4(); |
372 | void newIPv4(const void* hostAddr); |
373 | void newIPv4(unsigned prefix); |
374 | #if defined(POCO_HAVE_IPv6) |
375 | void newIPv6(); |
376 | void newIPv6(const void* hostAddr); |
377 | void newIPv6(const void* hostAddr, Poco::UInt32 scope); |
378 | void newIPv6(unsigned prefix); |
379 | #endif |
380 | void destruct(); |
381 | |
382 | char* storage(); |
383 | |
384 | static const unsigned sz = sizeof(Poco::Net::Impl::IPv6AddressImpl); |
385 | typedef std::aligned_storage<sz>::type AlignerType; |
386 | |
387 | union |
388 | { |
389 | char buffer[sz]; |
390 | private: |
391 | AlignerType aligner; |
392 | } _memory; |
393 | }; |
394 | |
395 | |
396 | // |
397 | // inlines |
398 | // |
399 | |
400 | inline IPAddress::Ptr IPAddress::pImpl() const |
401 | { |
402 | return reinterpret_cast<Ptr>(const_cast<char *>(_memory.buffer)); |
403 | } |
404 | |
405 | |
406 | inline char* IPAddress::storage() |
407 | { |
408 | return _memory.buffer; |
409 | } |
410 | |
411 | |
412 | } } // namespace Poco::Net |
413 | |
414 | |
415 | Net_API Poco::BinaryWriter& operator << (Poco::BinaryWriter& writer, const Poco::Net::IPAddress& value); |
416 | Net_API Poco::BinaryReader& operator >> (Poco::BinaryReader& reader, Poco::Net::IPAddress& value); |
417 | Net_API std::ostream& operator << (std::ostream& ostr, const Poco::Net::IPAddress& addr); |
418 | |
419 | |
420 | #endif // Net_IPAddress_INCLUDED |
421 | |