#include "config.h" #include "snmp_conf_manager.hpp" #include "snmp_serialize.hpp" #include "snmp_util.hpp" #include "xyz/openbmc_project/Common/error.hpp" #include #include #include #include namespace phosphor { namespace network { namespace snmp { using namespace phosphor::logging; using namespace sdbusplus::xyz::openbmc_project::Common::Error; using Argument = xyz::openbmc_project::Common::InvalidArgument; ConfManager::ConfManager(sdbusplus::bus::bus& bus, const char* objPath) : details::CreateIface(bus, objPath, true), dbusPersistentLocation(SNMP_CONF_PERSIST_PATH), bus(bus), objectPath(objPath) { } void ConfManager::client(std::string address, uint16_t port) { auto clientEntry = this->clients.find(address); if (clientEntry != this->clients.end()) { // address is already there return; } try { // just to check whether given address is valid or not. resolveAddress(address); } catch (InternalFailure& e) { log("Not a valid address"), entry("ADDRESS=%s", address.c_str()); elog(Argument::ARGUMENT_NAME("Address"), Argument::ARGUMENT_VALUE(address.c_str())); } // create the D-Bus object std::experimental::filesystem::path objPath; objPath /= objectPath; objPath /= generateId(address, port); auto client = std::make_unique( bus, objPath.string().c_str(), *this, address, port); // save the D-Bus object serialize(*client, dbusPersistentLocation); this->clients.emplace(address, std::move(client)); } std::string ConfManager::generateId(const std::string& address, uint16_t port) { std::stringstream hexId; std::string hashString = address; hashString += std::to_string(port); // Only want 8 hex digits. hexId << std::hex << ((std::hash{}(hashString)) & 0xFFFFFFFF); return hexId.str(); } void ConfManager::deleteSNMPClient(const std::string& address) { auto it = clients.find(address); if (it == clients.end()) { log("Unable to delete the snmp client.", entry("ADDRESS=%s", address.c_str())); return; } std::error_code ec; // remove the persistent file fs::path fileName = dbusPersistentLocation; fileName /= it->second->address() + SEPARATOR + std::to_string(it->second->port()); if (fs::exists(fileName)) { if (!fs::remove(fileName, ec)) { log("Unable to delete the file", entry("FILE=%s", fileName.c_str()), entry("ERROR=%d", ec.value())); } } else { log("File doesn't exist", entry("FILE=%s", fileName.c_str())); } // remove the D-Bus Object. this->clients.erase(it); } void ConfManager::restoreClients() { if (!fs::exists(dbusPersistentLocation) || fs::is_empty(dbusPersistentLocation)) { return; } for (auto& confFile : fs::recursive_directory_iterator(dbusPersistentLocation)) { if (!fs::is_regular_file(confFile)) { continue; } auto managerID = confFile.path().filename().string(); auto pos = managerID.find(SEPARATOR); auto ipaddress = managerID.substr(0, pos); auto port_str = managerID.substr(pos + 1); uint16_t port = stoi(port_str, nullptr); fs::path objPath = objectPath; objPath /= generateId(ipaddress, port); auto manager = std::make_unique(bus, objPath.string().c_str(), *this); if (deserialize(confFile.path(), *manager)) { manager->emit_object_added(); this->clients.emplace(ipaddress, std::move(manager)); } } } } // namespace snmp } // namespace network } // namespace phosphor