NSIS-ka
A free C++ implementation of NSIS protocols

Changeset 4191


Ignore:
Timestamp:
Aug 2, 2009, 10:42:05 PM (8 years ago)
Author:
bless
Message:
Location:
protlib/branches/20081127-merge-mobility-mk3
Files:
5 added
3 edited
2 copied

Legend:

Unmodified
Added
Removed
  • protlib/branches/20081127-merge-mobility-mk3/include/address.h

    r4168 r4191  
    4545#include "logfile.h"
    4646#include "threadsafe_db.h"
    47 
    48 #include "rfc5014_hack.h"
    4947
    5048namespace protlib {
     
    772770}; // end udsaddress
    773771
    774 template <typename _dT>
    775 class RadixTrie {
    776 public:
    777         typedef _dT     data_type;
    778 
    779         struct node {
    780                 node(netaddress *k, data_type *d) : key(k), data(d) {
    781                         left = right = this;
    782                         index = 0;
    783                 }
    784                 ~node() {
    785                         if (data)
    786                                 delete data;
    787                         if (key)
    788                                 delete key;
    789                         if (left != 0 && left->index > index)
    790                                 delete left;
    791                         if (right != 0 && right->index > index)
    792                                 delete right;
    793                 }
    794                 node                    *left;
    795                 node                    *right;
    796                 netaddress              *key;
    797                 data_type               *data;
    798                 int                      index;
    799         };
    800 
    801         RadixTrie() {
    802                 netaddress *def;
    803                 def = new netaddress("0.0.0.0", (prefix_length_t)0);
    804                 v4head = new node(def, 0);
    805                 def = new netaddress("::", (prefix_length_t)0);
    806                 v6head = new node(def, 0);
    807         }
    808 
    809         ~RadixTrie() {
    810                 delete v4head;
    811                 delete v6head;
    812         }
    813 
    814         node *insert(const netaddress &key, data_type &dat) {
    815                 node *a, *b, *c, *n, *m;
    816                 int cmp, pos = 0;
    817 
    818                 c = a = key.is_ipv4() ? v4head : v6head;
    819 
    820                 // search the tree as long as there are bits left in key
    821                 while (key.get_pref_len() > a->index) {
    822 
    823                         // compare key to key in node a from position a->index
    824                         pos = a->index - 1;
    825                         cmp = key.rdx_cmp(a->key, &pos);
    826                         if (pos < 0)
    827                                 abort();
    828 
    829                         // in case of a perfect match
    830                         if ((cmp == 0) &&
    831                             (a->key->get_pref_len() == key.get_pref_len())) {
    832                             // replace data in node
    833                                 if (a->data)
    834                                         delete a->data;
    835                                 a->data = &dat;
    836                                 return a;
    837                         }
    838 
    839                         if (cmp == 0)
    840                                 break;
    841 
    842                         // select node to continue the search based on the
    843                         // first different bit between a and key
    844                         b = cmp < 0 ? a->left : a->right;
    845 
    846                         // we reached a dead end
    847                         if (b->index <= a->index)
    848                                 break;
    849 
    850                         // the first difference was before a's bitmask ended
    851                         // we must not make any more progress
    852                         if (pos <= a->key->get_pref_len())
    853                                 break;
    854 
    855                         c = a;
    856                         a = b;
    857                 }
    858 
    859                 // first check if a and key share a common prefix
    860                 if ((key.get_pref_len() == a->key->get_pref_len()) ||
    861                    (pos > a->index && pos <= a->key->get_pref_len())) {
    862                         int opos = pos;
    863 
    864                         // make sure we didn't just miss the perfect match
    865                         pos = a->index;
    866                         cmp = key.rdx_cmp(a->key, &pos);
    867                         if (cmp == 0 &&
    868                             (a->key->get_pref_len() == key.get_pref_len())) {
    869                             // replace data in node
    870                                 if (a->data)
    871                                         delete a->data;
    872                                 a->data = &dat;
    873                                 return a;
    874                         }
    875 
    876                         // create a node with that prefix
    877                         pos = opos;
    878                         n = new node(new netaddress(key), 0);
    879                         n->key->set_pref_len(pos - 1);
    880 
    881                         // hook it to the previous node(c)
    882                         pos = c->index;
    883                         cmp = n->key->rdx_cmp(c->key, &pos);
    884                         n->index = pos;
    885                         if (n->index <= c->index) {
    886                                 cout << "DEAD NODE INSERTION!!!" << endl;
    887                                 abort();
    888                         }
    889                         if (cmp < 0) {
    890                                 if (c->left != a) {
    891                                         cout << "TREE CORRUPTION!!!" << endl;
    892                                         abort();
    893                                 }
    894                                 c->left = n;
    895                         } else {
    896                                 if (c->right != a) {
    897                                         cout << "TREE CORRUPTION!!!" << endl;
    898                                         abort();
    899                                 }
    900                                 c->right = n;
    901                         }
    902 
    903                         // hook the current node(a) to the common prefix
    904                         // node(n)
    905                         pos = n->index;
    906                         cmp = a->key->rdx_cmp(n->key, &pos);
    907                         a->index = pos;
    908                         if (a->index <= n->index) {
    909                                 cout << "DEAD NODE INSERTION!!!" << endl;
    910                                 abort();
    911                         }
    912                         if (cmp < 0)
    913                                 n->left = a;
    914                         else
    915                                 n->right = a;
    916 
    917                         // create a new node(m) for the insert
    918                         m = new node(new netaddress(key), &dat);                       
    919                         // hook node(m) to the common prefix node(n)
    920                         pos = n->index;
    921                         cmp = m->key->rdx_cmp(n->key, &pos);
    922                         m->index = pos;
    923                         if (cmp < 0) {
    924                                 if (n->left == a) {
    925                                         cout << "OVERWRITE!!!" << endl;
    926                                         abort();
    927                                 }
    928                                 n->left = m;
    929                         } else {
    930                                 if (n->right == a) {
    931                                         cout << "OVERWRITE!!!" << endl;
    932                                         abort();
    933                                 }
    934                                 n->right = m;
    935                         }
    936 
    937                         return m;
    938                 }
    939 
    940                 // c is a prefix of key, key is a prefix of a
    941                 if (a->index >= pos) {
    942                         // create a new node for the key
    943                         n = new node(new netaddress(key), &dat);
    944                         // hook it to the previous node(c)
    945                         n->index = pos;
    946                         if (n->index <= c->index) {
    947                                 cout << "DEAD NODE INSERTION!!!" << endl;
    948                                 abort();
    949                         }
    950                         if (cmp < 0) {
    951                                 if (c->left != a) {
    952                                         cout << "TREE CORRUPTION!!!" << endl;
    953                                         abort();
    954                                 }
    955                                 c->left = n;
    956                         } else {
    957                                 if (c->right != a) {
    958                                         cout << "TREE CORRUPTION!!!" << endl;
    959                                         abort();
    960                                 }
    961                                 c->right = n;
    962                         }
    963 
    964                         // hook the current node(a) to the newly created
    965                         // node(n)
    966                         pos = n->index;
    967                         cmp = a->key->rdx_cmp(n->key, &pos);
    968                         a->index = pos;
    969                         if (a->index <= c->index) {
    970                                 cout << "DEAD NODE INSERTION!!!" << endl;
    971                                 abort();
    972                         }
    973                         if (cmp < 0)
    974                                 n->left = a;
    975                         else
    976                                 n->right = a;
    977 
    978                         return n;
    979                 }
    980 
    981                 // reached a deadend, simply add a new node
    982                 n = new node(new netaddress(key), &dat);
    983                 n->index = pos;
    984                 if (n->index <= a->index) {
    985                         cout << "DEAD NODE INSERTION!!!" << endl;
    986                         abort();
    987                 }
    988                 if (b->index <= a->index) {
    989                         if (cmp < 0)
    990                                 a->left = n;
    991                         else
    992                                 a->right = n;
    993                 } else {
    994                         cout << "TREE CORRUPTION!!!" << endl;
    995                         abort();
    996                 }
    997 
    998                 return n;
    999         }
    1000 
    1001         node *lookup_node(const netaddress &key, bool lpfm = true,
    1002             bool with_data = true) {
    1003                 node *a, *b, *c, *lpfn;
    1004                 int cmp, pos = 0;
    1005 
    1006                 lpfn = 0;
    1007                 c = b = a = key.is_ipv4() ? v4head : v6head;
    1008                 if (lpfm) {
    1009                         if (!with_data)
    1010                                 lpfn = a;
    1011                         else if (a->data)
    1012                                 lpfn = a;
    1013                 }
    1014 
    1015                 // search the tree as long as there are bits left in key
    1016                 while (key.get_pref_len() > a->index) {
    1017 
    1018                         // compare key to key in node a from pos
    1019                         pos--;
    1020                         cmp = key.rdx_cmp(a->key, &pos);
    1021 
    1022                         // all of key consumed
    1023                         if (cmp == 0) {
    1024                                 // key is less specific than a
    1025                                 if (key.get_pref_len() <
    1026                                     a->key->get_pref_len())
    1027                                         return lpfm ? lpfn : NULL;
    1028                                
    1029                                 // key is an exact match for a
    1030                                 if (key.get_pref_len() >=
    1031                                     a->key->get_pref_len()) {
    1032                                         if (!with_data)
    1033                                                 return a;
    1034                                         if (a->data)
    1035                                                 return a;
    1036                                         return lpfm ? lpfn : NULL;
    1037                                 }
    1038                         }
    1039 
    1040                         // all of a consumed -> a is a prefix of key
    1041                         if (pos > a->key->get_pref_len()) {
    1042                                 if (!with_data)
    1043                                         lpfn = a;
    1044                                 else if (a->data)
    1045                                         lpfn = a;
    1046                         }
    1047 
    1048                         // select node to continue the search based on the
    1049                         // first different bit between a and key
    1050                         b = cmp < 0 ? a->left : a->right;
    1051 
    1052                         // we reached a dead end
    1053                         if (b->index <= a->index)
    1054                                 break;
    1055 
    1056                         c = a;
    1057                         a = b;
    1058                 }
    1059 
    1060                 return lpfm ? lpfn : NULL;
    1061         }
    1062 
    1063         data_type *lookup(const netaddress &key, bool lpfm = true) {
    1064                 node *n = lookup_node(key, lpfm);
    1065 
    1066                 return n ? n->data : NULL;
    1067         }
    1068 
    1069         bool remove(const netaddress &key) {
    1070                 node *n = lookup_node(key);
    1071 
    1072                 if (n && n->data) {
    1073                         delete n->data;
    1074                         n->data = NULL;
    1075                 }
    1076 
    1077                 return (n != 0);
    1078         }
    1079 
    1080         bool remove_all(netaddress &key) {
    1081                 node *n = lookup_node(key, false, false);
    1082 
    1083                 if (n == 0)
    1084                         return false;
    1085 
    1086                 if (n->data) {
    1087                         delete n->data;
    1088                         n->data = NULL;
    1089                 }
    1090 
    1091                 if (n->left->index > n->index) {
    1092                         delete n->left;
    1093                         n->left = n;
    1094                 }
    1095                 if (n->right->index > n->index) {
    1096                         delete n->right;
    1097                         n->right = n;
    1098                 }
    1099 
    1100                 return true;
    1101         }
    1102 
    1103         void print() {
    1104                 cout << "v4_TREE: " << endl;
    1105                 print_node(v4head);
    1106                 cout << "v6_TREE: " << endl;
    1107                 print_node(v6head);
    1108         }
    1109 
    1110         void print_node(node *x, bool decent = true) {
    1111                 if (x && x->key) {
    1112                         cout << "node: " << x << " key: " <<  *x->key;
    1113                         if (x->data != 0)
    1114                                 cout << " data: " << x->data;
    1115                         else
    1116                                 cout << " data: NULL";
    1117                         cout << " index: " << x->index << endl;
    1118                         cout << "\tleft: " << x->left << " right: " << x->right << endl;
    1119                         if (decent) {
    1120                                 if (x->left->index > x->index)
    1121                                         print_node(x->left);
    1122                                 if (x->right->index > x->index)
    1123                                         print_node(x->right);
    1124                         }
    1125                 }
    1126         }
    1127 
    1128 private:
    1129         struct node *v4head;
    1130         struct node *v6head;
    1131 };
    1132772
    1133773
    1134774ostream& operator<<(ostream& outstream, const list<hostaddress>& addresslist);
    1135775
    1136 /*
    1137  * AddressList
    1138  */
    1139 
    1140 class AddressList {
    1141 public:
    1142         class AddrProperty {
    1143                 public:
    1144                         AddrProperty(const char *name) {
    1145                                 pname = new string(name);
    1146                         }
    1147                         ~AddrProperty() {
    1148                                 delete pname;
    1149                         };
    1150 
    1151                         string *pname;
    1152         };
    1153 
    1154         // Default properties, N.B. Ignore will remove all other properties
    1155         static AddrProperty *LocalAddr_P;        // any physically address assigned to an i/f
    1156         static AddrProperty *ConfiguredAddr_P;   // address assigned by configuration
    1157         static AddrProperty *HomeAddr_P;         // Home Address (MobileIP)
    1158         static AddrProperty *HAAddr_P;           // Home Agent Address (MobileIP)
    1159         static AddrProperty *AltHAAddr_P;        // Alternative Home Agent Address (MobileIP)
    1160         static AddrProperty *HomeNet_P;          // Home Network Address
    1161 
    1162 private:
    1163         // This is special
    1164         static AddrProperty *IgnoreAddr_P;
    1165         static AddrProperty *AnyAddr_P;
    1166 
    1167 public:
    1168         struct ltstr {
    1169                 bool operator()(const char* s1, const char* s2) const
    1170                 { return strcmp(s1, s2) < 0; }
    1171         };
    1172         struct ltna {
    1173                 bool operator()(const netaddress &s1, const netaddress &s2)
    1174                     const {
    1175                         if (s1.is_ipv4() != s2.is_ipv4())
    1176                                 return (s1.is_ipv4());
    1177                         int cmp, pos = 0;
    1178                         cmp = s1.rdx_cmp(&s2, &pos);
    1179                         return (cmp < 0);
    1180                 }
    1181                
    1182         };
    1183         typedef set<char *, ltstr>      iflist_t;
    1184         typedef set<netaddress, ltna>   addrlist_t;
    1185 
    1186         AddressList();
    1187         ~AddressList();
    1188 
    1189         // Configure by interfaces
    1190         // Return a list of all local interfaces, which are monitored
    1191         iflist_t *get_interfaces();
    1192         // Begin interface list (otherwise the following have no effect)
    1193         // If start_empty is true use an empty list, otherwise add all
    1194         // currently configured interfaces
    1195         bool by_interface(bool start_empty = true);
    1196         // Add interface to monitoring
    1197         bool add_interface(char *name);
    1198         // Remove interface from monitoring
    1199         bool del_interface(char *name);
    1200 
    1201         // Manage properties
    1202         // If 'all' is true operate on all matching addresses as well
    1203         bool add_property(const netaddress &na, AddrProperty *p = ConfiguredAddr_P,
    1204             bool propagate = true);
    1205         bool del_property(const netaddress &na, AddrProperty *p = ConfiguredAddr_P,
    1206             bool propagate = true);
    1207         inline bool purge_properties(netaddress &na, bool prop = true) {
    1208                 return del_property(na, AnyAddr_P, prop);
    1209         };
    1210         bool add_host_prop(const char *name, AddrProperty *p = ConfiguredAddr_P);
    1211         bool del_host_prop(const char *name, AddrProperty *p = ConfiguredAddr_P);
    1212         inline bool purge_host_prop(const char *name) {
    1213                 return del_host_prop(name, AnyAddr_P);
    1214         }
    1215 
    1216         // Special property
    1217         bool ignore(netaddress &na, bool propagate = true);
    1218         bool unignore(netaddress &na, bool propagate = true);
    1219         bool ignore_bogons(void);
    1220         bool ignore_locals(void);
    1221         bool ignore_loopback(void);
    1222        
    1223         // Check if the given address has the given property
    1224         bool addr_is(netaddress &na, AddrProperty *prop);
    1225         bool addr_is(const hostaddress &ha, AddrProperty *prop) {
    1226                 netaddress na(ha);
    1227                 return addr_is(na, prop);
    1228         }
    1229         // Check if the given address is in a network with the given property
    1230         bool addr_is_in(netaddress &na, AddrProperty *prop);
    1231         bool addr_is_in(const hostaddress &ha, AddrProperty *prop) {
    1232                 netaddress na(ha);
    1233                 return addr_is_in(na, prop);
    1234         }
    1235 
    1236         addrlist_t *get_addrs(AddrProperty *prop = LocalAddr_P);
    1237         netaddress *get_first(AddrProperty *p = LocalAddr_P, bool IPv4 = true);
    1238 
    1239         netaddress *get_src_addr(const netaddress &dest, uint32_t *prefs);
    1240 private:
    1241         typedef map<AddrProperty *, bool>       propmap_t;
    1242         typedef RadixTrie<propmap_t>            addr2prop_t;
    1243 
    1244         iflist_t *interfaces;
    1245         addr2prop_t prop_trie;
    1246 
    1247         // Backends for public functions
    1248         void getifaddrs_iflist(iflist_t &list);
    1249         bool getifaddrs_is_local(netaddress &na);
    1250         void getifaddrs_get_addrs(addrlist_t &list);
    1251 
    1252         void bequeath(addr2prop_t::node *head, AddrProperty *p,
    1253             bool add = true);
    1254         void collect(addr2prop_t::node *head, AddrProperty *p,
    1255             addrlist_t &list);
    1256         addr2prop_t::node *collect_first(addr2prop_t::node *head,
    1257             AddrProperty *p);
    1258 };
    1259 
    1260 inline ostream &operator<<(ostream &out, const AddressList::AddrProperty &prop) {
    1261         return out << *prop.pname;
    1262 }
    1263776
    1264777
  • protlib/branches/20081127-merge-mobility-mk3/include/readnl.h

    r4187 r4191  
    3131
    3232#define NL_BUFSIZE 8192
     33namespace protlib {
    3334
    34 int readnl(int sock, char *buf);
     35        namespace util {
     36                int readnl(int sock, char *buf);
     37        }
     38}
    3539#endif
  • protlib/branches/20081127-merge-mobility-mk3/src/Makefile

    r4142 r4191  
    105105TP_QUERY_ENCAP_OBJ= tp_queryencap.o
    106106
    107 PROTLIB_OBJS    = address.o ie.o tp.o tp_over_tcp.o tp_over_tls_tcp.o \
     107PROTLIB_OBJS    = address.o ie.o addresslist.o tp.o tp_over_tcp.o tp_over_tls_tcp.o \
    108108                  cmsghdr_util.o tp_over_udp.o $(TP_QUERY_ENCAP_OBJ) tp_over_uds.o \
    109109                  $(TP_SCTPOBJ) connectionmap.o connectionmap_uds.o queuemanager.o fqueue.o \
    110110                  timer.o timer_module.o logfile.o fqueue.o protlib_types.o threads.o \
    111111                  threadsafe_db.o setuid.o messages.o network_message.o \
    112                   configuration.o configpar.o configpar_repository.o configfile.o
     112                  configuration.o configpar.o configpar_repository.o configfile.o \
     113                  routing_util.o readnl.o
    113114
    114115ALLSOURCES        := $(wildcard *.cpp)
  • protlib/branches/20081127-merge-mobility-mk3/src/address.cpp

    r4168 r4191  
    865865} // end operator==
    866866
    867 AddressList::AddrProperty *AddressList::LocalAddr_P;
    868 AddressList::AddrProperty *AddressList::ConfiguredAddr_P;
    869 AddressList::AddrProperty *AddressList::HomeAddr_P;
    870 AddressList::AddrProperty *AddressList::IgnoreAddr_P;
    871 AddressList::AddrProperty *AddressList::AnyAddr_P;
    872 AddressList::AddrProperty *AddressList::HAAddr_P; 
    873 AddressList::AddrProperty *AddressList::AltHAAddr_P;
    874 AddressList::AddrProperty *AddressList::HomeNet_P;
    875                
    876 
    877 AddressList::AddressList()
    878 {
    879         if (LocalAddr_P == 0) {
    880                 LocalAddr_P = new AddrProperty("local");
    881                 ConfiguredAddr_P = new AddrProperty("configured");
    882                 HomeAddr_P = new AddrProperty("HoA");
    883                 HAAddr_P = new AddrProperty("HA");
    884                 AltHAAddr_P = new AddrProperty("HA(alt)");
    885                 HomeNet_P = new AddrProperty("HomeNet");
    886                 IgnoreAddr_P = new AddrProperty("ignore");
    887                 AnyAddr_P = new AddrProperty("wildcard");
    888         }
    889         interfaces = 0;
    890 }
    891 
    892 AddressList::~AddressList()
    893 {
    894         // Refcount AddressLists in order to GC properties?
    895 }
    896 
    897 AddressList::iflist_t *
    898 AddressList::get_interfaces()
    899 {
    900         iflist_t *iflist;
    901 
    902         if (interfaces != 0)
    903                 iflist = new iflist_t(*interfaces);
    904         else {
    905                 iflist = new iflist_t();
    906                 getifaddrs_iflist(*iflist);
    907         }
    908 
    909         return iflist;
    910 }
    911 
    912 bool
    913 AddressList::by_interface(bool start_empty)
    914 {
    915         if (interfaces != 0)
    916                 return false;
    917 
    918         interfaces = new iflist_t();
    919         if (!start_empty)
    920                 getifaddrs_iflist(*interfaces);
    921 
    922         return true;
    923 }
    924 
    925 bool
    926 AddressList::add_interface(char *name)
    927 {
    928         if (interfaces == 0)
    929                 return false;
    930 
    931         return (interfaces->insert(name)).second;
    932 }
    933 
    934 bool
    935 AddressList::del_interface(char *name)
    936 {
    937         if (interfaces == 0)
    938                 return false;
    939 
    940         return (interfaces->erase(name) > 0);
    941 }
    942 
    943 bool
    944 AddressList::add_property(const netaddress &na, AddrProperty *p, bool propagate)
    945 {
    946         propmap_t *props, *lpfm_props;
    947         propmap_t::iterator it;
    948         addr2prop_t::node *node;
    949 
    950         node = prop_trie.lookup_node(na, false, false);
    951         if (node != NULL) {
    952                 props = node->data;
    953                 if (props == NULL) {
    954                         props = new propmap_t();
    955                         node->data = props;
    956                 }
    957                 props->insert(pair<AddrProperty *, bool>(p, propagate));
    958                
    959         } else {
    960                 props = new propmap_t();
    961                 props->insert(pair<AddrProperty *, bool>(p, propagate));
    962                 node = prop_trie.insert(na, *props);
    963         }
    964 
    965         if (propagate)
    966                 bequeath(node, p, true);
    967 
    968         // copy lpfm properties
    969         lpfm_props = prop_trie.lookup(na, true);
    970         if (lpfm_props == NULL)
    971                 return true;
    972 
    973         for (it = lpfm_props->begin(); it != lpfm_props->end(); it++) {
    974                 if ((*it).second)
    975                         props->insert((*it));
    976         }
    977 
    978         return true;
    979 }
    980 
    981 bool
    982 AddressList::del_property(const netaddress &na, AddrProperty *p, bool propagate)
    983 {
    984         propmap_t *props, *lpfm_props;
    985         propmap_t::iterator it;
    986         addr2prop_t::node *node;
    987 
    988         node = prop_trie.lookup_node(na, false, true);
    989         if (node == NULL) {
    990                 // no exact match
    991                 if (!propagate) {
    992                         node = prop_trie.lookup_node(na, true, true);
    993                         if (node == NULL) {
    994                                 // no lpfm either, we're done
    995                                 return false;
    996                         }
    997 
    998                         props = node->data;
    999                         it = props->find(p);
    1000                         if (it == props->end()) {
    1001                                 // lpfm doesn't have p set -> done
    1002                                 return false;
    1003                         }
    1004                 }
    1005                 // insert an empty propmap
    1006                 props = new propmap_t();
    1007                 node = prop_trie.insert(na, *props);
    1008 
    1009                 // copy other lpfm properties
    1010                 lpfm_props = prop_trie.lookup(na, true);
    1011                 if (p != AnyAddr_P && lpfm_props != NULL) {
    1012                         for (it = lpfm_props->begin(); it != lpfm_props->end();
    1013                             it++) {
    1014                                 if ((*it).first != p && (*it).second)
    1015                                         props->insert((*it));
    1016                         }
    1017                 }
    1018         } else {
    1019                 props = node->data;
    1020                 if (p == AnyAddr_P) {
    1021                         props->clear();
    1022                 } else {
    1023                         it = props->find(p);
    1024                         if (it == props->end() && !propagate)
    1025                                 return false;
    1026 
    1027                         props->erase(it);
    1028                 }
    1029         }
    1030 
    1031         if (propagate)
    1032                 bequeath(node, p, false);
    1033 
    1034         return true;
    1035 }
    1036 
    1037 bool
    1038 AddressList::add_host_prop(const char *name, AddrProperty *p)
    1039 {
    1040         netaddress na;
    1041         sockaddr_in *sin;
    1042         sockaddr_in6 *sin6;
    1043         struct addrinfo hints = {0}, *res, *cur;
    1044         int error;
    1045         char buf[1024];
    1046 
    1047         if (name == NULL) {
    1048                 name = buf;
    1049                 if (gethostname(buf, sizeof(buf)) != 0)
    1050                         return false;
    1051                 buf[sizeof(buf) - 1] = '\0';
    1052         }
    1053         hints.ai_flags = AI_ADDRCONFIG | AI_CANONNAME;
    1054         hints.ai_family = AF_UNSPEC;
    1055         error = getaddrinfo(name, NULL, &hints, &res);
    1056         if (error != 0)
    1057                 return false;
    1058 
    1059         for(cur = res; cur != NULL && error == 0; cur = cur->ai_next) {
    1060                 if (cur->ai_family == AF_INET) {
    1061                         sin = (struct sockaddr_in *)cur->ai_addr;
    1062                         na.set_ip(sin->sin_addr);
    1063                         na.set_pref_len(32);
    1064                 } else if (cur->ai_family == AF_INET6) {
    1065                         sin6 = (struct sockaddr_in6 *)cur->ai_addr;
    1066                         na.set_ip(sin6->sin6_addr);
    1067                         na.set_pref_len(128);
    1068                 } else
    1069                         continue;
    1070 
    1071                 // cout << ++i << "XXMOB: " << na << endl;
    1072 
    1073                 error += add_property(na, p) ? 0 : 1;
    1074                 // XXXMOB: for some reason we need a 'reset' here
    1075                 //         if we want to use /etc/hosts
    1076                 na.set_ip("127.0.0.1");
    1077         }
    1078         freeaddrinfo(res);
    1079 
    1080         return (error == 0);
    1081 }
    1082 
    1083 bool
    1084 AddressList::del_host_prop(const char *name, AddrProperty *p)
    1085 {
    1086         netaddress na;
    1087         sockaddr_in *sin;
    1088         sockaddr_in6 *sin6;
    1089         struct addrinfo hints = {0}, *res, *cur;
    1090         int error;
    1091         char buf[1024];
    1092 
    1093         if (name == NULL) {
    1094                 name = buf;
    1095                 if (gethostname(buf, sizeof(buf)) != 0)
    1096                         return false;
    1097                 buf[sizeof(buf) - 1] = '\0';
    1098         }
    1099         hints.ai_flags = AI_ADDRCONFIG;
    1100         hints.ai_family = AF_UNSPEC;
    1101         error = getaddrinfo(name, NULL, &hints, &res);
    1102         if (error != 0)
    1103                 return false;
    1104 
    1105         for(cur = res; cur != NULL && error == 0; cur = cur->ai_next) {
    1106                 if (cur->ai_family == AF_INET) {
    1107                         sin = (struct sockaddr_in *)cur->ai_addr;
    1108                         na.set_ip(sin->sin_addr);
    1109                         na.set_pref_len(32);
    1110                 } else if (cur->ai_family == AF_INET6) {
    1111                         sin6 = (struct sockaddr_in6 *)cur->ai_addr;
    1112                         na.set_ip(sin6->sin6_addr);
    1113                         na.set_pref_len(128);
    1114                 } else
    1115                         continue;
    1116 
    1117                 error += del_property(na, p) ? 0 : 1;
    1118         }
    1119         freeaddrinfo(res);
    1120 
    1121         return (error == 0);
    1122 }
    1123 
    1124 bool
    1125 AddressList::ignore(netaddress &na, bool propagate)
    1126 {
    1127         del_property(na, AnyAddr_P, propagate);
    1128         return add_property(na, IgnoreAddr_P);
    1129 }
    1130 
    1131 bool
    1132 AddressList::unignore(netaddress &na, bool propagate)
    1133 {
    1134         return del_property(na, IgnoreAddr_P, propagate);
    1135 }
    1136 
    1137 bool
    1138 AddressList::ignore_bogons(void)
    1139 {
    1140         netaddress na;
    1141 
    1142         // according to http://www.cymru.com/Documents/bogon-list.html
    1143         // 4.8 (30 Apr 2009)
    1144         na.set_ip("0.0.0.0");na.set_pref_len(7);
    1145         ignore(na);
    1146         na.set_ip("2.0.0.0");na.set_pref_len(8);
    1147         ignore(na);
    1148         na.set_ip("5.0.0.0");na.set_pref_len(8);
    1149         ignore(na);
    1150         na.set_ip("10.0.0.0");na.set_pref_len(8);
    1151         ignore(na);
    1152         na.set_ip("14.0.0.0");na.set_pref_len(8);
    1153         ignore(na);
    1154         na.set_ip("23.0.0.0");na.set_pref_len(8);
    1155         ignore(na);
    1156         na.set_ip("27.0.0.0");na.set_pref_len(8);
    1157         ignore(na);
    1158         na.set_ip("31.0.0.0");na.set_pref_len(8);
    1159         ignore(na);
    1160         na.set_ip("36.0.0.0");na.set_pref_len(7);
    1161         ignore(na);
    1162         na.set_ip("39.0.0.0");na.set_pref_len(8);
    1163         ignore(na);
    1164         na.set_ip("42.0.0.0");na.set_pref_len(8);
    1165         ignore(na);
    1166         na.set_ip("46.0.0.0");na.set_pref_len(8);
    1167         ignore(na);
    1168         na.set_ip("49.0.0.0");na.set_pref_len(8);
    1169         ignore(na);
    1170         na.set_ip("50.0.0.0");na.set_pref_len(8);
    1171         ignore(na);
    1172         na.set_ip("100.0.0.0");na.set_pref_len(6);
    1173         ignore(na);
    1174         na.set_ip("104.0.0.0");na.set_pref_len(5);
    1175         ignore(na);
    1176         na.set_ip("169.254.0.0");na.set_pref_len(16);
    1177         ignore(na);
    1178         na.set_ip("175.0.0.0");na.set_pref_len(7);
    1179         ignore(na);
    1180         na.set_ip("176.0.0.0");na.set_pref_len(5);
    1181         ignore(na);
    1182         na.set_ip("179.0.0.0");na.set_pref_len(5);
    1183         ignore(na);
    1184         na.set_ip("181.0.0.0");na.set_pref_len(6);
    1185         ignore(na);
    1186         na.set_ip("182.0.0.0");na.set_pref_len(6);
    1187         ignore(na);
    1188         na.set_ip("185.0.0.0");na.set_pref_len(6);
    1189         ignore(na);
    1190         na.set_ip("191.0.0.0");na.set_pref_len(8);
    1191         ignore(na);
    1192         na.set_ip("192.0.2.0");na.set_pref_len(24);
    1193         ignore(na);
    1194         na.set_ip("197.0.0.0");na.set_pref_len(8);
    1195         ignore(na);
    1196         na.set_ip("198.18.0.0");na.set_pref_len(15);
    1197         ignore(na);
    1198         na.set_ip("223.0.0.0");na.set_pref_len(8);
    1199         ignore(na);
    1200         na.set_ip("240.0.0.0");na.set_pref_len(4);
    1201         ignore(na);
    1202         // according to http://www.cymru.com/Bogons/v6bogon.html (2008-05-20)
    1203         na.set_ip("2001:db8::");na.set_pref_len(32);
    1204         ignore(na);
    1205         na.set_ip("0000::");na.set_pref_len(3);
    1206         ignore(na);
    1207         na.set_ip("2000::");na.set_pref_len(16);
    1208         ignore(na);
    1209         na.set_ip("2001:1::");na.set_pref_len(32);
    1210         ignore(na);
    1211         na.set_ip("2001:2::");na.set_pref_len(31);
    1212         ignore(na);
    1213         na.set_ip("2001:4::");na.set_pref_len(30);
    1214         ignore(na);
    1215         na.set_ip("2001:8::");na.set_pref_len(29);
    1216         ignore(na);
    1217         na.set_ip("2001:10::");na.set_pref_len(28);
    1218         ignore(na);
    1219         na.set_ip("2001:20::");na.set_pref_len(27);
    1220         ignore(na);
    1221         na.set_ip("2001:40::");na.set_pref_len(26);
    1222         ignore(na);
    1223         na.set_ip("2001:80::");na.set_pref_len(25);
    1224         ignore(na);
    1225         na.set_ip("2001:100::");na.set_pref_len(24);
    1226         ignore(na);
    1227         na.set_ip("2001:1000::");na.set_pref_len(23);
    1228         ignore(na);
    1229         na.set_ip("2001:4e00::");na.set_pref_len(23);
    1230         ignore(na);
    1231         na.set_ip("2001:6000::");na.set_pref_len(19);
    1232         ignore(na);
    1233         na.set_ip("2001:c000::");na.set_pref_len(18);
    1234         ignore(na);
    1235         na.set_ip("2003:4000::");na.set_pref_len(18);
    1236         ignore(na);
    1237         na.set_ip("2003:8000::");na.set_pref_len(17);
    1238         ignore(na);
    1239         na.set_ip("2004::");na.set_pref_len(14);
    1240         ignore(na);
    1241         na.set_ip("2008::");na.set_pref_len(13);
    1242         ignore(na);
    1243         na.set_ip("2010::");na.set_pref_len(12);
    1244         ignore(na);
    1245         na.set_ip("2020::");na.set_pref_len(11);
    1246         ignore(na);
    1247         na.set_ip("2040::");na.set_pref_len(10);
    1248         ignore(na);
    1249         na.set_ip("2080::");na.set_pref_len(9);
    1250         ignore(na);
    1251         na.set_ip("2100::");na.set_pref_len(8);
    1252         ignore(na);
    1253         na.set_ip("2200::");na.set_pref_len(7);
    1254         ignore(na);
    1255         na.set_ip("2410::");na.set_pref_len(12);
    1256         ignore(na);
    1257         na.set_ip("2420::");na.set_pref_len(11);
    1258         ignore(na);
    1259         na.set_ip("2440::");na.set_pref_len(10);
    1260         ignore(na);
    1261         na.set_ip("2480::");na.set_pref_len(9);
    1262         ignore(na);
    1263         na.set_ip("2500::");na.set_pref_len(8);
    1264         ignore(na);
    1265         na.set_ip("2610:200::");na.set_pref_len(23);
    1266         ignore(na);
    1267         na.set_ip("2610:400::");na.set_pref_len(22);
    1268         ignore(na);
    1269         na.set_ip("2610:800::");na.set_pref_len(21);
    1270         ignore(na);
    1271         na.set_ip("2610:1000::");na.set_pref_len(20);
    1272         ignore(na);
    1273         na.set_ip("2610:2000::");na.set_pref_len(19);
    1274         ignore(na);
    1275         na.set_ip("2610:4000::");na.set_pref_len(18);
    1276         ignore(na);
    1277         na.set_ip("2610:8000::");na.set_pref_len(17);
    1278         ignore(na);
    1279         na.set_ip("2611::");na.set_pref_len(16);
    1280         ignore(na);
    1281         na.set_ip("2612::");na.set_pref_len(15);
    1282         ignore(na);
    1283         na.set_ip("2614::");na.set_pref_len(14);
    1284         ignore(na);
    1285         na.set_ip("2618::");na.set_pref_len(13);
    1286         ignore(na);
    1287         na.set_ip("2620:200::");na.set_pref_len(23);
    1288         ignore(na);
    1289         na.set_ip("2620:400::");na.set_pref_len(22);
    1290         ignore(na);
    1291         na.set_ip("2620:800::");na.set_pref_len(21);
    1292         ignore(na);
    1293         na.set_ip("2620:1000::");na.set_pref_len(20);
    1294         ignore(na);
    1295         na.set_ip("2620:2000::");na.set_pref_len(19);
    1296         ignore(na);
    1297         na.set_ip("2620:4000::");na.set_pref_len(18);
    1298         ignore(na);
    1299         na.set_ip("2620:8000::");na.set_pref_len(17);
    1300         ignore(na);
    1301         na.set_ip("2621::");na.set_pref_len(16);
    1302         ignore(na);
    1303         na.set_ip("2622::");na.set_pref_len(15);
    1304         ignore(na);
    1305         na.set_ip("2624::");na.set_pref_len(14);
    1306         ignore(na);
    1307         na.set_ip("2628::");na.set_pref_len(13);
    1308         ignore(na);
    1309         na.set_ip("2630::");na.set_pref_len(12);
    1310         ignore(na);
    1311         na.set_ip("2640::");na.set_pref_len(10);
    1312         ignore(na);
    1313         na.set_ip("2680::");na.set_pref_len(9);
    1314         ignore(na);
    1315         na.set_ip("2700::");na.set_pref_len(8);
    1316         ignore(na);
    1317         na.set_ip("2810::");na.set_pref_len(12);
    1318         ignore(na);
    1319         na.set_ip("2820::");na.set_pref_len(11);
    1320         ignore(na);
    1321         na.set_ip("2840::");na.set_pref_len(10);
    1322         ignore(na);
    1323         na.set_ip("2880::");na.set_pref_len(9);
    1324         ignore(na);
    1325         na.set_ip("2900::");na.set_pref_len(8);
    1326         ignore(na);
    1327         na.set_ip("2a10::");na.set_pref_len(8);
    1328         ignore(na);
    1329         na.set_ip("2a20::");na.set_pref_len(8);
    1330         ignore(na);
    1331         na.set_ip("2a40::");na.set_pref_len(8);
    1332         ignore(na);
    1333         na.set_ip("2a80::");na.set_pref_len(8);
    1334         ignore(na);
    1335         na.set_ip("2b00::");na.set_pref_len(8);
    1336         ignore(na);
    1337         na.set_ip("2c10::");na.set_pref_len(12);
    1338         ignore(na);
    1339         na.set_ip("2c20::");na.set_pref_len(11);
    1340         ignore(na);
    1341         na.set_ip("2c40::");na.set_pref_len(10);
    1342         ignore(na);
    1343         na.set_ip("2c80::");na.set_pref_len(9);
    1344         ignore(na);
    1345         na.set_ip("2d00::");na.set_pref_len(8);
    1346         ignore(na);
    1347         na.set_ip("2e00::");na.set_pref_len(7);
    1348         ignore(na);
    1349         na.set_ip("3000::");na.set_pref_len(4);
    1350         ignore(na);
    1351         na.set_ip("4000::");na.set_pref_len(2);
    1352         ignore(na);
    1353         na.set_ip("8000::");na.set_pref_len(1);
    1354         ignore(na);
    1355         na.set_ip("F000::");na.set_pref_len(5);
    1356         ignore(na);
    1357         na.set_ip("F800::");na.set_pref_len(6);
    1358         ignore(na);
    1359         na.set_ip("FC00::");na.set_pref_len(7);
    1360         ignore(na);
    1361         na.set_ip("FE00::");na.set_pref_len(9);
    1362         ignore(na);
    1363 
    1364         return true;
    1365 }
    1366 
    1367 bool
    1368 AddressList::ignore_locals(void)
    1369 {
    1370         netaddress na;
    1371 
    1372         na.set_ip("10.0.0.0");na.set_pref_len(8);
    1373         ignore(na);
    1374         na.set_ip("172.16.0.0");na.set_pref_len(12);
    1375         ignore(na);
    1376         na.set_ip("192.168.0.0");na.set_pref_len(16);
    1377         ignore(na);
    1378         na.set_ip("FE80::");na.set_pref_len(10);
    1379         ignore(na);
    1380         na.set_ip("FEC0::");na.set_pref_len(10);
    1381         ignore(na);
    1382 
    1383         return true;
    1384 }
    1385 
    1386 bool
    1387 AddressList::ignore_loopback(void)
    1388 {
    1389         netaddress na;
    1390 
    1391         na.set_ip("127.0.0.0");na.set_pref_len(8);
    1392         ignore(na);
    1393         na.set_ip("::1");na.set_pref_len(128);
    1394         ignore(na);
    1395 
    1396         return true;
    1397 }
    1398 
    1399 bool
    1400 AddressList::addr_is(netaddress &na, AddrProperty *prop)
    1401 {
    1402         propmap_t *props;
    1403         propmap_t::iterator it;
    1404 
    1405         if (addr_is_in(na, IgnoreAddr_P))
    1406                 return false;
    1407 
    1408         props = prop_trie.lookup(na, false);
    1409         if (props != NULL) {
    1410                 it = props->find(prop);
    1411                 if (it != props->end()) {
    1412                         return true;
    1413                 }
    1414         }
    1415 
    1416         if (prop != LocalAddr_P)
    1417                 return false;
    1418 
    1419         return getifaddrs_is_local(na);
    1420 }
    1421 
    1422 bool
    1423 AddressList::addr_is_in(netaddress &na, AddrProperty *prop)
    1424 {
    1425         addr2prop_t::node *node;
    1426         propmap_t *props;
    1427         propmap_t::iterator it;
    1428 
    1429         node = prop_trie.lookup_node(na, true, true);
    1430         if (node == NULL)
    1431                 return false;
    1432 
    1433         props = node->data;
    1434         it = props->find(prop);
    1435         if (it == props->end())
    1436                 return false;
    1437 
    1438         if (!(*it).second && props != prop_trie.lookup(na, false))
    1439                         return false;
    1440 
    1441         return true;
    1442 }
    1443 
    1444 AddressList::addrlist_t *
    1445 AddressList::get_addrs(AddrProperty *prop)
    1446 {
    1447         addr2prop_t::node *node;
    1448         netaddress na;
    1449         addrlist_t *res = new addrlist_t();
    1450 
    1451         if (res == 0)
    1452                 return res;
    1453 
    1454         if (prop == LocalAddr_P || prop == AnyAddr_P)
    1455                 getifaddrs_get_addrs(*res);
    1456 
    1457         na.set_ip("0.0.0.0");
    1458         na.set_pref_len(0);
    1459         node = prop_trie.lookup_node(na, true, false);
    1460         collect(node, prop, *res);
    1461 
    1462         na.set_ip("::");
    1463         node = prop_trie.lookup_node(na, true, false);
    1464         collect(node, prop, *res);
    1465 
    1466         return res;
    1467 }
    1468 
    1469 netaddress *
    1470 AddressList::get_first(AddrProperty *p, bool IPv4)
    1471 {
    1472         addr2prop_t::node *node;
    1473         netaddress na;
    1474         addrlist_t list;
    1475         addrlist_t::iterator it;
    1476 
    1477         if (IPv4) {
    1478                 na.set_ip("0.0.0.0");
    1479                 na.set_pref_len(0);
    1480         } else {
    1481                 na.set_ip("::");
    1482                 na.set_pref_len(0);
    1483         }
    1484 
    1485         node = prop_trie.lookup_node(na, true, false);
    1486         node = collect_first(node, p);
    1487         if (node != NULL)
    1488                 return new netaddress(*node->key);
    1489 
    1490         if (p == LocalAddr_P) {
    1491                 getifaddrs_get_addrs(list);
    1492                 for (it = list.begin(); it != list.end(); it++)
    1493                         if ((*it).is_ipv4() == IPv4)
    1494                                 return new netaddress(*it);
    1495         }
    1496 
    1497         return NULL;
    1498 }
    1499 
    1500 netaddress *
    1501 AddressList::get_src_addr(const netaddress &dest, uint32_t *prefs)
    1502 {
    1503         netaddress *res;
    1504         int sfd;
    1505 
    1506         sfd = socket(dest.is_ipv4()?AF_INET:AF_INET6, SOCK_DGRAM, 0);
    1507         if (sfd == -1) {
    1508                 err(1, "socket");
    1509                 return NULL;
    1510         }
    1511 
    1512 #ifdef IPV6_ADDR_PREFERENCES
    1513         /* XXX: IPV6_PREFER_SRC_COA does not work */
    1514         if (prefs != NULL && (*prefs & IPV6_PREFER_SRC_COA)) {
    1515                 res = get_first(HomeAddr_P, dest.is_ipv4());
    1516                 if (res != NULL) {
    1517                         addrlist_t *alist;
    1518                         alist = get_addrs(LocalAddr_P);
    1519                         if (alist != NULL) {
    1520                                 addrlist_t::iterator it;
    1521                                 for (it = alist->begin(); it != alist->end();
    1522                                     it++) {
    1523                                         if ((*it).is_ipv4() == dest.is_ipv4() &&
    1524                                             !addr_is(*it, HomeAddr_P)) {
    1525                                                 res = new netaddress(*it);
    1526                                                 return res;
    1527                                         }
    1528                                 }
    1529                                 delete alist;
    1530                         }
    1531                 }
    1532         }
    1533 #endif
    1534         if (dest.is_ipv4()) {
    1535                 struct sockaddr_in sin = {0};
    1536                 socklen_t slen = sizeof(sin);
    1537                 sin.sin_family = AF_INET;
    1538                 sin.sin_port = htons(4);
    1539                 dest.get_ip(sin.sin_addr);
    1540                 if (connect(sfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
    1541                         err(1, "connect");
    1542                         close(sfd);
    1543                         return NULL;
    1544                 }
    1545                 if (getsockname(sfd, (struct sockaddr *)&sin, &slen) == -1) {
    1546                         err(1, "getsockname");
    1547                         close(sfd);
    1548                         return NULL;
    1549                 }
    1550                 close(sfd);
    1551                 res = new netaddress();
    1552                 res->set_ip(sin.sin_addr);
    1553                 res->set_pref_len(32);
    1554                 return (res);
    1555         } else {
    1556                 struct sockaddr_in6 sin6 = {0};
    1557                 socklen_t slen = sizeof(sin6);
    1558                 sin6.sin6_family = AF_INET6;
    1559                 sin6.sin6_port = htons(4);
    1560                 dest.get_ip(sin6.sin6_addr);
    1561                 if (connect(sfd, (struct sockaddr *)&sin6,
    1562                     sizeof(sin6)) == -1) {
    1563                         err(1, "connect");
    1564                         close(sfd);
    1565                         return NULL;
    1566                 }
    1567                 if (getsockname(sfd, (struct sockaddr *)&sin6, &slen) == -1) {
    1568                         err(1, "getsockname");
    1569                         close(sfd);
    1570                         return NULL;
    1571                 }
    1572                 close(sfd);
    1573                 res = new netaddress();
    1574                 res->set_ip(sin6.sin6_addr);
    1575                 res->set_pref_len(128);
    1576                 return (res);
    1577         }
    1578 }
    1579 
    1580 void
    1581 AddressList::getifaddrs_iflist(iflist_t &list)
    1582 {
    1583         struct ifaddrs *ifap, *cifa;
    1584 
    1585         if (::getifaddrs(&ifap) != 0)
    1586                 return;
    1587 
    1588         for (cifa = ifap; cifa != NULL; cifa = cifa->ifa_next) {
    1589                 list.insert(cifa->ifa_name);
    1590         }
    1591 
    1592         freeifaddrs(ifap);
    1593 }
    1594 
    1595 bool
    1596 AddressList::getifaddrs_is_local(netaddress &na)
    1597 {
    1598         struct ifaddrs *ifap, *cifa;
    1599 
    1600         if (::getifaddrs(&ifap) != 0)
    1601                 return false;
    1602 
    1603         for (cifa = ifap; cifa != NULL; cifa = cifa->ifa_next) {
    1604                 hostaddress ha;
    1605 
    1606                 if (cifa->ifa_addr->sa_family == AF_INET) {
    1607                         ha.set_ip(
    1608                             ((struct sockaddr_in *)cifa->ifa_addr)->sin_addr);
    1609                 } else if (cifa->ifa_addr->sa_family == AF_INET6) {
    1610                         ha.set_ip(
    1611                             ((struct sockaddr_in6 *)cifa->ifa_addr)->sin6_addr);
    1612                 } else {
    1613                         continue;
    1614                 }
    1615 
    1616                 if (interfaces &&
    1617                     interfaces->find(cifa->ifa_name) == interfaces->end())
    1618                         continue;
    1619 
    1620                 if (ha.match_against(na) >= na.get_pref_len()) {
    1621                         freeifaddrs(ifap);
    1622                         return true;
    1623                 }
    1624         }
    1625 
    1626         freeifaddrs(ifap);
    1627 
    1628         return false;
    1629 }
    1630 
    1631 void
    1632 AddressList::getifaddrs_get_addrs(addrlist_t &list)
    1633 {
    1634         struct ifaddrs *ifap, *cifa;
    1635 
    1636         if (::getifaddrs(&ifap) != 0)
    1637                 return;
    1638 
    1639         for (cifa = ifap; cifa != NULL; cifa = cifa->ifa_next) {
    1640                 hostaddress *ha;
    1641                 netaddress na;
    1642 
    1643                 if (interfaces &&
    1644                     interfaces->find(cifa->ifa_name) == interfaces->end())
    1645                         continue;
    1646 
    1647                 if (cifa->ifa_addr->sa_family == AF_INET) {
    1648                         ha = new hostaddress;
    1649                         ha->set_ip(
    1650                             ((struct sockaddr_in *)cifa->ifa_addr)->sin_addr);
    1651                         na.set_pref_len(32);
    1652                 } else if (cifa->ifa_addr->sa_family == AF_INET6) {
    1653                         ha = new hostaddress;
    1654                         ha->set_ip(
    1655                             ((struct sockaddr_in6 *)cifa->ifa_addr)->sin6_addr);
    1656                         na.set_pref_len(128);
    1657                 } else {
    1658                         continue;
    1659                 }
    1660 
    1661                 na.set_ip(*ha);
    1662                 if (!addr_is_in(na, IgnoreAddr_P))
    1663                         list.insert(*ha);
    1664         }
    1665 
    1666         freeifaddrs(ifap);
    1667 }
    1668 
    1669 void
    1670 AddressList::bequeath(addr2prop_t::node *head, AddrProperty *p, bool add)
    1671 {
    1672         propmap_t *props;
    1673         propmap_t::iterator it;
    1674 
    1675         if (p == AnyAddr_P && add)
    1676                 return;
    1677 
    1678         props = head->data;
    1679         if (props != NULL) {
    1680                 if (p == AnyAddr_P) {
    1681                         props->clear();
    1682                 } else {
    1683                         if (add) {
    1684                                 props->insert(pair<AddrProperty *, bool>
    1685                                     (p, true));
    1686                         } else {
    1687                                 it = props->find(p);
    1688                                 if (it != props->end())
    1689                                         props->erase(it);
    1690                         }
    1691                 }
    1692         }
    1693 
    1694         if (head->left->index > head->index)
    1695                 bequeath(head->left, p, add);
    1696         if (head->right->index > head->index)
    1697                 bequeath(head->right, p, add);
    1698 }
    1699 
    1700 void
    1701 AddressList::collect(addr2prop_t::node *head, AddrProperty *p,
    1702     addrlist_t &list)
    1703 {
    1704         propmap_t *props;
    1705         propmap_t::iterator it;
    1706 
    1707         props = head->data;
    1708         if (props != NULL) {
    1709                 if (p == AnyAddr_P) {
    1710                         it = props->begin();
    1711                 } else {
    1712                         it = props->find(p);
    1713                 }
    1714                 if (it != props->end()) {
    1715                         list.insert(*(new netaddress(*head->key)));
    1716                 }
    1717         }
    1718 
    1719         if (head->left->index > head->index)
    1720                 collect(head->left, p, list);
    1721         if (head->right->index > head->index)
    1722                 collect(head->right, p, list);
    1723        
    1724 }
    1725 
    1726 AddressList::addr2prop_t::node *
    1727 AddressList::collect_first(addr2prop_t::node *head, AddrProperty *p)
    1728 {
    1729         addr2prop_t::node *res = NULL;
    1730         propmap_t *props;
    1731         propmap_t::iterator it;
    1732 
    1733         props = head->data;
    1734         if (props != NULL) {
    1735                 if (p == AnyAddr_P) {
    1736                         it = props->begin();
    1737                 } else {
    1738                         it = props->find(p);
    1739                 }
    1740                 if (it != props->end()) {
    1741                         return head;
    1742                 }
    1743         }
    1744 
    1745         if (head->left->index > head->index) {
    1746                 res = collect_first(head->left, p);
    1747                 if (res != NULL)
    1748                         return res;
    1749         }
    1750         if (head->right->index > head->index) {
    1751                 res = collect_first(head->right, p);
    1752                 if (res != NULL)
    1753                         return res;
    1754         }
    1755 
    1756         return NULL;
    1757 }
    1758867
    1759868
  • protlib/branches/20081127-merge-mobility-mk3/src/readnl.cpp

    r4187 r4191  
    3838using namespace std;
    3939
     40namespace protlib {
     41
     42        namespace util {
    4043// read a netlink reply in it's entirety
    4144// responsibility of caller to make buf must at least NL_BUFSIZE
     
    8184  return ntread;
    8285}
     86
     87        } // end namespace util
     88
     89} // end namespace protlib
Note: See TracChangeset for help on using the changeset viewer.