170141561SBorawski.Lukasz /* 270141561SBorawski.Lukasz // Copyright (c) 2018 Intel Corporation 370141561SBorawski.Lukasz // 470141561SBorawski.Lukasz // Licensed under the Apache License, Version 2.0 (the "License"); 570141561SBorawski.Lukasz // you may not use this file except in compliance with the License. 670141561SBorawski.Lukasz // You may obtain a copy of the License at 770141561SBorawski.Lukasz // 870141561SBorawski.Lukasz // http://www.apache.org/licenses/LICENSE-2.0 970141561SBorawski.Lukasz // 1070141561SBorawski.Lukasz // Unless required by applicable law or agreed to in writing, software 1170141561SBorawski.Lukasz // distributed under the License is distributed on an "AS IS" BASIS, 1270141561SBorawski.Lukasz // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1370141561SBorawski.Lukasz // See the License for the specific language governing permissions and 1470141561SBorawski.Lukasz // limitations under the License. 1570141561SBorawski.Lukasz */ 1670141561SBorawski.Lukasz #pragma once 1770141561SBorawski.Lukasz 183a8a0088SKowalski, Kamil #include "error_messages.hpp" 1970141561SBorawski.Lukasz #include "node.hpp" 2070141561SBorawski.Lukasz 2170141561SBorawski.Lukasz namespace redfish { 2270141561SBorawski.Lukasz 233a8a0088SKowalski, Kamil enum NetworkProtocolUnitStructFields { 243a8a0088SKowalski, Kamil NET_PROTO_UNIT_NAME, 253a8a0088SKowalski, Kamil NET_PROTO_UNIT_DESC, 263a8a0088SKowalski, Kamil NET_PROTO_UNIT_LOAD_STATE, 273a8a0088SKowalski, Kamil NET_PROTO_UNIT_ACTIVE_STATE, 283a8a0088SKowalski, Kamil NET_PROTO_UNIT_SUB_STATE, 293a8a0088SKowalski, Kamil NET_PROTO_UNIT_DEVICE, 303a8a0088SKowalski, Kamil NET_PROTO_UNIT_OBJ_PATH, 313a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_0, 323a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_EMPTY, 333a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_ROOT_PATH 343a8a0088SKowalski, Kamil }; 353a8a0088SKowalski, Kamil 363a8a0088SKowalski, Kamil enum NetworkProtocolListenResponseElements { 373a8a0088SKowalski, Kamil NET_PROTO_LISTEN_TYPE, 383a8a0088SKowalski, Kamil NET_PROTO_LISTEN_STREAM 393a8a0088SKowalski, Kamil }; 403a8a0088SKowalski, Kamil 413a8a0088SKowalski, Kamil /** 423a8a0088SKowalski, Kamil * @brief D-Bus Unit structure returned in array from ListUnits Method 433a8a0088SKowalski, Kamil */ 443a8a0088SKowalski, Kamil using UnitStruct = 453a8a0088SKowalski, Kamil std::tuple<std::string, std::string, std::string, std::string, std::string, 463a8a0088SKowalski, Kamil std::string, sdbusplus::message::object_path, uint32_t, 473a8a0088SKowalski, Kamil std::string, sdbusplus::message::object_path>; 483a8a0088SKowalski, Kamil 493a8a0088SKowalski, Kamil struct ServiceConfiguration { 50*865fbb75SEd Tanous const char* serviceName; 51*865fbb75SEd Tanous const char* socketPath; 523a8a0088SKowalski, Kamil }; 533a8a0088SKowalski, Kamil 54*865fbb75SEd Tanous const static boost::container::flat_map<const char*, ServiceConfiguration> 55*865fbb75SEd Tanous protocolToDBus{ 56*865fbb75SEd Tanous {"SSH", 57*865fbb75SEd Tanous {"dropbear.service", 58*865fbb75SEd Tanous "/org/freedesktop/systemd1/unit/dropbear_2esocket"}}, 59*865fbb75SEd Tanous {"HTTPS", 60*865fbb75SEd Tanous {"phosphor-gevent.service", 61*865fbb75SEd Tanous "/org/freedesktop/systemd1/unit/phosphor_2dgevent_2esocket"}}, 62*865fbb75SEd Tanous {"IPMI", 63*865fbb75SEd Tanous {"phosphor-ipmi-net.service", 64*865fbb75SEd Tanous "/org/freedesktop/systemd1/unit/phosphor_2dipmi_2dnet_2esocket"}}}; 653a8a0088SKowalski, Kamil 6670141561SBorawski.Lukasz class NetworkProtocol : public Node { 6770141561SBorawski.Lukasz public: 6870141561SBorawski.Lukasz NetworkProtocol(CrowApp& app) 694b1b8683SBorawski.Lukasz : Node(app, "/redfish/v1/Managers/openbmc/NetworkProtocol") { 7070141561SBorawski.Lukasz Node::json["@odata.type"] = 7170141561SBorawski.Lukasz "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol"; 7270141561SBorawski.Lukasz Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc/NetworkProtocol"; 7370141561SBorawski.Lukasz Node::json["@odata.context"] = 7470141561SBorawski.Lukasz "/redfish/v1/$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol"; 7570141561SBorawski.Lukasz Node::json["Id"] = "NetworkProtocol"; 7670141561SBorawski.Lukasz Node::json["Name"] = "Manager Network Protocol"; 7770141561SBorawski.Lukasz Node::json["Description"] = "Manager Network Service"; 7870141561SBorawski.Lukasz Node::json["Status"]["Health"] = "OK"; 7970141561SBorawski.Lukasz Node::json["Status"]["HealthRollup"] = "OK"; 8070141561SBorawski.Lukasz Node::json["Status"]["State"] = "Enabled"; 813ebd75f7SEd Tanous 823a8a0088SKowalski, Kamil for (auto& protocol : protocolToDBus) { 833a8a0088SKowalski, Kamil Node::json[protocol.first]["ProtocolEnabled"] = false; 843a8a0088SKowalski, Kamil } 853a8a0088SKowalski, Kamil 864b1b8683SBorawski.Lukasz entityPrivileges = { 874b1b8683SBorawski.Lukasz {boost::beast::http::verb::get, {{"Login"}}}, 88e0d918bcSEd Tanous {boost::beast::http::verb::head, {{"Login"}}}, 89e0d918bcSEd Tanous {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 90e0d918bcSEd Tanous {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 91e0d918bcSEd Tanous {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 92e0d918bcSEd Tanous {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 9370141561SBorawski.Lukasz } 9470141561SBorawski.Lukasz 9570141561SBorawski.Lukasz private: 9655c7b7a2SEd Tanous void doGet(crow::Response& res, const crow::Request& req, 9770141561SBorawski.Lukasz const std::vector<std::string>& params) override { 983a8a0088SKowalski, Kamil std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 993a8a0088SKowalski, Kamil 1003a8a0088SKowalski, Kamil getData(asyncResp); 10170141561SBorawski.Lukasz } 10270141561SBorawski.Lukasz 10370141561SBorawski.Lukasz std::string getHostName() const { 10470141561SBorawski.Lukasz std::string hostName; 10570141561SBorawski.Lukasz 10670141561SBorawski.Lukasz std::array<char, HOST_NAME_MAX> hostNameCStr; 10770141561SBorawski.Lukasz if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) { 10870141561SBorawski.Lukasz hostName = hostNameCStr.data(); 10970141561SBorawski.Lukasz } 11070141561SBorawski.Lukasz return hostName; 11170141561SBorawski.Lukasz } 11270141561SBorawski.Lukasz 1133a8a0088SKowalski, Kamil void getData(const std::shared_ptr<AsyncResp>& asyncResp) { 1143a8a0088SKowalski, Kamil Node::json["HostName"] = getHostName(); 1153a8a0088SKowalski, Kamil asyncResp->res.jsonValue = Node::json; 1163a8a0088SKowalski, Kamil 117*865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 118*865fbb75SEd Tanous [asyncResp](const boost::system::error_code ec, 1193a8a0088SKowalski, Kamil const std::vector<UnitStruct>& resp) { 120*865fbb75SEd Tanous if (ec) { 1213a8a0088SKowalski, Kamil asyncResp->res.jsonValue = nlohmann::json::object(); 1223a8a0088SKowalski, Kamil messages::addMessageToErrorJson(asyncResp->res.jsonValue, 1233a8a0088SKowalski, Kamil messages::internalError()); 1243a8a0088SKowalski, Kamil asyncResp->res.result( 1253a8a0088SKowalski, Kamil boost::beast::http::status::internal_server_error); 126*865fbb75SEd Tanous return; 1273a8a0088SKowalski, Kamil } 1283a8a0088SKowalski, Kamil 1293a8a0088SKowalski, Kamil for (auto& unit : resp) { 1303a8a0088SKowalski, Kamil for (auto& kv : protocolToDBus) { 1313a8a0088SKowalski, Kamil if (kv.second.serviceName == 1323a8a0088SKowalski, Kamil std::get<NET_PROTO_UNIT_NAME>(unit)) { 133*865fbb75SEd Tanous continue; 13470141561SBorawski.Lukasz } 135*865fbb75SEd Tanous const char* service = kv.first; 136*865fbb75SEd Tanous const char* socketPath = kv.second.socketPath; 13770141561SBorawski.Lukasz 138*865fbb75SEd Tanous asyncResp->res.jsonValue[service]["ProtocolEnabled"] = 139*865fbb75SEd Tanous std::get<NET_PROTO_UNIT_SUB_STATE>(unit) == "running"; 140*865fbb75SEd Tanous 141*865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 142*865fbb75SEd Tanous [ asyncResp, service{std::string(service)}, socketPath ]( 143*865fbb75SEd Tanous const boost::system::error_code ec, 144*865fbb75SEd Tanous const sdbusplus::message::variant<std::vector< 145*865fbb75SEd Tanous std::tuple<std::string, std::string>>>& resp) { 146*865fbb75SEd Tanous if (ec) { 1473a8a0088SKowalski, Kamil messages::addMessageToJson(asyncResp->res.jsonValue, 1483a8a0088SKowalski, Kamil messages::internalError(), 1493a8a0088SKowalski, Kamil "/" + service); 150*865fbb75SEd Tanous return; 1513a8a0088SKowalski, Kamil } 152*865fbb75SEd Tanous const std::vector<std::tuple<std::string, std::string>>* 153*865fbb75SEd Tanous responsePtr = mapbox::getPtr<const std::vector< 154*865fbb75SEd Tanous std::tuple<std::string, std::string>>>(resp); 155*865fbb75SEd Tanous if (responsePtr == nullptr || responsePtr->size() < 1) { 156*865fbb75SEd Tanous return; 15770141561SBorawski.Lukasz } 15870141561SBorawski.Lukasz 159*865fbb75SEd Tanous const std::string& listenStream = 160*865fbb75SEd Tanous std::get<NET_PROTO_LISTEN_STREAM>((*responsePtr)[0]); 161*865fbb75SEd Tanous std::size_t lastColonPos = listenStream.rfind(":"); 162*865fbb75SEd Tanous if (lastColonPos == std::string::npos) { 163*865fbb75SEd Tanous // Not a port 164*865fbb75SEd Tanous return; 165*865fbb75SEd Tanous } 166*865fbb75SEd Tanous std::string portStr = listenStream.substr(lastColonPos + 1); 167*865fbb75SEd Tanous char* endPtr = nullptr; 168*865fbb75SEd Tanous // Use strtol instead of stroi to avoid exceptions 169*865fbb75SEd Tanous long port = std::strtol(portStr.c_str(), &endPtr, 10); 170*865fbb75SEd Tanous 171*865fbb75SEd Tanous if (*endPtr != '\0' || portStr.empty()) { 172*865fbb75SEd Tanous // Invalid value 173*865fbb75SEd Tanous asyncResp->res.jsonValue[service]["Port"] = nullptr; 174*865fbb75SEd Tanous } else { 175*865fbb75SEd Tanous // Everything OK 176*865fbb75SEd Tanous asyncResp->res.jsonValue[service]["Port"] = port; 177*865fbb75SEd Tanous } 178*865fbb75SEd Tanous }, 179*865fbb75SEd Tanous "org.freedesktop.systemd1", socketPath, 180*865fbb75SEd Tanous "org.freedesktop.DBus.Properties", "Get", 181*865fbb75SEd Tanous "org.freedesktop.systemd1.Socket", "Listen"); 182*865fbb75SEd Tanous } 183*865fbb75SEd Tanous } 184*865fbb75SEd Tanous }, 185*865fbb75SEd Tanous "org.freedesktop.systemd1", "/org/freedesktop/systemd1", 186*865fbb75SEd Tanous "org.freedesktop.systemd1.Manager", "ListUnits"); 187*865fbb75SEd Tanous } 18870141561SBorawski.Lukasz }; 18970141561SBorawski.Lukasz 19070141561SBorawski.Lukasz } // namespace redfish 191