11dc9178dSRatan Gupta #include "config.h" 21dc9178dSRatan Gupta #include "snmp_conf_manager.hpp" 3212f53e8SRatan Gupta #include "snmp_serialize.hpp" 4213517baSRatan Gupta #include "snmp_util.hpp" 5213517baSRatan Gupta #include "xyz/openbmc_project/Common/error.hpp" 6213517baSRatan Gupta 7213517baSRatan Gupta #include <phosphor-logging/elog-errors.hpp> 81dc9178dSRatan Gupta #include <phosphor-logging/log.hpp> 91dc9178dSRatan Gupta 101dc9178dSRatan Gupta #include <experimental/filesystem> 111dc9178dSRatan Gupta 12213517baSRatan Gupta #include <arpa/inet.h> 13213517baSRatan Gupta 141dc9178dSRatan Gupta namespace phosphor 151dc9178dSRatan Gupta { 161dc9178dSRatan Gupta namespace network 171dc9178dSRatan Gupta { 181dc9178dSRatan Gupta namespace snmp 191dc9178dSRatan Gupta { 201dc9178dSRatan Gupta 211dc9178dSRatan Gupta using namespace phosphor::logging; 22213517baSRatan Gupta using namespace sdbusplus::xyz::openbmc_project::Common::Error; 23213517baSRatan Gupta using Argument = xyz::openbmc_project::Common::InvalidArgument; 241dc9178dSRatan Gupta 251dc9178dSRatan Gupta ConfManager::ConfManager(sdbusplus::bus::bus& bus, const char* objPath) : 26212f53e8SRatan Gupta details::CreateIface(bus, objPath, true), 27212f53e8SRatan Gupta dbusPersistentLocation(SNMP_CONF_PERSIST_PATH), bus(bus), 28212f53e8SRatan Gupta objectPath(objPath) 291dc9178dSRatan Gupta { 301dc9178dSRatan Gupta } 311dc9178dSRatan Gupta 321dc9178dSRatan Gupta void ConfManager::client(std::string address, uint16_t port) 331dc9178dSRatan Gupta { 341dc9178dSRatan Gupta auto clientEntry = this->clients.find(address); 35213517baSRatan Gupta if (clientEntry != this->clients.end()) 361dc9178dSRatan Gupta { 37213517baSRatan Gupta // address is already there 38213517baSRatan Gupta return; 39213517baSRatan Gupta } 40213517baSRatan Gupta try 41213517baSRatan Gupta { 42213517baSRatan Gupta // just to check whether given address is valid or not. 43213517baSRatan Gupta resolveAddress(address); 44213517baSRatan Gupta } 45213517baSRatan Gupta catch (InternalFailure& e) 46213517baSRatan Gupta { 47213517baSRatan Gupta log<level::ERR>("Not a valid address"), 48213517baSRatan Gupta entry("ADDRESS=%s", address.c_str()); 49213517baSRatan Gupta elog<InvalidArgument>(Argument::ARGUMENT_NAME("Address"), 50213517baSRatan Gupta Argument::ARGUMENT_VALUE(address.c_str())); 51213517baSRatan Gupta } 52213517baSRatan Gupta // create the D-Bus object 531dc9178dSRatan Gupta std::experimental::filesystem::path objPath; 541dc9178dSRatan Gupta objPath /= objectPath; 551dc9178dSRatan Gupta objPath /= generateId(address, port); 561dc9178dSRatan Gupta 57212f53e8SRatan Gupta auto client = std::make_unique<phosphor::network::snmp::Client>( 58212f53e8SRatan Gupta bus, objPath.string().c_str(), *this, address, port); 59212f53e8SRatan Gupta // save the D-Bus object 60212f53e8SRatan Gupta serialize(*client, dbusPersistentLocation); 61212f53e8SRatan Gupta 62212f53e8SRatan Gupta this->clients.emplace(address, std::move(client)); 631dc9178dSRatan Gupta } 641dc9178dSRatan Gupta 651dc9178dSRatan Gupta std::string ConfManager::generateId(const std::string& address, uint16_t port) 661dc9178dSRatan Gupta { 671dc9178dSRatan Gupta std::stringstream hexId; 681dc9178dSRatan Gupta std::string hashString = address; 691dc9178dSRatan Gupta hashString += std::to_string(port); 701dc9178dSRatan Gupta 711dc9178dSRatan Gupta // Only want 8 hex digits. 721dc9178dSRatan Gupta hexId << std::hex << ((std::hash<std::string>{}(hashString)) & 0xFFFFFFFF); 731dc9178dSRatan Gupta return hexId.str(); 741dc9178dSRatan Gupta } 751dc9178dSRatan Gupta 761dc9178dSRatan Gupta void ConfManager::deleteSNMPClient(const std::string& address) 771dc9178dSRatan Gupta { 781dc9178dSRatan Gupta auto it = clients.find(address); 791dc9178dSRatan Gupta if (it == clients.end()) 801dc9178dSRatan Gupta { 811dc9178dSRatan Gupta log<level::ERR>("Unable to delete the snmp client.", 821dc9178dSRatan Gupta entry("ADDRESS=%s", address.c_str())); 831dc9178dSRatan Gupta return; 841dc9178dSRatan Gupta } 85212f53e8SRatan Gupta 86212f53e8SRatan Gupta std::error_code ec; 87212f53e8SRatan Gupta // remove the persistent file 88212f53e8SRatan Gupta fs::path fileName = dbusPersistentLocation; 89212f53e8SRatan Gupta fileName /= 90*f3fac222SGunnar Mills it->second->address() + SEPARATOR + std::to_string(it->second->port()); 91212f53e8SRatan Gupta 92212f53e8SRatan Gupta if (fs::exists(fileName)) 93212f53e8SRatan Gupta { 94212f53e8SRatan Gupta if (!fs::remove(fileName, ec)) 95212f53e8SRatan Gupta { 96212f53e8SRatan Gupta log<level::ERR>("Unable to delete the file", 97212f53e8SRatan Gupta entry("FILE=%s", fileName.c_str()), 98212f53e8SRatan Gupta entry("ERROR=%d", ec.value())); 99212f53e8SRatan Gupta } 100212f53e8SRatan Gupta } 101212f53e8SRatan Gupta else 102212f53e8SRatan Gupta { 103212f53e8SRatan Gupta log<level::ERR>("File doesn't exist", 104212f53e8SRatan Gupta entry("FILE=%s", fileName.c_str())); 105212f53e8SRatan Gupta } 106212f53e8SRatan Gupta // remove the D-Bus Object. 1071dc9178dSRatan Gupta this->clients.erase(it); 1081dc9178dSRatan Gupta } 1091dc9178dSRatan Gupta 110212f53e8SRatan Gupta void ConfManager::restoreClients() 111212f53e8SRatan Gupta { 112212f53e8SRatan Gupta if (!fs::exists(dbusPersistentLocation) || 113212f53e8SRatan Gupta fs::is_empty(dbusPersistentLocation)) 114212f53e8SRatan Gupta { 115212f53e8SRatan Gupta return; 116212f53e8SRatan Gupta } 117212f53e8SRatan Gupta 118212f53e8SRatan Gupta for (auto& confFile : 119212f53e8SRatan Gupta fs::recursive_directory_iterator(dbusPersistentLocation)) 120212f53e8SRatan Gupta { 121212f53e8SRatan Gupta if (!fs::is_regular_file(confFile)) 122212f53e8SRatan Gupta { 123212f53e8SRatan Gupta continue; 124212f53e8SRatan Gupta } 125212f53e8SRatan Gupta 126212f53e8SRatan Gupta auto managerID = confFile.path().filename().string(); 127*f3fac222SGunnar Mills auto pos = managerID.find(SEPARATOR); 128212f53e8SRatan Gupta auto ipaddress = managerID.substr(0, pos); 129212f53e8SRatan Gupta auto port_str = managerID.substr(pos + 1); 130212f53e8SRatan Gupta uint16_t port = stoi(port_str, nullptr); 131212f53e8SRatan Gupta 132212f53e8SRatan Gupta fs::path objPath = objectPath; 133212f53e8SRatan Gupta objPath /= generateId(ipaddress, port); 134212f53e8SRatan Gupta auto manager = 135212f53e8SRatan Gupta std::make_unique<Client>(bus, objPath.string().c_str(), *this); 136212f53e8SRatan Gupta if (deserialize(confFile.path(), *manager)) 137212f53e8SRatan Gupta { 138212f53e8SRatan Gupta manager->emit_object_added(); 139212f53e8SRatan Gupta this->clients.emplace(ipaddress, std::move(manager)); 140212f53e8SRatan Gupta } 141212f53e8SRatan Gupta } 142212f53e8SRatan Gupta } 143212f53e8SRatan Gupta 1441dc9178dSRatan Gupta } // namespace snmp 1451dc9178dSRatan Gupta } // namespace network 1461dc9178dSRatan Gupta } // namespace phosphor 147