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
00034 #ifndef PROTLIB__ADDRESS_H
00035 #define PROTLIB__ADDRESS_H
00036
00037 #include "protlib_types.h"
00038 #include "ie.h"
00039
00040 #include <boost/unordered_map.hpp>
00041 #include <boost/functional/hash.hpp>
00042
00043 #include <netinet/in.h>
00044 #include <set>
00045
00046 #include "logfile.h"
00047 #include "threadsafe_db.h"
00048
00049 namespace protlib {
00050 using namespace log;
00051
00053
00056 class address {
00057 public:
00058 virtual address* new_instance() const = 0;
00059 virtual address* copy() const = 0;
00060 virtual bool operator==(const address& address) const = 0;
00061
00062 inline bool operator!=(const address& address) const {
00063 return (!(*this==address));
00064 }
00065
00066
00067 enum subtype_t {
00072 all_subtypes = 255,
00073
00075
00076 IPv4HostAddress = 1,
00077 IPv6HostAddress = 2,
00078 IPv4NetAddress = 3,
00079 IPv6NetAddress = 4,
00080 IPv4ApplAddress = 5,
00081 IPv6ApplAddress = 6,
00082 IPv6Unspecified = 7,
00083 UDSAddress = 8,
00084 FlowAddressSpec = 12,
00085 AS16 = 14,
00086 AS32 = 15,
00087 IEEE48 = 16,
00088 EUI48 = 17,
00089 EUI64 = 18,
00090 NAI = 32,
00091 X509 = 33
00092
00093 };
00094
00095 virtual ~address() {};
00096
00097 subtype_t get_type() const { return subtype; };
00098
00099 protected:
00101 address(subtype_t st);
00103
00104 void throw_nomem_error() const;
00105
00106 subtype_t subtype;
00107 };
00108
00109
00110 class netaddress;
00111
00113
00114 class hostaddress : public address {
00115
00116 public:
00117 virtual hostaddress* new_instance() const;
00118 virtual hostaddress* copy() const;
00119 virtual bool operator==(const address& ie) const;
00120
00122 hostaddress();
00124 hostaddress(const hostaddress& h);
00126 hostaddress& operator=(const hostaddress& h);
00128 hostaddress(const char *str, bool *res = NULL);
00130 hostaddress(const struct in6_addr& ipv6addr);
00132 virtual ~hostaddress();
00134 bool set_ipv4(const char *str);
00136 void set_ip(const struct in_addr &in);
00138 bool set_ipv6(const char *str);
00140 void set_ip(const struct in6_addr &in);
00142 bool set_ip(const char *str);
00143 bool set_ip(const string& str);
00145 void set_ip(const hostaddress& h);
00147 bool is_ip_unspec() const;
00149 const char *get_ip_str() const;
00151 const char *get_ip_str(char *str) const;
00153 bool is_ipv4() const;
00155 bool is_ipv6() const;
00157 bool is_bogus_source() const;
00159 bool is_mapped_ip() const;
00161 bool get_ip(struct in_addr& in) const;
00163 bool get_ip(struct in6_addr& in) const;
00165 const struct in6_addr *get_ip() const { return ipv4flag ? 0 : &ipv6addr; };
00167 virtual void convert_to_ipv6();
00169 virtual bool equiv(const hostaddress& h) const;
00171 string get_host_name(bool *res = NULL) const;
00173 virtual size_t get_hash() const;
00175 virtual int match_against(const hostaddress& ha) const;
00177 virtual int match_against(const netaddress& na) const;
00178 protected:
00180 bool ipv4flag;
00182 virtual void set_subtype(bool ipv4);
00184
00187 union {
00189 struct in_addr ipv4addr;
00191 struct in6_addr ipv6addr;
00192 };
00193 public:
00195 void clear_ip();
00196 private:
00198 mutable char *outstring;
00199 };
00200
00201 inline ostream &operator<<(ostream &out, const hostaddress &addr) {
00202 return out << addr.get_ip_str();
00203 }
00204
00205 inline
00206 hostaddress::hostaddress(const struct in6_addr& ipv6addr)
00207 : address(IPv6HostAddress),
00208 ipv4flag(false),
00209 ipv6addr(ipv6addr),
00210 outstring(NULL)
00211 { set_subtype(false); }
00212
00213
00217
00218 class appladdress : public hostaddress {
00219 public:
00220 virtual appladdress* new_instance() const;
00221 virtual appladdress* copy() const;
00222 virtual bool operator==(const address& ie) const;
00223
00225 virtual size_t get_hash() const;
00226
00227 protected:
00229 virtual void set_subtype(bool ipv4);
00230
00231 public:
00233 appladdress();
00235 appladdress(const appladdress& app);
00237 appladdress(string socket);
00239 appladdress(int socket);
00241 appladdress(const hostaddress& h, protocol_t prot, port_t p);
00243 appladdress(const sockaddr_in6& sockaddr, protocol_t prot);
00245 appladdress(const hostaddress& h, const char* pname, port_t p, bool *res = NULL);
00247 appladdress(const char* str, protocol_t prot, port_t p, bool *res = NULL);
00249 appladdress(const char* str, const char* pname, port_t p, bool *res = NULL);
00251 appladdress(const char* str, const char* pname, const char* portname, bool *res = NULL);
00253 appladdress& operator=(const appladdress& app);
00255 virtual ~appladdress() {};
00256
00257
00260
00262 port_t set_port(port_t p);
00264 port_t set_port(const char* pname, bool *res = NULL);
00266 port_t set_port(const string& pname, bool *res = NULL);
00268 port_t get_port() const;
00269
00271 void get_sockaddr(struct sockaddr_in6& sockaddr) const;
00273 string get_port_name(bool *res = NULL) const;
00275 protocol_t set_protocol(protocol_t p);
00277 protocol_t set_protocol(const char* pname, bool *res = NULL);
00279 protocol_t set_protocol(const string& pname, bool *res = NULL);
00281 protocol_t get_protocol() const;
00283 string get_protocol_name(bool *res = NULL) const;
00285 inline
00286 uint8 get_prefix() const {
00287 return prefix;
00288 }
00289
00291 inline
00292 void set_prefix(uint8 prfx) {
00293 prefix=prfx;
00294 }
00295
00297 inline
00298 void set_ip_ttl(uint16 ttl) {
00299 ip_ttl = ttl;
00300 }
00301
00302
00304 inline
00305 void unset_ip_ttl() {
00306 ip_ttl = 0;
00307 }
00308
00309
00311 inline
00312 uint16 get_ip_ttl() const {
00313 return ip_ttl;
00314 }
00315
00316
00318 inline
00319 void set_rao(uint16 value) {
00320 rao_presence = true;
00321 rao = value;
00322 }
00323
00325 inline
00326 void unset_rao() {
00327 rao_presence = false;
00328 rao = 0;
00329 }
00330
00332 inline
00333 uint16 get_rao() const {
00334 return rao;
00335 }
00336
00337
00339 inline
00340 bool rao_present() const {
00341 return rao_presence;
00342 }
00343
00345 inline
00346 void set_if_index(uint16 value) {
00347 if_index = value;
00348 }
00349
00351 inline
00352 uint16 get_if_index() const {
00353 return if_index;
00354 }
00355
00357 inline
00358 void unset_if_index() {
00359 if_index = 0;
00360 }
00361
00362
00363
00364
00365
00366 private:
00367 protocol_t proto;
00368 port_t port;
00369 uint8 prefix;
00370
00371 uint16 rao;
00372 uint16 ip_ttl;
00373 bool rao_presence;
00374 uint16 if_index;
00375
00376 };
00377
00378
00379 inline
00380 appladdress::appladdress(const sockaddr_in6& sockaddr, protocol_t prot)
00381 : hostaddress(sockaddr.sin6_addr), proto(prot), port(ntohs(sockaddr.sin6_port)), rao(0), ip_ttl(0), rao_presence(false), if_index(0)
00382 {
00383
00384 }
00385
00387 inline
00388 appladdress::appladdress() : hostaddress(),
00389 proto(0),
00390 port(0),
00391 prefix(32),
00392 rao(0),
00393 ip_ttl(0),
00394 rao_presence(false),
00395 if_index(0)
00396
00397 {
00398
00399 set_subtype(ipv4flag);
00400 }
00401
00402 inline
00403 appladdress::appladdress(const appladdress& app) : hostaddress(app),
00404 proto(app.proto),
00405 port(app.port),
00406 prefix(app.prefix),
00407 rao(app.rao),
00408 ip_ttl(app.ip_ttl),
00409 rao_presence(app.rao_presence),
00410 if_index(app.if_index)
00411
00412 {
00413
00414
00415
00416
00417
00418 set_subtype(ipv4flag);
00419 }
00420
00422 inline
00423 appladdress::appladdress(const hostaddress& h, protocol_t prot, port_t p)
00424 : hostaddress(h),
00425 proto(prot),
00426 port(p),
00427 prefix(0),
00428 rao(0),
00429 ip_ttl(0),
00430 rao_presence(false),
00431 if_index(0)
00432 {
00433
00434
00435 set_subtype(ipv4flag);
00436 }
00437
00441 inline
00442 appladdress::appladdress(const hostaddress& h, const char* pname, port_t p, bool *res)
00443 : hostaddress(h),
00444 proto(tsdb::getprotobyname(pname,res)),
00445 port(p),
00446 prefix(0),
00447 rao(0),
00448 ip_ttl(0),
00449 rao_presence(false),
00450 if_index(0)
00451
00452 {
00453
00454
00455 set_subtype(ipv4flag);
00456 }
00457
00462 inline
00463 appladdress::appladdress(const char* str, protocol_t prot, port_t p, bool *res)
00464 : hostaddress(str,res),
00465 proto(prot),
00466 port(p),
00467 prefix(0),
00468 rao(0),
00469 ip_ttl(0),
00470 rao_presence(false),
00471 if_index(0)
00472 {
00473 set_subtype(ipv4flag);
00474 }
00475
00481 inline
00482 appladdress::appladdress(const char* str, const char* pname, port_t p, bool *res)
00483 : hostaddress(str,res),
00484 port(p),
00485 prefix(0),
00486 rao(0),
00487 ip_ttl(0),
00488 rao_presence(false),
00489 if_index(0)
00490 {
00491
00492
00493 register bool tmpres = false;
00494 proto = tsdb::getprotobyname(pname,&tmpres);
00495 if (res) *res = ((*res) && tmpres);
00496 set_subtype(ipv4flag);
00497 }
00498
00505 inline
00506 appladdress::appladdress(const char* str, const char* pname, const char* portname, bool *res)
00507 : hostaddress(str,res),
00508 prefix(0),
00509 rao(0),
00510 ip_ttl(0),
00511 rao_presence(false),
00512 if_index(0)
00513 {
00514
00515
00516 bool res1 = false;
00517 bool res2 = false;
00518 proto = tsdb::getprotobyname(pname,&res1);
00519 port = tsdb::get_portnumber(portname,proto,&res2);
00520 if (res) *res = ((*res) && res1 && res2);
00521 set_subtype(ipv4flag);
00522 prefix = 0;
00523 }
00524
00526 inline
00527 appladdress&
00528 appladdress::operator=(const appladdress& app)
00529 {
00530 hostaddress::operator=(app);
00531 proto = app.proto;
00532 port = app.port;
00533 prefix = app.prefix;
00534 ip_ttl = app.ip_ttl;
00535 rao_presence = app.rao_presence;
00536 rao = app.rao;
00537 if_index = app.if_index;
00538 return *this;
00539 }
00540
00541
00543 inline
00544 port_t appladdress::set_port(port_t p) {
00545 register port_t op = port;
00546 port = p;
00547 return op;
00548 }
00549
00550
00551
00555 inline
00556 port_t appladdress::set_port(const char* pname, bool *res) {
00557 register port_t op = port;
00558 port = tsdb::get_portnumber(pname,proto,res);
00559 return op;
00560 }
00561
00565 inline
00566 port_t appladdress::set_port(const string& pname, bool *res) {
00567 register port_t op = port;
00568 port = tsdb::get_portnumber(pname,proto,res);
00569 return op;
00570 }
00571
00572 inline
00573 port_t appladdress::get_port() const { return port; }
00574
00575 inline
00576 string appladdress::get_port_name(bool *res) const {
00577 return tsdb::get_portname(port,proto,res);
00578 }
00579
00581 inline
00582 protocol_t appladdress::set_protocol(protocol_t p) {
00583 register protocol_t o = proto;
00584 proto = p;
00585 return o;
00586 }
00587
00591 inline
00592 protocol_t appladdress::set_protocol(const char* pname, bool *res) {
00593 register protocol_t o = proto;
00594 proto = tsdb::getprotobyname(pname,res);
00595 return o;
00596 }
00597
00601 inline
00602 protocol_t appladdress::set_protocol(const string& pname, bool *res) {
00603 register protocol_t o = proto;
00604 proto = tsdb::getprotobyname(pname,res);
00605 return o;
00606 }
00607
00608 inline
00609 protocol_t appladdress::get_protocol() const { return proto; }
00610
00611 inline
00612 string appladdress::get_protocol_name(bool *res) const {
00613 return tsdb::getprotobynumber(proto,res);
00614 }
00615
00616 inline
00617 size_t appladdress::get_hash() const {
00618 uint32 tmp = (proto<<16)+port;
00619 return (hostaddress::get_hash() ^ tmp);
00620 }
00621
00622 inline
00623 void
00624 appladdress::get_sockaddr(struct sockaddr_in6& sa) const
00625 {
00626 if (!ipv4flag)
00627 {
00628 sa.sin6_family= PF_INET6;
00629 sa.sin6_port = htons(port);
00630 sa.sin6_addr = ipv6addr;
00631 }
00632 }
00633
00635
00636 class netaddress : public hostaddress {
00637
00638 public:
00639 virtual netaddress* new_instance() const;
00640 virtual netaddress* copy() const;
00641 virtual bool operator==(const address& ie) const;
00642
00644 virtual void convert_to_ipv6();
00646 virtual size_t get_hash() const;
00647 virtual int match_against(const netaddress& na) const;
00648 protected:
00650 virtual void set_subtype(bool ipv4);
00651
00652 public:
00654 netaddress();
00656 netaddress(const netaddress& na);
00658 netaddress(const hostaddress& h, prefix_length_t len = 128);
00660 netaddress(const char* str, bool *res = NULL);
00662 netaddress(const char* str, prefix_length_t len, bool *res = NULL);
00664 netaddress& operator=(const netaddress& na);
00666 netaddress& operator=(const hostaddress& ha);
00667
00668
00669 prefix_length_t set_pref_len(prefix_length_t len);
00670
00671 prefix_length_t get_pref_len() const;
00673 bool operator<(const netaddress& na) const;
00674
00675 int rdx_cmp(const netaddress *na, int *pos) const;
00676 private:
00677 prefix_length_t prefix_length;
00678 };
00679
00680 inline ostream &operator<<(ostream &out, const netaddress &addr) {
00681 return out << addr.get_ip_str() << "/" << (int)addr.get_pref_len();
00682 }
00683
00685
00686 class udsaddress : public address {
00687
00688 public:
00689 virtual udsaddress* new_instance() const;
00690 virtual udsaddress* copy() const;
00691 virtual bool operator==(const address& ie) const;
00692
00694 udsaddress() : address(UDSAddress) { uds_socket = ""; socknum=0;};
00696 udsaddress(const udsaddress& h) : address(UDSAddress) { uds_socket = string(h.uds_socket.c_str()); socknum = h.socknum; };
00698 udsaddress& operator=(const udsaddress& uds) {
00699 uds_socket = string(uds.uds_socket);
00700 socknum = uds.socknum;
00701 return *this;
00702 };
00704 udsaddress(string sockstring): address(UDSAddress) { uds_socket = string(sockstring.c_str()); socknum=0; };
00706 udsaddress(int num): address(UDSAddress) { socknum = num; uds_socket=""; };
00708 udsaddress(string sockstring, int num): address(UDSAddress) { socknum = num; uds_socket=string(sockstring.c_str()); };
00710 virtual ~udsaddress() {};
00711
00713 virtual size_t get_hash() const;
00714
00715 private:
00717 string uds_socket;
00719 int socknum;
00720
00721 public:
00722
00724 inline
00725 void set_udssocket(string socket) {
00726 uds_socket = socket;
00727 }
00728
00729
00731 inline
00732 const string get_udssocket() const {
00733 return uds_socket;
00734 }
00735
00736
00738 inline
00739 void set_socknum(int socket) {
00740 socknum = socket;
00741 }
00742
00744 inline
00745 const int get_socknum() const {
00746 return socknum;
00747 }
00748
00749
00750
00751 };
00752
00753 template <typename _dT>
00754 class RadixTrie {
00755 public:
00756 typedef _dT data_type;
00757
00758 struct node {
00759 node(netaddress *k, data_type *d) : key(k), data(d) {
00760 left = right = this;
00761 index = 0;
00762 }
00763 ~node() {
00764 if (data)
00765 delete data;
00766 if (key)
00767 delete key;
00768 if (left != 0 && left->index > index)
00769 delete left;
00770 if (right != 0 && right->index > index)
00771 delete right;
00772 }
00773 node *left;
00774 node *right;
00775 netaddress *key;
00776 data_type *data;
00777 int index;
00778 };
00779
00780 RadixTrie() {
00781 netaddress *def;
00782 def = new netaddress("0.0.0.0", (prefix_length_t)0);
00783 v4head = new node(def, 0);
00784 def = new netaddress("::", (prefix_length_t)0);
00785 v6head = new node(def, 0);
00786 }
00787
00788 ~RadixTrie() {
00789 delete v4head;
00790 delete v6head;
00791 }
00792
00793 node *insert(netaddress &key, data_type &dat) {
00794 node *a, *b = NULL, *c, *n, *m;
00795 int cmp = 0, pos = 0;
00796
00797 c = a = key.is_ipv4() ? v4head : v6head;
00798
00799
00800 while (key.get_pref_len() > a->index) {
00801
00802
00803 pos = a->index - 1;
00804 cmp = key.rdx_cmp(a->key, &pos);
00805 if (pos < 0)
00806 abort();
00807
00808
00809 if ((cmp == 0) &&
00810 (a->key->get_pref_len() == key.get_pref_len())) {
00811
00812 if (a->data)
00813 delete a->data;
00814 a->data = &dat;
00815 return a;
00816 }
00817
00818 if (cmp == 0)
00819 break;
00820
00821
00822
00823 b = cmp < 0 ? a->left : a->right;
00824
00825
00826 if (b->index <= a->index)
00827 break;
00828
00829
00830
00831 if (pos <= a->key->get_pref_len())
00832 break;
00833
00834 c = a;
00835 a = b;
00836 }
00837
00838
00839 if ((key.get_pref_len() == a->key->get_pref_len()) ||
00840 (pos > a->index && pos <= a->key->get_pref_len())) {
00841 int opos = pos;
00842
00843
00844 pos = a->index;
00845 cmp = key.rdx_cmp(a->key, &pos);
00846 if (cmp == 0 &&
00847 (a->key->get_pref_len() == key.get_pref_len())) {
00848
00849 if (a->data)
00850 delete a->data;
00851 a->data = &dat;
00852 return a;
00853 }
00854
00855
00856 pos = opos;
00857 n = new node(new netaddress(key), 0);
00858 n->key->set_pref_len(pos - 1);
00859
00860
00861 pos = c->index;
00862 cmp = n->key->rdx_cmp(c->key, &pos);
00863 n->index = pos;
00864 if (n->index <= c->index) {
00865 cout << "DEAD NODE INSERTION!!!" << endl;
00866 abort();
00867 }
00868 if (cmp < 0) {
00869 if (c->left != a) {
00870 cout << "TREE CORRUPTION!!!" << endl;
00871 abort();
00872 }
00873 c->left = n;
00874 } else {
00875 if (c->right != a) {
00876 cout << "TREE CORRUPTION!!!" << endl;
00877 abort();
00878 }
00879 c->right = n;
00880 }
00881
00882
00883
00884 pos = n->index;
00885 cmp = a->key->rdx_cmp(n->key, &pos);
00886 a->index = pos;
00887 if (a->index <= n->index) {
00888 cout << "DEAD NODE INSERTION!!!" << endl;
00889 abort();
00890 }
00891 if (cmp < 0)
00892 n->left = a;
00893 else
00894 n->right = a;
00895
00896
00897 m = new node(new netaddress(key), &dat);
00898
00899 pos = n->index;
00900 cmp = m->key->rdx_cmp(n->key, &pos);
00901 m->index = pos;
00902 if (cmp < 0) {
00903 if (n->left == a) {
00904 cout << "OVERWRITE!!!" << endl;
00905 abort();
00906 }
00907 n->left = m;
00908 } else {
00909 if (n->right == a) {
00910 cout << "OVERWRITE!!!" << endl;
00911 abort();
00912 }
00913 n->right = m;
00914 }
00915
00916 return m;
00917 }
00918
00919
00920 if (a->index >= pos) {
00921
00922 n = new node(new netaddress(key), &dat);
00923
00924 n->index = pos;
00925 if (n->index <= c->index) {
00926 cout << "DEAD NODE INSERTION!!!" << endl;
00927 abort();
00928 }
00929 if (cmp < 0) {
00930 if (c->left != a) {
00931 cout << "TREE CORRUPTION!!!" << endl;
00932 abort();
00933 }
00934 c->left = n;
00935 } else {
00936 if (c->right != a) {
00937 cout << "TREE CORRUPTION!!!" << endl;
00938 abort();
00939 }
00940 c->right = n;
00941 }
00942
00943
00944
00945 pos = n->index;
00946 cmp = a->key->rdx_cmp(n->key, &pos);
00947 a->index = pos;
00948 if (a->index <= c->index) {
00949 cout << "DEAD NODE INSERTION!!!" << endl;
00950 abort();
00951 }
00952 if (cmp < 0)
00953 n->left = a;
00954 else
00955 n->right = a;
00956
00957 return n;
00958 }
00959
00960
00961 n = new node(new netaddress(key), &dat);
00962 n->index = pos;
00963 if (n->index <= a->index) {
00964 cout << "DEAD NODE INSERTION!!!" << endl;
00965 abort();
00966 }
00967 if (b->index <= a->index) {
00968 if (cmp < 0)
00969 a->left = n;
00970 else
00971 a->right = n;
00972 } else {
00973 cout << "TREE CORRUPTION!!!" << endl;
00974 abort();
00975 }
00976
00977 return n;
00978 }
00979
00980 node *lookup_node(netaddress &key, bool lpfm = true,
00981 bool with_data = true) {
00982 node *a, *b, *c, *lpfn;
00983 int cmp, pos = 0;
00984
00985 lpfn = 0;
00986 c = b = a = key.is_ipv4() ? v4head : v6head;
00987 if (lpfm) {
00988 if (!with_data)
00989 lpfn = a;
00990 else if (a->data)
00991 lpfn = a;
00992 }
00993
00994
00995 while (key.get_pref_len() > a->index) {
00996
00997
00998 pos--;
00999 cmp = key.rdx_cmp(a->key, &pos);
01000
01001
01002 if (cmp == 0) {
01003
01004 if (key.get_pref_len() <
01005 a->key->get_pref_len())
01006 return lpfm ? lpfn : NULL;
01007
01008
01009 if (key.get_pref_len() >=
01010 a->key->get_pref_len()) {
01011 if (!with_data)
01012 return a;
01013 if (a->data)
01014 return a;
01015 return lpfm ? lpfn : NULL;
01016 }
01017 }
01018
01019
01020 if (pos > a->key->get_pref_len()) {
01021 if (!with_data)
01022 lpfn = a;
01023 else if (a->data)
01024 lpfn = a;
01025 }
01026
01027
01028
01029 b = cmp < 0 ? a->left : a->right;
01030
01031
01032 if (b->index <= a->index)
01033 break;
01034
01035 c = a;
01036 a = b;
01037 }
01038
01039 return lpfm ? lpfn : NULL;
01040 }
01041
01042 data_type *lookup(netaddress &key, bool lpfm = true) {
01043 node *n = lookup_node(key, lpfm);
01044
01045 return n ? n->data : NULL;
01046 }
01047
01048 bool remove(netaddress &key) {
01049 node *n = lookup_node(key);
01050
01051 if (n && n->data) {
01052 delete n->data;
01053 n->data = NULL;
01054 }
01055
01056 return (n != 0);
01057 }
01058
01059 bool remove_all(netaddress &key) {
01060 node *n = lookup_node(key, false, false);
01061
01062 if (n == 0)
01063 return false;
01064
01065 if (n->data) {
01066 delete n->data;
01067 n->data = NULL;
01068 }
01069
01070 if (n->left->index > n->index) {
01071 delete n->left;
01072 n->left = n;
01073 }
01074 if (n->right->index > n->index) {
01075 delete n->right;
01076 n->right = n;
01077 }
01078
01079 return true;
01080 }
01081
01082 void print() {
01083 cout << "v4_TREE: " << endl;
01084 print_node(v4head);
01085 cout << "v6_TREE: " << endl;
01086 print_node(v6head);
01087 }
01088
01089 void print_node(node *x, bool decent = true) {
01090 if (x && x->key) {
01091 cout << "node: " << x << " key: " << *x->key;
01092 if (x->data != 0)
01093 cout << " data: " << x->data;
01094 else
01095 cout << " data: NULL";
01096 cout << " index: " << x->index << endl;
01097 cout << "\tleft: " << x->left << " right: " << x->right << endl;
01098 if (decent) {
01099 if (x->left->index > x->index)
01100 print_node(x->left);
01101 if (x->right->index > x->index)
01102 print_node(x->right);
01103 }
01104 }
01105 }
01106
01107 private:
01108 struct node *v4head;
01109 struct node *v6head;
01110 };
01111
01112
01113
01114
01115
01116
01117 class AddressList {
01118 public:
01119 class AddrProperty {
01120 public:
01121 AddrProperty(const char *name) {
01122 pname = new string(name);
01123 }
01124 ~AddrProperty() {
01125 delete pname;
01126 };
01127
01128 string *pname;
01129 };
01130
01131
01132 static AddrProperty *LocalAddr_P;
01133 static AddrProperty *ConfiguredAddr_P;
01134
01135 private:
01136
01137 static AddrProperty *IgnoreAddr_P;
01138 static AddrProperty *AnyAddr_P;
01139
01140 public:
01141 struct ltstr {
01142 bool operator()(const char* s1, const char* s2) const
01143 { return strcmp(s1, s2) < 0; }
01144 };
01145 struct ltna {
01146 bool operator()(const netaddress &s1, const netaddress &s2)
01147 const {
01148 if (s1.is_ipv4() != s2.is_ipv4())
01149 return (s1.is_ipv4());
01150 int cmp, pos = 0;
01151 cmp = s1.rdx_cmp(&s2, &pos);
01152 return (cmp < 0);
01153 }
01154
01155 };
01156 typedef set<char *, ltstr> iflist_t;
01157 typedef set<netaddress, ltna> addrlist_t;
01158
01159 AddressList();
01160 ~AddressList();
01161
01162
01163
01164 iflist_t *get_interfaces();
01165
01166
01167
01168 bool by_interface(bool start_empty = true);
01169
01170 bool add_interface(char *name);
01171
01172 bool del_interface(char *name);
01173
01174
01175
01176 bool add_property(netaddress &na, AddrProperty *p = ConfiguredAddr_P,
01177 bool propagate = true);
01178 bool del_property(netaddress &na, AddrProperty *p = ConfiguredAddr_P,
01179 bool propagate = true);
01180 inline bool purge_properties(netaddress &na, bool prop = true) {
01181 return del_property(na, AnyAddr_P, prop);
01182 };
01183 bool add_host_prop(const char *name, AddrProperty *p = ConfiguredAddr_P);
01184 bool del_host_prop(const char *name, AddrProperty *p = ConfiguredAddr_P);
01185 inline bool purge_host_prop(const char *name) {
01186 return del_host_prop(name, AnyAddr_P);
01187 }
01188
01189
01190 bool ignore(netaddress &na, bool propagate = true);
01191 bool unignore(netaddress &na, bool propagate = true);
01192 bool ignore_bogons(void);
01193 bool ignore_locals(void);
01194 bool ignore_loopback(void);
01195
01196
01197 bool addr_is(netaddress &na, AddrProperty *prop);
01198 bool addr_is(const hostaddress &ha, AddrProperty *prop) {
01199 netaddress na(ha);
01200 return addr_is(na, prop);
01201 }
01202
01203 bool addr_is_in(netaddress &na, AddrProperty *prop);
01204 bool addr_is_in(const hostaddress &ha, AddrProperty *prop) {
01205 netaddress na(ha);
01206 return addr_is_in(na, prop);
01207 }
01208
01209 addrlist_t *get_addrs(AddrProperty *prop = LocalAddr_P);
01210 netaddress *get_first(AddrProperty *p = LocalAddr_P, bool IPv4 = true);
01211
01212 netaddress *get_src_addr(const netaddress &dest, uint32_t *prefs);
01213 private:
01214 typedef map<AddrProperty *, bool> propmap_t;
01215 typedef RadixTrie<propmap_t> addr2prop_t;
01216
01217 iflist_t *interfaces;
01218 addr2prop_t prop_trie;
01219
01220
01221 void getifaddrs_iflist(iflist_t &list);
01222 bool getifaddrs_is_local(netaddress &na);
01223 void getifaddrs_get_addrs(addrlist_t &list);
01224
01225 void bequeath(addr2prop_t::node *head, AddrProperty *p,
01226 bool add = true);
01227 void collect(addr2prop_t::node *head, AddrProperty *p,
01228 addrlist_t &list);
01229 addr2prop_t::node *collect_first(addr2prop_t::node *head,
01230 AddrProperty *p);
01231 };
01232
01233 inline ostream &operator<<(ostream &out, const AddressList::AddrProperty &prop) {
01234 return out << *prop.pname;
01235 }
01236
01237
01238
01239
01240 inline
01241 size_t
01242 hostaddress::get_hash() const
01243 {
01244 return (ipv6addr.s6_addr32[0] ^ ipv6addr.s6_addr32[1] ^ ipv6addr.s6_addr32[2] ^ ipv6addr.s6_addr32[3]);
01245 }
01246
01247
01248
01249
01254 inline
01255 hostaddress::hostaddress()
01256 : address(IPv6HostAddress),
01257 ipv4flag(false),
01258 outstring(NULL)
01259 {
01260 clear_ip();
01261 set_subtype(false);
01262 }
01263
01264
01266 inline
01267 hostaddress&
01268 hostaddress::operator=(const hostaddress& h) {
01269 address::operator=(h);
01270 this->set_ip(h);
01271 if (outstring)
01272 delete outstring;
01273 outstring= 0;
01274 return *this;
01275 }
01276
01278 inline
01279 hostaddress::hostaddress(const hostaddress& h) :
01280 address(h),
01281 outstring(NULL)
01282 {
01283 this->set_ip(h);
01284
01285
01286
01287 }
01288
01290 inline
01291 bool
01292 hostaddress::is_ipv4() const {
01293 return ipv4flag;
01294 }
01295
01297 inline
01298 bool
01299 hostaddress::is_ipv6() const {
01300 return (!ipv4flag);
01301 }
01302
01304 inline
01305 bool
01306 hostaddress::is_mapped_ip() const
01307 {
01308 return (ipv4flag) ? false : IN6_IS_ADDR_V4MAPPED(ipv6addr.s6_addr);
01309 }
01310
01311 inline
01312 bool
01313 hostaddress::set_ip(const string& str) { return set_ip(str.c_str()); }
01314
01315 inline
01317 hostaddress::~hostaddress() {
01318 if (outstring)
01319 {
01320 delete[] outstring;
01321 outstring= 0;
01322 }
01323 }
01324
01329 inline
01330 bool
01331 hostaddress::set_ip(const char *str)
01332 {
01333 return (!str) ? false :
01334 ( strchr(str,':') ? set_ipv6(str) : set_ipv4(str));
01335
01336 }
01337
01338
01340 inline
01341 string hostaddress::get_host_name(bool *res) const
01342 {
01343 return ipv4flag ? tsdb::get_hostname(ipv4addr,res) : tsdb::get_hostname(ipv6addr,res);
01344 }
01345
01346
01347
01351 inline
01352 void
01353 appladdress::set_subtype(bool ipv4)
01354 {
01355 ipv4flag = ipv4;
01356 subtype = (ipv4) ? IPv4ApplAddress : IPv6ApplAddress;
01357 }
01358
01359 inline
01360 prefix_length_t netaddress::get_pref_len() const { return prefix_length; }
01361
01362 inline
01363 size_t netaddress::get_hash() const {
01364 return (hostaddress::get_hash() ^ prefix_length);
01365 }
01366
01367 inline
01368 int
01369 netaddress::match_against(const netaddress& na) const
01370 {
01371
01372 return (prefix_length<na.prefix_length) ? -1 : hostaddress::match_against(na);
01373 }
01374
01375
01376 inline
01377 ostream &operator<<(ostream &out, const appladdress &addr) {
01378 if (addr.is_mapped_ip()) return out << "[IPv4-mapped address]: " << addr.get_ip_str() << ":" << (int)addr.get_port() << ", " << addr.get_protocol_name();
01379 return out << "[IP address]: " << addr.get_ip_str() << ":" << (int)addr.get_port() << ", " << addr.get_protocol_name();
01380 }
01381
01382 inline
01383 ostream &operator<<(ostream &out, const udsaddress &addr) {
01384 if (addr.get_socknum()) return out << "[Socketnumber]: " << addr.get_socknum();
01385 return out << "[Unix Domain Socket]: " << addr.get_udssocket();
01386 }
01387
01388
01389
01390
01391
01392
01393 inline
01394 size_t udsaddress::get_hash() const {
01395 size_t tmp2 = 1;
01396 for (unsigned int i = 0; i<uds_socket.size(); i++) {
01397 tmp2 = tmp2 * (int) uds_socket[i];
01398 }
01399 return (tmp2 ^ socknum);
01400 }
01401
01402
01403
01404 }
01405
01406
01407
01408 namespace boost {
01410 template <> struct hash<protlib::hostaddress> {
01411 inline size_t operator()(const protlib::hostaddress& addr) const { return addr.get_hash(); }
01412 };
01413
01415 template <> struct hash<protlib::appladdress> {
01416 inline size_t operator()(const protlib::appladdress& addr) const { return addr.get_hash(); }
01417 };
01418
01420 template <> struct hash<protlib::udsaddress> {
01421 inline size_t operator()(const protlib::udsaddress& addr) const { return addr.get_hash(); }
01422 };
01423
01425 template <> struct hash<protlib::netaddress> {
01426 inline size_t operator() (const protlib::netaddress& addr) const { return addr.get_hash(); }
01427 };
01428
01429 }
01430
01431
01432 namespace std {
01433
01435 template <> struct equal_to<protlib::hostaddress> {
01436 inline bool operator()(const protlib::hostaddress& addr1, const protlib::hostaddress& addr2) const { return addr1.equiv(addr2); }
01437 };
01438
01440
01441 template <> struct equal_to<protlib::appladdress> {
01442 inline bool operator()(const protlib::appladdress& addr1, const protlib::appladdress& addr2) const { return addr1.equiv(addr2); }
01443 };
01444
01446 template <> struct equal_to<protlib::netaddress> {
01447 inline bool operator()(const protlib::netaddress& addr1, const protlib::netaddress& addr2) const { return addr1.equiv(addr2); }
01448
01449 };
01450
01451 }
01452 #endif // PROTLIB__ADDRESS_H