00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00033 #include <sys/types.h>
00034 #include <sys/socket.h>
00035
00036 #include "address.h"
00037 #include "threadsafe_db.h"
00038 #include "logfile.h"
00039
00040 #include <net/if.h>
00041 #include <netinet/in.h>
00042 #include <arpa/inet.h>
00043 #include <ifaddrs.h>
00044 #include <iomanip>
00045 #include <netdb.h>
00046
00047 namespace protlib {
00048
00052 using namespace log;
00053
00054
00056 address::address(subtype_t st)
00057 : subtype(st)
00058 {
00059
00060 }
00061
00063 void address::throw_nomem_error() const {
00064 try {
00065 ERRCLog("address", "Not enough memory for address");
00066 } catch(...) {}
00067 throw IEError(IEError::ERROR_NO_MEM);
00068 }
00069
00070
00071
00072
00073
00074
00075 hostaddress* hostaddress::new_instance() const {
00076 hostaddress* ha = NULL;
00077 catch_bad_alloc(ha = new hostaddress());
00078 return ha;
00079 }
00080
00081 hostaddress* hostaddress::copy() const {
00082 hostaddress* ha = NULL;
00083 catch_bad_alloc(ha = new hostaddress(*this));
00084 return ha;
00085 }
00086
00087 bool hostaddress::operator==(const address& ie) const {
00088 const hostaddress* haddr = dynamic_cast<const hostaddress*>(&ie);
00089 if (haddr) {
00090 #ifdef DEBUG_HARD
00091 Log(DEBUG_LOG,LOG_NORMAL,"hostaddress","::operator==()" << haddr->get_ip_str()<<"=="<<this->get_ip_str());
00092 if (!ipv4flag)
00093 Log(DEBUG_LOG,LOG_NORMAL,"hostaddress","::operator==(), v6=" << IN6_ARE_ADDR_EQUAL(ipv6addr.s6_addr, haddr->ipv6addr.s6_addr));
00094 #endif
00095 return ipv4flag ? (ipv4addr.s_addr==haddr->ipv4addr.s_addr) :
00096 IN6_ARE_ADDR_EQUAL(ipv6addr.s6_addr, haddr->ipv6addr.s6_addr);
00097 } else return false;
00098 }
00099
00100
00101
00102
00104 hostaddress::hostaddress(const char *str, bool *res)
00105 : address(IPv6HostAddress),
00106 ipv4flag(false),
00107 outstring(NULL)
00108 {
00109 register bool tmpres = false;
00110 clear_ip();
00111 tmpres = set_ip(str);
00112 if (res) *res = tmpres;
00113 }
00114
00115
00120 bool
00121 hostaddress::set_ipv4(const char *str) {
00122 struct in_addr in;
00123 if (str && (inet_pton(AF_INET,str,&in)>0)) {
00124 set_ip(in);
00125 return true;
00126 } else return false;
00127 }
00128
00132 void hostaddress::set_ip(const struct in_addr &in) {
00133 clear_ip();
00134 ipv4addr = in;
00135
00136 set_subtype(true);
00137 return;
00138 }
00139
00144 bool hostaddress::set_ipv6(const char *str) {
00145 struct in6_addr in;
00146 if (str && (inet_pton(AF_INET6,str,&in)>0)) {
00147 set_ip(in);
00148 return true;
00149 } else return false;
00150 }
00151
00155 void
00156 hostaddress::set_ip(const struct in6_addr &in) {
00157 clear_ip();
00158 ipv6addr = in;
00159
00160 set_subtype(false);
00161 return;
00162 }
00163
00164
00165
00166 void hostaddress::set_ip(const hostaddress& h) {
00167 clear_ip();
00168 if (h.ipv4flag) {
00169 ipv4addr = h.ipv4addr;
00170 } else {
00171 ipv6addr = h.ipv6addr;
00172 }
00173 set_subtype(h.ipv4flag);
00174 }
00175
00177 bool hostaddress::is_ip_unspec() const {
00178 if (ipv4flag) return (ipv4addr.s_addr==0);
00179 else return IN6_IS_ADDR_UNSPECIFIED(ipv6addr.s6_addr);
00180
00181 return true;
00182 }
00183
00187 const char* hostaddress::get_ip_str() const
00188 {
00189
00190 if (outstring)
00191 return outstring;
00192 else
00193 outstring= (ipv4flag ? new(nothrow) char[INET_ADDRSTRLEN] :
00194 new(nothrow) char[INET6_ADDRSTRLEN]);
00195
00196 if (hostaddress::get_ip_str(outstring))
00197 return outstring;
00198 else
00199 {
00200
00201 if (outstring)
00202 delete[] outstring;
00203
00204 return (outstring = NULL);
00205 }
00206 }
00207
00211 const char* hostaddress::get_ip_str(char *str) const
00212 {
00213 if (!str) return NULL;
00214 memset(str,0, ipv4flag ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN);
00215 return ipv4flag ? inet_ntop(AF_INET,(void*)&ipv4addr,str,INET_ADDRSTRLEN)
00216 : inet_ntop(AF_INET6,(void*)&ipv6addr,str,INET6_ADDRSTRLEN);
00217 }
00218
00219
00223 bool hostaddress::get_ip(struct in_addr& in) const {
00224 if (ipv4flag) {
00225 in = ipv4addr;
00226 return true;
00227 } else if (IN6_IS_ADDR_V4MAPPED(ipv6addr.s6_addr)) {
00228 memcpy(&(in.s_addr),ipv6addr.s6_addr+12,4);
00229 return true;
00230 } else return false;
00231 }
00232
00237 bool hostaddress::get_ip(struct in6_addr& in) const {
00238 if (ipv4flag) {
00239
00240 memset(in.s6_addr,0,10);
00241 memset(in.s6_addr+10,255,2);
00242 memcpy(in.s6_addr+12,&(ipv4addr.s_addr),4);
00243 } else in = ipv6addr;
00244 return true;
00245 }
00246
00249 bool
00250 hostaddress::is_bogus_source() const
00251 {
00252 if (ipv4flag)
00253 {
00254 if ( IN_MULTICAST(ipv4addr.s_addr) ||
00255 ipv4addr.s_addr == INADDR_LOOPBACK ||
00256 ipv4addr.s_addr == INADDR_ANY ||
00257 ipv4addr.s_addr == INADDR_BROADCAST
00258 )
00259 {
00260 return true;
00261 }
00262 }
00263 else
00264 {
00265 if ( ipv6addr.s6_addr == in6addr_any.s6_addr ||
00266 ipv6addr.s6_addr == in6addr_loopback.s6_addr )
00267 return true;
00268 }
00269
00270 return false;
00271 }
00272
00273
00277 void hostaddress::convert_to_ipv6() {
00278 if (ipv4flag) {
00279 if (is_ip_unspec()) {
00280
00281 clear_ip();
00282 set_subtype(false);
00283 } else {
00284
00285 struct in6_addr in;
00286 get_ip(in);
00287
00288 set_ip(in);
00289 }
00290 }
00291 }
00292
00296 bool hostaddress::equiv(const hostaddress& h) const {
00297 bool thisipv4 = is_ipv4();
00298 bool result = false;
00299 hostaddress* ipv4haddr = NULL;
00300 const hostaddress* ipv6haddr = NULL;
00301
00302 if (thisipv4==h.is_ipv4()) return operator==(h);
00303
00304
00305
00306 try {
00307 if (thisipv4) {
00308 ipv6haddr = &h;
00309 if (h.is_mapped_ip()) ipv4haddr = this->copy();
00310 } else {
00311 ipv6haddr = this;
00312 if (is_mapped_ip()) ipv4haddr = h.copy();
00313 }
00314 } catch(IEError&) { ipv4haddr = NULL; }
00315 if (ipv4haddr) {
00316 ipv4haddr->convert_to_ipv6();
00317 result = ((*ipv4haddr)==(*ipv6haddr));
00318 delete ipv4haddr;
00319 return result;
00320 } else return false;
00321 }
00322
00323
00327 void hostaddress::set_subtype(bool ipv4) {
00328 ipv4flag = ipv4;
00329 subtype = ipv4flag ? IPv4HostAddress : IPv6HostAddress;
00330 }
00331
00333 void hostaddress::clear_ip() {
00334
00335 ipv6addr = in6addr_any;
00336 if (outstring) {
00337 delete[] outstring;
00338 outstring = NULL;
00339 }
00340 }
00341
00342
00348 int hostaddress::match_against(const hostaddress& ha) const {
00349 if (ipv4flag==ha.ipv4flag) {
00350 if (operator==(ha)) {
00351 if (ipv4flag) return 32;
00352 else return 128;
00353 } else return -1;
00354 } else return -1;
00355 }
00356
00361 int hostaddress::match_against(const netaddress& na) const {
00362 uint32 word1 = 0;
00363 uint32 word2 = 0;
00364 const prefix_length_t preflen = na.get_pref_len();
00365 prefix_length_t lenwords = preflen/32;
00366 prefix_length_t lenbits = preflen%32;
00367
00368 prefix_length_t i;
00369 const hostaddress& ha = dynamic_cast<const hostaddress&>(na);
00370 if (ipv4flag==na.ipv4flag) {
00371 if (ipv4flag) {
00372 if (preflen >= 32)
00373 lenbits = 32;
00374
00375 word1 = ntohl(ipv4addr.s_addr);
00376 word2 = ntohl(ha.ipv4addr.s_addr);
00377
00378 word1 >>= (32-lenbits);
00379 word2 >>= (32-lenbits);
00380 if (word1==word2) return preflen;
00381 else return -1;
00382 } else {
00383 if (preflen > 128)
00384 return -1;
00385
00386
00387 for (i=0;i<lenwords;i++) {
00388 word1 = ntohl(ipv6addr.s6_addr32[i]);
00389 word2 = ntohl(ha.ipv6addr.s6_addr32[i]);
00390 if (word1!=word2) return -1;
00391 }
00392
00393
00394 if (lenbits) {
00395 word1 = ntohl(ipv6addr.s6_addr32[i]);
00396 word2 = ntohl(ha.ipv6addr.s6_addr32[i]);
00397
00398 word1 >>= (32-lenbits);
00399 word2 >>= (32-lenbits);
00400 if (word1==word2) return preflen;
00401 else return -1;
00402 } else {
00403
00404 return preflen;
00405 }
00406 }
00407 } else return -1;
00408 }
00409
00410
00411
00412
00413
00414 appladdress* appladdress::new_instance() const {
00415 appladdress* aa = NULL;
00416 catch_bad_alloc(aa = new appladdress());
00417 return aa;
00418 }
00419
00420 appladdress* appladdress::copy() const {
00421 appladdress* aa = NULL;
00422 catch_bad_alloc(aa = new appladdress(*this));
00423 return aa;
00424 }
00425
00426 bool appladdress::operator==(const address& ie) const {
00427 const appladdress* app = dynamic_cast<const appladdress*>(&ie);
00428 if (app) {
00429
00430
00431
00432 if (hostaddress::operator==(ie)) {
00433
00434
00435
00436 return ((proto==app->proto) && (port==app->port));
00437 } else return false;
00438 } else return false;
00439 }
00440
00441
00442
00443
00444
00445
00446 netaddress* netaddress::new_instance() const {
00447 netaddress* na = NULL;
00448 catch_bad_alloc(na = new netaddress());
00449 return na;
00450 }
00451
00452 netaddress* netaddress::copy() const {
00453 netaddress* na = NULL;
00454 catch_bad_alloc(na = new netaddress(*this));
00455 return na;
00456 }
00457
00458 bool netaddress::operator==(const address& ie) const {
00459 const netaddress* na = dynamic_cast<const netaddress*>(&ie);
00460 if (na) {
00461
00462
00463
00464 if (hostaddress::operator==(ie)) {
00465 if (prefix_length!=na->prefix_length) cout << "Prefix length not matching" << endl;
00466 return (prefix_length==na->prefix_length);
00467 } else return false;
00468 } else return false;
00469 }
00470
00471
00472
00473
00477 void netaddress::convert_to_ipv6() {
00478 if (ipv4flag) {
00479
00480 hostaddress::convert_to_ipv6();
00481
00482 set_pref_len(prefix_length+96);
00483 }
00484 }
00485
00490 void netaddress::set_subtype(bool ipv4) {
00491 ipv4flag = ipv4;
00492 if (ipv4) {
00493 subtype = IPv4NetAddress;
00494 if (prefix_length>32) prefix_length = 32;
00495 } else {
00496 subtype = IPv6NetAddress;
00497 if (prefix_length>128) prefix_length = 128;
00498 }
00499 }
00500
00501
00502
00504 netaddress::netaddress() :
00505 hostaddress(),
00506 prefix_length(0)
00507 {
00508 set_subtype(ipv4flag);
00509 }
00510
00511 netaddress::netaddress(const netaddress& na) : hostaddress(na) {
00512 prefix_length = na.prefix_length;
00513 set_subtype(ipv4flag);
00514 }
00515
00519 netaddress::netaddress(const hostaddress& h, prefix_length_t len) : hostaddress(h) {
00520 set_subtype(ipv4flag);
00521 set_pref_len(len);
00522 }
00523
00527 netaddress::netaddress(const char* str, bool *res) : hostaddress() {
00528 bool tmpres = true;
00529 bool tmpres2 = false;
00530 long int len = 0;
00531 uint32 iplen;
00532 char* i = NULL;
00533 char* errptr = NULL;
00534 char ipstr[INET6_ADDRSTRLEN] = {0};
00535
00536 i = strchr(str,'/');
00537 if (i) {
00538 iplen = i-str;
00539 i++;
00540
00541 len = strtol(i,&errptr,10);
00542 if ((*i) && errptr && ((*errptr)==0)) {
00543
00544 prefix_length = len;
00545 } else {
00546 prefix_length = 0;
00547 tmpres = false;
00548 }
00549 if (iplen<=INET6_ADDRSTRLEN) {
00550
00551 strncpy(ipstr,str,iplen);
00552 ipstr[INET6_ADDRSTRLEN-1] = 0;
00553
00554 str = ipstr;
00555 }
00556 } else {
00557
00558 prefix_length = 0;
00559 }
00560
00561 tmpres2 = set_ip(str);
00562 if (res) *res = (tmpres && tmpres2);
00563 set_subtype(ipv4flag);
00564 }
00565
00570 netaddress::netaddress(const char* str, prefix_length_t len, bool *res) : hostaddress(str,res) {
00571 set_subtype(ipv4flag);
00572 set_pref_len(len);
00573 }
00574
00576 netaddress& netaddress::operator=(const netaddress& na) {
00577 prefix_length = na.prefix_length;
00578 hostaddress::operator=(na);
00579 return *this;
00580 }
00581
00582
00584 netaddress& netaddress::operator=(const hostaddress& na) {
00585 hostaddress::operator=(na);
00586 set_pref_len(128);
00587 return *this;
00588 }
00589
00590
00594 prefix_length_t netaddress::set_pref_len(prefix_length_t len) {
00595 register prefix_length_t olen = prefix_length;
00596 prefix_length = ipv4flag ? ( (len>32) ? 32 : len ) :
00597 ( (len>128) ? 128 : len );
00598 return olen;
00599 }
00600
00601
00602
00606 bool netaddress::operator<(const netaddress& na) const {
00607 uint32 word1 = 0;
00608 uint32 word2 = 0;
00609 prefix_length_t lenwords = prefix_length/32;
00610 prefix_length_t lenbits = prefix_length%32;
00611
00612 prefix_length_t i;
00613
00614 if ((!ipv4flag) && na.ipv4flag) return false;
00615 else if (ipv4flag && (!na.ipv4flag)) return true;
00616
00617 else if (prefix_length<na.prefix_length) return true;
00618 else if (prefix_length>na.prefix_length) return false;
00619
00620 else if (ipv4flag) {
00621
00622 word1 = ntohl(ipv4addr.s_addr);
00623 word2 = ntohl(na.ipv4addr.s_addr);
00624
00625 word1 >>= (32-lenbits);
00626 word2 >>= (32-lenbits);
00627 if (word1<word2) return true;
00628 else return false;
00629 } else {
00630
00631
00632 for (i=0;i<lenwords;i++) {
00633 word1 = ntohl(ipv6addr.s6_addr32[i]);
00634 word2 = ntohl(na.ipv6addr.s6_addr32[i]);
00635 if (word1<word2) return true;
00636 if (word1>word2) return false;
00637 }
00638
00639
00640 if (lenbits) {
00641 word1 = ntohl(ipv6addr.s6_addr32[i]);
00642 word2 = ntohl(na.ipv6addr.s6_addr32[i]);
00643
00644 word1 >>= (32-lenbits);
00645 word2 >>= (32-lenbits);
00646 if (word1<word2) return true;
00647 else return false;
00648 } else {
00649
00650 return false;
00651 }
00652 }
00653 }
00654
00668 int
00669 netaddress::rdx_cmp(const netaddress *na, int *pos) const
00670 {
00671 if (na == NULL) {
00672 *pos = -1;
00673 return 0;
00674 }
00675
00676 if (na->ipv4flag != ipv4flag ||
00677 *pos > na->prefix_length ||
00678 *pos > prefix_length) {
00679 *pos = -1;
00680 return 0;
00681 }
00682
00683 if (na->prefix_length == 0) {
00684 *pos = 1;
00685 if (ipv4flag)
00686 return ((ntohl(ipv4addr.s_addr) & 0x80000000) == 0 ?
00687 -1 : 1);
00688 else
00689 return ((htonl(ipv6addr.s6_addr32[0]) & 0x80000000) == 0 ?
00690 -1 : 1);
00691 }
00692
00693 if (*pos < 0)
00694 *pos = 0;
00695
00696 uint32_t w1, w2, w3;
00697 int diff, i, p1, p2;
00698
00699 if (ipv4flag) {
00700 diff = *pos;
00701 w1 = ntohl(ipv4addr.s_addr);
00702 w2 = ntohl(na->ipv4addr.s_addr);
00703
00704 w3 = w1 ^ w2;
00705
00706 w3 = (w3 >> (32 - prefix_length)) << (32 - prefix_length + diff);
00707 if (w3 == 0 && prefix_length <= na->prefix_length) {
00708 *pos = min(prefix_length, na->prefix_length);
00709 return 0;
00710 }
00711
00712 diff++;
00713 while (diff <= prefix_length && diff <= na->prefix_length) {
00714 if ((w3 & 0x80000000) != 0) {
00715 *pos = diff;
00716 return (((w1 & (1 << (32 - diff))) >>
00717 (32 - diff)) == 0 ? -1 : 1);
00718 }
00719 w3 = w3 << 1;
00720 diff++;
00721 }
00722
00723 *pos = diff;
00724 return (((w1 & (1 << (32 - diff))) >>
00725 (32 - diff)) == 0 ? -1 : 1);
00726 }
00727
00728 diff = *pos;
00729 for (i = diff / 32; i < 4; i++) {
00730 diff = diff % 32;
00731 w1 = ntohl(ipv6addr.s6_addr32[i]);
00732 w2 = ntohl(na->ipv6addr.s6_addr32[i]);
00733 w3 = w1 ^ w2;
00734 p1 = (prefix_length - (i * 32));
00735 p1 = p1 > 32 ? 32 : p1;
00736 p2 = (na->prefix_length - (i * 32));
00737 p1 = p2 > 32 ? 32 : p2;
00738
00739 w3 = (w3 >> (32 - p1)) << (32 - p1 + diff);
00740 if (w3 == 0 && prefix_length <= na->prefix_length) {
00741 *pos = min(prefix_length, na->prefix_length);
00742 if (prefix_length <= ((i + 1) * 32))
00743 return 0;
00744 }
00745
00746 diff++;
00747 while (diff <= p1 && diff <= p2) {
00748 if ((w3 & 0x80000000) != 0) {
00749 *pos = diff + (i * 32);
00750 return (((w1 & (1 << (32 - diff))) >>
00751 (32 - diff)) == 0 ? -1 : 1);
00752 }
00753 w3 = w3 << 1;
00754 diff++;
00755 }
00756 if (diff + (32 * i) <= prefix_length &&
00757 diff + (32 * i) <= na->prefix_length) {
00758 diff--;
00759 continue;
00760 }
00761
00762 *pos = diff + (i * 32);
00763 if (diff == 33) {
00764 diff = 1;
00765 if (i == 3)
00766 abort();
00767 w1 = ntohl(ipv6addr.s6_addr32[i+1]);
00768 }
00769 return (((w1 & (1 << (32 - diff))) >>
00770 (32 - diff)) == 0 ? -1 : 1);
00771 }
00772
00773
00774 return 0;
00775 }
00776
00777 udsaddress* udsaddress::new_instance() const {
00778 udsaddress* ha = NULL;
00779 catch_bad_alloc(ha = new udsaddress());
00780 return ha;
00781 }
00782
00783 udsaddress* udsaddress::copy() const {
00784 udsaddress* ha = NULL;
00785 catch_bad_alloc(ha = new udsaddress(*this));
00786 return ha;
00787 }
00788
00789 bool udsaddress::operator==(const address& ie) const {
00790 const udsaddress* app = dynamic_cast<const udsaddress*>(&ie);
00791 if (app) {
00792 return (app->socknum == socknum) && (app->uds_socket == uds_socket);
00793 } else return false;
00794 }
00795
00796 AddressList::AddrProperty *AddressList::LocalAddr_P;
00797 AddressList::AddrProperty *AddressList::ConfiguredAddr_P;
00798 AddressList::AddrProperty *AddressList::IgnoreAddr_P;
00799 AddressList::AddrProperty *AddressList::AnyAddr_P;
00800
00801 AddressList::AddressList()
00802 {
00803 if (LocalAddr_P == 0) {
00804 LocalAddr_P = new AddrProperty("local");
00805 ConfiguredAddr_P = new AddrProperty("configured");
00806 IgnoreAddr_P = new AddrProperty("ignore");
00807 AnyAddr_P = new AddrProperty("wildcard");
00808 }
00809 interfaces = 0;
00810 }
00811
00812 AddressList::~AddressList()
00813 {
00814
00815 }
00816
00817 AddressList::iflist_t *
00818 AddressList::get_interfaces()
00819 {
00820 iflist_t *iflist;
00821
00822 if (interfaces != 0)
00823 iflist = new iflist_t(*interfaces);
00824 else {
00825 iflist = new iflist_t();
00826 getifaddrs_iflist(*iflist);
00827 }
00828
00829 return iflist;
00830 }
00831
00832 bool
00833 AddressList::by_interface(bool start_empty)
00834 {
00835 if (interfaces != 0)
00836 return false;
00837
00838 interfaces = new iflist_t();
00839 if (!start_empty)
00840 getifaddrs_iflist(*interfaces);
00841
00842 return true;
00843 }
00844
00845 bool
00846 AddressList::add_interface(char *name)
00847 {
00848 if (interfaces == 0)
00849 return false;
00850
00851 return (interfaces->insert(name)).second;
00852 }
00853
00854 bool
00855 AddressList::del_interface(char *name)
00856 {
00857 if (interfaces == 0)
00858 return false;
00859
00860 return (interfaces->erase(name) > 0);
00861 }
00862
00863 bool
00864 AddressList::add_property(netaddress &na, AddrProperty *p, bool propagate)
00865 {
00866 propmap_t *props, *lpfm_props;
00867 propmap_t::iterator it;
00868 addr2prop_t::node *node;
00869
00870 node = prop_trie.lookup_node(na, false, false);
00871 if (node != NULL) {
00872 props = node->data;
00873 if (props == NULL) {
00874 props = new propmap_t();
00875 node->data = props;
00876 }
00877 props->insert(pair<AddrProperty *, bool>(p, propagate));
00878
00879 } else {
00880 props = new propmap_t();
00881 props->insert(pair<AddrProperty *, bool>(p, propagate));
00882 node = prop_trie.insert(na, *props);
00883 }
00884
00885 if (propagate)
00886 bequeath(node, p, true);
00887
00888
00889 lpfm_props = prop_trie.lookup(na, true);
00890 if (lpfm_props == NULL)
00891 return true;
00892
00893 for (it = lpfm_props->begin(); it != lpfm_props->end(); it++) {
00894 if ((*it).second)
00895 props->insert((*it));
00896 }
00897
00898 return true;
00899 }
00900
00901 bool
00902 AddressList::del_property(netaddress &na, AddrProperty *p, bool propagate)
00903 {
00904 propmap_t *props, *lpfm_props;
00905 propmap_t::iterator it;
00906 addr2prop_t::node *node;
00907
00908 node = prop_trie.lookup_node(na, false, true);
00909 if (node == NULL) {
00910
00911 if (!propagate) {
00912 node = prop_trie.lookup_node(na, true, true);
00913 if (node == NULL) {
00914
00915 return false;
00916 }
00917
00918 props = node->data;
00919 it = props->find(p);
00920 if (it == props->end()) {
00921
00922 return false;
00923 }
00924 }
00925
00926 props = new propmap_t();
00927 node = prop_trie.insert(na, *props);
00928
00929
00930 lpfm_props = prop_trie.lookup(na, true);
00931 if (p != AnyAddr_P && lpfm_props != NULL) {
00932 for (it = lpfm_props->begin(); it != lpfm_props->end();
00933 it++) {
00934 if ((*it).first != p && (*it).second)
00935 props->insert((*it));
00936 }
00937 }
00938 } else {
00939 props = node->data;
00940 if (p == AnyAddr_P) {
00941 props->clear();
00942 } else {
00943 it = props->find(p);
00944 if (it == props->end() && !propagate)
00945 return false;
00946
00947 props->erase(it);
00948 }
00949 }
00950
00951 if (propagate)
00952 bequeath(node, p, false);
00953
00954 return true;
00955 }
00956
00957 bool
00958 AddressList::add_host_prop(const char *name, AddrProperty *p)
00959 {
00960 netaddress na;
00961 sockaddr_in *sin;
00962 sockaddr_in6 *sin6;
00963 struct addrinfo hints = {0}, *res, *cur;
00964 int error;
00965 char buf[1024];
00966
00967 if (name == NULL) {
00968 name = buf;
00969 if (gethostname(buf, sizeof(buf)) != 0)
00970 return false;
00971 buf[sizeof(buf) - 1] = '\0';
00972 }
00973 hints.ai_flags = AI_ADDRCONFIG | AI_CANONNAME;
00974 hints.ai_family = AF_UNSPEC;
00975 error = getaddrinfo(name, NULL, &hints, &res);
00976 if (error != 0)
00977 return false;
00978
00979 for(cur = res; cur != NULL && error == 0; cur = cur->ai_next) {
00980 if (cur->ai_family == AF_INET) {
00981 sin = (struct sockaddr_in *)cur->ai_addr;
00982 na.set_ip(sin->sin_addr);
00983 na.set_pref_len(32);
00984 } else if (cur->ai_family == AF_INET6) {
00985 sin6 = (struct sockaddr_in6 *)cur->ai_addr;
00986 na.set_ip(sin6->sin6_addr);
00987 na.set_pref_len(128);
00988 } else
00989 continue;
00990
00991
00992
00993 error += add_property(na, p) ? 0 : 1;
00994
00995
00996 na.set_ip("127.0.0.1");
00997 }
00998 freeaddrinfo(res);
00999
01000 return (error == 0);
01001 }
01002
01003 bool
01004 AddressList::del_host_prop(const char *name, AddrProperty *p)
01005 {
01006 netaddress na;
01007 sockaddr_in *sin;
01008 sockaddr_in6 *sin6;
01009 struct addrinfo hints = {0}, *res, *cur;
01010 int error;
01011 char buf[1024];
01012
01013 if (name == NULL) {
01014 name = buf;
01015 if (gethostname(buf, sizeof(buf)) != 0)
01016 return false;
01017 buf[sizeof(buf) - 1] = '\0';
01018 }
01019 hints.ai_flags = AI_ADDRCONFIG;
01020 hints.ai_family = AF_UNSPEC;
01021 error = getaddrinfo(name, NULL, &hints, &res);
01022 if (error != 0)
01023 return false;
01024
01025 for(cur = res; cur != NULL && error == 0; cur = cur->ai_next) {
01026 if (cur->ai_family == AF_INET) {
01027 sin = (struct sockaddr_in *)cur->ai_addr;
01028 na.set_ip(sin->sin_addr);
01029 na.set_pref_len(32);
01030 } else if (cur->ai_family == AF_INET6) {
01031 sin6 = (struct sockaddr_in6 *)cur->ai_addr;
01032 na.set_ip(sin6->sin6_addr);
01033 na.set_pref_len(128);
01034 } else
01035 continue;
01036
01037 error += del_property(na, p) ? 0 : 1;
01038 }
01039 freeaddrinfo(res);
01040
01041 return (error == 0);
01042 }
01043
01044 bool
01045 AddressList::ignore(netaddress &na, bool propagate)
01046 {
01047 del_property(na, AnyAddr_P, propagate);
01048 return add_property(na, IgnoreAddr_P);
01049 }
01050
01051 bool
01052 AddressList::unignore(netaddress &na, bool propagate)
01053 {
01054 return del_property(na, IgnoreAddr_P, propagate);
01055 }
01056
01057 bool
01058 AddressList::ignore_bogons(void)
01059 {
01060 netaddress na;
01061
01062
01063 na.set_ip("0.0.0.0");na.set_pref_len(7);
01064 ignore(na);
01065 na.set_ip("2.0.0.0");na.set_pref_len(8);
01066 ignore(na);
01067 na.set_ip("5.0.0.0");na.set_pref_len(8);
01068 ignore(na);
01069 na.set_ip("7.0.0.0");na.set_pref_len(8);
01070 ignore(na);
01071 na.set_ip("23.0.0.0");na.set_pref_len(8);
01072 ignore(na);
01073 na.set_ip("27.0.0.0");na.set_pref_len(8);
01074 ignore(na);
01075 na.set_ip("31.0.0.0");na.set_pref_len(8);
01076 ignore(na);
01077 na.set_ip("36.0.0.0");na.set_pref_len(7);
01078 ignore(na);
01079 na.set_ip("39.0.0.0");na.set_pref_len(8);
01080 ignore(na);
01081 na.set_ip("42.0.0.0");na.set_pref_len(8);
01082 ignore(na);
01083 na.set_ip("49.0.0.0");na.set_pref_len(8);
01084 ignore(na);
01085 na.set_ip("50.0.0.0");na.set_pref_len(8);
01086 ignore(na);
01087 na.set_ip("94.0.0.0");na.set_pref_len(7);
01088 ignore(na);
01089 na.set_ip("100.0.0.0");na.set_pref_len(6);
01090 ignore(na);
01091 na.set_ip("104.0.0.0");na.set_pref_len(5);
01092 ignore(na);
01093 na.set_ip("112.0.0.0");na.set_pref_len(6);
01094 ignore(na);
01095 na.set_ip("169.254.0.0");na.set_pref_len(16);
01096 ignore(na);
01097 na.set_ip("173.0.0.0");na.set_pref_len(8);
01098 ignore(na);
01099 na.set_ip("174.0.0.0");na.set_pref_len(7);
01100 ignore(na);
01101 na.set_ip("176.0.0.0");na.set_pref_len(5);
01102 ignore(na);
01103 na.set_ip("184.0.0.0");na.set_pref_len(6);
01104 ignore(na);
01105 na.set_ip("191.0.0.0");na.set_pref_len(8);
01106 ignore(na);
01107 na.set_ip("192.0.2.0");na.set_pref_len(24);
01108 ignore(na);
01109 na.set_ip("197.0.0.0");na.set_pref_len(8);
01110 ignore(na);
01111 na.set_ip("198.18.0.0");na.set_pref_len(15);
01112 ignore(na);
01113 na.set_ip("223.0.0.0");na.set_pref_len(8);
01114 ignore(na);
01115 na.set_ip("240.0.0.0");na.set_pref_len(4);
01116 ignore(na);
01117
01118 na.set_ip("0000::");na.set_pref_len(8);
01119 ignore(na);
01120 na.set_ip("0100::");na.set_pref_len(8);
01121 ignore(na);
01122 na.set_ip("0200::");na.set_pref_len(7);
01123 ignore(na);
01124 na.set_ip("0400::");na.set_pref_len(7);
01125 ignore(na);
01126 na.set_ip("0600::");na.set_pref_len(7);
01127 ignore(na);
01128 na.set_ip("0800::");na.set_pref_len(5);
01129 ignore(na);
01130 na.set_ip("1000::");na.set_pref_len(4);
01131 ignore(na);
01132 na.set_ip("2000::");na.set_pref_len(16);
01133 ignore(na);
01134 na.set_ip("2001:1000::");na.set_pref_len(23);
01135 ignore(na);
01136 na.set_ip("2001:1600::");na.set_pref_len(23);
01137 ignore(na);
01138 na.set_ip("2001:2000::");na.set_pref_len(20);
01139 ignore(na);
01140 na.set_ip("2001:3000::");na.set_pref_len(20);
01141 ignore(na);
01142 na.set_ip("2001:4000::");na.set_pref_len(20);
01143 ignore(na);
01144 na.set_ip("2001:5000::");na.set_pref_len(20);
01145 ignore(na);
01146 na.set_ip("2001:6000::");na.set_pref_len(20);
01147 ignore(na);
01148 na.set_ip("2001:7000::");na.set_pref_len(20);
01149 ignore(na);
01150 na.set_ip("2001:8000::");na.set_pref_len(20);
01151 ignore(na);
01152 na.set_ip("2001:9000::");na.set_pref_len(20);
01153 ignore(na);
01154 na.set_ip("2001:A000::");na.set_pref_len(20);
01155 ignore(na);
01156 na.set_ip("2001:B000::");na.set_pref_len(20);
01157 ignore(na);
01158 na.set_ip("2001:C000::");na.set_pref_len(20);
01159 ignore(na);
01160 na.set_ip("2001:D000::");na.set_pref_len(20);
01161 ignore(na);
01162 na.set_ip("2001:E000::");na.set_pref_len(20);
01163 ignore(na);
01164 na.set_ip("2001:F000::");na.set_pref_len(20);
01165 ignore(na);
01166 na.set_ip("3FFF::");na.set_pref_len(16);
01167 ignore(na);
01168 na.set_ip("4000::");na.set_pref_len(3);
01169 ignore(na);
01170 na.set_ip("6000::");na.set_pref_len(3);
01171 ignore(na);
01172 na.set_ip("8000::");na.set_pref_len(3);
01173 ignore(na);
01174 na.set_ip("A000::");na.set_pref_len(3);
01175 ignore(na);
01176 na.set_ip("C000::");na.set_pref_len(3);
01177 ignore(na);
01178 na.set_ip("E000::");na.set_pref_len(4);
01179 ignore(na);
01180 na.set_ip("F000::");na.set_pref_len(5);
01181 ignore(na);
01182 na.set_ip("F800::");na.set_pref_len(6);
01183 ignore(na);
01184 na.set_ip("FC00::");na.set_pref_len(7);
01185 ignore(na);
01186 na.set_ip("FE00::");na.set_pref_len(9);
01187 ignore(na);
01188
01189 return true;
01190 }
01191
01192 bool
01193 AddressList::ignore_locals(void)
01194 {
01195 netaddress na;
01196
01197 na.set_ip("10.0.0.0");na.set_pref_len(8);
01198 ignore(na);
01199 na.set_ip("172.16.0.0");na.set_pref_len(12);
01200 ignore(na);
01201 na.set_ip("192.168.0.0");na.set_pref_len(16);
01202 ignore(na);
01203 na.set_ip("FE80::");na.set_pref_len(10);
01204 ignore(na);
01205 na.set_ip("FEC0::");na.set_pref_len(10);
01206 ignore(na);
01207
01208 return true;
01209 }
01210
01211 bool
01212 AddressList::ignore_loopback(void)
01213 {
01214 netaddress na;
01215
01216 na.set_ip("127.0.0.0");na.set_pref_len(8);
01217 ignore(na);
01218 na.set_ip("::1");na.set_pref_len(128);
01219 ignore(na);
01220
01221 return true;
01222 }
01223
01224 bool
01225 AddressList::addr_is(netaddress &na, AddrProperty *prop)
01226 {
01227 propmap_t *props;
01228 propmap_t::iterator it;
01229
01230 if (addr_is_in(na, IgnoreAddr_P))
01231 return false;
01232
01233 props = prop_trie.lookup(na, false);
01234 if (props != NULL) {
01235 it = props->find(prop);
01236 if (it != props->end()) {
01237 return true;
01238 }
01239 }
01240
01241 if (prop != LocalAddr_P)
01242 return false;
01243
01244 return getifaddrs_is_local(na);
01245 }
01246
01247 bool
01248 AddressList::addr_is_in(netaddress &na, AddrProperty *prop)
01249 {
01250 addr2prop_t::node *node;
01251 propmap_t *props;
01252 propmap_t::iterator it;
01253
01254 node = prop_trie.lookup_node(na, true, true);
01255 if (node == NULL)
01256 return false;
01257
01258 props = node->data;
01259 it = props->find(prop);
01260 if (it == props->end())
01261 return false;
01262
01263 if (!(*it).second && props != prop_trie.lookup(na, false))
01264 return false;
01265
01266 return true;
01267 }
01268
01269 AddressList::addrlist_t *
01270 AddressList::get_addrs(AddrProperty *prop)
01271 {
01272 addr2prop_t::node *node;
01273 netaddress na;
01274 addrlist_t *res = new addrlist_t();
01275
01276 if (res == 0)
01277 return res;
01278
01279 if (prop == LocalAddr_P || prop == AnyAddr_P)
01280 getifaddrs_get_addrs(*res);
01281
01282 na.set_ip("0.0.0.0");
01283 na.set_pref_len(0);
01284 node = prop_trie.lookup_node(na, true, false);
01285 collect(node, prop, *res);
01286
01287 na.set_ip("::");
01288 node = prop_trie.lookup_node(na, true, false);
01289 collect(node, prop, *res);
01290
01291 return res;
01292 }
01293
01294 netaddress *
01295 AddressList::get_first(AddrProperty *p, bool IPv4)
01296 {
01297 addr2prop_t::node *node;
01298 netaddress na;
01299 addrlist_t list;
01300 addrlist_t::iterator it;
01301
01302 if (IPv4) {
01303 na.set_ip("0.0.0.0");
01304 na.set_pref_len(0);
01305 } else {
01306 na.set_ip("::");
01307 na.set_pref_len(0);
01308 }
01309
01310 node = prop_trie.lookup_node(na, true, false);
01311 node = collect_first(node, p);
01312 if (node != NULL)
01313 return new netaddress(*node->key);
01314
01315 if (p == LocalAddr_P) {
01316 getifaddrs_get_addrs(list);
01317 for (it = list.begin(); it != list.end(); it++)
01318 if ((*it).is_ipv4() == IPv4)
01319 return new netaddress(*it);
01320 }
01321
01322 return NULL;
01323 }
01324
01325 netaddress *
01326 AddressList::get_src_addr(const netaddress &dest, uint32_t *prefs)
01327 {
01328 netaddress *res;
01329 int sfd;
01330
01331 sfd = socket(dest.is_ipv4()?AF_INET:AF_INET6, SOCK_DGRAM, 0);
01332 if (sfd == -1)
01333 return NULL;
01334
01335 #ifdef IPV6_ADDR_PREFERENCES
01336 if (prefs != NULL && setsockopt(s, IPV6_ADDR_PREFERENCES,
01337 (void *)prefs, sizeof (*prefs)) == -1) {
01338 close(sfd);
01339 return NULL;
01340 }
01341 #endif
01342 if (dest.is_ipv4()) {
01343 struct sockaddr_in sin = {0};
01344 socklen_t slen = sizeof(sin);
01345 sin.sin_family = AF_INET;
01346 sin.sin_port = htons(4);
01347 dest.get_ip(sin.sin_addr);
01348 if (connect(sfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
01349 close(sfd);
01350 return NULL;
01351 }
01352 if (getsockname(sfd, (struct sockaddr *)&sin, &slen) == -1) {
01353 close(sfd);
01354 return NULL;
01355 }
01356 close(sfd);
01357 res = new netaddress();
01358 res->set_ip(sin.sin_addr);
01359 res->set_pref_len(32);
01360 return (res);
01361 } else {
01362 struct sockaddr_in6 sin6 = {0};
01363 socklen_t slen = sizeof(sin6);
01364 sin6.sin6_family = AF_INET6;
01365 sin6.sin6_port = htons(4);
01366 dest.get_ip(sin6.sin6_addr);
01367 if (connect(sfd, (struct sockaddr *)&sin6,
01368 sizeof(sin6)) == -1) {
01369 close(sfd);
01370 return NULL;
01371 }
01372 if (getsockname(sfd, (struct sockaddr *)&sin6, &slen) == -1) {
01373 close(sfd);
01374 return NULL;
01375 }
01376 close(sfd);
01377 res = new netaddress();
01378 res->set_ip(sin6.sin6_addr);
01379 res->set_pref_len(128);
01380 return (res);
01381 }
01382 }
01383
01384 void
01385 AddressList::getifaddrs_iflist(iflist_t &list)
01386 {
01387 struct ifaddrs *ifap, *cifa;
01388
01389 if (::getifaddrs(&ifap) != 0)
01390 return;
01391
01392 for (cifa = ifap; cifa != NULL; cifa = cifa->ifa_next) {
01393 list.insert(cifa->ifa_name);
01394 }
01395
01396 freeifaddrs(ifap);
01397 }
01398
01399 bool
01400 AddressList::getifaddrs_is_local(netaddress &na)
01401 {
01402 struct ifaddrs *ifap, *cifa;
01403
01404 if (::getifaddrs(&ifap) != 0)
01405 return false;
01406
01407 for (cifa = ifap; cifa != NULL; cifa = cifa->ifa_next) {
01408 hostaddress ha;
01409
01410 if (cifa->ifa_addr->sa_family == AF_INET) {
01411 ha.set_ip(
01412 ((struct sockaddr_in *)cifa->ifa_addr)->sin_addr);
01413 } else if (cifa->ifa_addr->sa_family == AF_INET6) {
01414 ha.set_ip(
01415 ((struct sockaddr_in6 *)cifa->ifa_addr)->sin6_addr);
01416 } else {
01417 continue;
01418 }
01419
01420 if (interfaces &&
01421 interfaces->find(cifa->ifa_name) == interfaces->end())
01422 continue;
01423
01424 if (ha.match_against(na) >= na.get_pref_len()) {
01425 freeifaddrs(ifap);
01426 return true;
01427 }
01428 }
01429
01430 freeifaddrs(ifap);
01431
01432 return false;
01433 }
01434
01435 void
01436 AddressList::getifaddrs_get_addrs(addrlist_t &list)
01437 {
01438 struct ifaddrs *ifap, *cifa;
01439
01440 if (::getifaddrs(&ifap) != 0)
01441 return;
01442
01443 for (cifa = ifap; cifa != NULL; cifa = cifa->ifa_next) {
01444 hostaddress *ha;
01445 netaddress na;
01446
01447 if (interfaces &&
01448 interfaces->find(cifa->ifa_name) == interfaces->end())
01449 continue;
01450
01451 if (cifa->ifa_addr->sa_family == AF_INET) {
01452 ha = new hostaddress;
01453 ha->set_ip(
01454 ((struct sockaddr_in *)cifa->ifa_addr)->sin_addr);
01455 na.set_pref_len(32);
01456 } else if (cifa->ifa_addr->sa_family == AF_INET6) {
01457 ha = new hostaddress;
01458 ha->set_ip(
01459 ((struct sockaddr_in6 *)cifa->ifa_addr)->sin6_addr);
01460 na.set_pref_len(128);
01461 } else {
01462 continue;
01463 }
01464
01465 na.set_ip(*ha);
01466 if (!addr_is_in(na, IgnoreAddr_P))
01467 list.insert(*ha);
01468 }
01469
01470 freeifaddrs(ifap);
01471 }
01472
01473 void
01474 AddressList::bequeath(addr2prop_t::node *head, AddrProperty *p, bool add)
01475 {
01476 propmap_t *props;
01477 propmap_t::iterator it;
01478
01479 if (p == AnyAddr_P && add)
01480 return;
01481
01482 props = head->data;
01483 if (props != NULL) {
01484 if (p == AnyAddr_P) {
01485 props->clear();
01486 } else {
01487 if (add) {
01488 props->insert(pair<AddrProperty *, bool>
01489 (p, true));
01490 } else {
01491 it = props->find(p);
01492 if (it != props->end())
01493 props->erase(it);
01494 }
01495 }
01496 }
01497
01498 if (head->left->index > head->index)
01499 bequeath(head->left, p, add);
01500 if (head->right->index > head->index)
01501 bequeath(head->right, p, add);
01502 }
01503
01504 void
01505 AddressList::collect(addr2prop_t::node *head, AddrProperty *p,
01506 addrlist_t &list)
01507 {
01508 propmap_t *props;
01509 propmap_t::iterator it;
01510
01511 props = head->data;
01512 if (props != NULL) {
01513 if (p == AnyAddr_P) {
01514 it = props->begin();
01515 } else {
01516 it = props->find(p);
01517 }
01518 if (it != props->end()) {
01519 list.insert(*(new netaddress(*head->key)));
01520 }
01521 }
01522
01523 if (head->left->index > head->index)
01524 collect(head->left, p, list);
01525 if (head->right->index > head->index)
01526 collect(head->right, p, list);
01527
01528 }
01529
01530 AddressList::addr2prop_t::node *
01531 AddressList::collect_first(addr2prop_t::node *head, AddrProperty *p)
01532 {
01533 addr2prop_t::node *res = NULL;
01534 propmap_t *props;
01535 propmap_t::iterator it;
01536
01537 props = head->data;
01538 if (props != NULL) {
01539 if (p == AnyAddr_P) {
01540 it = props->begin();
01541 } else {
01542 it = props->find(p);
01543 }
01544 if (it != props->end()) {
01545 return head;
01546 }
01547 }
01548
01549 if (head->left->index > head->index) {
01550 res = collect_first(head->left, p);
01551 if (res != NULL)
01552 return res;
01553 }
01554 if (head->right->index > head->index) {
01555 res = collect_first(head->right, p);
01556 if (res != NULL)
01557 return res;
01558 }
01559
01560 return NULL;
01561 }
01562
01563
01564 }