xref: /openbmc/bmcweb/features/redfish/lib/network_protocol.hpp (revision 0f74e643ec246c333ef4724af1ecd5adeb1b6658)
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 
211abe55efSEd Tanous namespace redfish
221abe55efSEd Tanous {
2370141561SBorawski.Lukasz 
241abe55efSEd Tanous enum NetworkProtocolUnitStructFields
251abe55efSEd Tanous {
263a8a0088SKowalski, Kamil     NET_PROTO_UNIT_NAME,
273a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DESC,
283a8a0088SKowalski, Kamil     NET_PROTO_UNIT_LOAD_STATE,
293a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ACTIVE_STATE,
303a8a0088SKowalski, Kamil     NET_PROTO_UNIT_SUB_STATE,
313a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DEVICE,
323a8a0088SKowalski, Kamil     NET_PROTO_UNIT_OBJ_PATH,
333a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_0,
343a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_EMPTY,
353a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_ROOT_PATH
363a8a0088SKowalski, Kamil };
373a8a0088SKowalski, Kamil 
381abe55efSEd Tanous enum NetworkProtocolListenResponseElements
391abe55efSEd Tanous {
403a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_TYPE,
413a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_STREAM
423a8a0088SKowalski, Kamil };
433a8a0088SKowalski, Kamil 
443a8a0088SKowalski, Kamil /**
453a8a0088SKowalski, Kamil  * @brief D-Bus Unit structure returned in array from ListUnits Method
463a8a0088SKowalski, Kamil  */
473a8a0088SKowalski, Kamil using UnitStruct =
483a8a0088SKowalski, Kamil     std::tuple<std::string, std::string, std::string, std::string, std::string,
493a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path, uint32_t,
503a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path>;
513a8a0088SKowalski, Kamil 
521abe55efSEd Tanous struct ServiceConfiguration
531abe55efSEd Tanous {
54865fbb75SEd Tanous     const char* serviceName;
55865fbb75SEd Tanous     const char* socketPath;
563a8a0088SKowalski, Kamil };
573a8a0088SKowalski, Kamil 
58865fbb75SEd Tanous const static boost::container::flat_map<const char*, ServiceConfiguration>
59865fbb75SEd Tanous     protocolToDBus{
60865fbb75SEd Tanous         {"SSH",
61865fbb75SEd Tanous          {"dropbear.service",
62865fbb75SEd Tanous           "/org/freedesktop/systemd1/unit/dropbear_2esocket"}},
63865fbb75SEd Tanous         {"HTTPS",
64865fbb75SEd Tanous          {"phosphor-gevent.service",
65865fbb75SEd Tanous           "/org/freedesktop/systemd1/unit/phosphor_2dgevent_2esocket"}},
66865fbb75SEd Tanous         {"IPMI",
67865fbb75SEd Tanous          {"phosphor-ipmi-net.service",
68865fbb75SEd Tanous           "/org/freedesktop/systemd1/unit/phosphor_2dipmi_2dnet_2esocket"}}};
693a8a0088SKowalski, Kamil 
701abe55efSEd Tanous class NetworkProtocol : public Node
711abe55efSEd Tanous {
7270141561SBorawski.Lukasz   public:
731abe55efSEd Tanous     NetworkProtocol(CrowApp& app) :
7497b7ccf3SEd Tanous         Node(app, "/redfish/v1/Managers/bmc/NetworkProtocol")
751abe55efSEd Tanous     {
764b1b8683SBorawski.Lukasz         entityPrivileges = {
774b1b8683SBorawski.Lukasz             {boost::beast::http::verb::get, {{"Login"}}},
78e0d918bcSEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
79e0d918bcSEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
80e0d918bcSEd Tanous             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
81e0d918bcSEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
82e0d918bcSEd Tanous             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
8370141561SBorawski.Lukasz     }
8470141561SBorawski.Lukasz 
8570141561SBorawski.Lukasz   private:
8655c7b7a2SEd Tanous     void doGet(crow::Response& res, const crow::Request& req,
871abe55efSEd Tanous                const std::vector<std::string>& params) override
881abe55efSEd Tanous     {
893a8a0088SKowalski, Kamil         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
903a8a0088SKowalski, Kamil 
913a8a0088SKowalski, Kamil         getData(asyncResp);
9270141561SBorawski.Lukasz     }
9370141561SBorawski.Lukasz 
941abe55efSEd Tanous     std::string getHostName() const
951abe55efSEd Tanous     {
9670141561SBorawski.Lukasz         std::string hostName;
9770141561SBorawski.Lukasz 
9870141561SBorawski.Lukasz         std::array<char, HOST_NAME_MAX> hostNameCStr;
991abe55efSEd Tanous         if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
1001abe55efSEd Tanous         {
10170141561SBorawski.Lukasz             hostName = hostNameCStr.data();
10270141561SBorawski.Lukasz         }
10370141561SBorawski.Lukasz         return hostName;
10470141561SBorawski.Lukasz     }
10570141561SBorawski.Lukasz 
1061abe55efSEd Tanous     void getData(const std::shared_ptr<AsyncResp>& asyncResp)
1071abe55efSEd Tanous     {
108*0f74e643SEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
109*0f74e643SEd Tanous             "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol";
110*0f74e643SEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
111*0f74e643SEd Tanous             "/redfish/v1/Managers/bmc/NetworkProtocol";
112*0f74e643SEd Tanous         asyncResp->res.jsonValue["@odata.context"] =
113*0f74e643SEd Tanous             "/redfish/v1/"
114*0f74e643SEd Tanous             "$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol";
115*0f74e643SEd Tanous         asyncResp->res.jsonValue["Id"] = "NetworkProtocol";
116*0f74e643SEd Tanous         asyncResp->res.jsonValue["Name"] = "Manager Network Protocol";
117*0f74e643SEd Tanous         asyncResp->res.jsonValue["Description"] = "Manager Network Service";
118*0f74e643SEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
119*0f74e643SEd Tanous         asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
120*0f74e643SEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
121*0f74e643SEd Tanous 
122*0f74e643SEd Tanous         for (auto& protocol : protocolToDBus)
123*0f74e643SEd Tanous         {
124*0f74e643SEd Tanous             asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false;
125*0f74e643SEd Tanous         }
126*0f74e643SEd Tanous 
127*0f74e643SEd Tanous         asyncResp->res.jsonValue["HostName"] = getHostName();
1283a8a0088SKowalski, Kamil 
129865fbb75SEd Tanous         crow::connections::systemBus->async_method_call(
130865fbb75SEd Tanous             [asyncResp](const boost::system::error_code ec,
1313a8a0088SKowalski, Kamil                         const std::vector<UnitStruct>& resp) {
1321abe55efSEd Tanous                 if (ec)
1331abe55efSEd Tanous                 {
1343a8a0088SKowalski, Kamil                     asyncResp->res.jsonValue = nlohmann::json::object();
135f12894f8SJason M. Bills                     messages::internalError(asyncResp->res);
136865fbb75SEd Tanous                     return;
1373a8a0088SKowalski, Kamil                 }
1383a8a0088SKowalski, Kamil 
1391abe55efSEd Tanous                 for (auto& unit : resp)
1401abe55efSEd Tanous                 {
1411abe55efSEd Tanous                     for (auto& kv : protocolToDBus)
1421abe55efSEd Tanous                     {
1433a8a0088SKowalski, Kamil                         if (kv.second.serviceName ==
1441abe55efSEd Tanous                             std::get<NET_PROTO_UNIT_NAME>(unit))
1451abe55efSEd Tanous                         {
146865fbb75SEd Tanous                             continue;
14770141561SBorawski.Lukasz                         }
148865fbb75SEd Tanous                         const char* service = kv.first;
149865fbb75SEd Tanous                         const char* socketPath = kv.second.socketPath;
15070141561SBorawski.Lukasz 
151865fbb75SEd Tanous                         asyncResp->res.jsonValue[service]["ProtocolEnabled"] =
1521abe55efSEd Tanous                             std::get<NET_PROTO_UNIT_SUB_STATE>(unit) ==
1531abe55efSEd Tanous                             "running";
154865fbb75SEd Tanous 
155865fbb75SEd Tanous                         crow::connections::systemBus->async_method_call(
1561abe55efSEd Tanous                             [asyncResp, service{std::string(service)},
1571abe55efSEd Tanous                              socketPath](
158865fbb75SEd Tanous                                 const boost::system::error_code ec,
159865fbb75SEd Tanous                                 const sdbusplus::message::variant<std::vector<
1601abe55efSEd Tanous                                     std::tuple<std::string, std::string>>>&
1611abe55efSEd Tanous                                     resp) {
1621abe55efSEd Tanous                                 if (ec)
1631abe55efSEd Tanous                                 {
164a08b46ccSJason M. Bills                                     messages::internalError(asyncResp->res);
165865fbb75SEd Tanous                                     return;
1663a8a0088SKowalski, Kamil                                 }
1671abe55efSEd Tanous                                 const std::vector<std::tuple<
1681abe55efSEd Tanous                                     std::string, std::string>>* responsePtr =
1691abe55efSEd Tanous                                     mapbox::getPtr<const std::vector<
1701abe55efSEd Tanous                                         std::tuple<std::string, std::string>>>(
1711abe55efSEd Tanous                                         resp);
1721abe55efSEd Tanous                                 if (responsePtr == nullptr ||
1731abe55efSEd Tanous                                     responsePtr->size() < 1)
1741abe55efSEd Tanous                                 {
175865fbb75SEd Tanous                                     return;
17670141561SBorawski.Lukasz                                 }
17770141561SBorawski.Lukasz 
178865fbb75SEd Tanous                                 const std::string& listenStream =
1791abe55efSEd Tanous                                     std::get<NET_PROTO_LISTEN_STREAM>(
1801abe55efSEd Tanous                                         (*responsePtr)[0]);
1811abe55efSEd Tanous                                 std::size_t lastColonPos =
1821abe55efSEd Tanous                                     listenStream.rfind(":");
1831abe55efSEd Tanous                                 if (lastColonPos == std::string::npos)
1841abe55efSEd Tanous                                 {
185865fbb75SEd Tanous                                     // Not a port
186865fbb75SEd Tanous                                     return;
187865fbb75SEd Tanous                                 }
1881abe55efSEd Tanous                                 std::string portStr =
1891abe55efSEd Tanous                                     listenStream.substr(lastColonPos + 1);
190865fbb75SEd Tanous                                 char* endPtr = nullptr;
1911abe55efSEd Tanous                                 // Use strtol instead of stroi to avoid
1921abe55efSEd Tanous                                 // exceptions
1931abe55efSEd Tanous                                 long port =
1941abe55efSEd Tanous                                     std::strtol(portStr.c_str(), &endPtr, 10);
195865fbb75SEd Tanous 
1961abe55efSEd Tanous                                 if (*endPtr != '\0' || portStr.empty())
1971abe55efSEd Tanous                                 {
198865fbb75SEd Tanous                                     // Invalid value
1991abe55efSEd Tanous                                     asyncResp->res.jsonValue[service]["Port"] =
2001abe55efSEd Tanous                                         nullptr;
2011abe55efSEd Tanous                                 }
2021abe55efSEd Tanous                                 else
2031abe55efSEd Tanous                                 {
204865fbb75SEd Tanous                                     // Everything OK
2051abe55efSEd Tanous                                     asyncResp->res.jsonValue[service]["Port"] =
2061abe55efSEd Tanous                                         port;
207865fbb75SEd Tanous                                 }
208865fbb75SEd Tanous                             },
209865fbb75SEd Tanous                             "org.freedesktop.systemd1", socketPath,
210865fbb75SEd Tanous                             "org.freedesktop.DBus.Properties", "Get",
211865fbb75SEd Tanous                             "org.freedesktop.systemd1.Socket", "Listen");
212865fbb75SEd Tanous                     }
213865fbb75SEd Tanous                 }
214865fbb75SEd Tanous             },
215865fbb75SEd Tanous             "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
216865fbb75SEd Tanous             "org.freedesktop.systemd1.Manager", "ListUnits");
217865fbb75SEd Tanous     }
21870141561SBorawski.Lukasz };
21970141561SBorawski.Lukasz 
22070141561SBorawski.Lukasz } // namespace redfish
221