realinterfaceinfo.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2003, 2004, 2005 Laboratoire de Recherche en Informatique
00002 
00003 // This file is part of Qolyester.
00004 
00005 // Qolyester is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 // Qolyester is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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   } // namespace sys
00164 
00165 } // namespace olsr
00166 
00167 # endif // ! QOLYESTER_DAEMON_SYS_REALINTERFACEINFO_HXX
00168 
00169 #endif // ! QOLYESTER_ENABLE_VIRTUAL

Generated on Mon Sep 10 17:02:12 2007 for Qolyester daemon by  doxygen 1.5.1