1 #include "snmp_util.hpp" 2 3 #include "xyz/openbmc_project/Common/error.hpp" 4 5 #include <arpa/inet.h> 6 #include <netdb.h> 7 8 #include <phosphor-logging/elog-errors.hpp> 9 #include <phosphor-logging/log.hpp> 10 11 #include <string> 12 13 namespace phosphor 14 { 15 16 using namespace phosphor::logging; 17 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 18 19 ObjectValueTree getManagedObjects(sdbusplus::bus::bus& bus, 20 const std::string& service, 21 const std::string& objPath) 22 { 23 ObjectValueTree interfaces; 24 25 auto method = bus.new_method_call(service.c_str(), objPath.c_str(), 26 "org.freedesktop.DBus.ObjectManager", 27 "GetManagedObjects"); 28 29 auto reply = bus.call(method); 30 31 if (reply.is_method_error()) 32 { 33 log<level::ERR>("Failed to get managed objects", 34 entry("PATH=%s", objPath.c_str())); 35 elog<InternalFailure>(); 36 } 37 38 reply.read(interfaces); 39 return interfaces; 40 } 41 42 namespace network 43 { 44 45 std::string resolveAddress(const std::string& address) 46 { 47 addrinfo hints{}; 48 addrinfo* addr = nullptr; 49 50 hints.ai_family = AF_UNSPEC; 51 hints.ai_socktype = SOCK_STREAM; 52 hints.ai_flags |= AI_CANONNAME; 53 54 auto result = getaddrinfo(address.c_str(), NULL, &hints, &addr); 55 if (result) 56 { 57 log<level::ERR>("getaddrinfo failed", 58 entry("ADDRESS=%s", address.c_str())); 59 elog<InternalFailure>(); 60 } 61 62 AddrPtr addrPtr{addr}; 63 addr = nullptr; 64 65 char ipaddress[INET6_ADDRSTRLEN]{0}; 66 result = getnameinfo(addrPtr->ai_addr, addrPtr->ai_addrlen, ipaddress, 67 sizeof(ipaddress), NULL, 0, NI_NUMERICHOST); 68 if (result) 69 { 70 log<level::ERR>("getnameinfo failed", 71 entry("ADDRESS=%s", address.c_str())); 72 elog<InternalFailure>(); 73 } 74 75 unsigned char buf[sizeof(struct in6_addr)]; 76 int isValid = inet_pton(AF_INET, ipaddress, buf); 77 if (isValid < 0) 78 { 79 log<level::ERR>("Invalid address", 80 entry("ADDRESS=%s", address.c_str())); 81 elog<InternalFailure>(); 82 } 83 if (isValid == 0) 84 { 85 int isValid6 = inet_pton(AF_INET6, ipaddress, buf); 86 if (isValid6 < 1) 87 { 88 log<level::ERR>("Invalid address", 89 entry("ADDRESS=%s", address.c_str())); 90 elog<InternalFailure>(); 91 } 92 } 93 94 return ipaddress; 95 } 96 97 namespace snmp 98 { 99 100 static constexpr auto busName = "xyz.openbmc_project.Network.SNMP"; 101 static constexpr auto root = "/xyz/openbmc_project/network/snmp/manager"; 102 static constexpr auto clientIntf = "xyz.openbmc_project.Network.Client"; 103 104 /** @brief Gets the sdbus object for this process. 105 * @return the bus object. 106 */ 107 static auto& getBus() 108 { 109 static auto bus = sdbusplus::bus::new_default(); 110 return bus; 111 } 112 113 std::vector<std::string> getManagers() 114 { 115 std::vector<std::string> managers; 116 auto& bus = getBus(); 117 auto objTree = phosphor::getManagedObjects(bus, busName, root); 118 for (const auto& objIter : objTree) 119 { 120 try 121 { 122 auto& intfMap = objIter.second; 123 auto& snmpClientProps = intfMap.at(clientIntf); 124 auto& address = 125 std::get<std::string>(snmpClientProps.at("Address")); 126 auto& port = std::get<uint16_t>(snmpClientProps.at("Port")); 127 auto ipaddress = phosphor::network::resolveAddress(address); 128 auto mgr = std::move(ipaddress); 129 if (port > 0) 130 { 131 mgr += ":"; 132 mgr += std::to_string(port); 133 } 134 managers.push_back(mgr); 135 } 136 catch (const std::exception& e) 137 { 138 log<level::ERR>(e.what()); 139 } 140 } 141 return managers; 142 } 143 144 } // namespace snmp 145 } // namespace network 146 } // namespace phosphor 147