00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "config.hh"
00020
00021 #ifndef QOLYESTER_ENABLE_VIRTUAL
00022
00023 # ifndef QOLYESTER_DAEMON_SYS_REALINTERFACEINFO_HXX
00024 # define QOLYESTER_DAEMON_SYS_REALINTERFACEINFO_HXX 1
00025
00026 # include <cassert>
00027 # include <stdexcept>
00028
00029 # include "config.hh"
00030
00031 # include "set/interfaces.hh"
00032 # include "sys/linux/routingsocket.hh"
00033
00034 # include "realinterfaceinfo.hh"
00035
00036 namespace olsr {
00037
00038 extern ifaceset_t iface_set;
00039
00040 namespace sys {
00041
00042 RealInterfaceInfo::RealInterfaceInfo()
00043 : _name(),
00044 _mtu(0),
00045 _index(0),
00046 _addrs()
00047 {}
00048
00049 RealInterfaceInfo::RealInterfaceInfo(const std::string& name)
00050 : _name(name),
00051 _mtu(0),
00052 _index(0),
00053 _addrs() {
00054 internal::InterfaceInfo info(name);
00055 _mtu = info.mtu();
00056 _index = info.index();
00057 assert(_index != 0);
00058 _addrs = info.addrs();
00059 }
00060
00061 RealInterfaceInfo&
00062 RealInterfaceInfo::operator=(const This& other) {
00063 const_cast<std::string&>(_name) = other._name;
00064 _mtu = other._mtu;
00065 _index = other._index;
00066 _addrs = other._addrs;
00067 return *this;
00068 }
00069
00070 const address_t&
00071 RealInterfaceInfo::get_addr() const {
00072 const address_t* paddr = 0;
00073
00074 # if QOLYESTER_FAMILY_INET == 6
00075 bool have_ll = false;
00076 # endif
00077
00078 for (addrs_t::iterator i = _addrs.begin(); i != _addrs.end(); ++i) {
00079 if (paddr == 0 && !i->address().is_linklocal() &&
00080 i->prefix() == ADDRESS_SIZE * 8) {
00081 paddr = &i->address();
00082 # if QOLYESTER_FAMILY_INET == 4
00083 break;
00084 # endif
00085 }
00086 # if QOLYESTER_FAMILY_INET == 6
00087 if (i->address().is_linklocal())
00088 have_ll = true;
00089 # endif
00090 }
00091
00092 if (paddr == 0)
00093 throw std::runtime_error(_name + " has no usable address, a global address with full prefix is needed");
00094
00095 # if QOLYESTER_FAMILY_INET == 6
00096 if (!have_ll)
00097 throw std::runtime_error(_name + " has usable address, but no link-local address");
00098 # endif
00099 return *paddr;
00100 }
00101
00102 const address_t&
00103 RealInterfaceInfo::get_addr(const address_t& a) const {
00104
00105 if (_addrs.find(addr_t::make_key(a)) == _addrs.end())
00106 throw std::runtime_error(_name + " has no address " + a.to_string());
00107
00108 return a;
00109 }
00110
00111 # if defined QOLYESTER_LL_MCAST && QOLYESTER_FAMILY_INET == 6
00112 const address_t
00113 RealInterfaceInfo::get_bcast(const address_t&) const {
00114 return address_t(QOLYESTER_LINKLOCAL_MCAST);
00115 }
00116 # else
00117 const address_t
00118 RealInterfaceInfo::get_bcast(const address_t& a) const {
00119 # if QOLYESTER_FAMILY_INET == 6
00120 if (a.is_linklocal())
00121 return address_t(QOLYESTER_LINKLOCAL_MCAST);
00122 return address_t(QOLYESTER_GLOBAL_MCAST);
00123 # else // QOLYESTER_FAMILY_INET != 6
00124 addrs_t::iterator x = _addrs.find(addr_t::make_key(a));
00125 if (x != _addrs.end() && x->broadcast() != address_t())
00126 return x->broadcast();
00127 return address_t("255.255.255.255");
00128 # endif
00129 }
00130 # endif
00131
00132 unsigned
00133 RealInterfaceInfo::get_prefix(const address_t& a) const {
00134 addrs_t::iterator x = _addrs.find(addr_t::make_key(a));
00135 if (x != _addrs.end())
00136 return x->prefix();
00137 return 0;
00138 }
00139
00140 void
00141 RealInterfaceInfo::add_addr(const address_t& a, unsigned p) {
00142 internal::RoutingSocket().add_addr(_index, addr_t(p, IFA_F_PERMANENT,
00143 a, address_t()));
00144 *this = RealInterfaceInfo(_name);
00145 }
00146
00147 void
00148 RealInterfaceInfo::del_addr(const address_t& a) {
00149 addrs_t::iterator x = _addrs.find(addr_t::make_key(a));
00150
00151 if (x == _addrs.end())
00152 throw std::runtime_error("Attempt to delete inexistant address " +
00153 a.to_string() + " from " + _name);
00154
00155 if (iface_set.find(a) != iface_set.end())
00156 throw std::runtime_error("Attempt to delete address " + a.to_string() +
00157 " from " + _name + ", while using it");
00158
00159 internal::RoutingSocket().del_addr(_index, *x);
00160 *this = RealInterfaceInfo(_name);
00161 }
00162
00163 }
00164
00165 }
00166
00167 # endif // ! QOLYESTER_DAEMON_SYS_REALINTERFACEINFO_HXX
00168
00169 #endif // ! QOLYESTER_ENABLE_VIRTUAL