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 32d84e327dSRatan Gupta std::string ConfManager::client(std::string address, uint16_t port) 331dc9178dSRatan Gupta { 34*9c4fed6dSRatan Gupta // will throw exception if it is already configured. 35*9c4fed6dSRatan Gupta checkClientConfigured(address, port); 36a7ff3850SRatan Gupta 37a7ff3850SRatan Gupta lastClientId++; 38213517baSRatan Gupta try 39213517baSRatan Gupta { 40213517baSRatan Gupta // just to check whether given address is valid or not. 41213517baSRatan Gupta resolveAddress(address); 42213517baSRatan Gupta } 43213517baSRatan Gupta catch (InternalFailure& e) 44213517baSRatan Gupta { 45213517baSRatan Gupta log<level::ERR>("Not a valid address"), 46213517baSRatan Gupta entry("ADDRESS=%s", address.c_str()); 47213517baSRatan Gupta elog<InvalidArgument>(Argument::ARGUMENT_NAME("Address"), 48213517baSRatan Gupta Argument::ARGUMENT_VALUE(address.c_str())); 49213517baSRatan Gupta } 50d84e327dSRatan Gupta 51a7ff3850SRatan Gupta // create the D-Bus object 521dc9178dSRatan Gupta std::experimental::filesystem::path objPath; 531dc9178dSRatan Gupta objPath /= objectPath; 54a7ff3850SRatan Gupta objPath /= std::to_string(lastClientId); 55a7ff3850SRatan Gupta 56212f53e8SRatan Gupta auto client = std::make_unique<phosphor::network::snmp::Client>( 57212f53e8SRatan Gupta bus, objPath.string().c_str(), *this, address, port); 58212f53e8SRatan Gupta 59a7ff3850SRatan Gupta // save the D-Bus object 60a7ff3850SRatan Gupta serialize(lastClientId, *client, dbusPersistentLocation); 61a7ff3850SRatan Gupta 62a7ff3850SRatan Gupta this->clients.emplace(lastClientId, std::move(client)); 63d84e327dSRatan Gupta return objPath.string(); 641dc9178dSRatan Gupta } 651dc9178dSRatan Gupta 66*9c4fed6dSRatan Gupta void ConfManager::checkClientConfigured(const std::string& address, 67*9c4fed6dSRatan Gupta uint16_t port) 68*9c4fed6dSRatan Gupta { 69*9c4fed6dSRatan Gupta if (address.empty()) 70*9c4fed6dSRatan Gupta { 71*9c4fed6dSRatan Gupta log<level::ERR>("Invalid address"); 72*9c4fed6dSRatan Gupta elog<InvalidArgument>(Argument::ARGUMENT_NAME("ADDRESS"), 73*9c4fed6dSRatan Gupta Argument::ARGUMENT_VALUE(address.c_str())); 74*9c4fed6dSRatan Gupta } 75*9c4fed6dSRatan Gupta 76*9c4fed6dSRatan Gupta for (const auto& val : clients) 77*9c4fed6dSRatan Gupta { 78*9c4fed6dSRatan Gupta if (val.second.get()->address() == address && 79*9c4fed6dSRatan Gupta val.second.get()->port() == port) 80*9c4fed6dSRatan Gupta { 81*9c4fed6dSRatan Gupta log<level::ERR>("Client already exist"); 82*9c4fed6dSRatan Gupta // TODO Add the error(Object already exist) in the D-Bus interface 83*9c4fed6dSRatan Gupta // then make the change here,meanwhile send the Internal Failure. 84*9c4fed6dSRatan Gupta elog<InvalidArgument>( 85*9c4fed6dSRatan Gupta Argument::ARGUMENT_NAME("ADDRESS"), 86*9c4fed6dSRatan Gupta Argument::ARGUMENT_VALUE("Client already exist.")); 87*9c4fed6dSRatan Gupta } 88*9c4fed6dSRatan Gupta } 89*9c4fed6dSRatan Gupta } 90*9c4fed6dSRatan Gupta 91a7ff3850SRatan Gupta void ConfManager::deleteSNMPClient(Id id) 921dc9178dSRatan Gupta { 93a7ff3850SRatan Gupta auto it = clients.find(id); 941dc9178dSRatan Gupta if (it == clients.end()) 951dc9178dSRatan Gupta { 961dc9178dSRatan Gupta log<level::ERR>("Unable to delete the snmp client.", 97a7ff3850SRatan Gupta entry("ID=%d", id)); 981dc9178dSRatan Gupta return; 991dc9178dSRatan Gupta } 100212f53e8SRatan Gupta 101212f53e8SRatan Gupta std::error_code ec; 102212f53e8SRatan Gupta // remove the persistent file 103212f53e8SRatan Gupta fs::path fileName = dbusPersistentLocation; 104a7ff3850SRatan Gupta fileName /= std::to_string(id); 105212f53e8SRatan Gupta 106212f53e8SRatan Gupta if (fs::exists(fileName)) 107212f53e8SRatan Gupta { 108212f53e8SRatan Gupta if (!fs::remove(fileName, ec)) 109212f53e8SRatan Gupta { 110212f53e8SRatan Gupta log<level::ERR>("Unable to delete the file", 111212f53e8SRatan Gupta entry("FILE=%s", fileName.c_str()), 112212f53e8SRatan Gupta entry("ERROR=%d", ec.value())); 113212f53e8SRatan Gupta } 114212f53e8SRatan Gupta } 115212f53e8SRatan Gupta else 116212f53e8SRatan Gupta { 117212f53e8SRatan Gupta log<level::ERR>("File doesn't exist", 118212f53e8SRatan Gupta entry("FILE=%s", fileName.c_str())); 119212f53e8SRatan Gupta } 120212f53e8SRatan Gupta // remove the D-Bus Object. 1211dc9178dSRatan Gupta this->clients.erase(it); 1221dc9178dSRatan Gupta } 1231dc9178dSRatan Gupta 124212f53e8SRatan Gupta void ConfManager::restoreClients() 125212f53e8SRatan Gupta { 126212f53e8SRatan Gupta if (!fs::exists(dbusPersistentLocation) || 127212f53e8SRatan Gupta fs::is_empty(dbusPersistentLocation)) 128212f53e8SRatan Gupta { 129212f53e8SRatan Gupta return; 130212f53e8SRatan Gupta } 131212f53e8SRatan Gupta 132212f53e8SRatan Gupta for (auto& confFile : 133212f53e8SRatan Gupta fs::recursive_directory_iterator(dbusPersistentLocation)) 134212f53e8SRatan Gupta { 135212f53e8SRatan Gupta if (!fs::is_regular_file(confFile)) 136212f53e8SRatan Gupta { 137212f53e8SRatan Gupta continue; 138212f53e8SRatan Gupta } 139212f53e8SRatan Gupta 140212f53e8SRatan Gupta auto managerID = confFile.path().filename().string(); 141a7ff3850SRatan Gupta Id idNum = std::stol(managerID); 142212f53e8SRatan Gupta 143212f53e8SRatan Gupta fs::path objPath = objectPath; 144a7ff3850SRatan Gupta objPath /= managerID; 145212f53e8SRatan Gupta auto manager = 146212f53e8SRatan Gupta std::make_unique<Client>(bus, objPath.string().c_str(), *this); 147212f53e8SRatan Gupta if (deserialize(confFile.path(), *manager)) 148212f53e8SRatan Gupta { 149212f53e8SRatan Gupta manager->emit_object_added(); 150a7ff3850SRatan Gupta this->clients.emplace(idNum, std::move(manager)); 151a7ff3850SRatan Gupta if (idNum > lastClientId) 152a7ff3850SRatan Gupta { 153a7ff3850SRatan Gupta lastClientId = idNum; 154a7ff3850SRatan Gupta } 155212f53e8SRatan Gupta } 156212f53e8SRatan Gupta } 157212f53e8SRatan Gupta } 158212f53e8SRatan Gupta 1591dc9178dSRatan Gupta } // namespace snmp 1601dc9178dSRatan Gupta } // namespace network 1611dc9178dSRatan Gupta } // namespace phosphor 162