Browse Source

[1959] Enabled Solicit packets creation and send.

Marcin Siodelski 12 years ago
parent
commit
25ae3625bc
2 changed files with 150 additions and 11 deletions
  1. 118 7
      tests/tools/perfdhcp/test_control.cc
  2. 32 4
      tests/tools/perfdhcp/test_control.h

+ 118 - 7
tests/tools/perfdhcp/test_control.cc

@@ -96,14 +96,51 @@ TestControl::checkExitConditions() const {
 }
 
 OptionPtr
-TestControl::factoryGeneric4(Option::Universe u,
-                                 uint16_t type,
-                                 const OptionBuffer& buf) {
+TestControl::factoryElapsedTimeSolicit6(Option::Universe, uint16_t,
+                                        const OptionBuffer&) {
+    return OptionPtr(new Option(Option::V6, D6O_ELAPSED_TIME,
+                                OptionBuffer(2, 0)));
+}
+
+OptionPtr
+TestControl::factoryGeneric(Option::Universe u, uint16_t type,
+                            const OptionBuffer& buf) {
     OptionPtr opt(new Option(u, type, buf));
     return opt;
 }
 
 OptionPtr
+TestControl::factoryIana6(Option::Universe, uint16_t,
+                          const OptionBuffer&) {
+    const uint8_t buf_array[] = {
+        0, 0, 0, 1,                     // IAID = 1
+        0, 0, 3600 >> 8, 3600 && 0xff,  // T1 = 3600
+        0, 0, 5400 >> 8, 5400 & 0xff,   // T2 = 5400
+    };
+    OptionBuffer buf(buf_array, buf_array + sizeof(buf_array));
+    return OptionPtr(new Option(Option::V6, D6O_IA_NA, buf));
+}
+
+OptionPtr
+TestControl::factoryRapidCommit6(Option::Universe, uint16_t,
+                                 const OptionBuffer&) {
+    return OptionPtr(new Option(Option::V6, D6O_RAPID_COMMIT, OptionBuffer()));
+}
+
+OptionPtr
+TestControl::factoryOptionRequestOption6(Option::Universe,
+                                         uint16_t,
+                                         const OptionBuffer&) {
+    const uint8_t buf_array[] = {
+        D6O_NAME_SERVERS,
+        D6O_DOMAIN_SEARCH
+    };
+    OptionBuffer buf_with_options(buf_array, buf_array + sizeof(buf_array));
+    return OptionPtr(new Option(Option::V6, D6O_ORO, buf_with_options));
+}
+
+
+OptionPtr
 TestControl::factoryRequestList4(Option::Universe u,
                                  uint16_t type,
                                  const OptionBuffer& buf) {
@@ -123,6 +160,8 @@ TestControl::factoryRequestList4(Option::Universe u,
     return opt;
 }
 
+
+
 std::vector<uint8_t>
 TestControl::generateMacAddress() const {
     CommandOptions& options = CommandOptions::instance();
@@ -160,6 +199,18 @@ TestControl::generateMacAddress() const {
     return mac_addr;
 }
 
+std::vector<uint8_t>
+TestControl::generateDuid() const {
+    CommandOptions& options = CommandOptions::instance();
+    uint32_t clients_num = options.getClientsNum();
+    if ((clients_num == 0) || (clients_num == 1)) {
+        return options.getDuidPrefix();
+    }
+    // Get the base MAC address. We are going to randomize part of it.
+    std::vector<uint8_t> duid(options.getDuidPrefix());
+    return duid;
+}
+
 uint64_t
 TestControl::getNextExchangesNum() const {
     CommandOptions& options = CommandOptions::instance();
@@ -287,7 +338,7 @@ TestControl::registerOptionFactories4() const {
         // DHCP_MESSAGE_TYPE option factory.
         LibDHCP::OptionFactoryRegister(Option::V4,
                                        DHO_DHCP_MESSAGE_TYPE,
-                                       &TestControl::factoryGeneric4);
+                                       &TestControl::factoryGeneric);
         // DHCP_PARAMETER_REQUEST_LIST option factory.
         LibDHCP::OptionFactoryRegister(Option::V4,
                                        DHO_DHCP_PARAMETER_REQUEST_LIST,
@@ -300,7 +351,24 @@ void
 TestControl::registerOptionFactories6() const {
     static bool factories_registered = false;
     if (!factories_registered) {
-        // This is a placeholder for v6 factories.
+        LibDHCP::OptionFactoryRegister(Option::V6,
+                                       D6O_ELAPSED_TIME,
+                                       &TestControl::factoryElapsedTimeSolicit6);
+        LibDHCP::OptionFactoryRegister(Option::V6,
+                                       D6O_RAPID_COMMIT,
+                                       &TestControl::factoryRapidCommit6);
+        LibDHCP::OptionFactoryRegister(Option::V6,
+                                       D6O_ORO,
+                                       &TestControl::factoryOptionRequestOption6);
+        LibDHCP::OptionFactoryRegister(Option::V6,
+                                       D6O_CLIENTID,
+                                       &TestControl::factoryGeneric);
+
+        LibDHCP::OptionFactoryRegister(Option::V6,
+                                       D6O_IA_NA,
+                                       &TestControl::factoryIana6);
+
+
     }
     factories_registered = true;
 }
@@ -347,7 +415,11 @@ TestControl::run() {
         receivePackets();
 
         for (uint64_t i = packets_due; i > 0; --i) {
-            sendDiscover4(socket);
+            if (options.getIpVersion() == 4) {
+                sendDiscover4(socket);
+            } else {
+                sendSolicit6(socket);
+            }
             ++packets_sent;
             cout << "Packets sent " << packets_sent << endl;
         }
@@ -382,7 +454,32 @@ TestControl::sendDiscover4(const TestControlSocket& socket) {
 }
 
 void
-TestControl::setDefaults4(const TestControlSocket &socket,
+TestControl::sendSolicit6(const TestControlSocket& socket) {
+    ++sent_packets_0_;
+    last_sent_ = microsec_clock::universal_time();
+    // Generate the MAC address to be passed in the packet.
+    std::vector<uint8_t> mac_address = generateMacAddress();
+    // Generate DUID to be passed to the packet
+    std::vector<uint8_t> duid = generateDuid();
+    // Generate trasnaction id to be set for the new exchange.
+    const uint32_t transid = static_cast<uint32_t>(random());
+    boost::shared_ptr<Pkt6> pkt6(new Pkt6(DHCPV6_SOLICIT, transid));
+    if (!pkt6) {
+        isc_throw(Unexpected, "failed to create SOLICIT packet");
+    }
+    pkt6->addOption(Option::factory(Option::V6, D6O_ELAPSED_TIME));
+    pkt6->addOption(Option::factory(Option::V6, D6O_RAPID_COMMIT));
+    pkt6->addOption(Option::factory(Option::V6, D6O_CLIENTID, duid));
+    pkt6->addOption(Option::factory(Option::V6, D6O_ORO));
+    pkt6->addOption(Option::factory(Option::V6, D6O_IA_NA));
+
+    setDefaults6(socket, pkt6);
+    pkt6->pack();
+    IfaceMgr::instance().send(pkt6);
+}
+
+void
+TestControl::setDefaults4(const TestControlSocket& socket,
                           const boost::shared_ptr<Pkt4>& pkt) {
     CommandOptions& options = CommandOptions::instance();
     // Interface name.
@@ -400,6 +497,20 @@ TestControl::setDefaults4(const TestControlSocket &socket,
 }
 
 void
+TestControl::setDefaults6(const TestControlSocket& socket,
+                          const boost::shared_ptr<Pkt6>& pkt) {
+    CommandOptions& options = CommandOptions::instance();
+    // Interface name.
+    pkt->setIface(socket.getIface());
+    // Local client's port (547)
+    pkt->setLocalPort(DHCP6_CLIENT_PORT);
+    // Server's port (548)
+    pkt->setRemotePort(DHCP6_SERVER_PORT);
+    // The remote server's name or IP.
+    pkt->setRemoteAddr(IOAddress(options.getServerName()));
+}
+
+void
 TestControl::updateSendDue() {
     // If default constructor was called, this should not happen but
     // if somebody has changed default constructor it is better to

+ 32 - 4
tests/tools/perfdhcp/test_control.h

@@ -21,6 +21,7 @@
 #include <boost/noncopyable.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>
 
+#include <dhcp/dhcp6.h>
 #include <dhcp/pkt4.h>
 #include <dhcp/pkt6.h>
 
@@ -132,6 +133,12 @@ private:
     /// \return true if any of the exit conditions is fulfiled.
     bool checkExitConditions() const;
 
+    static dhcp::OptionPtr
+    factoryElapsedTimeSolicit6(dhcp::Option::Universe u,
+                               uint16_t type,
+                               const dhcp::OptionBuffer& buf);
+    
+
     /// \brief Factory function to create generic option.
     ///
     /// Factory function is registered using \ref LibDHCP::OptionFactoryRegister.
@@ -147,9 +154,23 @@ private:
     /// \param type option-type.
     /// \param buf option-buffer.
     /// \return instance o the generic option.
-    static dhcp::OptionPtr factoryGeneric4(dhcp::Option::Universe u,
-                                           uint16_t type,
-                                           const dhcp::OptionBuffer& buf);
+    static dhcp::OptionPtr factoryGeneric(dhcp::Option::Universe u,
+                                          uint16_t type,
+                                          const dhcp::OptionBuffer& buf);
+
+    static dhcp::OptionPtr factoryIana6(dhcp::Option::Universe u,
+                                        uint16_t type,
+                                        const dhcp::OptionBuffer& buf);
+
+    static dhcp::OptionPtr
+    factoryOptionRequestOption6(dhcp::Option::Universe u,
+                                uint16_t type,
+                                const dhcp::OptionBuffer& buf);
+
+    static dhcp::OptionPtr factoryRapidCommit6(dhcp::Option::Universe u,
+                                               uint16_t type,
+                                               const dhcp::OptionBuffer& buf);
+
 
     /// \brief Factory function to create DHCPv4 Request List option.
     ///
@@ -177,6 +198,8 @@ private:
                                                uint16_t type,
                                                const dhcp::OptionBuffer& buf);
 
+    std::vector<uint8_t> generateDuid() const;
+
     /// \brief Generate MAC address.
     ///
     /// This method generates MAC address. The number of unique
@@ -256,7 +279,9 @@ private:
     /// \param socket socket to be used to send the message.
     /// \throw isc::Unexpected if failed to create new packet instance.
     /// \throw isc::BadValue if MAC address has invalid length.
-    void sendDiscover4(const TestControlSocket &socket);
+    void sendDiscover4(const TestControlSocket& socket);
+
+    void sendSolicit6(const TestControlSocket& socket);
 
     /// \brief Set default DHCPv4 packet data.
     ///
@@ -273,6 +298,9 @@ private:
     void setDefaults4(const TestControlSocket& socket,
                       const boost::shared_ptr<dhcp::Pkt4>& pkt);
 
+    void setDefaults6(const TestControlSocket& socket,
+                      const boost::shared_ptr<dhcp::Pkt6>& pkt);
+
     /// \brief Update due time to initiate next chunk of exchanges.
     ///
     /// Method updates due time to initiate next chunk of exchanges.