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