iface_mgr_test_config.cc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <dhcp/pkt_filter.h>
  15. #include <dhcp/pkt_filter_inet.h>
  16. #include <dhcp/pkt_filter_inet6.h>
  17. #include <dhcp/tests/iface_mgr_test_config.h>
  18. #include <dhcp/tests/pkt_filter_test_stub.h>
  19. #include <dhcp/tests/pkt_filter6_test_stub.h>
  20. using namespace isc::asiolink;
  21. namespace isc {
  22. namespace dhcp {
  23. namespace test {
  24. IfaceMgrTestConfig::IfaceMgrTestConfig(const bool default_config) {
  25. IfaceMgr::instance().closeSockets();
  26. IfaceMgr::instance().clearIfaces();
  27. packet_filter4_ = PktFilterPtr(new PktFilterTestStub());
  28. packet_filter6_ = PktFilter6Ptr(new PktFilter6TestStub());
  29. IfaceMgr::instance().setPacketFilter(packet_filter4_);
  30. IfaceMgr::instance().setPacketFilter(packet_filter6_);
  31. // Create default set of fake interfaces: lo, eth0 and eth1.
  32. if (default_config) {
  33. createIfaces();
  34. }
  35. }
  36. IfaceMgrTestConfig::~IfaceMgrTestConfig() {
  37. IfaceMgr::instance().closeSockets();
  38. IfaceMgr::instance().clearIfaces();
  39. IfaceMgr::instance().setPacketFilter(PktFilterPtr(new PktFilterInet()));
  40. IfaceMgr::instance().setPacketFilter(PktFilter6Ptr(new PktFilterInet6()));
  41. IfaceMgr::instance().detectIfaces();
  42. }
  43. void
  44. IfaceMgrTestConfig::addAddress(const std::string& iface_name,
  45. const IOAddress& address) {
  46. Iface* iface = IfaceMgr::instance().getIface(iface_name);
  47. if (iface == NULL) {
  48. isc_throw(isc::BadValue, "interface '" << iface_name
  49. << "' doesn't exist");
  50. }
  51. iface->addAddress(address);
  52. }
  53. void
  54. IfaceMgrTestConfig::addIface(const Iface& iface) {
  55. IfaceMgr::instance().addInterface(iface);
  56. }
  57. void
  58. IfaceMgrTestConfig::addIface(const std::string& name, const int ifindex) {
  59. IfaceMgr::instance().addInterface(createIface(name, ifindex));
  60. }
  61. Iface
  62. IfaceMgrTestConfig::createIface(const std::string &name, const int ifindex) {
  63. Iface iface(name, ifindex);
  64. if (name == "lo") {
  65. iface.flag_loopback_ = true;
  66. // Don't open sockets on the loopback interface.
  67. iface.inactive4_ = true;
  68. iface.inactive6_ = true;
  69. } else {
  70. iface.inactive4_ = false;
  71. iface.inactive6_ = false;
  72. }
  73. iface.flag_multicast_ = true;
  74. // On BSD systems, the SO_BINDTODEVICE option is not supported.
  75. // Therefore the IfaceMgr will throw an exception on attempt to
  76. // open sockets on more than one broadcast-capable interface at
  77. // the same time. In order to prevent this error, we mark all
  78. // interfaces broadcast-incapable for unit testing.
  79. iface.flag_broadcast_ = false;
  80. iface.flag_up_ = true;
  81. iface.flag_running_ = true;
  82. return (iface);
  83. }
  84. void
  85. IfaceMgrTestConfig::createIfaces() {
  86. // local loopback
  87. addIface("lo", 0);
  88. addAddress("lo", IOAddress("127.0.0.1"));
  89. addAddress("lo", IOAddress("::1"));
  90. // eth0
  91. addIface("eth0", 1);
  92. addAddress("eth0", IOAddress("10.0.0.1"));
  93. addAddress("eth0", IOAddress("fe80::3a60:77ff:fed5:cdef"));
  94. addAddress("eth0", IOAddress("2001:db8:1::1"));
  95. // eth1
  96. addIface("eth1", 2);
  97. addAddress("eth1", IOAddress("192.0.2.3"));
  98. addAddress("eth1", IOAddress("fe80::3a60:77ff:fed5:abcd"));
  99. }
  100. void
  101. IfaceMgrTestConfig::setDirectResponse(const bool direct_resp) {
  102. boost::shared_ptr<PktFilterTestStub> stub =
  103. boost::dynamic_pointer_cast<PktFilterTestStub>(getPacketFilter4());
  104. if (!stub) {
  105. isc_throw(isc::Unexpected, "unable to set direct response capability for"
  106. " test packet filter - current packet filter is not"
  107. " of a PktFilterTestStub");
  108. }
  109. stub->direct_response_supported_ = direct_resp;
  110. }
  111. void
  112. IfaceMgrTestConfig::setIfaceFlags(const std::string& name,
  113. const FlagLoopback& loopback,
  114. const FlagUp& up,
  115. const FlagRunning& running,
  116. const FlagInactive4& inactive4,
  117. const FlagInactive6& inactive6) {
  118. Iface* iface = IfaceMgr::instance().getIface(name);
  119. if (iface == NULL) {
  120. isc_throw(isc::BadValue, "interface '" << name << "' doesn't exist");
  121. }
  122. iface->flag_loopback_ = loopback.flag_;
  123. iface->flag_up_ = up.flag_;
  124. iface->flag_running_ = running.flag_;
  125. iface->inactive4_ = inactive4.flag_;
  126. iface->inactive6_ = inactive6.flag_;
  127. }
  128. bool
  129. IfaceMgrTestConfig::socketOpen(const std::string& iface_name,
  130. const int family) const {
  131. Iface* iface = IfaceMgr::instance().getIface(iface_name);
  132. if (iface == NULL) {
  133. isc_throw(Unexpected, "No such interface '" << iface_name << "'");
  134. }
  135. const Iface::SocketCollection& sockets = iface->getSockets();
  136. for (Iface::SocketCollection::const_iterator sock = sockets.begin();
  137. sock != sockets.end(); ++sock) {
  138. if (sock->family_ == family) {
  139. return (true);
  140. }
  141. }
  142. return (false);
  143. }
  144. bool
  145. IfaceMgrTestConfig::unicastOpen(const std::string& iface_name) const {
  146. Iface* iface = IfaceMgr::instance().getIface(iface_name);
  147. if (iface == NULL) {
  148. isc_throw(Unexpected, "No such interface '" << iface_name << "'");
  149. }
  150. const Iface::SocketCollection& sockets = iface->getSockets();
  151. for (Iface::SocketCollection::const_iterator sock = sockets.begin();
  152. sock != sockets.end(); ++sock) {
  153. if ((!sock->addr_.isV6LinkLocal()) &&
  154. (!sock->addr_.isV6Multicast())) {
  155. return (true);
  156. }
  157. }
  158. return (false);
  159. }
  160. }
  161. }
  162. }