xref: /openbmc/bmcweb/features/redfish/lib/network_protocol.hpp (revision 720487803a1890e8d4e5d91463e7ec62b4b23f74)
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"
1967a78d87STom Joseph #include "openbmc_dbus_rest.hpp"
2070141561SBorawski.Lukasz 
217e860f15SJohn Edward Broadbent #include <app.hpp>
2220e6ea5dSraviteja-b #include <utils/json_utils.hpp>
231214b7e7SGunnar Mills 
241214b7e7SGunnar Mills #include <optional>
25abf2add6SEd Tanous #include <variant>
261abe55efSEd Tanous namespace redfish
271abe55efSEd Tanous {
2870141561SBorawski.Lukasz 
297e860f15SJohn Edward Broadbent void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp);
307e860f15SJohn Edward Broadbent std::string getHostName();
317e860f15SJohn Edward Broadbent 
321abe55efSEd Tanous enum NetworkProtocolUnitStructFields
331abe55efSEd Tanous {
343a8a0088SKowalski, Kamil     NET_PROTO_UNIT_NAME,
353a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DESC,
363a8a0088SKowalski, Kamil     NET_PROTO_UNIT_LOAD_STATE,
373a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ACTIVE_STATE,
383a8a0088SKowalski, Kamil     NET_PROTO_UNIT_SUB_STATE,
393a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DEVICE,
403a8a0088SKowalski, Kamil     NET_PROTO_UNIT_OBJ_PATH,
413a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_0,
423a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_EMPTY,
433a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_ROOT_PATH
443a8a0088SKowalski, Kamil };
453a8a0088SKowalski, Kamil 
461abe55efSEd Tanous enum NetworkProtocolListenResponseElements
471abe55efSEd Tanous {
483a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_TYPE,
493a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_STREAM
503a8a0088SKowalski, Kamil };
513a8a0088SKowalski, Kamil 
523a8a0088SKowalski, Kamil /**
533a8a0088SKowalski, Kamil  * @brief D-Bus Unit structure returned in array from ListUnits Method
543a8a0088SKowalski, Kamil  */
553a8a0088SKowalski, Kamil using UnitStruct =
563a8a0088SKowalski, Kamil     std::tuple<std::string, std::string, std::string, std::string, std::string,
573a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path, uint32_t,
583a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path>;
593a8a0088SKowalski, Kamil 
60b0972a63SEd Tanous const static std::array<std::pair<const char*, const char*>, 3> protocolToDBus{
61b0972a63SEd Tanous     {{"SSH", "dropbear"}, {"HTTPS", "bmcweb"}, {"IPMI", "phosphor-ipmi-net"}}};
623a8a0088SKowalski, Kamil 
63d24bfc7aSJennifer Lee inline void
6481ce609eSEd Tanous     extractNTPServersAndDomainNamesData(const GetManagedObjects& dbusData,
65d24bfc7aSJennifer Lee                                         std::vector<std::string>& ntpData,
66d24bfc7aSJennifer Lee                                         std::vector<std::string>& dnData)
6720e6ea5dSraviteja-b {
6881ce609eSEd Tanous     for (const auto& obj : dbusData)
6920e6ea5dSraviteja-b     {
7020e6ea5dSraviteja-b         for (const auto& ifacePair : obj.second)
7120e6ea5dSraviteja-b         {
7220e6ea5dSraviteja-b             if (obj.first == "/xyz/openbmc_project/network/eth0")
7320e6ea5dSraviteja-b             {
7420e6ea5dSraviteja-b                 if (ifacePair.first ==
7520e6ea5dSraviteja-b                     "xyz.openbmc_project.Network.EthernetInterface")
7620e6ea5dSraviteja-b                 {
7720e6ea5dSraviteja-b                     for (const auto& propertyPair : ifacePair.second)
7820e6ea5dSraviteja-b                     {
7920e6ea5dSraviteja-b                         if (propertyPair.first == "NTPServers")
8020e6ea5dSraviteja-b                         {
8120e6ea5dSraviteja-b                             const std::vector<std::string>* ntpServers =
828d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
8320e6ea5dSraviteja-b                                     &propertyPair.second);
8420e6ea5dSraviteja-b                             if (ntpServers != nullptr)
8520e6ea5dSraviteja-b                             {
86f23b7296SEd Tanous                                 ntpData = *ntpServers;
8720e6ea5dSraviteja-b                             }
8820e6ea5dSraviteja-b                         }
89d24bfc7aSJennifer Lee                         else if (propertyPair.first == "DomainName")
90d24bfc7aSJennifer Lee                         {
91d24bfc7aSJennifer Lee                             const std::vector<std::string>* domainNames =
928d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
93d24bfc7aSJennifer Lee                                     &propertyPair.second);
94d24bfc7aSJennifer Lee                             if (domainNames != nullptr)
95d24bfc7aSJennifer Lee                             {
96f23b7296SEd Tanous                                 dnData = *domainNames;
97d24bfc7aSJennifer Lee                             }
98d24bfc7aSJennifer Lee                         }
9920e6ea5dSraviteja-b                     }
10020e6ea5dSraviteja-b                 }
10120e6ea5dSraviteja-b             }
10220e6ea5dSraviteja-b         }
10320e6ea5dSraviteja-b     }
10420e6ea5dSraviteja-b }
10520e6ea5dSraviteja-b 
10620e6ea5dSraviteja-b template <typename CallbackFunc>
10720e6ea5dSraviteja-b void getEthernetIfaceData(CallbackFunc&& callback)
10820e6ea5dSraviteja-b {
10920e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
11020e6ea5dSraviteja-b         [callback{std::move(callback)}](
11181ce609eSEd Tanous             const boost::system::error_code errorCode,
11281ce609eSEd Tanous             const GetManagedObjects& dbusData) {
11320e6ea5dSraviteja-b             std::vector<std::string> ntpServers;
114d24bfc7aSJennifer Lee             std::vector<std::string> domainNames;
11520e6ea5dSraviteja-b 
11681ce609eSEd Tanous             if (errorCode)
11720e6ea5dSraviteja-b             {
118d24bfc7aSJennifer Lee                 callback(false, ntpServers, domainNames);
11920e6ea5dSraviteja-b                 return;
12020e6ea5dSraviteja-b             }
12120e6ea5dSraviteja-b 
12281ce609eSEd Tanous             extractNTPServersAndDomainNamesData(dbusData, ntpServers,
123d24bfc7aSJennifer Lee                                                 domainNames);
12420e6ea5dSraviteja-b 
125d24bfc7aSJennifer Lee             callback(true, ntpServers, domainNames);
12620e6ea5dSraviteja-b         },
12720e6ea5dSraviteja-b         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
12820e6ea5dSraviteja-b         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
129271584abSEd Tanous }
13020e6ea5dSraviteja-b 
131*72048780SAbhishek Patel void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
132*72048780SAbhishek Patel                     const crow::Request& req)
1331abe55efSEd Tanous {
1340f74e643SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
13561932318SXiaochao Ma         "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol";
1360f74e643SEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
1370f74e643SEd Tanous         "/redfish/v1/Managers/bmc/NetworkProtocol";
1380f74e643SEd Tanous     asyncResp->res.jsonValue["Id"] = "NetworkProtocol";
1390f74e643SEd Tanous     asyncResp->res.jsonValue["Name"] = "Manager Network Protocol";
1400f74e643SEd Tanous     asyncResp->res.jsonValue["Description"] = "Manager Network Service";
1410f74e643SEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
1420f74e643SEd Tanous     asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
1430f74e643SEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
1440f74e643SEd Tanous 
14561932318SXiaochao Ma     // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0,
146818ea7b8SJoshi-Mansi     // but from security perspective it is not recommended to use.
147818ea7b8SJoshi-Mansi     // Hence using protocolEnabled as false to make it OCP and security-wise
148818ea7b8SJoshi-Mansi     // compliant
149818ea7b8SJoshi-Mansi     asyncResp->res.jsonValue["HTTP"]["Port"] = 0;
150818ea7b8SJoshi-Mansi     asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false;
151818ea7b8SJoshi-Mansi 
1520f74e643SEd Tanous     for (auto& protocol : protocolToDBus)
1530f74e643SEd Tanous     {
1540870f8c7SJayaprakash Mutyala         asyncResp->res.jsonValue[protocol.first]["Port"] =
1550870f8c7SJayaprakash Mutyala             nlohmann::detail::value_t::null;
1560f74e643SEd Tanous         asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false;
1570f74e643SEd Tanous     }
1580f74e643SEd Tanous 
159d24bfc7aSJennifer Lee     std::string hostName = getHostName();
160d24bfc7aSJennifer Lee 
161d24bfc7aSJennifer Lee     asyncResp->res.jsonValue["HostName"] = hostName;
1623a8a0088SKowalski, Kamil 
16320e6ea5dSraviteja-b     getNTPProtocolEnabled(asyncResp);
16420e6ea5dSraviteja-b 
16520e6ea5dSraviteja-b     // TODO Get eth0 interface data, and call the below callback for JSON
16620e6ea5dSraviteja-b     // preparation
167271584abSEd Tanous     getEthernetIfaceData(
168271584abSEd Tanous         [hostName, asyncResp](const bool& success,
169d24bfc7aSJennifer Lee                               const std::vector<std::string>& ntpServers,
170d24bfc7aSJennifer Lee                               const std::vector<std::string>& domainNames) {
17120e6ea5dSraviteja-b             if (!success)
17220e6ea5dSraviteja-b             {
1737e860f15SJohn Edward Broadbent                 messages::resourceNotFound(asyncResp->res, "EthernetInterface",
1747e860f15SJohn Edward Broadbent                                            "eth0");
17520e6ea5dSraviteja-b                 return;
17620e6ea5dSraviteja-b             }
17720e6ea5dSraviteja-b             asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers;
178d24bfc7aSJennifer Lee             if (hostName.empty() == false)
179d24bfc7aSJennifer Lee             {
180f23b7296SEd Tanous                 std::string fqdn = hostName;
181d24bfc7aSJennifer Lee                 if (domainNames.empty() == false)
182d24bfc7aSJennifer Lee                 {
183f23b7296SEd Tanous                     fqdn += ".";
184f23b7296SEd Tanous                     fqdn += domainNames[0];
185d24bfc7aSJennifer Lee                 }
1862c70f800SEd Tanous                 asyncResp->res.jsonValue["FQDN"] = std::move(fqdn);
187d24bfc7aSJennifer Lee             }
18820e6ea5dSraviteja-b         });
18920e6ea5dSraviteja-b 
190*72048780SAbhishek Patel     Privileges effectiveUserPrivileges =
191*72048780SAbhishek Patel         redfish::getUserPrivileges(req.userRole);
192*72048780SAbhishek Patel 
193865fbb75SEd Tanous     crow::connections::systemBus->async_method_call(
194*72048780SAbhishek Patel         [asyncResp,
195*72048780SAbhishek Patel          &effectiveUserPrivileges](const boost::system::error_code e,
196271584abSEd Tanous                                    const std::vector<UnitStruct>& r) {
197271584abSEd Tanous             if (e)
1981abe55efSEd Tanous             {
1993a8a0088SKowalski, Kamil                 asyncResp->res.jsonValue = nlohmann::json::object();
200f12894f8SJason M. Bills                 messages::internalError(asyncResp->res);
201865fbb75SEd Tanous                 return;
2023a8a0088SKowalski, Kamil             }
203*72048780SAbhishek Patel             // /redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates is
204*72048780SAbhishek Patel             // something only ConfigureManager can access then only display when
205*72048780SAbhishek Patel             // the user has permissions ConfigureManager
206*72048780SAbhishek Patel             if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
207*72048780SAbhishek Patel                                                  effectiveUserPrivileges))
208*72048780SAbhishek Patel             {
2095968caeeSMarri Devender Rao                 asyncResp->res.jsonValue["HTTPS"]["Certificates"] = {
2105968caeeSMarri Devender Rao                     {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol/"
211659dd62eSJason M. Bills                                   "HTTPS/Certificates"}};
212*72048780SAbhishek Patel             }
213271584abSEd Tanous             for (auto& unit : r)
2141abe55efSEd Tanous             {
215ec4974ddSAppaRao Puli                 /* Only traverse through <xyz>.socket units */
2163174e4dfSEd Tanous                 const std::string& unitName =
2173174e4dfSEd Tanous                     std::get<NET_PROTO_UNIT_NAME>(unit);
218ec4974ddSAppaRao Puli                 if (!boost::ends_with(unitName, ".socket"))
2191abe55efSEd Tanous                 {
220865fbb75SEd Tanous                     continue;
22170141561SBorawski.Lukasz                 }
22270141561SBorawski.Lukasz 
223ec4974ddSAppaRao Puli                 for (auto& kv : protocolToDBus)
224ec4974ddSAppaRao Puli                 {
225ec4974ddSAppaRao Puli                     // We are interested in services, which starts with
226ec4974ddSAppaRao Puli                     // mapped service name
227ec4974ddSAppaRao Puli                     if (!boost::starts_with(unitName, kv.second))
228ec4974ddSAppaRao Puli                     {
229ec4974ddSAppaRao Puli                         continue;
230ec4974ddSAppaRao Puli                     }
231ec4974ddSAppaRao Puli                     const char* rfServiceKey = kv.first;
2323174e4dfSEd Tanous                     const std::string& socketPath =
233ec4974ddSAppaRao Puli                         std::get<NET_PROTO_UNIT_OBJ_PATH>(unit);
2343174e4dfSEd Tanous                     const std::string& unitState =
235ec4974ddSAppaRao Puli                         std::get<NET_PROTO_UNIT_SUB_STATE>(unit);
236ec4974ddSAppaRao Puli 
2377e860f15SJohn Edward Broadbent                     asyncResp->res.jsonValue[rfServiceKey]["ProtocolEnabled"] =
2387e860f15SJohn Edward Broadbent                         (unitState == "running") || (unitState == "listening");
239ec4974ddSAppaRao Puli 
240865fbb75SEd Tanous                     crow::connections::systemBus->async_method_call(
2417e860f15SJohn Edward Broadbent                         [asyncResp, rfServiceKey{std::string(rfServiceKey)}](
242865fbb75SEd Tanous                             const boost::system::error_code ec,
2437e860f15SJohn Edward Broadbent                             const std::variant<std::vector<
2447e860f15SJohn Edward Broadbent                                 std::tuple<std::string, std::string>>>& resp) {
2451abe55efSEd Tanous                             if (ec)
2461abe55efSEd Tanous                             {
247a08b46ccSJason M. Bills                                 messages::internalError(asyncResp->res);
248865fbb75SEd Tanous                                 return;
2493a8a0088SKowalski, Kamil                             }
250abf2add6SEd Tanous                             const std::vector<
251abf2add6SEd Tanous                                 std::tuple<std::string, std::string>>*
252abf2add6SEd Tanous                                 responsePtr = std::get_if<std::vector<
253abf2add6SEd Tanous                                     std::tuple<std::string, std::string>>>(
2541b6b96c5SEd Tanous                                     &resp);
2551abe55efSEd Tanous                             if (responsePtr == nullptr ||
2561abe55efSEd Tanous                                 responsePtr->size() < 1)
2571abe55efSEd Tanous                             {
258865fbb75SEd Tanous                                 return;
25970141561SBorawski.Lukasz                             }
26070141561SBorawski.Lukasz 
261865fbb75SEd Tanous                             const std::string& listenStream =
2621abe55efSEd Tanous                                 std::get<NET_PROTO_LISTEN_STREAM>(
2631abe55efSEd Tanous                                     (*responsePtr)[0]);
2647e860f15SJohn Edward Broadbent                             std::size_t lastColonPos = listenStream.rfind(':');
2651abe55efSEd Tanous                             if (lastColonPos == std::string::npos)
2661abe55efSEd Tanous                             {
267865fbb75SEd Tanous                                 // Not a port
268865fbb75SEd Tanous                                 return;
269865fbb75SEd Tanous                             }
2701abe55efSEd Tanous                             std::string portStr =
2711abe55efSEd Tanous                                 listenStream.substr(lastColonPos + 1);
272ec4974ddSAppaRao Puli                             if (portStr.empty())
273ec4974ddSAppaRao Puli                             {
274ec4974ddSAppaRao Puli                                 return;
275ec4974ddSAppaRao Puli                             }
276865fbb75SEd Tanous                             char* endPtr = nullptr;
277ec4974ddSAppaRao Puli                             errno = 0;
2781abe55efSEd Tanous                             // Use strtol instead of stroi to avoid
2791abe55efSEd Tanous                             // exceptions
2801abe55efSEd Tanous                             long port =
2811abe55efSEd Tanous                                 std::strtol(portStr.c_str(), &endPtr, 10);
282ec4974ddSAppaRao Puli                             if ((errno == 0) && (*endPtr == '\0'))
2831abe55efSEd Tanous                             {
2847e860f15SJohn Edward Broadbent                                 asyncResp->res.jsonValue[rfServiceKey]["Port"] =
2857e860f15SJohn Edward Broadbent                                     port;
2861abe55efSEd Tanous                             }
287ec4974ddSAppaRao Puli                             return;
288865fbb75SEd Tanous                         },
289865fbb75SEd Tanous                         "org.freedesktop.systemd1", socketPath,
290865fbb75SEd Tanous                         "org.freedesktop.DBus.Properties", "Get",
291865fbb75SEd Tanous                         "org.freedesktop.systemd1.Socket", "Listen");
292ec4974ddSAppaRao Puli 
293ec4974ddSAppaRao Puli                     // We found service, break the inner loop.
294ec4974ddSAppaRao Puli                     break;
295865fbb75SEd Tanous                 }
296865fbb75SEd Tanous             }
297865fbb75SEd Tanous         },
298865fbb75SEd Tanous         "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
299865fbb75SEd Tanous         "org.freedesktop.systemd1.Manager", "ListUnits");
300865fbb75SEd Tanous }
301501be32bSraviteja-b 
3022db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH
3037e860f15SJohn Edward Broadbent void handleHostnamePatch(const std::string& hostName,
3048d1b46d7Szhanghch05                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
305501be32bSraviteja-b {
306501be32bSraviteja-b     crow::connections::systemBus->async_method_call(
307501be32bSraviteja-b         [asyncResp](const boost::system::error_code ec) {
308501be32bSraviteja-b             if (ec)
309501be32bSraviteja-b             {
310501be32bSraviteja-b                 messages::internalError(asyncResp->res);
311501be32bSraviteja-b                 return;
312501be32bSraviteja-b             }
313501be32bSraviteja-b         },
3147e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/config",
315501be32bSraviteja-b         "org.freedesktop.DBus.Properties", "Set",
316501be32bSraviteja-b         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
317501be32bSraviteja-b         std::variant<std::string>(hostName));
318501be32bSraviteja-b }
3192db77d34SJohnathan Mantey #endif
320501be32bSraviteja-b 
3218d1b46d7Szhanghch05 void handleNTPProtocolEnabled(
3227e860f15SJohn Edward Broadbent     const bool& ntpEnabled, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
32320e6ea5dSraviteja-b {
32420e6ea5dSraviteja-b     std::string timeSyncMethod;
32520e6ea5dSraviteja-b     if (ntpEnabled)
32620e6ea5dSraviteja-b     {
3277e860f15SJohn Edward Broadbent         timeSyncMethod = "xyz.openbmc_project.Time.Synchronization.Method.NTP";
32820e6ea5dSraviteja-b     }
32920e6ea5dSraviteja-b     else
33020e6ea5dSraviteja-b     {
33120e6ea5dSraviteja-b         timeSyncMethod =
33220e6ea5dSraviteja-b             "xyz.openbmc_project.Time.Synchronization.Method.Manual";
33320e6ea5dSraviteja-b     }
33420e6ea5dSraviteja-b 
33520e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
33681ce609eSEd Tanous         [asyncResp](const boost::system::error_code errorCode) {
33781ce609eSEd Tanous             if (errorCode)
338cb13a392SEd Tanous             {
339cb13a392SEd Tanous                 messages::internalError(asyncResp->res);
340cb13a392SEd Tanous             }
341cb13a392SEd Tanous         },
3427e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method",
34320e6ea5dSraviteja-b         "org.freedesktop.DBus.Properties", "Set",
34420e6ea5dSraviteja-b         "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod",
34520e6ea5dSraviteja-b         std::variant<std::string>{timeSyncMethod});
34620e6ea5dSraviteja-b }
34720e6ea5dSraviteja-b 
3487e860f15SJohn Edward Broadbent void handleNTPServersPatch(const std::vector<std::string>& ntpServers,
3498d1b46d7Szhanghch05                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
35020e6ea5dSraviteja-b {
35120e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
352cf05f9dcSJohnathan Mantey         [asyncResp](const boost::system::error_code ec) {
35320e6ea5dSraviteja-b             if (ec)
35420e6ea5dSraviteja-b             {
35520e6ea5dSraviteja-b                 messages::internalError(asyncResp->res);
35620e6ea5dSraviteja-b                 return;
35720e6ea5dSraviteja-b             }
35820e6ea5dSraviteja-b         },
35920e6ea5dSraviteja-b         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0",
36020e6ea5dSraviteja-b         "org.freedesktop.DBus.Properties", "Set",
36120e6ea5dSraviteja-b         "xyz.openbmc_project.Network.EthernetInterface", "NTPServers",
36220e6ea5dSraviteja-b         std::variant<std::vector<std::string>>{ntpServers});
36320e6ea5dSraviteja-b }
36420e6ea5dSraviteja-b 
365e5a99777SAlbert Zhang void handleProtocolEnabled(const bool protocolEnabled,
366e5a99777SAlbert Zhang                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
367e5a99777SAlbert Zhang                            const std::string_view netBasePath)
36867a78d87STom Joseph {
36967a78d87STom Joseph     crow::connections::systemBus->async_method_call(
370e5a99777SAlbert Zhang         [protocolEnabled, asyncResp,
371e5a99777SAlbert Zhang          netBasePath](const boost::system::error_code ec,
37267a78d87STom Joseph                       const crow::openbmc_mapper::GetSubTreeType& subtree) {
37367a78d87STom Joseph             if (ec)
37467a78d87STom Joseph             {
37567a78d87STom Joseph                 messages::internalError(asyncResp->res);
37667a78d87STom Joseph                 return;
37767a78d87STom Joseph             }
37867a78d87STom Joseph 
37967a78d87STom Joseph             for (const auto& entry : subtree)
38067a78d87STom Joseph             {
381e5a99777SAlbert Zhang                 if (boost::algorithm::starts_with(entry.first, netBasePath))
38267a78d87STom Joseph                 {
38367a78d87STom Joseph                     crow::connections::systemBus->async_method_call(
38423a21a1cSEd Tanous                         [asyncResp](const boost::system::error_code ec2) {
38523a21a1cSEd Tanous                             if (ec2)
38667a78d87STom Joseph                             {
38767a78d87STom Joseph                                 messages::internalError(asyncResp->res);
38867a78d87STom Joseph                                 return;
38967a78d87STom Joseph                             }
39067a78d87STom Joseph                         },
39167a78d87STom Joseph                         entry.second.begin()->first, entry.first,
39267a78d87STom Joseph                         "org.freedesktop.DBus.Properties", "Set",
39367a78d87STom Joseph                         "xyz.openbmc_project.Control.Service.Attributes",
394e5a99777SAlbert Zhang                         "Running", std::variant<bool>{protocolEnabled});
39567a78d87STom Joseph 
39667a78d87STom Joseph                     crow::connections::systemBus->async_method_call(
39723a21a1cSEd Tanous                         [asyncResp](const boost::system::error_code ec2) {
39823a21a1cSEd Tanous                             if (ec2)
39967a78d87STom Joseph                             {
40067a78d87STom Joseph                                 messages::internalError(asyncResp->res);
40167a78d87STom Joseph                                 return;
40267a78d87STom Joseph                             }
40367a78d87STom Joseph                         },
40467a78d87STom Joseph                         entry.second.begin()->first, entry.first,
40567a78d87STom Joseph                         "org.freedesktop.DBus.Properties", "Set",
40667a78d87STom Joseph                         "xyz.openbmc_project.Control.Service.Attributes",
407e5a99777SAlbert Zhang                         "Enabled", std::variant<bool>{protocolEnabled});
40867a78d87STom Joseph                 }
40967a78d87STom Joseph             }
41067a78d87STom Joseph         },
41167a78d87STom Joseph         "xyz.openbmc_project.ObjectMapper",
41267a78d87STom Joseph         "/xyz/openbmc_project/object_mapper",
41367a78d87STom Joseph         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
41467a78d87STom Joseph         "/xyz/openbmc_project/control/service", 0,
41567a78d87STom Joseph         std::array<const char*, 1>{
41667a78d87STom Joseph             "xyz.openbmc_project.Control.Service.Attributes"});
41767a78d87STom Joseph }
41867a78d87STom Joseph 
4197e860f15SJohn Edward Broadbent std::string getHostName()
420501be32bSraviteja-b {
4217e860f15SJohn Edward Broadbent     std::string hostName;
4228d1b46d7Szhanghch05 
4237e860f15SJohn Edward Broadbent     std::array<char, HOST_NAME_MAX> hostNameCStr;
4247e860f15SJohn Edward Broadbent     if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
4257e860f15SJohn Edward Broadbent     {
4267e860f15SJohn Edward Broadbent         hostName = hostNameCStr.data();
4277e860f15SJohn Edward Broadbent     }
4287e860f15SJohn Edward Broadbent     return hostName;
4297e860f15SJohn Edward Broadbent }
4307e860f15SJohn Edward Broadbent 
4317e860f15SJohn Edward Broadbent void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
4327e860f15SJohn Edward Broadbent {
4337e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
4347e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code errorCode,
4357e860f15SJohn Edward Broadbent                     const std::variant<std::string>& timeSyncMethod) {
4367e860f15SJohn Edward Broadbent             if (errorCode)
4377e860f15SJohn Edward Broadbent             {
4387e860f15SJohn Edward Broadbent                 return;
4397e860f15SJohn Edward Broadbent             }
4407e860f15SJohn Edward Broadbent 
4417e860f15SJohn Edward Broadbent             const std::string* s = std::get_if<std::string>(&timeSyncMethod);
4427e860f15SJohn Edward Broadbent 
4437e860f15SJohn Edward Broadbent             if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP")
4447e860f15SJohn Edward Broadbent             {
4457e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true;
4467e860f15SJohn Edward Broadbent             }
4477e860f15SJohn Edward Broadbent             else if (*s == "xyz.openbmc_project.Time.Synchronization."
4487e860f15SJohn Edward Broadbent                            "Method.Manual")
4497e860f15SJohn Edward Broadbent             {
4507e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false;
4517e860f15SJohn Edward Broadbent             }
4527e860f15SJohn Edward Broadbent         },
4537e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method",
4547e860f15SJohn Edward Broadbent         "org.freedesktop.DBus.Properties", "Get",
4557e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod");
4567e860f15SJohn Edward Broadbent }
4577e860f15SJohn Edward Broadbent 
4587e860f15SJohn Edward Broadbent inline void requestRoutesNetworkProtocol(App& app)
4597e860f15SJohn Edward Broadbent {
4607e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
461432a890cSEd Tanous         .privileges({{"ConfigureManager"}})
4627e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
4637e860f15SJohn Edward Broadbent             [](const crow::Request& req,
4647e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
465501be32bSraviteja-b                 std::optional<std::string> newHostName;
466cf05f9dcSJohnathan Mantey                 std::optional<nlohmann::json> ntp;
46767a78d87STom Joseph                 std::optional<nlohmann::json> ipmi;
468e5a99777SAlbert Zhang                 std::optional<nlohmann::json> ssh;
469501be32bSraviteja-b 
4707e860f15SJohn Edward Broadbent                 if (!json_util::readJson(req, asyncResp->res, "NTP", ntp,
471e5a99777SAlbert Zhang                                          "HostName", newHostName, "IPMI", ipmi,
472e5a99777SAlbert Zhang                                          "SSH", ssh))
473501be32bSraviteja-b                 {
474501be32bSraviteja-b                     return;
475501be32bSraviteja-b                 }
476cf05f9dcSJohnathan Mantey 
4778d1b46d7Szhanghch05                 asyncResp->res.result(boost::beast::http::status::no_content);
478501be32bSraviteja-b                 if (newHostName)
479501be32bSraviteja-b                 {
4802db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH
481501be32bSraviteja-b                     handleHostnamePatch(*newHostName, asyncResp);
4822db77d34SJohnathan Mantey #else
4832db77d34SJohnathan Mantey                     messages::propertyNotWritable(asyncResp->res, "HostName");
4842db77d34SJohnathan Mantey #endif
485cf05f9dcSJohnathan Mantey                 }
486cf05f9dcSJohnathan Mantey 
487cf05f9dcSJohnathan Mantey                 if (ntp)
488cf05f9dcSJohnathan Mantey                 {
489cf05f9dcSJohnathan Mantey                     std::optional<std::vector<std::string>> ntpServers;
490cf05f9dcSJohnathan Mantey                     std::optional<bool> ntpEnabled;
4918d1b46d7Szhanghch05                     if (!json_util::readJson(*ntp, asyncResp->res, "NTPServers",
4927e860f15SJohn Edward Broadbent                                              ntpServers, "ProtocolEnabled",
4937e860f15SJohn Edward Broadbent                                              ntpEnabled))
494cf05f9dcSJohnathan Mantey                     {
495501be32bSraviteja-b                         return;
496501be32bSraviteja-b                     }
497cf05f9dcSJohnathan Mantey 
49820e6ea5dSraviteja-b                     if (ntpEnabled)
49920e6ea5dSraviteja-b                     {
50020e6ea5dSraviteja-b                         handleNTPProtocolEnabled(*ntpEnabled, asyncResp);
50120e6ea5dSraviteja-b                     }
502cf05f9dcSJohnathan Mantey 
50320e6ea5dSraviteja-b                     if (ntpServers)
50420e6ea5dSraviteja-b                     {
505dc3fbbd0STony Lee                         std::sort((*ntpServers).begin(), (*ntpServers).end());
506dc3fbbd0STony Lee                         (*ntpServers)
5077e860f15SJohn Edward Broadbent                             .erase(std::unique((*ntpServers).begin(),
5087e860f15SJohn Edward Broadbent                                                (*ntpServers).end()),
509dc3fbbd0STony Lee                                    (*ntpServers).end());
51020e6ea5dSraviteja-b                         handleNTPServersPatch(*ntpServers, asyncResp);
51120e6ea5dSraviteja-b                     }
512501be32bSraviteja-b                 }
51367a78d87STom Joseph 
51467a78d87STom Joseph                 if (ipmi)
51567a78d87STom Joseph                 {
51667a78d87STom Joseph                     std::optional<bool> ipmiProtocolEnabled;
5177e860f15SJohn Edward Broadbent                     if (!json_util::readJson(*ipmi, asyncResp->res,
5187e860f15SJohn Edward Broadbent                                              "ProtocolEnabled",
51967a78d87STom Joseph                                              ipmiProtocolEnabled))
52067a78d87STom Joseph                     {
52167a78d87STom Joseph                         return;
52267a78d87STom Joseph                     }
52367a78d87STom Joseph 
52467a78d87STom Joseph                     if (ipmiProtocolEnabled)
52567a78d87STom Joseph                     {
526e5a99777SAlbert Zhang                         handleProtocolEnabled(
527e5a99777SAlbert Zhang                             *ipmiProtocolEnabled, asyncResp,
528e5a99777SAlbert Zhang                             "/xyz/openbmc_project/control/service/"
529e5a99777SAlbert Zhang                             "phosphor_2dipmi_2dnet_40");
530e5a99777SAlbert Zhang                     }
531e5a99777SAlbert Zhang                 }
532e5a99777SAlbert Zhang 
533e5a99777SAlbert Zhang                 if (ssh)
534e5a99777SAlbert Zhang                 {
535e5a99777SAlbert Zhang                     std::optional<bool> sshProtocolEnabled;
536e5a99777SAlbert Zhang                     if (!json_util::readJson(*ssh, asyncResp->res,
537e5a99777SAlbert Zhang                                              "ProtocolEnabled",
538e5a99777SAlbert Zhang                                              sshProtocolEnabled))
539e5a99777SAlbert Zhang                     {
540e5a99777SAlbert Zhang                         return;
541e5a99777SAlbert Zhang                     }
542e5a99777SAlbert Zhang 
543e5a99777SAlbert Zhang                     if (sshProtocolEnabled)
544e5a99777SAlbert Zhang                     {
545e5a99777SAlbert Zhang                         handleProtocolEnabled(
546e5a99777SAlbert Zhang                             *sshProtocolEnabled, asyncResp,
547e5a99777SAlbert Zhang                             "/xyz/openbmc_project/control/service/dropbear");
54867a78d87STom Joseph                     }
54967a78d87STom Joseph                 }
5507e860f15SJohn Edward Broadbent             });
5517e860f15SJohn Edward Broadbent 
5527e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
553432a890cSEd Tanous         .privileges({{"Login"}})
5547e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
555*72048780SAbhishek Patel             [](const crow::Request& req,
5567e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
557*72048780SAbhishek Patel                 getNetworkData(asyncResp, req);
5587e860f15SJohn Edward Broadbent             });
559cf05f9dcSJohnathan Mantey }
56070141561SBorawski.Lukasz 
56170141561SBorawski.Lukasz } // namespace redfish
562