1 #include "config.h" 2 3 #include "snmp_conf_manager.hpp" 4 5 #include "snmp_serialize.hpp" 6 #include "snmp_util.hpp" 7 #include "xyz/openbmc_project/Common/error.hpp" 8 9 #include <arpa/inet.h> 10 11 #include <phosphor-logging/elog-errors.hpp> 12 #include <phosphor-logging/log.hpp> 13 14 #include <filesystem> 15 16 namespace phosphor 17 { 18 namespace network 19 { 20 namespace snmp 21 { 22 23 using namespace phosphor::logging; 24 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 25 using Argument = xyz::openbmc_project::Common::InvalidArgument; 26 27 ConfManager::ConfManager(sdbusplus::bus::bus& bus, const char* objPath) : 28 details::CreateIface(bus, objPath, 29 details::CreateIface::action::defer_emit), 30 dbusPersistentLocation(SNMP_CONF_PERSIST_PATH), bus(bus), 31 objectPath(objPath) 32 {} 33 34 std::string ConfManager::client(std::string address, uint16_t port) 35 { 36 // will throw exception if it is already configured. 37 checkClientConfigured(address, port); 38 39 lastClientId++; 40 try 41 { 42 // just to check whether given address is valid or not. 43 resolveAddress(address); 44 } 45 catch (const InternalFailure& e) 46 { 47 log<level::ERR>("Not a valid address"), 48 entry("ADDRESS=%s", address.c_str()); 49 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Address"), 50 Argument::ARGUMENT_VALUE(address.c_str())); 51 } 52 53 // create the D-Bus object 54 std::filesystem::path objPath; 55 objPath /= objectPath; 56 objPath /= std::to_string(lastClientId); 57 58 auto client = std::make_unique<phosphor::network::snmp::Client>( 59 bus, objPath.string().c_str(), *this, address, port); 60 61 // save the D-Bus object 62 serialize(lastClientId, *client, dbusPersistentLocation); 63 64 this->clients.emplace(lastClientId, std::move(client)); 65 return objPath.string(); 66 } 67 68 void ConfManager::checkClientConfigured(const std::string& address, 69 uint16_t port) 70 { 71 if (address.empty()) 72 { 73 log<level::ERR>("Invalid address"); 74 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ADDRESS"), 75 Argument::ARGUMENT_VALUE(address.c_str())); 76 } 77 78 for (const auto& val : clients) 79 { 80 if (val.second.get()->address() == address && 81 val.second.get()->port() == port) 82 { 83 log<level::ERR>("Client already exist"); 84 // TODO Add the error(Object already exist) in the D-Bus interface 85 // then make the change here,meanwhile send the Internal Failure. 86 elog<InvalidArgument>( 87 Argument::ARGUMENT_NAME("ADDRESS"), 88 Argument::ARGUMENT_VALUE("Client already exist.")); 89 } 90 } 91 } 92 93 void ConfManager::deleteSNMPClient(Id id) 94 { 95 auto it = clients.find(id); 96 if (it == clients.end()) 97 { 98 log<level::ERR>("Unable to delete the snmp client.", 99 entry("ID=%d", id)); 100 return; 101 } 102 103 std::error_code ec; 104 // remove the persistent file 105 fs::path fileName = dbusPersistentLocation; 106 fileName /= std::to_string(id); 107 108 if (fs::exists(fileName)) 109 { 110 if (!fs::remove(fileName, ec)) 111 { 112 log<level::ERR>("Unable to delete the file", 113 entry("FILE=%s", fileName.c_str()), 114 entry("ERROR=%d", ec.value())); 115 } 116 } 117 else 118 { 119 log<level::ERR>("File doesn't exist", 120 entry("FILE=%s", fileName.c_str())); 121 } 122 // remove the D-Bus Object. 123 this->clients.erase(it); 124 } 125 126 void ConfManager::restoreClients() 127 { 128 if (!fs::exists(dbusPersistentLocation) || 129 fs::is_empty(dbusPersistentLocation)) 130 { 131 return; 132 } 133 134 for (auto& confFile : 135 fs::recursive_directory_iterator(dbusPersistentLocation)) 136 { 137 if (!fs::is_regular_file(confFile)) 138 { 139 continue; 140 } 141 142 auto managerID = confFile.path().filename().string(); 143 Id idNum = std::stol(managerID); 144 145 fs::path objPath = objectPath; 146 objPath /= managerID; 147 auto manager = 148 std::make_unique<Client>(bus, objPath.string().c_str(), *this); 149 if (deserialize(confFile.path(), *manager)) 150 { 151 manager->emit_object_added(); 152 this->clients.emplace(idNum, std::move(manager)); 153 if (idNum > lastClientId) 154 { 155 lastClientId = idNum; 156 } 157 } 158 } 159 } 160 161 } // namespace snmp 162 } // namespace network 163 } // namespace phosphor 164