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_LINUX_INTERFACEDESC_HXX
00024 # define QOLYESTER_DAEMON_SYS_LINUX_INTERFACEDESC_HXX 1
00025
00026 # include <cstring>
00027 # include <cassert>
00028
00029 # include "utl/exception.hh"
00030 # include "utl/log.hh"
00031
00032 # include "interfacedesc.hh"
00033
00034 namespace olsr {
00035
00036 extern debug_ostream_t debug;
00037
00038 namespace sys {
00039
00040 namespace internal {
00041
00042 InterfaceAddress::InterfaceAddress() :
00043 _prefix(0),
00044 _scope(0),
00045 _address(),
00046 _broadcast()
00047 {}
00048
00049 InterfaceAddress::InterfaceAddress(unsigned p,
00050 unsigned char s,
00051 const address_t& a,
00052 const address_t& b) :
00053 _prefix(p),
00054 _scope(s),
00055 _address(a),
00056 _broadcast(b)
00057 {}
00058
00059 bool
00060 InterfaceAddress::operator<(const This& rhs) const {
00061 return _address < rhs._address;
00062 }
00063
00064 InterfaceAddress
00065 InterfaceAddress::make_key(const address_t& a) {
00066 This tmp = _dummy_for_find;
00067
00068 const_cast<address_t&>(tmp._address) = a;
00069 return tmp;
00070 }
00071
00072 }
00073
00074 namespace netlink {
00075
00076 # ifdef DEBUG
00077 DebugVisitor::DebugVisitor(std::ostream& os) : _os(os) {
00078 _os << "DebugVisitor {\n";
00079 }
00080
00081 DebugVisitor::~DebugVisitor() {
00082 _os << '}' << std::endl;
00083 }
00084
00085 void
00086 DebugVisitor::visit(const NLError& e) {
00087 _os << " Error: " << strerror(e.get_errno()) << " ("
00088 << e.get_errno() << ")\n";
00089 }
00090
00091 void
00092 DebugVisitor::visit(const NLNewLink& e) {
00093 _os << " NewLink {\n"
00094 << " index = " << e.index() << '\n'
00095 << " attrs {\n";
00096
00097 for (NLNewLink::attrs_t::const_iterator i = e.attrs().begin();
00098 i != e.attrs().end(); ++i)
00099 (*i)->accept(*this);
00100
00101 _os << " }\n"
00102 << " }\n";
00103 }
00104
00105 void
00106 DebugVisitor::visit(const NLLinkAttrName& e) {
00107 _os << " name = \"" << e.name() << "\"\n";
00108 }
00109
00110 void
00111 DebugVisitor::visit(const NLLinkAttrMTU& e) {
00112 _os << " MTU = " << e.mtu() << '\n';
00113 }
00114
00115 void
00116 DebugVisitor::visit(const NLNewAddr& e) {
00117 if (e.family() != address_t::family)
00118 return;
00119
00120 _os << " NLNewAddr {\n"
00121 << " family = " << (int) e.family() << '\n'
00122 << " index = " << e.index() << '\n'
00123 << " prefix = " << (int) e.prefixlen() << '\n'
00124 << " scope = " << (int) e.scope() << '\n'
00125 << " attrs {\n";
00126
00127 for (NLNewAddr::attrs_t::const_iterator i = e.attrs().begin();
00128 i != e.attrs().end(); ++i)
00129 (*i)->accept(*this);
00130
00131 _os << " }\n"
00132 << " }\n";
00133 }
00134
00135 void
00136 DebugVisitor::visit(const NLAddrAttrAddress& e) {
00137 _os << " address = " << address_t(e.bytes(), e.length()) << '\n';
00138 }
00139
00140 void
00141 DebugVisitor::visit(const NLAddrAttrBroadcast& e) {
00142 _os << " broadcast = " << address_t(e.bytes(), e.length())
00143 << '\n';
00144 }
00145 # endif // !DEBUG
00146
00147 InitVisitor::InitVisitor(std::string& name,
00148 unsigned& index,
00149 unsigned& mtu,
00150 addrs_t& addrs)
00151 : _name(name),
00152 _index(index),
00153 _mtu(mtu),
00154 _addrs(addrs),
00155 _prefix(0),
00156 _scope(0),
00157 _address(),
00158 _broadcast()
00159 {}
00160
00161 void
00162 InitVisitor::visit(const NLError& e) {
00163 throw errnoexcept_t(strerror(e.get_errno()), e.get_errno());
00164 }
00165
00166 void
00167 InitVisitor::visit(const NLNewLink& e) {
00168 _index = e.index();
00169
00170 for (NLNewLink::attrs_t::const_iterator i = e.attrs().begin();
00171 i != e.attrs().end(); ++i)
00172 (*i)->accept(*this);
00173
00174 assert(!_name.empty());
00175 assert(_index != 0);
00176
00177 }
00178
00179 void
00180 InitVisitor::visit(const NLLinkAttrName& e) {
00181 _name = e.name();
00182 }
00183
00184 void
00185 InitVisitor::visit(const NLLinkAttrMTU& e) {
00186 _mtu = e.mtu();
00187 }
00188
00189 void
00190 InitVisitor::visit(const NLNewAddr& e) {
00191 if (e.family() != address_t::family ||
00192 e.index() != _index)
00193 return;
00194
00195 _prefix = e.prefixlen();
00196 _scope = e.scope();
00197
00198 for (NLNewAddr::attrs_t::const_iterator i = e.attrs().begin();
00199 i != e.attrs().end(); ++i)
00200 (*i)->accept(*this);
00201
00202 assert(_address != address_t());
00203
00204 _addrs.insert(addr_t(_prefix, _scope, _address, _broadcast));
00205
00206 _prefix = 0;
00207 _scope = 0;
00208 _address = address_t();
00209 _broadcast = address_t();
00210 }
00211
00212 void
00213 InitVisitor::visit(const NLAddrAttrAddress& e) {
00214 _address = address_t(e.bytes(), e.length());
00215 }
00216
00217 void
00218 InitVisitor::visit(const NLAddrAttrBroadcast& e) {
00219 _broadcast = address_t(e.bytes(), e.length());
00220 }
00221
00222 }
00223
00224 namespace internal {
00225
00226 InterfaceInfo::InterfaceInfo(const std::string& name) :
00227 _name(),
00228 _index(0),
00229 _mtu(0),
00230 _addrs() {
00231 # ifdef DEBUG
00232 using netlink::DebugVisitor;
00233 # endif // !DEBUG
00234 using netlink::InitVisitor;
00235 using netlink::NLMessage;
00236 using netlink::NLSocket;
00237 using netlink::NLGetLink;
00238 using netlink::NLGetAddr;
00239
00240 InitVisitor v(_name, _index, _mtu, _addrs);
00241
00242 NLSocket s;
00243
00244 s.send(NLGetLink());
00245
00246 NLSocket::answer_t li = s.receive();
00247
00248 bool found = false;
00249
00250 while (!li.empty()) {
00251 NLMessage* m = li.front();
00252 li.pop_front();
00253
00254 # ifdef DEBUG
00255 {
00256 DebugVisitor dv(debug);
00257 m->accept(dv);
00258 }
00259 # endif // !DEBUG
00260
00261 if (!found) {
00262 m->accept(v);
00263
00264 if (_name == name)
00265 found = true;
00266 }
00267
00268 delete m;
00269 }
00270
00271 if (!found)
00272 throw std::runtime_error(name + " is not an interface");
00273
00274 s.send(NLGetAddr(address_t::family));
00275
00276 li = s.receive();
00277
00278 while (!li.empty()) {
00279 NLMessage* m = li.front();
00280 li.pop_front();
00281 # ifdef DEBUG
00282 {
00283 DebugVisitor dv(debug);
00284 m->accept(dv);
00285 }
00286 # endif // !DEBUG
00287 m->accept(v);
00288 delete m;
00289 }
00290 }
00291
00292 bool
00293 InterfaceInfo::operator<(const This& rhs) const {
00294 return _index < rhs._index;
00295 }
00296
00297 }
00298
00299 }
00300
00301 }
00302
00303 # endif // ! QOLYESTER_DAEMON_SYS_LINUX_INTERFACEDESC_HXX
00304
00305 #endif // ! QOLYESTER_ENABLE_VIRTUAL