blob: a215ef453c40f4663a32b557bb6726fc5e61b1b4 [file] [log] [blame]
Ratan Gupta1dc91782018-04-19 16:47:12 +05301#include "config.h"
2#include "snmp_conf_manager.hpp"
Ratan Gupta212f53e2018-04-30 17:28:05 +05303#include "snmp_serialize.hpp"
Ratan Gupta213517b2018-04-28 13:41:09 +05304#include "snmp_util.hpp"
5#include "xyz/openbmc_project/Common/error.hpp"
6
7#include <phosphor-logging/elog-errors.hpp>
Ratan Gupta1dc91782018-04-19 16:47:12 +05308#include <phosphor-logging/log.hpp>
9
10#include <experimental/filesystem>
11
Ratan Gupta213517b2018-04-28 13:41:09 +053012#include <arpa/inet.h>
13
Ratan Gupta1dc91782018-04-19 16:47:12 +053014namespace phosphor
15{
16namespace network
17{
18namespace snmp
19{
20
21using namespace phosphor::logging;
Ratan Gupta213517b2018-04-28 13:41:09 +053022using namespace sdbusplus::xyz::openbmc_project::Common::Error;
23using Argument = xyz::openbmc_project::Common::InvalidArgument;
Ratan Gupta1dc91782018-04-19 16:47:12 +053024
25ConfManager::ConfManager(sdbusplus::bus::bus& bus, const char* objPath) :
Ratan Gupta212f53e2018-04-30 17:28:05 +053026 details::CreateIface(bus, objPath, true),
27 dbusPersistentLocation(SNMP_CONF_PERSIST_PATH), bus(bus),
28 objectPath(objPath)
Ratan Gupta1dc91782018-04-19 16:47:12 +053029{
30}
31
Ratan Guptad84e3272018-09-06 16:52:52 +053032std::string ConfManager::client(std::string address, uint16_t port)
Ratan Gupta1dc91782018-04-19 16:47:12 +053033{
34 auto clientEntry = this->clients.find(address);
Ratan Gupta213517b2018-04-28 13:41:09 +053035 if (clientEntry != this->clients.end())
Ratan Gupta1dc91782018-04-19 16:47:12 +053036 {
Ratan Guptad84e3272018-09-06 16:52:52 +053037 log<level::ERR>("Client already configured"),
38 entry("ADDRESS=%s", address.c_str());
39 elog<InternalFailure>();
Ratan Gupta1dc91782018-04-19 16:47:12 +053040 }
Ratan Gupta213517b2018-04-28 13:41:09 +053041 try
42 {
43 // just to check whether given address is valid or not.
44 resolveAddress(address);
45 }
46 catch (InternalFailure& e)
47 {
48 log<level::ERR>("Not a valid address"),
49 entry("ADDRESS=%s", address.c_str());
50 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Address"),
51 Argument::ARGUMENT_VALUE(address.c_str()));
52 }
Ratan Guptad84e3272018-09-06 16:52:52 +053053
Ratan Gupta213517b2018-04-28 13:41:09 +053054 std::experimental::filesystem::path objPath;
55 objPath /= objectPath;
56 objPath /= generateId(address, port);
Ratan Guptad84e3272018-09-06 16:52:52 +053057 // create the D-Bus object
Ratan Gupta212f53e2018-04-30 17:28:05 +053058 auto client = std::make_unique<phosphor::network::snmp::Client>(
59 bus, objPath.string().c_str(), *this, address, port);
60 // save the D-Bus object
61 serialize(*client, dbusPersistentLocation);
62
63 this->clients.emplace(address, std::move(client));
Ratan Guptad84e3272018-09-06 16:52:52 +053064 return objPath.string();
Ratan Gupta1dc91782018-04-19 16:47:12 +053065}
66
67std::string ConfManager::generateId(const std::string& address, uint16_t port)
68{
69 std::stringstream hexId;
70 std::string hashString = address;
71 hashString += std::to_string(port);
72
73 // Only want 8 hex digits.
74 hexId << std::hex << ((std::hash<std::string>{}(hashString)) & 0xFFFFFFFF);
75 return hexId.str();
76}
77
78void ConfManager::deleteSNMPClient(const std::string& address)
79{
80 auto it = clients.find(address);
81 if (it == clients.end())
82 {
83 log<level::ERR>("Unable to delete the snmp client.",
84 entry("ADDRESS=%s", address.c_str()));
85 return;
86 }
Ratan Gupta212f53e2018-04-30 17:28:05 +053087
88 std::error_code ec;
89 // remove the persistent file
90 fs::path fileName = dbusPersistentLocation;
91 fileName /=
Gunnar Millsf3fac222018-08-14 11:59:10 -050092 it->second->address() + SEPARATOR + std::to_string(it->second->port());
Ratan Gupta212f53e2018-04-30 17:28:05 +053093
94 if (fs::exists(fileName))
95 {
96 if (!fs::remove(fileName, ec))
97 {
98 log<level::ERR>("Unable to delete the file",
99 entry("FILE=%s", fileName.c_str()),
100 entry("ERROR=%d", ec.value()));
101 }
102 }
103 else
104 {
105 log<level::ERR>("File doesn't exist",
106 entry("FILE=%s", fileName.c_str()));
107 }
108 // remove the D-Bus Object.
Ratan Gupta1dc91782018-04-19 16:47:12 +0530109 this->clients.erase(it);
110}
111
Ratan Gupta212f53e2018-04-30 17:28:05 +0530112void ConfManager::restoreClients()
113{
114 if (!fs::exists(dbusPersistentLocation) ||
115 fs::is_empty(dbusPersistentLocation))
116 {
117 return;
118 }
119
120 for (auto& confFile :
121 fs::recursive_directory_iterator(dbusPersistentLocation))
122 {
123 if (!fs::is_regular_file(confFile))
124 {
125 continue;
126 }
127
128 auto managerID = confFile.path().filename().string();
Gunnar Millsf3fac222018-08-14 11:59:10 -0500129 auto pos = managerID.find(SEPARATOR);
Ratan Gupta212f53e2018-04-30 17:28:05 +0530130 auto ipaddress = managerID.substr(0, pos);
131 auto port_str = managerID.substr(pos + 1);
132 uint16_t port = stoi(port_str, nullptr);
133
134 fs::path objPath = objectPath;
135 objPath /= generateId(ipaddress, port);
136 auto manager =
137 std::make_unique<Client>(bus, objPath.string().c_str(), *this);
138 if (deserialize(confFile.path(), *manager))
139 {
140 manager->emit_object_added();
141 this->clients.emplace(ipaddress, std::move(manager));
142 }
143 }
144}
145
Ratan Gupta1dc91782018-04-19 16:47:12 +0530146} // namespace snmp
147} // namespace network
148} // namespace phosphor