00001
00002
00003
00004
00005
00006
00007
00008
00009 static const char rcsid[] __attribute__((used)) = "$Id: IPAddress.cpp 1243 2014-11-21 01:01:24Z sella $";
00010
00011 #include "IPAddress.h"
00012 #include "AddressException.h"
00013 #include "../util/CommonMacro.h"
00014
00015 #include <unistd.h>
00016 #include <string.h>
00017 #include <stdlib.h>
00018 #include <assert.h>
00019 #include <net/if.h>
00020 #include <arpa/inet.h>
00021 #include <sys/ioctl.h>
00022 #include <sys/types.h>
00023
00024 #include <limits>
00025 #include <string>
00026
00027 #define HASH_ALGO_INT1
00028
00029 union __sockaddr_union {
00030 struct sockaddr_storage *ss;
00031 struct sockaddr *sa;
00032 struct sockaddr_in *sa_in;
00033 struct sockaddr_in6 *sa_in6;
00034 };
00035
00036 using namespace sella::net;
00037
00038 IPAddress::IPAddress(const std::string &text, int family, uint8_t cidr) throw (AddressException) :
00039 family(family),
00040 addr(),
00041 scache(),
00042 hcache(0)
00043 {
00044 char buffer[INET6_ADDRSTRLEN];
00045
00046 switch (family) {
00047 case IPv4Family:
00048 case IPv4Required:
00049 if (this->parse(this->family, this->addr.v4, text) == false) {
00050 THROW(AddressException, "unable to parse address: '%s' does not represent a valid IPv4 address", text.c_str());
00051 }
00052 break;
00053
00054 case IPv4Preferred:
00055 if (this->parse(this->family, this->addr.v4, this->addr.v6, text) == false) {
00056 THROW(AddressException, "unable to parse address: '%s' does not represent a valid IPv4 or IPv6 address", text.c_str());
00057 }
00058 break;
00059
00060 case IPv6Family:
00061 case IPv6Required:
00062 if (this->parse(this->family, this->addr.v6, text) == false) {
00063 THROW(AddressException, "unable to parse address: '%s' does not represent a valid IPv6 address", text.c_str());
00064 }
00065 break;
00066
00067 case IPv6Preferred:
00068 if (this->parse(this->family, this->addr.v6, this->addr.v4, text) == false) {
00069 THROW(AddressException, "unable to parse address: '%s' does not represent a valid IPv4 or IPv6 address", text.c_str());
00070 }
00071 break;
00072
00073 default:
00074 THROW(AddressException, "unable to parse address: unknown family supplied for address '%s'", text.c_str());
00075 }
00076
00077 if (inet_ntop(this->family, &(this->addr), buffer, sizeof(buffer)) == NULL) {
00078 THROW(AddressException, "unable to parse address '%s'", text.c_str());
00079 }
00080
00081 if (cidr != 255) {
00082 applyCIDR(cidr);
00083 }
00084 }
00085
00086 IPAddress::IPAddress(int family) throw (AddressException) : family(family), hcache(0) {
00087 char buffer[INET6_ADDRSTRLEN];
00088
00089 switch (family) {
00090 case IPv4Family:
00091 case IPv4Preferred:
00092 case IPv4Required:
00093 if (this->parse(this->family, this->addr.v4, "0.0.0.0") == false) {
00094 THROW(AddressException, "unable to parse address: '%s' does not represent a valid IPv4 address", "0.0.0.0");
00095 }
00096 break;
00097
00098 case IPv6Family:
00099 case IPv6Preferred:
00100 case IPv6Required:
00101 if (this->parse(this->family, this->addr.v6, "::") == false) {
00102 THROW(AddressException, "unable to parse address: '%s' does not represent a valid IPv6 address", "::");
00103 }
00104 break;
00105
00106 default:
00107 THROW(AddressException, "unable to parse address: unknown family supplied for default address");
00108 }
00109
00110 if (inet_ntop(this->family, &(this->addr), buffer, sizeof(buffer)) == NULL) {
00111 THROW(AddressException, "unable to parse default address");
00112 }
00113 }
00114
00115 IPAddress::IPAddress(const struct sockaddr_storage *ss, uint8_t cidr) throw (AddressException) : hcache(0) {
00116 char buffer[INET6_ADDRSTRLEN];
00117 union __sockaddr_union u;
00118
00119 if (ss == NULL) {
00120 THROW(AddressException, "passed sockaddr_storage is null");
00121 }
00122
00123 u.ss = (struct sockaddr_storage*) ss;
00124 this->family = u.sa->sa_family;
00125
00126 if (this->family == AF_INET) {
00127 this->addr.v4 = u.sa_in->sin_addr;
00128 } else if (this->family == AF_INET6) {
00129 this->addr.v6 = u.sa_in6->sin6_addr;
00130 } else {
00131 THROW(AddressException, "unknown family '%d'", this->family);
00132 }
00133
00134 if (inet_ntop(this->family, &(this->addr), buffer, sizeof(buffer)) == NULL) {
00135 THROW(AddressException, "unable to convert sockaddr");
00136 }
00137
00138 if (cidr != 255) {
00139 applyCIDR(cidr);
00140 }
00141 }
00142
00143 IPAddress::IPAddress(const struct sockaddr *sa, uint8_t cidr) throw (AddressException) : hcache(0) {
00144 char buffer[INET6_ADDRSTRLEN];
00145 union __sockaddr_union u;
00146
00147 if (sa == NULL) {
00148 THROW(AddressException, "passed sockaddr is null");
00149 }
00150
00151 u.sa = (struct sockaddr*) sa;
00152 this->family = sa->sa_family;
00153
00154 if (this->family == AF_INET) {
00155 this->addr.v4 = u.sa_in->sin_addr;
00156 } else if (this->family == AF_INET6) {
00157 this->addr.v6 = u.sa_in6->sin6_addr;
00158 } else {
00159 THROW(AddressException, "unknown family '%d'", this->family);
00160 }
00161
00162 if (inet_ntop(this->family, &(this->addr), buffer, sizeof(buffer)) == NULL) {
00163 THROW(AddressException, "unable to convert sockaddr");
00164 }
00165
00166 if (cidr != 255) {
00167 applyCIDR(cidr);
00168 }
00169 }
00170
00171 IPAddress::IPAddress(const struct in_addr *in, uint8_t cidr) throw (AddressException) : hcache(0) {
00172 char buffer[INET6_ADDRSTRLEN];
00173
00174 if (in == NULL) {
00175 THROW(AddressException, "passed in_addr is null");
00176 }
00177
00178 this->family = AF_INET;
00179 this->addr.v4 = *in;
00180
00181 if (inet_ntop(this->family, &(this->addr), buffer, sizeof(buffer)) == NULL) {
00182 THROW(AddressException, "unable to convert in_addr");
00183 }
00184
00185 if (cidr != 255) {
00186 applyCIDR(cidr);
00187 }
00188 }
00189
00190 IPAddress::IPAddress(const struct in6_addr *in6, uint8_t cidr) throw (AddressException) {
00191 char buffer[INET6_ADDRSTRLEN];
00192
00193 if (in6 == NULL) {
00194 THROW(AddressException, "passed in6_addr is null");
00195 }
00196
00197 this->family = AF_INET6;
00198 this->addr.v6 = *in6;
00199
00200 if (inet_ntop(this->family, &(this->addr), buffer, sizeof(buffer)) == NULL) {
00201 THROW(AddressException, "unable to convert in_addr");
00202 }
00203
00204 if (cidr != 255) {
00205 applyCIDR(cidr);
00206 }
00207 }
00208
00209 IPAddress::IPAddress(uint32_t address, uint8_t cidr) throw (AddressException) : hcache(0) {
00210 this->family = AF_INET;
00211 this->addr.v4.s_addr = htonl(address);
00212
00213 if (cidr != 255) {
00214 applyCIDR(cidr);
00215 }
00216 }
00217
00218 IPAddress::IPAddress(unsigned char address[16], uint8_t cidr) throw (AddressException) : hcache(0) {
00219 this->family = AF_INET6;
00220 memcpy(&(this->addr.v6), address, sizeof(addr));
00221
00222 if (cidr != 255) {
00223 applyCIDR(cidr);
00224 }
00225 }
00226
00227 IPAddress::IPAddress(const IPAddress &other) throw () :
00228 family(other.family),
00229 addr(other.addr),
00230 scache(other.scache),
00231 hcache(other.hcache)
00232 { }
00233
00234 IPAddress::IPAddress(const IPAddress &&other) throw () :
00235 family(other.family),
00236 addr(other.addr),
00237 scache(std::move(other.scache)),
00238 hcache(other.hcache)
00239 { }
00240
00241 IPAddress::~IPAddress() throw () {
00242 family = 0;
00243 }
00244
00245 IPAddress & IPAddress::operator=(const IPAddress &other) throw () {
00246 assert(other.family != 0);
00247
00248 if (this != &other) {
00249 this->family = other.family;
00250 this->addr = other.addr;
00251 this->scache = other.scache;
00252 this->hcache = other.hcache;
00253 }
00254
00255 return *this;
00256 }
00257
00258 IPAddress & IPAddress::operator=(const IPAddress &&other) throw () {
00259 assert(other.family != 0);
00260
00261 if (this != &other) {
00262 this->family = other.family;
00263 this->addr = other.addr;
00264 this->scache = std::move(other.scache);
00265 this->hcache = other.hcache;
00266 }
00267
00268 return *this;
00269 }
00270
00271 bool IPAddress::operator==(const IPAddress &other) const throw () {
00272 assert(this->family != 0);
00273
00274 if (this->family != other.family) {
00275 return false;
00276 }
00277
00278 if (this->family == AF_INET) {
00279 return (this->addr.v4.s_addr == other.addr.v4.s_addr);
00280 } else {
00281 const uint64_t *a = (const uint64_t*) this->addr.v6.s6_addr;
00282 const uint64_t *b = (const uint64_t*) other.addr.v6.s6_addr;
00283
00284
00285 return (a[1] == b[1] && a[0] == b[0]);
00286 }
00287 }
00288
00289 bool IPAddress::operator!=(const IPAddress &other) const throw () {
00290 return !(*this == other);
00291 }
00292
00293 bool IPAddress::operator>=(const IPAddress &other) const throw () {
00294 if (*this == other) {
00295 return true;
00296 }
00297
00298 return (*this > other);
00299 }
00300
00301 bool IPAddress::operator<=(const IPAddress &other) const throw () {
00302 if (*this == other) {
00303 return true;
00304 }
00305
00306 return (*this < other);
00307 }
00308
00309 bool IPAddress::operator>(const IPAddress &other) const throw () {
00310 if (this->family < other.family) {
00311 return false;
00312 }
00313
00314 if (this->family == AF_INET) {
00315 return (ntohl(this->addr.v4.s_addr) > ntohl(other.addr.v4.s_addr));
00316 } else {
00317 const uint64_t *a = (const uint64_t*) this->addr.v6.s6_addr;
00318 const uint64_t *b = (const uint64_t*) other.addr.v6.s6_addr;
00319
00320 return (ntohll(a[0]) > ntohll(b[0]) || ntohll(a[1]) > ntohll(b[1]));
00321 }
00322 }
00323
00324 bool IPAddress::operator<(const IPAddress &other) const throw () {
00325 if (this->family > other.family) {
00326 return false;
00327 }
00328
00329 if (this->family == AF_INET) {
00330 return (ntohl(this->addr.v4.s_addr) < ntohl(other.addr.v4.s_addr));
00331 } else {
00332 const uint64_t *a = (const uint64_t*) this->addr.v6.s6_addr;
00333 const uint64_t *b = (const uint64_t*) other.addr.v6.s6_addr;
00334
00335 return (ntohll(a[0]) < ntohll(b[0]) || ntohll(a[1]) < ntohll(b[1]));
00336 }
00337 }
00338
00339 IPAddress IPAddress::operator&(const IPAddress &other) const throw (AddressException) {
00340 if (this->family != other.family) {
00341 THROW(AddressException, "mismatched family not supported");
00342 }
00343
00344 IPAddress res(other);
00345
00346 res.hcache = 0;
00347 res.scache.clear();
00348
00349 if (this->family == AF_INET) {
00350 res.addr.v4.s_addr &= this->addr.v4.s_addr;
00351 } else {
00352 uint64_t *a = (uint64_t*) this->addr.v6.s6_addr;
00353 uint64_t *r = (uint64_t*) res.addr.v6.s6_addr;
00354
00355 r[0] &= a[0];
00356 r[1] &= a[1];
00357 }
00358
00359 return res;
00360 }
00361
00362 IPAddress IPAddress::operator|(const IPAddress &other) const throw (AddressException) {
00363 if (this->family != other.family) {
00364 THROW(AddressException, "mismatched family not supported");
00365 }
00366
00367 IPAddress res(other);
00368
00369 res.hcache = 0;
00370 res.scache.clear();
00371
00372 if (this->family == AF_INET) {
00373 res.addr.v4.s_addr |= this->addr.v4.s_addr;
00374 } else {
00375 uint64_t *a = (uint64_t*) this->addr.v6.s6_addr;
00376 uint64_t *r = (uint64_t*) res.addr.v6.s6_addr;
00377
00378 r[0] |= a[0];
00379 r[1] |= a[1];
00380 }
00381
00382 return res;
00383 }
00384
00385 IPAddress IPAddress::operator^(const IPAddress &other) const throw (AddressException) {
00386 if (this->family != other.family) {
00387 THROW(AddressException, "mismatched family not supported");
00388 }
00389
00390 IPAddress res(other);
00391
00392 res.hcache = 0;
00393 res.scache.clear();
00394
00395 if (this->family == AF_INET) {
00396 res.addr.v4.s_addr ^= this->addr.v4.s_addr;
00397 } else {
00398 uint64_t *a = (uint64_t*) this->addr.v6.s6_addr;
00399 uint64_t *r = (uint64_t*) res.addr.v6.s6_addr;
00400
00401 r[0] ^= a[0];
00402 r[1] ^= a[1];
00403 }
00404
00405 return res;
00406 }
00407
00408 IPAddress IPAddress::operator~() const throw () {
00409 IPAddress res(*this);
00410
00411 res.hcache = 0;
00412 res.scache.clear();
00413
00414 if (this->family == AF_INET) {
00415 res.addr.v4.s_addr = ~(res.addr.v4.s_addr);
00416 } else {
00417 uint64_t *r = (uint64_t*) res.addr.v6.s6_addr;
00418
00419 r[0] = ~r[0];
00420 r[1] = ~r[1];
00421 }
00422
00423 return res;
00424 }
00425
00426 IPAddress& IPAddress::operator+=(uint32_t increment) throw () {
00427 this->hcache = 0;
00428 this->scache.clear();
00429
00430 if (this->family == AF_INET) {
00431 addr.v4.s_addr = htonl(ntohl(addr.v4.s_addr) + increment);
00432 } else {
00433 uint64_t t[2] { 0, 0 };
00434 uint64_t *a = (uint64_t*) addr.v6.s6_addr;
00435
00436 t[1] = ntohll(a[1]) + increment;
00437
00438 if (t[1] < ntohll(a[1]) || t[1] < (uint64_t) increment) {
00439 t[0] = ntohll(a[0]) + t[1] + 1;
00440 t[1] = 0;
00441
00442 if (t[0] < ntohll(a[0])) {
00443 t[1] = t[0];
00444 t[0] = 0;
00445 }
00446 } else {
00447 t[0] = ntohll(a[0]);
00448 }
00449
00450 a[0] = htonll(t[0]);
00451 a[1] = htonll(t[1]);
00452 }
00453
00454 return *this;
00455 }
00456
00457 IPAddress IPAddress::operator+(uint32_t increment) const throw () {
00458 IPAddress res(*this);
00459
00460 return (res += increment);
00461 }
00462
00463 IPAddress IPAddress::operator++(int) throw () {
00464 IPAddress res(*this);
00465 ++(*this);
00466
00467 return res;
00468 }
00469
00470 IPAddress& IPAddress::operator++() throw () {
00471 return (*this += 1);
00472 }
00473
00474 IPAddress& IPAddress::operator-=(uint32_t increment) throw () {
00475 this->hcache = 0;
00476 this->scache.clear();
00477
00478 if (this->family == AF_INET) {
00479 addr.v4.s_addr = htonl(ntohl(addr.v4.s_addr) - increment);
00480 } else {
00481 uint64_t t[2] { 0, 0 };
00482 uint64_t *a = (uint64_t*) addr.v6.s6_addr;
00483
00484 t[1] = ntohll(a[1]) - increment;
00485
00486 if (t[1] > ntohll(a[1]) && t[1] > (uint64_t) increment) {
00487 t[0] = ntohll(a[0]) - (std::numeric_limits<uint64_t>::max() - t[1] + 1);
00488 t[1] = std::numeric_limits<uint64_t>::max();
00489
00490 if (t[0] > ntohll(a[0])) {
00491 t[1] = t[0];
00492 t[0] = std::numeric_limits<uint64_t>::max();
00493 }
00494 } else {
00495 t[0] = ntohll(a[0]);
00496 }
00497
00498 a[0] = htonll(t[0]);
00499 a[1] = htonll(t[1]);
00500 }
00501
00502 return *this;
00503 }
00504
00505 IPAddress IPAddress::operator-(uint32_t increment) const throw () {
00506 IPAddress res(*this);
00507
00508 return (res -= increment);
00509 }
00510
00511 IPAddress IPAddress::operator--(int) throw () {
00512 IPAddress res(*this);
00513 --(*this);
00514
00515 return res;
00516 }
00517
00518 IPAddress& IPAddress::operator--() throw () {
00519 return (*this -= 1);
00520 }
00521
00522 bool IPAddress::parse(int &family, struct in6_addr &v6, struct in_addr &v4, const std::string &addr) throw () {
00523 if (this->parse(family, v6, addr) == false) {
00524 return this->parse(family, v4, addr);
00525 }
00526 return true;
00527 }
00528
00529 bool IPAddress::parse(int &family, struct in_addr &v4, struct in6_addr &v6, const std::string &addr) throw () {
00530 if (this->parse(family, v4, addr) == false) {
00531 return this->parse(family, v6, addr);
00532 }
00533 return true;
00534 }
00535
00536 bool IPAddress::parse(int &family, struct in_addr &v4, const std::string &addr) throw () {
00537 bool result = false;
00538
00539 struct ifreq interface[256];
00540 struct sockaddr_in *sockaddr;
00541 int s;
00542
00543 assert(family != 0);
00544
00545 if (inet_pton(AF_INET, addr.c_str(), &v4) != 1) {
00546 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) > 1) {
00547 strncpy(interface[0].ifr_name, addr.c_str(), IFNAMSIZ);
00548 interface[0].ifr_addr.sa_family = AF_INET;
00549
00550 if (ioctl(s, SIOCGIFADDR, interface) == 0) {
00551 sockaddr = (struct sockaddr_in *)&(interface[0].ifr_ifru.ifru_addr);
00552 memcpy(&v4, &(sockaddr->sin_addr), sizeof(addr));
00553
00554 family = AF_INET;
00555 result = true;
00556 }
00557 close(s);
00558 }
00559 } else {
00560 family = AF_INET;
00561 result = true;
00562 }
00563 return result;
00564 }
00565
00566 bool IPAddress::parse(int &famiy, struct in6_addr &v6, const std::string &addr) throw () {
00567 bool result = false;
00568
00569 struct ifreq interface[256];
00570 struct sockaddr_in6 *sockaddr;
00571 int s;
00572
00573 assert(family != 0);
00574
00575 if (inet_pton(AF_INET6, addr.c_str(), &v6) != 1) {
00576 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) > 1) {
00577 strncpy(interface[0].ifr_name, addr.c_str(), IFNAMSIZ);
00578 interface[0].ifr_addr.sa_family = AF_INET6;
00579
00580 if (ioctl(s, SIOCGIFADDR, interface) == 0) {
00581 sockaddr = (struct sockaddr_in6 *)&(interface[0].ifr_ifru.ifru_addr);
00582 memcpy(&v6, &(sockaddr->sin6_addr), sizeof(addr));
00583
00584 family = AF_INET6;
00585 result = true;
00586 }
00587 close(s);
00588 }
00589 } else {
00590 family = AF_INET6;
00591 result = true;
00592 }
00593 return result;
00594 }
00595
00596 void IPAddress::applyCIDR(uint8_t cidr) throw (AddressException) {
00597 assert(this->family != 0);
00598
00599 if (this->family == AF_INET) {
00600 if (cidr > 32) {
00601 THROW(AddressException, "IPv4 CIDR %u outside of valid range (0-32)", cidr);
00602 }
00603
00604 addr.v4.s_addr = htonl(ntohl(addr.v4.s_addr) >> (32 - cidr) << (32 - cidr));
00605 } else {
00606 if (cidr > 128) {
00607 THROW(AddressException, "IPv6 CIDR %u outside of valid range (0-128)", cidr);
00608 }
00609
00610 for (int i = 15; i > cidr / 8 - 1; i--) {
00611 if (i == cidr / 8) {
00612 addr.v6.s6_addr[i] = addr.v6.s6_addr[i] >> (8 - cidr % 8) << (8 - cidr % 8);
00613 } else {
00614 addr.v6.s6_addr[i] = 0;
00615 }
00616 }
00617 }
00618 }
00619
00620 int IPAddress::getFamily(void) const throw () {
00621 assert(this->family != 0);
00622
00623 return this->family;
00624 }
00625
00626 const struct in_addr& IPAddress::getIPv4AddressStructure(void) const throw (AddressException) {
00627 if (this->family != IPv4Family) {
00628 THROW(AddressException, "instance is not an IPv4 address");
00629 }
00630 return this->addr.v4;
00631 }
00632
00633 const struct in6_addr& IPAddress::getIPv6AddressStructure(void) const throw (AddressException) {
00634 if (this->family != IPv6Family) {
00635 THROW(AddressException, "instance is not an IPv6 address");
00636 }
00637 return this->addr.v6;
00638 }
00639
00640 size_t IPAddress::getAddressStructureSize(void) const throw () {
00641 assert(this->family != 0);
00642
00643 return (this->family == IPv4Family) ? sizeof(this->addr.v4) : sizeof(this->addr.v6);
00644 }
00645
00646 const std::string& IPAddress::str(void) const throw (AddressException) {
00647 char buffer[INET6_ADDRSTRLEN];
00648
00649 assert(this->family != 0);
00650
00651 if (scache.empty()) {
00652 if (inet_ntop(this->family, &(this->addr), buffer, sizeof(buffer)) == NULL) {
00653 THROW(AddressException, "inet_ntop failure");
00654 }
00655
00656 scache = buffer;
00657 }
00658
00659 return scache;
00660 }
00661
00662 const char* IPAddress::c_str(void) const throw (AddressException) {
00663 return str().c_str();
00664 }
00665
00666 uint32_t IPAddress::getU32(void) const throw () {
00667 assert(this->family != 0);
00668
00669 if (this->family == IPv4Family) {
00670 return ntohl(this->addr.v4.s_addr);
00671 }
00672
00673 const uint32_t *a = (const uint32_t*) this->addr.v6.s6_addr;
00674
00675 return ntohl(a[0] ^ ~a[1] ^ a[2] ^ ~a[3]);
00676 }
00677
00678 uint32_t IPAddress::getHash(void) const throw () {
00679 if (hcache != 0) {
00680 return hcache;
00681 }
00682
00683 #if defined HASH_ALGO_INT1
00684 uint32_t k = getU32();
00685
00686 hcache = ((k & 0xF0F0F0F0) >> 4) | ((k & 0x0F0F0F0F) << 4);
00687 #elif defined HASH_ALGO_INT2
00688 uint32_t k = getU32();
00689
00690 hcache = (k<<16)^(k>>16)^k;
00691 #elif defined HASH_ALGO_INT3
00692 hcache = getU32();
00693 #else
00694 #error No hash algo selected.
00695 #endif
00696
00697 return hcache;
00698 }
00699
00700 bool IPAddress::empty(void) const throw () {
00701 const uint64_t *a = (const uint64_t*) this->addr.v6.s6_addr;
00702
00703 return (a[0] == 0 && a[1] == 0);
00704 }
00705
00706 void IPAddress::clear(void) throw () {
00707 hcache = 0;
00708 scache.clear();
00709 family = IPv4Family;
00710 memset(&addr, 0, sizeof(addr));
00711 }
00712
00713 const IPAddress::shared IPAddress::shared_ptr(const std::string &text, int family, uint8_t cidr) throw (AddressException) {
00714 return std::make_shared<IPAddress>(text, family, cidr);
00715 }
00716
00717 const IPAddress::shared IPAddress::shared_ptr(int family, uint8_t cidr) throw (AddressException) {
00718 return std::make_shared<IPAddress>(family, cidr);
00719 }
00720
00721 const IPAddress::shared IPAddress::shared_ptr(const struct sockaddr_storage *ss, uint8_t cidr) throw (AddressException) {
00722 return std::make_shared<IPAddress>(ss, cidr);
00723 }
00724
00725 const IPAddress::shared IPAddress::shared_ptr(const struct sockaddr *sa, uint8_t cidr) throw (AddressException) {
00726 return std::make_shared<IPAddress>(sa, cidr);
00727 }
00728
00729 const IPAddress::shared IPAddress::shared_ptr(const struct in_addr *in, uint8_t cidr) throw (AddressException) {
00730 return std::make_shared<IPAddress>(in, cidr);
00731 }
00732
00733 const IPAddress::shared IPAddress::shared_ptr(const struct in6_addr *in6, uint8_t cidr) throw (AddressException) {
00734 return std::make_shared<IPAddress>(in6, cidr);
00735 }
00736
00737 const IPAddress::shared IPAddress::shared_ptr(uint32_t address, uint8_t cidr) throw (AddressException) {
00738 return std::make_shared<IPAddress>(address, cidr);
00739 }
00740
00741 const IPAddress::shared IPAddress::shared_ptr(unsigned char address[16], uint8_t cidr) throw (AddressException) {
00742 return std::make_shared<IPAddress>(address, cidr);
00743 }
00744
00745
00746
00747