IPAddress.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. //
  2. // IPAddress.cpp
  3. //
  4. // $Id: //poco/Main/Net/src/IPAddress.cpp#16 $
  5. //
  6. // Library: Net
  7. // Package: NetCore
  8. // Module: IPAddress
  9. //
  10. // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // Permission is hereby granted, free of charge, to any person or organization
  14. // obtaining a copy of the software and accompanying documentation covered by
  15. // this license (the "Software") to use, reproduce, display, distribute,
  16. // execute, and transmit the Software, and to prepare derivative works of the
  17. // Software, and to permit third-parties to whom the Software is furnished to
  18. // do so, all subject to the following:
  19. //
  20. // The copyright notices in the Software and this entire statement, including
  21. // the above license grant, this restriction and the following disclaimer,
  22. // must be included in all copies of the Software, in whole or in part, and
  23. // all derivative works of the Software, unless such copies or derivative
  24. // works are solely in the form of machine-executable object code generated by
  25. // a source language processor.
  26. //
  27. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  28. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  29. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  30. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  31. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  32. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  33. // DEALINGS IN THE SOFTWARE.
  34. //
  35. #include "Poco/Net/IPAddress.h"
  36. #include "Poco/Net/NetException.h"
  37. #include "Poco/RefCountedObject.h"
  38. #include "Poco/NumberFormatter.h"
  39. #include "Poco/Types.h"
  40. #include <algorithm>
  41. #include <cstring>
  42. using Poco::RefCountedObject;
  43. using Poco::NumberFormatter;
  44. using Poco::UInt8;
  45. using Poco::UInt16;
  46. using Poco::UInt32;
  47. namespace Poco {
  48. namespace Net {
  49. //
  50. // IPAddressImpl
  51. //
  52. class IPAddressImpl: public RefCountedObject
  53. {
  54. public:
  55. virtual std::string toString() const = 0;
  56. virtual poco_socklen_t length() const = 0;
  57. virtual const void* addr() const = 0;
  58. virtual IPAddress::Family family() const = 0;
  59. virtual int af() const = 0;
  60. virtual bool isWildcard() const = 0;
  61. virtual bool isBroadcast() const = 0;
  62. virtual bool isLoopback() const = 0;
  63. virtual bool isMulticast() const = 0;
  64. virtual bool isLinkLocal() const = 0;
  65. virtual bool isSiteLocal() const = 0;
  66. virtual bool isIPv4Mapped() const = 0;
  67. virtual bool isIPv4Compatible() const = 0;
  68. virtual bool isWellKnownMC() const = 0;
  69. virtual bool isNodeLocalMC() const = 0;
  70. virtual bool isLinkLocalMC() const = 0;
  71. virtual bool isSiteLocalMC() const = 0;
  72. virtual bool isOrgLocalMC() const = 0;
  73. virtual bool isGlobalMC() const = 0;
  74. virtual void mask(const IPAddressImpl* pMask, const IPAddressImpl* pSet) = 0;
  75. protected:
  76. IPAddressImpl()
  77. {
  78. }
  79. virtual ~IPAddressImpl()
  80. {
  81. }
  82. private:
  83. IPAddressImpl(const IPAddressImpl&);
  84. IPAddressImpl& operator = (const IPAddressImpl&);
  85. };
  86. class IPv4AddressImpl: public IPAddressImpl
  87. {
  88. public:
  89. IPv4AddressImpl()
  90. {
  91. std::memset(&_addr, 0, sizeof(_addr));
  92. }
  93. IPv4AddressImpl(const void* addr)
  94. {
  95. std::memcpy(&_addr, addr, sizeof(_addr));
  96. }
  97. std::string toString() const
  98. {
  99. const UInt8* bytes = reinterpret_cast<const UInt8*>(&_addr);
  100. std::string result;
  101. result.reserve(16);
  102. result.append(NumberFormatter::format(bytes[0]));
  103. result.append(".");
  104. result.append(NumberFormatter::format(bytes[1]));
  105. result.append(".");
  106. result.append(NumberFormatter::format(bytes[2]));
  107. result.append(".");
  108. result.append(NumberFormatter::format(bytes[3]));
  109. return result;
  110. }
  111. poco_socklen_t length() const
  112. {
  113. return sizeof(_addr);
  114. }
  115. const void* addr() const
  116. {
  117. return &_addr;
  118. }
  119. IPAddress::Family family() const
  120. {
  121. return IPAddress::IPv4;
  122. }
  123. int af() const
  124. {
  125. return AF_INET;
  126. }
  127. bool isWildcard() const
  128. {
  129. return _addr.s_addr == INADDR_ANY;
  130. }
  131. bool isBroadcast() const
  132. {
  133. return _addr.s_addr == INADDR_NONE;
  134. }
  135. bool isLoopback() const
  136. {
  137. return ntohl(_addr.s_addr) == 0x7F000001; // 127.0.0.1
  138. }
  139. bool isMulticast() const
  140. {
  141. return (ntohl(_addr.s_addr) & 0xF0000000) == 0xE0000000; // 224.0.0.0/24 to 239.0.0.0/24
  142. }
  143. bool isLinkLocal() const
  144. {
  145. return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xA9FE0000; // 169.254.0.0/16
  146. }
  147. bool isSiteLocal() const
  148. {
  149. UInt32 addr = ntohl(_addr.s_addr);
  150. return (addr & 0xFF000000) == 0x0A000000 || // 10.0.0.0/24
  151. (addr & 0xFFFF0000) == 0xC0A80000 || // 192.68.0.0/16
  152. addr >= 0xAC100000 && addr <= 0xAC1FFFFF; // 172.16.0.0 to 172.31.255.255
  153. }
  154. bool isIPv4Compatible() const
  155. {
  156. return true;
  157. }
  158. bool isIPv4Mapped() const
  159. {
  160. return true;
  161. }
  162. bool isWellKnownMC() const
  163. {
  164. return (ntohl(_addr.s_addr) & 0xFFFFFF00) == 0xE0000000; // 224.0.0.0/8
  165. }
  166. bool isNodeLocalMC() const
  167. {
  168. return false;
  169. }
  170. bool isLinkLocalMC() const
  171. {
  172. return (ntohl(_addr.s_addr) & 0xFF000000) == 0xE0000000; // 244.0.0.0/24
  173. }
  174. bool isSiteLocalMC() const
  175. {
  176. return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xEFFF0000; // 239.255.0.0/16
  177. }
  178. bool isOrgLocalMC() const
  179. {
  180. return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xEFC00000; // 239.192.0.0/16
  181. }
  182. bool isGlobalMC() const
  183. {
  184. UInt32 addr = ntohl(_addr.s_addr);
  185. return addr >= 0xE0000100 && addr <= 0xEE000000; // 224.0.1.0 to 238.255.255.255
  186. }
  187. static IPv4AddressImpl* parse(const std::string& addr)
  188. {
  189. if (addr.empty()) return 0;
  190. #if defined(_WIN32)
  191. struct in_addr ia;
  192. ia.s_addr = inet_addr(addr.c_str());
  193. if (ia.s_addr == INADDR_NONE && addr != "255.255.255.255")
  194. return 0;
  195. else
  196. return new IPv4AddressImpl(&ia);
  197. #else
  198. struct in_addr ia;
  199. if (inet_aton(addr.c_str(), &ia))
  200. return new IPv4AddressImpl(&ia);
  201. else
  202. return 0;
  203. #endif
  204. }
  205. void mask(const IPAddressImpl* pMask, const IPAddressImpl* pSet)
  206. {
  207. poco_assert (pMask->af() == AF_INET && pSet->af() == AF_INET);
  208. _addr.s_addr &= static_cast<const IPv4AddressImpl*>(pMask)->_addr.s_addr;
  209. _addr.s_addr |= static_cast<const IPv4AddressImpl*>(pSet)->_addr.s_addr & ~static_cast<const IPv4AddressImpl*>(pMask)->_addr.s_addr;
  210. }
  211. private:
  212. struct in_addr _addr;
  213. };
  214. #if defined(POCO_HAVE_IPv6)
  215. class IPv6AddressImpl: public IPAddressImpl
  216. {
  217. public:
  218. IPv6AddressImpl()
  219. {
  220. std::memset(&_addr, 0, sizeof(_addr));
  221. }
  222. IPv6AddressImpl(const void* addr)
  223. {
  224. std::memcpy(&_addr, addr, sizeof(_addr));
  225. }
  226. std::string toString() const
  227. {
  228. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  229. if (isIPv4Compatible() || isIPv4Mapped())
  230. {
  231. std::string result;
  232. result.reserve(24);
  233. if (words[5] == 0)
  234. result.append("::");
  235. else
  236. result.append("::FFFF:");
  237. const UInt8* bytes = reinterpret_cast<const UInt8*>(&_addr);
  238. result.append(NumberFormatter::format(bytes[12]));
  239. result.append(".");
  240. result.append(NumberFormatter::format(bytes[13]));
  241. result.append(".");
  242. result.append(NumberFormatter::format(bytes[14]));
  243. result.append(".");
  244. result.append(NumberFormatter::format(bytes[15]));
  245. return result;
  246. }
  247. else
  248. {
  249. std::string result;
  250. result.reserve(46);
  251. bool zeroSequence = false;
  252. int i = 0;
  253. while (i < 8)
  254. {
  255. if (!zeroSequence && words[i] == 0)
  256. {
  257. int zi = i;
  258. while (zi < 8 && words[zi] == 0) ++zi;
  259. if (zi > i + 1)
  260. {
  261. i = zi;
  262. result.append(":");
  263. zeroSequence = true;
  264. }
  265. }
  266. if (i > 0) result.append(":");
  267. if (i < 8) result.append(NumberFormatter::formatHex(ntohs(words[i++])));
  268. }
  269. return result;
  270. }
  271. }
  272. poco_socklen_t length() const
  273. {
  274. return sizeof(_addr);
  275. }
  276. const void* addr() const
  277. {
  278. return &_addr;
  279. }
  280. IPAddress::Family family() const
  281. {
  282. return IPAddress::IPv6;
  283. }
  284. int af() const
  285. {
  286. return AF_INET6;
  287. }
  288. bool isWildcard() const
  289. {
  290. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  291. return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
  292. words[4] == 0 && words[5] == 0 && words[6] == 0 && words[7] == 0;
  293. }
  294. bool isBroadcast() const
  295. {
  296. return false;
  297. }
  298. bool isLoopback() const
  299. {
  300. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  301. return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
  302. words[4] == 0 && words[5] == 0 && words[6] == 0 && words[7] == 1;
  303. }
  304. bool isMulticast() const
  305. {
  306. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  307. return (words[0] & 0xFFE0) == 0xFF00;
  308. }
  309. bool isLinkLocal() const
  310. {
  311. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  312. return (words[0] & 0xFFE0) == 0xFE80;
  313. }
  314. bool isSiteLocal() const
  315. {
  316. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  317. return (words[0] & 0xFFE0) == 0xFEC0;
  318. }
  319. bool isIPv4Compatible() const
  320. {
  321. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  322. return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && words[5] == 0;
  323. }
  324. bool isIPv4Mapped() const
  325. {
  326. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  327. return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && words[5] == 0xFFFF;
  328. }
  329. bool isWellKnownMC() const
  330. {
  331. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  332. return (words[0] & 0xFFF0) == 0xFF00;
  333. }
  334. bool isNodeLocalMC() const
  335. {
  336. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  337. return (words[0] & 0xFFEF) == 0xFF01;
  338. }
  339. bool isLinkLocalMC() const
  340. {
  341. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  342. return (words[0] & 0xFFEF) == 0xFF02;
  343. }
  344. bool isSiteLocalMC() const
  345. {
  346. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  347. return (words[0] & 0xFFEF) == 0xFF05;
  348. }
  349. bool isOrgLocalMC() const
  350. {
  351. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  352. return (words[0] & 0xFFEF) == 0xFF08;
  353. }
  354. bool isGlobalMC() const
  355. {
  356. const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
  357. return (words[0] & 0xFFEF) == 0xFF0F;
  358. }
  359. static IPv6AddressImpl* parse(const std::string& addr)
  360. {
  361. if (addr.empty()) return 0;
  362. #if defined(_WIN32)
  363. struct addrinfo* pAI;
  364. struct addrinfo hints;
  365. std::memset(&hints, 0, sizeof(hints));
  366. hints.ai_flags = AI_NUMERICHOST;
  367. int rc = getaddrinfo(addr.c_str(), NULL, &hints, &pAI);
  368. if (rc == 0)
  369. {
  370. IPv6AddressImpl* pResult = new IPv6AddressImpl(&reinterpret_cast<struct sockaddr_in6*>(pAI->ai_addr)->sin6_addr);
  371. freeaddrinfo(pAI);
  372. return pResult;
  373. }
  374. else return 0;
  375. #else
  376. struct in6_addr ia;
  377. if (inet_pton(AF_INET6, addr.c_str(), &ia) == 1)
  378. return new IPv6AddressImpl(&ia);
  379. else
  380. return 0;
  381. #endif
  382. }
  383. void mask(const IPAddressImpl* pMask, const IPAddressImpl* pSet)
  384. {
  385. throw Poco::NotImplementedException("mask() is only supported for IPv4 addresses");
  386. }
  387. private:
  388. struct in6_addr _addr;
  389. };
  390. #endif // POCO_HAVE_IPv6
  391. //
  392. // IPAddress
  393. //
  394. IPAddress::IPAddress(): _pImpl(new IPv4AddressImpl)
  395. {
  396. }
  397. IPAddress::IPAddress(const IPAddress& addr): _pImpl(addr._pImpl)
  398. {
  399. _pImpl->duplicate();
  400. }
  401. IPAddress::IPAddress(Family family): _pImpl(0)
  402. {
  403. if (family == IPv4)
  404. _pImpl = new IPv4AddressImpl();
  405. #if defined(POCO_HAVE_IPv6)
  406. else if (family == IPv6)
  407. _pImpl = new IPv6AddressImpl();
  408. #endif
  409. else Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
  410. }
  411. IPAddress::IPAddress(const std::string& addr)
  412. {
  413. _pImpl = IPv4AddressImpl::parse(addr);
  414. #if defined(POCO_HAVE_IPv6)
  415. if (!_pImpl)
  416. _pImpl = IPv6AddressImpl::parse(addr);
  417. #endif
  418. if (!_pImpl) throw InvalidAddressException(addr);
  419. }
  420. IPAddress::IPAddress(const std::string& addr, Family family): _pImpl(0)
  421. {
  422. if (family == IPv4)
  423. _pImpl = IPv4AddressImpl::parse(addr);
  424. #if defined(POCO_HAVE_IPv6)
  425. else if (family == IPv6)
  426. _pImpl = IPv6AddressImpl::parse(addr);
  427. #endif
  428. else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
  429. }
  430. IPAddress::IPAddress(const void* addr, poco_socklen_t length)
  431. {
  432. if (length == sizeof(struct in_addr))
  433. _pImpl = new IPv4AddressImpl(addr);
  434. #if defined(POCO_HAVE_IPv6)
  435. else if (length == sizeof(struct in6_addr))
  436. _pImpl = new IPv6AddressImpl(addr);
  437. #endif
  438. else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()");
  439. }
  440. IPAddress::~IPAddress()
  441. {
  442. _pImpl->release();
  443. }
  444. IPAddress& IPAddress::operator = (const IPAddress& addr)
  445. {
  446. if (&addr != this)
  447. {
  448. _pImpl->release();
  449. _pImpl = addr._pImpl;
  450. _pImpl->duplicate();
  451. }
  452. return *this;
  453. }
  454. void IPAddress::swap(IPAddress& address)
  455. {
  456. std::swap(_pImpl, address._pImpl);
  457. }
  458. IPAddress::Family IPAddress::family() const
  459. {
  460. return _pImpl->family();
  461. }
  462. std::string IPAddress::toString() const
  463. {
  464. return _pImpl->toString();
  465. }
  466. bool IPAddress::isWildcard() const
  467. {
  468. return _pImpl->isWildcard();
  469. }
  470. bool IPAddress::isBroadcast() const
  471. {
  472. return _pImpl->isBroadcast();
  473. }
  474. bool IPAddress::isLoopback() const
  475. {
  476. return _pImpl->isLoopback();
  477. }
  478. bool IPAddress::isMulticast() const
  479. {
  480. return _pImpl->isMulticast();
  481. }
  482. bool IPAddress::isUnicast() const
  483. {
  484. return !isWildcard() && !isBroadcast() && !isMulticast();
  485. }
  486. bool IPAddress::isLinkLocal() const
  487. {
  488. return _pImpl->isLinkLocal();
  489. }
  490. bool IPAddress::isSiteLocal() const
  491. {
  492. return _pImpl->isSiteLocal();
  493. }
  494. bool IPAddress::isIPv4Compatible() const
  495. {
  496. return _pImpl->isIPv4Compatible();
  497. }
  498. bool IPAddress::isIPv4Mapped() const
  499. {
  500. return _pImpl->isIPv4Mapped();
  501. }
  502. bool IPAddress::isWellKnownMC() const
  503. {
  504. return _pImpl->isWellKnownMC();
  505. }
  506. bool IPAddress::isNodeLocalMC() const
  507. {
  508. return _pImpl->isNodeLocalMC();
  509. }
  510. bool IPAddress::isLinkLocalMC() const
  511. {
  512. return _pImpl->isLinkLocalMC();
  513. }
  514. bool IPAddress::isSiteLocalMC() const
  515. {
  516. return _pImpl->isSiteLocalMC();
  517. }
  518. bool IPAddress::isOrgLocalMC() const
  519. {
  520. return _pImpl->isOrgLocalMC();
  521. }
  522. bool IPAddress::isGlobalMC() const
  523. {
  524. return _pImpl->isGlobalMC();
  525. }
  526. bool IPAddress::operator == (const IPAddress& a) const
  527. {
  528. poco_socklen_t l1 = length();
  529. poco_socklen_t l2 = a.length();
  530. if (l1 == l2)
  531. return std::memcmp(addr(), a.addr(), l1) == 0;
  532. else
  533. return false;
  534. }
  535. bool IPAddress::operator != (const IPAddress& a) const
  536. {
  537. poco_socklen_t l1 = length();
  538. poco_socklen_t l2 = a.length();
  539. if (l1 == l2)
  540. return std::memcmp(addr(), a.addr(), l1) != 0;
  541. else
  542. return true;
  543. }
  544. bool IPAddress::operator < (const IPAddress& a) const
  545. {
  546. poco_socklen_t l1 = length();
  547. poco_socklen_t l2 = a.length();
  548. if (l1 == l2)
  549. return std::memcmp(addr(), a.addr(), l1) < 0;
  550. else
  551. return l1 < l2;
  552. }
  553. bool IPAddress::operator <= (const IPAddress& a) const
  554. {
  555. poco_socklen_t l1 = length();
  556. poco_socklen_t l2 = a.length();
  557. if (l1 == l2)
  558. return std::memcmp(addr(), a.addr(), l1) <= 0;
  559. else
  560. return l1 < l2;
  561. }
  562. bool IPAddress::operator > (const IPAddress& a) const
  563. {
  564. poco_socklen_t l1 = length();
  565. poco_socklen_t l2 = a.length();
  566. if (l1 == l2)
  567. return std::memcmp(addr(), a.addr(), l1) > 0;
  568. else
  569. return l1 > l2;
  570. }
  571. bool IPAddress::operator >= (const IPAddress& a) const
  572. {
  573. poco_socklen_t l1 = length();
  574. poco_socklen_t l2 = a.length();
  575. if (l1 == l2)
  576. return std::memcmp(addr(), a.addr(), l1) >= 0;
  577. else
  578. return l1 > l2;
  579. }
  580. poco_socklen_t IPAddress::length() const
  581. {
  582. return _pImpl->length();
  583. }
  584. const void* IPAddress::addr() const
  585. {
  586. return _pImpl->addr();
  587. }
  588. int IPAddress::af() const
  589. {
  590. return _pImpl->af();
  591. }
  592. void IPAddress::init(IPAddressImpl* pImpl)
  593. {
  594. _pImpl->release();
  595. _pImpl = pImpl;
  596. }
  597. IPAddress IPAddress::parse(const std::string& addr)
  598. {
  599. return IPAddress(addr);
  600. }
  601. bool IPAddress::tryParse(const std::string& addr, IPAddress& result)
  602. {
  603. IPAddressImpl* pImpl = IPv4AddressImpl::parse(addr);
  604. #if defined(POCO_HAVE_IPv6)
  605. if (!pImpl) pImpl = IPv6AddressImpl::parse(addr);
  606. #endif
  607. if (pImpl)
  608. {
  609. result.init(pImpl);
  610. return true;
  611. }
  612. else return false;
  613. }
  614. void IPAddress::mask(const IPAddress& mask)
  615. {
  616. IPAddress null;
  617. _pImpl->mask(mask._pImpl, null._pImpl);
  618. }
  619. void IPAddress::mask(const IPAddress& mask, const IPAddress& set)
  620. {
  621. _pImpl->mask(mask._pImpl, set._pImpl);
  622. }
  623. } } // namespace Poco::Net