00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef QOLYESTER_SYS_LINUX_NETLINK_HH
00020 # define QOLYESTER_SYS_LINUX_NETLINK_HH 1
00021
00022 # include <unistd.h>
00023 # include <string>
00024 # include <sys/uio.h>
00025 # include <asm/types.h>
00026 # include <sys/socket.h>
00027 # include <linux/netlink.h>
00028 # include <list>
00029 # include <cassert>
00030
00031 namespace olsr {
00032
00033 namespace sys {
00034
00035 namespace netlink {
00036
00037 class NLMessage;
00038 class NLAck;
00039 class NLError;
00040 class NLLinkAttr;
00041 class NLAddrAttr;
00042 class NLRouteAttr;
00043 class NLLinkAttrMTU;
00044 class NLLinkAttrName;
00045 class NLNewLink;
00046 class NLDelLink;
00047 class NLGetLink;
00048 class NLAddrAttrAddress;
00049 class NLAddrAttrLocal;
00050 class NLAddrAttrBroadcast;
00051 class NLAddrAttrAnycast;
00052 class NLAddrAttrLabel;
00053 class NLNewAddr;
00054 class NLDelAddr;
00055 class NLGetAddr;
00056 class NLRouteAttrDestination;
00057 class NLRouteAttrGateway;
00058 class NLRouteAttrOutInterface;
00059 class NLGetRoute;
00060 class NLNewRoute;
00061 class NLDelRoute;
00062 class RequestVisitor;
00063 class NLSocket;
00064
00065 class Visitor {
00066 public:
00067
00068 # define VISIT(M) \
00069 virtual void visit(M&) = 0; \
00070 virtual void visit(const M&) = 0
00071
00072 VISIT(NLAck);
00073 VISIT(NLError);
00074
00075 VISIT(NLNewLink);
00076 VISIT(NLGetLink);
00077 VISIT(NLDelLink);
00078
00079 VISIT(NLNewAddr);
00080 VISIT(NLGetAddr);
00081 VISIT(NLDelAddr);
00082
00083 VISIT(NLNewRoute);
00084 VISIT(NLGetRoute);
00085 VISIT(NLDelRoute);
00086
00087 VISIT(NLLinkAttrName);
00088 VISIT(NLLinkAttrMTU);
00089
00090 VISIT(NLAddrAttrAddress);
00091 VISIT(NLAddrAttrLocal);
00092 VISIT(NLAddrAttrLabel);
00093 VISIT(NLAddrAttrBroadcast);
00094 VISIT(NLAddrAttrAnycast);
00095
00096 VISIT(NLRouteAttrDestination);
00097 VISIT(NLRouteAttrGateway);
00098 VISIT(NLRouteAttrOutInterface);
00099
00100 # undef VISIT
00101
00102 virtual ~Visitor() {}
00103 };
00104
00105 class DefaultVisitor : public Visitor {
00106 public:
00107 DefaultVisitor() : Visitor() {}
00108
00109 # define VISIT(M) \
00110 virtual void visit(M&) {} \
00111 virtual void visit(const M&) {}
00112
00113 VISIT(NLAck)
00114 VISIT(NLError)
00115
00116 VISIT(NLNewLink)
00117 VISIT(NLGetLink)
00118 VISIT(NLDelLink)
00119
00120 VISIT(NLNewAddr)
00121 VISIT(NLGetAddr)
00122 VISIT(NLDelAddr)
00123
00124 VISIT(NLNewRoute)
00125 VISIT(NLGetRoute)
00126 VISIT(NLDelRoute)
00127
00128 VISIT(NLLinkAttrName)
00129 VISIT(NLLinkAttrMTU)
00130
00131 VISIT(NLAddrAttrAddress)
00132 VISIT(NLAddrAttrLocal)
00133 VISIT(NLAddrAttrLabel)
00134 VISIT(NLAddrAttrBroadcast)
00135 VISIT(NLAddrAttrAnycast)
00136
00137 VISIT(NLRouteAttrDestination)
00138 VISIT(NLRouteAttrGateway)
00139 VISIT(NLRouteAttrOutInterface)
00140
00141 # undef VISIT
00142
00143 };
00144
00145
00146
00147 class NLMessage {
00148 public:
00149 virtual ~NLMessage() {}
00150 virtual void accept(Visitor&) const = 0;
00151 };
00152
00153 class NLAck : public NLMessage {
00154 public:
00155 virtual ~NLAck() {}
00156 virtual void accept(Visitor& v) const { v.visit(*this); }
00157 };
00158
00159 class NLError : public NLMessage {
00160 public:
00161 NLError(int e)
00162 : _errno(e)
00163 {}
00164 virtual ~NLError() {}
00165 int get_errno() const { return _errno; }
00166 virtual void accept(Visitor& v) const { v.visit(*this); }
00167 private:
00168 int _errno;
00169 };
00170
00171
00172
00173
00174 class NLLinkAttr {
00175 public:
00176 virtual ~NLLinkAttr() {}
00177 virtual void accept(Visitor&) const = 0;
00178 };
00179
00180 class NLAddrAttr {
00181 public:
00182 virtual ~NLAddrAttr() {}
00183 virtual void accept(Visitor&) const = 0;
00184 };
00185
00186 class NLRouteAttr {
00187 public:
00188 virtual ~NLRouteAttr() {}
00189 virtual void accept(Visitor&) const = 0;
00190 };
00191
00192
00193
00194 class NLLinkAttrMTU : public NLLinkAttr {
00195 public:
00196 NLLinkAttrMTU(unsigned mtu) : _mtu(mtu) {}
00197
00198 virtual ~NLLinkAttrMTU() {}
00199
00200 virtual void accept(Visitor& v) const { v.visit(*this); }
00201
00202 unsigned mtu() const { return _mtu; }
00203 private:
00204 const unsigned _mtu;
00205 };
00206
00207 class NLLinkAttrName : public NLLinkAttr {
00208 public:
00209 NLLinkAttrName(const std::string& s) : _name(s) {}
00210 virtual ~NLLinkAttrName() {}
00211
00212 virtual void accept(Visitor& v) const { v.visit(*this); }
00213
00214 const std::string& name() const { return _name; }
00215 private:
00216 const std::string _name;
00217 };
00218
00219
00220
00221 class NLNewLink : public NLMessage {
00222 public:
00223 typedef std::list<NLLinkAttr*> attrs_t;
00224 NLNewLink(unsigned char f,
00225 unsigned short t,
00226 int i,
00227 unsigned int fl) :
00228 _family(f),
00229 _type(t),
00230 _index(i),
00231 _flags(fl),
00232 _attrs()
00233 {}
00234 virtual ~NLNewLink() {
00235 for (attrs_t::const_iterator i = _attrs.begin(); i != _attrs.end(); ++i)
00236 delete *i;
00237 }
00238
00239 virtual void accept(Visitor& v) const {
00240 v.visit(*this);
00241
00242
00243 }
00244
00245 void add_attr(NLLinkAttr* a) {
00246 _attrs.push_back(a);
00247 }
00248
00249 unsigned char family() const { return _family; }
00250 unsigned short type() const { return _type; }
00251 unsigned index() const { return _index; }
00252 unsigned int flags() const { return _flags; }
00253 const attrs_t& attrs() const { return _attrs; }
00254 private:
00255 unsigned char _family;
00256 unsigned short _type;
00257 unsigned _index;
00258 unsigned int _flags;
00259 attrs_t _attrs;
00260 };
00261
00262 class NLDelLink : public NLMessage {
00263 public:
00264 virtual ~NLDelLink() {}
00265
00266 };
00267
00268 class NLGetLink : public NLMessage {
00269 public:
00270 virtual ~NLGetLink() {}
00271 virtual void accept(Visitor& v) const { v.visit(*this); }
00272 };
00273
00274 class NLAddrAttrAddress : public NLAddrAttr {
00275 public:
00276 NLAddrAttrAddress(const unsigned char* b, unsigned len) :
00277 _bytes(new unsigned char[len]), _len(len) {
00278 memcpy(_bytes, b, len);
00279 }
00280 virtual ~NLAddrAttrAddress() { delete[] _bytes; }
00281
00282 virtual void accept(Visitor& v) const { v.visit(*this); }
00283
00284 const unsigned char* bytes() const { return _bytes; }
00285 unsigned length() const { return _len; }
00286 private:
00287 unsigned char* _bytes;
00288 unsigned _len;
00289 };
00290
00291 class NLAddrAttrLocal : public NLAddrAttr {
00292 public:
00293 NLAddrAttrLocal(const unsigned char* b, unsigned len) :
00294 _bytes(new unsigned char[len]), _len(len) {
00295 memcpy(_bytes, b, len);
00296 }
00297 virtual ~NLAddrAttrLocal() { delete[] _bytes; }
00298
00299 virtual void accept(Visitor& v) const { v.visit(*this); }
00300 const unsigned char* bytes() const { return _bytes; }
00301 unsigned length() const { return _len; }
00302 private:
00303 unsigned char* _bytes;
00304 unsigned _len;
00305 };
00306
00307 class NLAddrAttrBroadcast : public NLAddrAttr {
00308 public:
00309 NLAddrAttrBroadcast(const unsigned char* b, unsigned len) :
00310 _bytes(new unsigned char[len]), _len(len) {
00311 memcpy(_bytes, b, len);
00312 }
00313 virtual ~NLAddrAttrBroadcast() { delete[] _bytes; }
00314
00315 virtual void accept(Visitor& v) const { v.visit(*this); }
00316 const unsigned char* bytes() const { return _bytes; }
00317 unsigned length() const { return _len; }
00318 private:
00319 unsigned char* _bytes;
00320 unsigned _len;
00321 };
00322
00323 class NLAddrAttrAnycast : public NLAddrAttr {
00324 public:
00325 NLAddrAttrAnycast(const unsigned char* b, unsigned len) :
00326 _bytes(new unsigned char[len]), _len(len) {
00327 memcpy(_bytes, b, len);
00328 }
00329 virtual ~NLAddrAttrAnycast() { delete[] _bytes; }
00330
00331 virtual void accept(Visitor& v) const { v.visit(*this); }
00332 const unsigned char* bytes() const { return _bytes; }
00333 unsigned length() const { return _len; }
00334 private:
00335 unsigned char* _bytes;
00336 unsigned _len;
00337 };
00338
00339 class NLAddrAttrLabel : public NLAddrAttr {
00340 public:
00341 NLAddrAttrLabel(const std::string& label) :
00342 _label(label)
00343 {}
00344 virtual ~NLAddrAttrLabel() {}
00345
00346 virtual void accept(Visitor& v) const { v.visit(*this); }
00347 const std::string& label() const { return _label; }
00348 private:
00349 const std::string _label;
00350 };
00351
00352 class NLNewAddr : public NLMessage {
00353 public:
00354 typedef std::list<NLAddrAttr*> attrs_t;
00355 NLNewAddr(unsigned char f,
00356 unsigned char p,
00357 unsigned char fl,
00358 unsigned char s,
00359 int i) :
00360 _family(f), _prefixlen(p), _flags(fl), _scope(s), _index(i), _attrs()
00361 {}
00362 virtual ~NLNewAddr() {
00363 for (attrs_t::iterator i = _attrs.begin(); i != _attrs.end(); ++i)
00364 delete *i;
00365 }
00366
00367 virtual void accept(Visitor& v) const {
00368 v.visit(*this);
00369
00370
00371 }
00372 unsigned char family() const { return _family; }
00373 unsigned char prefixlen() const { return _prefixlen; }
00374 unsigned char flags() const { return _flags; }
00375 unsigned char scope() const { return _scope; }
00376 unsigned index() const { return _index; }
00377 const attrs_t& attrs() const { return _attrs; }
00378
00379 void add_attr(NLAddrAttr* a) { _attrs.push_back(a); }
00380 private:
00381 unsigned char _family;
00382 unsigned char _prefixlen;
00383 unsigned char _flags;
00384 unsigned char _scope;
00385 unsigned _index;
00386 attrs_t _attrs;
00387 };
00388
00389 class NLGetAddr : public NLMessage {
00390 public:
00391 NLGetAddr(unsigned char f) : _family(f) {}
00392 virtual ~NLGetAddr() {}
00393
00394 virtual void accept(Visitor& v) const { v.visit(*this); }
00395 unsigned char family() const { return _family; }
00396 private:
00397 unsigned char _family;
00398 };
00399
00400 class NLDelAddr : public NLMessage {
00401 public:
00402 typedef std::list<NLAddrAttr*> attrs_t;
00403 NLDelAddr(unsigned char f,
00404 unsigned char p,
00405 unsigned char fl,
00406 unsigned char s,
00407 int i) :
00408 _family(f), _prefixlen(p), _flags(fl), _scope(s), _index(i), _attrs()
00409 {}
00410 virtual ~NLDelAddr() {
00411 for (attrs_t::iterator i = _attrs.begin(); i != _attrs.end(); ++i)
00412 delete *i;
00413 }
00414
00415 virtual void accept(Visitor& v) const {
00416 v.visit(*this);
00417
00418
00419
00420 }
00421 unsigned char family() const { return _family; }
00422 unsigned char prefixlen() const { return _prefixlen; }
00423 unsigned char flags() const { return _flags; }
00424 unsigned char scope() const { return _scope; }
00425 int index() const { return _index; }
00426 const attrs_t& attrs() const { return _attrs; }
00427
00428 void add_attr(NLAddrAttr* a) { _attrs.push_back(a); }
00429 private:
00430 unsigned char _family;
00431 unsigned char _prefixlen;
00432 unsigned char _flags;
00433 unsigned char _scope;
00434 int _index;
00435 attrs_t _attrs;
00436 };
00437
00438 class NLRouteAttrDestination : public NLRouteAttr {
00439 public:
00440 NLRouteAttrDestination(const unsigned char* b, unsigned len)
00441 : _bytes(new unsigned char[len]),
00442 _len(len) {
00443 memcpy(_bytes, b, len);
00444 }
00445 virtual ~NLRouteAttrDestination() { delete[] _bytes; }
00446
00447 virtual void accept(Visitor& v) const { v.visit(*this); }
00448
00449 const unsigned char* bytes() const { return _bytes; }
00450 unsigned length() const { return _len; }
00451 private:
00452 unsigned char* _bytes;
00453 unsigned _len;
00454 };
00455
00456 class NLRouteAttrGateway : public NLRouteAttr {
00457 public:
00458 NLRouteAttrGateway(const unsigned char* b, unsigned len)
00459 : _bytes(new unsigned char[len]),
00460 _len(len) {
00461 memcpy(_bytes, b, len);
00462 }
00463 virtual ~NLRouteAttrGateway() { delete[] _bytes; }
00464
00465 virtual void accept(Visitor& v) const { v.visit(*this); }
00466
00467 const unsigned char* bytes() const { return _bytes; }
00468 unsigned length() const { return _len; }
00469 private:
00470 unsigned char* _bytes;
00471 unsigned _len;
00472 };
00473
00474 class NLRouteAttrOutInterface : public NLRouteAttr {
00475 public:
00476 NLRouteAttrOutInterface(int index)
00477 : _index(index)
00478 {}
00479 virtual ~NLRouteAttrOutInterface() {}
00480
00481 virtual void accept(Visitor& v) const { v.visit(*this); }
00482
00483 int index() const { return _index; }
00484 private:
00485 int _index;
00486 };
00487
00488 class NLGetRoute : public NLMessage {
00489 public:
00490 NLGetRoute(unsigned char f) : _family(f) {}
00491 virtual ~NLGetRoute() {}
00492
00493 virtual void accept(Visitor& v) const { v.visit(*this); }
00494 unsigned char family() const { return _family; }
00495 private:
00496 unsigned char _family;
00497 };
00498
00499 class NLNewRoute : public NLMessage {
00500 public:
00501 typedef std::list<NLRouteAttr*> attrs_t;
00502
00503 NLNewRoute(unsigned char f,
00504 unsigned char dlen,
00505 unsigned char slen,
00506 unsigned char tos,
00507 unsigned char table,
00508 unsigned char proto,
00509 unsigned char scope,
00510 unsigned char type,
00511 unsigned int flags)
00512 : _family(f),
00513 _dlen(dlen),
00514 _slen(slen),
00515 _tos(tos),
00516 _table(table),
00517 _proto(proto),
00518 _scope(scope),
00519 _type(type),
00520 _flags(flags),
00521 _attrs()
00522 {}
00523 virtual ~NLNewRoute() {
00524 for (attrs_t::iterator i = _attrs.begin(); i != _attrs.end(); ++i)
00525 delete *i;
00526 }
00527 virtual void accept(Visitor& v) const {
00528 v.visit(*this);
00529
00530
00531 }
00532 unsigned char family() const { return _family; }
00533 unsigned char dlen() const { return _dlen; }
00534 unsigned char slen() const { return _slen; }
00535 unsigned char tos() const { return _tos; }
00536 unsigned char table() const { return _table; }
00537 unsigned char proto() const { return _proto; }
00538 unsigned char scope() const { return _scope; }
00539 unsigned char type() const { return _type; }
00540 unsigned int flags() const { return _flags; }
00541
00542 attrs_t& attrs() { return _attrs; }
00543 const attrs_t& attrs() const { return _attrs; }
00544
00545 void add_attr(NLRouteAttr* a) { _attrs.push_back(a); }
00546 private:
00547 unsigned char _family;
00548 unsigned char _dlen;
00549 unsigned char _slen;
00550 unsigned char _tos;
00551 unsigned char _table;
00552 unsigned char _proto;
00553 unsigned char _scope;
00554 unsigned char _type;
00555 unsigned int _flags;
00556 attrs_t _attrs;
00557 };
00558
00559 class NLDelRoute : public NLMessage {
00560 public:
00561 typedef std::list<NLRouteAttr*> attrs_t;
00562
00563 NLDelRoute(unsigned char f,
00564 unsigned char dlen,
00565 unsigned char slen,
00566 unsigned char tos,
00567 unsigned char table,
00568 unsigned char proto,
00569 unsigned char scope,
00570 unsigned char type,
00571 unsigned int flags)
00572 : _family(f),
00573 _dlen(dlen),
00574 _slen(slen),
00575 _tos(tos),
00576 _table(table),
00577 _proto(proto),
00578 _scope(scope),
00579 _type(type),
00580 _flags(flags),
00581 _attrs()
00582 {}
00583 virtual ~NLDelRoute() {
00584 for (attrs_t::iterator i = _attrs.begin(); i != _attrs.end(); ++i)
00585 delete *i;
00586 }
00587 virtual void accept(Visitor& v) const {
00588 v.visit(*this);
00589
00590
00591 }
00592 unsigned char family() const { return _family; }
00593 unsigned char dlen() const { return _dlen; }
00594 unsigned char slen() const { return _slen; }
00595 unsigned char tos() const { return _tos; }
00596 unsigned char table() const { return _table; }
00597 unsigned char proto() const { return _proto; }
00598 unsigned char scope() const { return _scope; }
00599 unsigned char type() const { return _type; }
00600 unsigned int flags() const { return _flags; }
00601
00602 const attrs_t& attrs() const { return _attrs; }
00603 attrs_t& attrs() { return _attrs; }
00604
00605 void add_attr(NLRouteAttr* a) { _attrs.push_back(a); }
00606 private:
00607 unsigned char _family;
00608 unsigned char _dlen;
00609 unsigned char _slen;
00610 unsigned char _tos;
00611 unsigned char _table;
00612 unsigned char _proto;
00613 unsigned char _scope;
00614 unsigned char _type;
00615 unsigned int _flags;
00616 attrs_t _attrs;
00617 };
00618
00619
00620
00621 class RequestVisitor : public DefaultVisitor {
00622 typedef std::list<iovec> buffers_t;
00623 public:
00624 inline RequestVisitor();
00625
00626 inline ~RequestVisitor();
00627
00628 virtual inline void visit(const NLGetLink&);
00629
00630 virtual inline void visit(const NLNewAddr&);
00631 virtual inline void visit(const NLGetAddr&);
00632 virtual inline void visit(const NLDelAddr&);
00633
00634 virtual inline void visit(const NLGetRoute&);
00635 virtual inline void visit(const NLNewRoute&);
00636 virtual inline void visit(const NLDelRoute&);
00637
00638 virtual inline void visit(const NLAddrAttrAddress&);
00639 virtual inline void visit(const NLAddrAttrLocal&);
00640
00641 virtual inline void visit(const NLAddrAttrBroadcast&);
00642 virtual inline void visit(const NLAddrAttrAnycast&);
00643
00644 virtual inline void visit(const NLRouteAttrDestination&);
00645 virtual inline void visit(const NLRouteAttrGateway&);
00646 virtual inline void visit(const NLRouteAttrOutInterface&);
00647
00648 inline const char* buffer();
00649 inline const unsigned length();
00650
00651 static unsigned seqnum;
00652 private:
00653
00654 unsigned totalsize() const;
00655
00656 buffers_t _buffers;
00657 char* _buffer;
00658 unsigned _length;
00659 };
00660
00661
00662
00663 class NLSocket {
00664 typedef sockaddr_nl sockaddr_t;
00665
00666 public:
00667 typedef std::list<NLMessage*> answer_t;
00668
00669 inline NLSocket();
00670
00671 inline ~NLSocket();
00672
00673 inline void send(const NLMessage& m);
00674 private:
00675 inline void do_receive(char*& buffer, unsigned& length);
00676 public:
00677 inline answer_t receive();
00678 private:
00679 int _fd;
00680 };
00681
00682 }
00683
00684 }
00685
00686 }
00687
00688 # include "netlink.hxx"
00689
00690 #endif // ! QOLYESTER_SYS_LINUX_NETLINK_HH