namespace perfdhcp {
TestControl::TestControlSocket::TestControlSocket(int socket) :
- socket_(socket) {
- initInterface();
+ socket_(socket),
+ addr_("127.0.0.1") {
+ initSocketData();
}
TestControl::TestControlSocket::~TestControlSocket() {
}
void
-TestControl::TestControlSocket::initInterface() {
+TestControl::TestControlSocket::initSocketData() {
const IfaceMgr::IfaceCollection& ifaces =
IfaceMgr::instance().getIfaces();
for (IfaceMgr::IfaceCollection::const_iterator it = ifaces.begin();
++s) {
if (s->sockfd_ == socket_) {
iface_ = it->getName();
+ addr_ = s->addr_;
return;
}
}
return(false);
}
-boost::shared_ptr<Pkt4>
-TestControl::createDiscoverPkt4(const std::vector<uint8_t>& mac_addr) const {
- const uint32_t transid = static_cast<uint32_t>(random());
- boost::shared_ptr<Pkt4> pkt4(new Pkt4(DHCPDISCOVER, transid));
- if (!pkt4) {
- isc_throw(isc::Unexpected, "failed to create DISCOVER packet");
- }
-
- if (HW_ETHER_LEN != mac_addr.size()) {
- isc_throw(BadValue, "invalid MAC address size");
- }
- pkt4->setHWAddr(HTYPE_ETHER, HW_ETHER_LEN, mac_addr);
-
- OptionBuffer buf_msg_type;
- buf_msg_type.push_back(DHCPDISCOVER);
- pkt4->addOption(Option::factory(Option::V4, DHO_DHCP_MESSAGE_TYPE, buf_msg_type));
- pkt4->addOption(Option::factory(Option::V4, DHO_DHCP_PARAMETER_REQUEST_LIST));
- return pkt4;
-}
-
OptionPtr
TestControl::factoryGeneric4(Option::Universe u,
uint16_t type,
return options.getMacPrefix();
}
std::vector<uint8_t> mac_addr(options.getMacPrefix());
+ if (mac_addr.size() != HW_ETHER_LEN) {
+ isc_throw(BadValue, "invalid MAC address prefix specified");
+ }
uint32_t r = random();
- r %= clients_num + 1;
+ r %= clients_num;
for (std::vector<uint8_t>::iterator it = mac_addr.end() - 1;
it >= mac_addr.begin();
--it) {
receivePackets();
for (uint64_t i = packets_due; i > 0; --i) {
- startExchange(socket);
+ sendDiscover4(socket);
++packets_sent;
cout << "Packets sent " << packets_sent << endl;
}
}
void
-TestControl::startExchange(const TestControlSocket& socket) {
+TestControl::sendDiscover4(const TestControlSocket& socket) {
++sent_packets_0_;
last_sent_ = microsec_clock::universal_time();
std::vector<uint8_t> mac_address = generateMacAddress();
- boost::shared_ptr<Pkt4> pkt4 = createDiscoverPkt4(mac_address);
- pkt4->setIface(socket.getIface());
+ const uint32_t transid = static_cast<uint32_t>(random());
+ boost::shared_ptr<Pkt4> pkt4(new Pkt4(DHCPDISCOVER, transid));
+ if (!pkt4) {
+ isc_throw(Unexpected, "failed to create DISCOVER packet");
+ }
+ OptionBuffer buf_msg_type;
+ buf_msg_type.push_back(DHCPDISCOVER);
+ pkt4->addOption(Option::factory(Option::V4, DHO_DHCP_MESSAGE_TYPE,
+ buf_msg_type));
+ pkt4->addOption(Option::factory(Option::V4,
+ DHO_DHCP_PARAMETER_REQUEST_LIST));
+
+ setDefaults4(socket, pkt4);
pkt4->pack();
IfaceMgr::instance().send(pkt4);
}
+void
+TestControl::setDefaults4(const TestControlSocket &socket,
+ const boost::shared_ptr<Pkt4>& pkt) {
+ CommandOptions& options = CommandOptions::instance();
+ pkt->setIface(socket.getIface());
+ pkt->setLocalPort(DHCP4_CLIENT_PORT);
+ pkt->setRemotePort(DHCP4_SERVER_PORT);
+ pkt->setRemoteAddr(IOAddress(options.getServerName()));
+ pkt->setGiaddr(IOAddress(socket.getAddress()));
+ pkt->setHops(1);
+}
+
void
TestControl::updateSendDue() {
// If default constructor was called, this should not happen but
- // if somebody has changed default constructor it is better to
+ // if somebody has cw/e August 3, 2012hanged default constructor it is better to
// keep this check.
if (last_sent_.is_not_a_date_time()) {
isc_throw(Unexpected, "time of last sent packet not initialized");
/// \return name of the interface where socket is bound to.
const std::string& getIface() const { return(iface_); }
+ /// \brief Return address where socket is bound to.
+ ///
+ /// \return address where socket is bound to.
+ const asiolink::IOAddress& getAddress() const { return(addr_); }
+
private:
/// \brief Private default constructor.
///
/// socket descriptor is passed to create object.
TestControlSocket();
- /// \brief Initialize name of the interface.
+ /// \brief Initialize socket data.
///
- /// This method intializes the name of the interface where
- /// socket is bound to. This name can be later retreived by
- /// client class to set interface name in DHCP packet objects.
+ /// This method initializes members of the class that Interface
+ /// Manager holds: interface name, local address.
///
/// \throw isc::BadValue if interface for specified socket
/// descriptor does not exist.
- void initInterface();
+ void initSocketData();
- int socket_; ///< Socket descirptor.
- std::string iface_; ///< Name of the interface.
+ int socket_; ///< Socket descirptor.
+ std::string iface_; ///< Name of the interface.
+ asiolink::IOAddress addr_; ///< Address bound.
};
/// \brief Length of the Ethernet HW address (MAC) in bytes.
/// \return true if any of the exit conditions is fulfiled.
bool checkExitConditions() const;
- /// \brief Create DHCPv4 DISCOVER packet.
- ///
- /// Create instance of DHCPv4 DISCOVER packet with ethernet
- /// HW type and MAC address specified as parameter. The following
- /// DHCP options are added to the packet:
- /// - DHO_DHCP_MESSAGE_TYPE with DHCPDISCOVER message type value
- /// - DHO_DHCP_PARAMETER_REQUEST_LIST with the following options
- /// being requested from the server:
- /// - DHO_SUBNET_MASK,
- /// - DHO_BROADCAST_ADDRESS,
- /// - DHO_TIME_OFFSET,
- /// - DHO_ROUTERS,
- /// - DHO_DOMAIN_NAME,
- /// - DHO_DOMAIN_NAME_SERVERS,
- /// - DHO_HOST_NAME.
- ///
- /// \param mac_addr MAC address to be set for the packet. MAC address
- /// has to be exactly 6 octets long.
- /// \throw isc::Unexpected if failed to create new packet instance.
- /// \throw isc::BadValue if MAC address has invalid length.
- /// \return insance of the DHCPv4 DISCOVER packet.
- boost::shared_ptr<dhcp::Pkt4>
- createDiscoverPkt4(const std::vector<uint8_t>& mac_addr) const;
-
/// \brief Factory function to create generic option.
///
/// Factory function is registered using \ref LibDHCP::OptionFactoryRegister.
/// Based on this the random value is generated and added to
/// the MAC address prefix (default MAC address).
///
+ /// \throw isc::BadValue if MAC address prefix (default or specified
+ /// from the command line) has invalid size (expected 6 octets).
/// \return generated MAC address.
std::vector<uint8_t> generateMacAddress() const;
///
/// Method registers option factory functions for DHCPv4 or DHCPv6,
/// depending in whch mode test is currently running.
- void registerOptionFactories() const;
+ void registerOptionFactories() const;
+
+ /// \brief Send DHCPv4 DISCOVER message.
+ ///
+ /// Method creates and sends DHCPv4 DISCOVER message to the server
+ /// with the following options:
+ /// - MESSAGE_TYPE set to DHCPDISCOVER
+ /// - PARAMETER_REQUEST_LIST with the same list of requested options
+ /// as described in \ref factoryRequestList.
+ /// The transaction id and MAC address are randomly generated for
+ /// the message. Range of unique MAC addresses generated depends
+ /// on the number of clients specified from the command line.
+ ///
+ /// \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);
- /// \brief Start new exchange of DHCP messages.
+ /// \brief Set default DHCPv4 packet data.
///
- /// Method starts new DHCP exchange by sending new DHCPv4 DISCOVER
- /// or DHCPv6 SOLICIT packet to the server.
+ /// This method sets default data on the DHCPv4 packet:
+ /// - interface name,
+ /// - local port = 68 (DHCP client port),
+ /// - remote port = 67 (DHCP server port),
+ /// - server's address,
+ /// - GIADDR = local address where socket is bound to,
+ /// - hops = 1 (pretending that we are a relay)
///
- /// \param socket socket used to send DHCP message.
- /// \throw isc::Unexpected if failed to create or send packet
- void startExchange(const TestControlSocket& socket);
+ /// \param socket socket used to send the packet.
+ /// \param pkt packet to be configured.
+ void setDefaults4(const TestControlSocket& socket,
+ const boost::shared_ptr<dhcp::Pkt4>& pkt);
/// \brief Update due time to initiate next chunk of exchanges.
///