xref: /openbmc/bmcweb/features/redfish/lib/network_protocol.hpp (revision 1abe55ef9844afcddcab9d862ae06118f3a2390c)
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 
21*1abe55efSEd Tanous namespace redfish
22*1abe55efSEd Tanous {
2370141561SBorawski.Lukasz 
24*1abe55efSEd Tanous enum NetworkProtocolUnitStructFields
25*1abe55efSEd 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 
38*1abe55efSEd Tanous enum NetworkProtocolListenResponseElements
39*1abe55efSEd 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 
52*1abe55efSEd Tanous struct ServiceConfiguration
53*1abe55efSEd 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 
70*1abe55efSEd Tanous class NetworkProtocol : public Node
71*1abe55efSEd Tanous {
7270141561SBorawski.Lukasz   public:
73*1abe55efSEd Tanous     NetworkProtocol(CrowApp& app) :
74*1abe55efSEd Tanous         Node(app, "/redfish/v1/Managers/openbmc/NetworkProtocol")
75*1abe55efSEd Tanous     {
7670141561SBorawski.Lukasz         Node::json["@odata.type"] =
7770141561SBorawski.Lukasz             "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol";
78*1abe55efSEd Tanous         Node::json["@odata.id"] =
79*1abe55efSEd Tanous             "/redfish/v1/Managers/openbmc/NetworkProtocol";
8070141561SBorawski.Lukasz         Node::json["@odata.context"] =
81*1abe55efSEd Tanous             "/redfish/v1/"
82*1abe55efSEd Tanous             "$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol";
8370141561SBorawski.Lukasz         Node::json["Id"] = "NetworkProtocol";
8470141561SBorawski.Lukasz         Node::json["Name"] = "Manager Network Protocol";
8570141561SBorawski.Lukasz         Node::json["Description"] = "Manager Network Service";
8670141561SBorawski.Lukasz         Node::json["Status"]["Health"] = "OK";
8770141561SBorawski.Lukasz         Node::json["Status"]["HealthRollup"] = "OK";
8870141561SBorawski.Lukasz         Node::json["Status"]["State"] = "Enabled";
893ebd75f7SEd Tanous 
90*1abe55efSEd Tanous         for (auto& protocol : protocolToDBus)
91*1abe55efSEd Tanous         {
923a8a0088SKowalski, Kamil             Node::json[protocol.first]["ProtocolEnabled"] = false;
933a8a0088SKowalski, Kamil         }
943a8a0088SKowalski, Kamil 
954b1b8683SBorawski.Lukasz         entityPrivileges = {
964b1b8683SBorawski.Lukasz             {boost::beast::http::verb::get, {{"Login"}}},
97e0d918bcSEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
98e0d918bcSEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
99e0d918bcSEd Tanous             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
100e0d918bcSEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
101e0d918bcSEd Tanous             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
10270141561SBorawski.Lukasz     }
10370141561SBorawski.Lukasz 
10470141561SBorawski.Lukasz   private:
10555c7b7a2SEd Tanous     void doGet(crow::Response& res, const crow::Request& req,
106*1abe55efSEd Tanous                const std::vector<std::string>& params) override
107*1abe55efSEd Tanous     {
1083a8a0088SKowalski, Kamil         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
1093a8a0088SKowalski, Kamil 
1103a8a0088SKowalski, Kamil         getData(asyncResp);
11170141561SBorawski.Lukasz     }
11270141561SBorawski.Lukasz 
113*1abe55efSEd Tanous     std::string getHostName() const
114*1abe55efSEd Tanous     {
11570141561SBorawski.Lukasz         std::string hostName;
11670141561SBorawski.Lukasz 
11770141561SBorawski.Lukasz         std::array<char, HOST_NAME_MAX> hostNameCStr;
118*1abe55efSEd Tanous         if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
119*1abe55efSEd Tanous         {
12070141561SBorawski.Lukasz             hostName = hostNameCStr.data();
12170141561SBorawski.Lukasz         }
12270141561SBorawski.Lukasz         return hostName;
12370141561SBorawski.Lukasz     }
12470141561SBorawski.Lukasz 
125*1abe55efSEd Tanous     void getData(const std::shared_ptr<AsyncResp>& asyncResp)
126*1abe55efSEd Tanous     {
1273a8a0088SKowalski, Kamil         Node::json["HostName"] = getHostName();
1283a8a0088SKowalski, Kamil         asyncResp->res.jsonValue = Node::json;
1293a8a0088SKowalski, Kamil 
130865fbb75SEd Tanous         crow::connections::systemBus->async_method_call(
131865fbb75SEd Tanous             [asyncResp](const boost::system::error_code ec,
1323a8a0088SKowalski, Kamil                         const std::vector<UnitStruct>& resp) {
133*1abe55efSEd Tanous                 if (ec)
134*1abe55efSEd Tanous                 {
1353a8a0088SKowalski, Kamil                     asyncResp->res.jsonValue = nlohmann::json::object();
1363a8a0088SKowalski, Kamil                     messages::addMessageToErrorJson(asyncResp->res.jsonValue,
1373a8a0088SKowalski, Kamil                                                     messages::internalError());
1383a8a0088SKowalski, Kamil                     asyncResp->res.result(
1393a8a0088SKowalski, Kamil                         boost::beast::http::status::internal_server_error);
140865fbb75SEd Tanous                     return;
1413a8a0088SKowalski, Kamil                 }
1423a8a0088SKowalski, Kamil 
143*1abe55efSEd Tanous                 for (auto& unit : resp)
144*1abe55efSEd Tanous                 {
145*1abe55efSEd Tanous                     for (auto& kv : protocolToDBus)
146*1abe55efSEd Tanous                     {
1473a8a0088SKowalski, Kamil                         if (kv.second.serviceName ==
148*1abe55efSEd Tanous                             std::get<NET_PROTO_UNIT_NAME>(unit))
149*1abe55efSEd Tanous                         {
150865fbb75SEd Tanous                             continue;
15170141561SBorawski.Lukasz                         }
152865fbb75SEd Tanous                         const char* service = kv.first;
153865fbb75SEd Tanous                         const char* socketPath = kv.second.socketPath;
15470141561SBorawski.Lukasz 
155865fbb75SEd Tanous                         asyncResp->res.jsonValue[service]["ProtocolEnabled"] =
156*1abe55efSEd Tanous                             std::get<NET_PROTO_UNIT_SUB_STATE>(unit) ==
157*1abe55efSEd Tanous                             "running";
158865fbb75SEd Tanous 
159865fbb75SEd Tanous                         crow::connections::systemBus->async_method_call(
160*1abe55efSEd Tanous                             [asyncResp, service{std::string(service)},
161*1abe55efSEd Tanous                              socketPath](
162865fbb75SEd Tanous                                 const boost::system::error_code ec,
163865fbb75SEd Tanous                                 const sdbusplus::message::variant<std::vector<
164*1abe55efSEd Tanous                                     std::tuple<std::string, std::string>>>&
165*1abe55efSEd Tanous                                     resp) {
166*1abe55efSEd Tanous                                 if (ec)
167*1abe55efSEd Tanous                                 {
168*1abe55efSEd Tanous                                     messages::addMessageToJson(
169*1abe55efSEd Tanous                                         asyncResp->res.jsonValue,
1703a8a0088SKowalski, Kamil                                         messages::internalError(),
1713a8a0088SKowalski, Kamil                                         "/" + service);
172865fbb75SEd Tanous                                     return;
1733a8a0088SKowalski, Kamil                                 }
174*1abe55efSEd Tanous                                 const std::vector<std::tuple<
175*1abe55efSEd Tanous                                     std::string, std::string>>* responsePtr =
176*1abe55efSEd Tanous                                     mapbox::getPtr<const std::vector<
177*1abe55efSEd Tanous                                         std::tuple<std::string, std::string>>>(
178*1abe55efSEd Tanous                                         resp);
179*1abe55efSEd Tanous                                 if (responsePtr == nullptr ||
180*1abe55efSEd Tanous                                     responsePtr->size() < 1)
181*1abe55efSEd Tanous                                 {
182865fbb75SEd Tanous                                     return;
18370141561SBorawski.Lukasz                                 }
18470141561SBorawski.Lukasz 
185865fbb75SEd Tanous                                 const std::string& listenStream =
186*1abe55efSEd Tanous                                     std::get<NET_PROTO_LISTEN_STREAM>(
187*1abe55efSEd Tanous                                         (*responsePtr)[0]);
188*1abe55efSEd Tanous                                 std::size_t lastColonPos =
189*1abe55efSEd Tanous                                     listenStream.rfind(":");
190*1abe55efSEd Tanous                                 if (lastColonPos == std::string::npos)
191*1abe55efSEd Tanous                                 {
192865fbb75SEd Tanous                                     // Not a port
193865fbb75SEd Tanous                                     return;
194865fbb75SEd Tanous                                 }
195*1abe55efSEd Tanous                                 std::string portStr =
196*1abe55efSEd Tanous                                     listenStream.substr(lastColonPos + 1);
197865fbb75SEd Tanous                                 char* endPtr = nullptr;
198*1abe55efSEd Tanous                                 // Use strtol instead of stroi to avoid
199*1abe55efSEd Tanous                                 // exceptions
200*1abe55efSEd Tanous                                 long port =
201*1abe55efSEd Tanous                                     std::strtol(portStr.c_str(), &endPtr, 10);
202865fbb75SEd Tanous 
203*1abe55efSEd Tanous                                 if (*endPtr != '\0' || portStr.empty())
204*1abe55efSEd Tanous                                 {
205865fbb75SEd Tanous                                     // Invalid value
206*1abe55efSEd Tanous                                     asyncResp->res.jsonValue[service]["Port"] =
207*1abe55efSEd Tanous                                         nullptr;
208*1abe55efSEd Tanous                                 }
209*1abe55efSEd Tanous                                 else
210*1abe55efSEd Tanous                                 {
211865fbb75SEd Tanous                                     // Everything OK
212*1abe55efSEd Tanous                                     asyncResp->res.jsonValue[service]["Port"] =
213*1abe55efSEd Tanous                                         port;
214865fbb75SEd Tanous                                 }
215865fbb75SEd Tanous                             },
216865fbb75SEd Tanous                             "org.freedesktop.systemd1", socketPath,
217865fbb75SEd Tanous                             "org.freedesktop.DBus.Properties", "Get",
218865fbb75SEd Tanous                             "org.freedesktop.systemd1.Socket", "Listen");
219865fbb75SEd Tanous                     }
220865fbb75SEd Tanous                 }
221865fbb75SEd Tanous             },
222865fbb75SEd Tanous             "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
223865fbb75SEd Tanous             "org.freedesktop.systemd1.Manager", "ListUnits");
224865fbb75SEd Tanous     }
22570141561SBorawski.Lukasz };
22670141561SBorawski.Lukasz 
22770141561SBorawski.Lukasz } // namespace redfish
228