xref: /openbmc/bmcweb/features/redfish/lib/network_protocol.hpp (revision 4f48d5f67f293e50340e7f4bf866435e03a6fc62)
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>
22ed398213SEd Tanous #include <registries/privilege_registry.hpp>
2320e6ea5dSraviteja-b #include <utils/json_utils.hpp>
241214b7e7SGunnar Mills 
251214b7e7SGunnar Mills #include <optional>
26abf2add6SEd Tanous #include <variant>
271abe55efSEd Tanous namespace redfish
281abe55efSEd Tanous {
2970141561SBorawski.Lukasz 
307e860f15SJohn Edward Broadbent void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp);
317e860f15SJohn Edward Broadbent std::string getHostName();
327e860f15SJohn Edward Broadbent 
331abe55efSEd Tanous enum NetworkProtocolUnitStructFields
341abe55efSEd Tanous {
353a8a0088SKowalski, Kamil     NET_PROTO_UNIT_NAME,
363a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DESC,
373a8a0088SKowalski, Kamil     NET_PROTO_UNIT_LOAD_STATE,
383a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ACTIVE_STATE,
393a8a0088SKowalski, Kamil     NET_PROTO_UNIT_SUB_STATE,
403a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DEVICE,
413a8a0088SKowalski, Kamil     NET_PROTO_UNIT_OBJ_PATH,
423a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_0,
433a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_EMPTY,
443a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_ROOT_PATH
453a8a0088SKowalski, Kamil };
463a8a0088SKowalski, Kamil 
471abe55efSEd Tanous enum NetworkProtocolListenResponseElements
481abe55efSEd Tanous {
493a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_TYPE,
503a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_STREAM
513a8a0088SKowalski, Kamil };
523a8a0088SKowalski, Kamil 
533a8a0088SKowalski, Kamil /**
543a8a0088SKowalski, Kamil  * @brief D-Bus Unit structure returned in array from ListUnits Method
553a8a0088SKowalski, Kamil  */
563a8a0088SKowalski, Kamil using UnitStruct =
573a8a0088SKowalski, Kamil     std::tuple<std::string, std::string, std::string, std::string, std::string,
583a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path, uint32_t,
593a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path>;
603a8a0088SKowalski, Kamil 
61b0972a63SEd Tanous const static std::array<std::pair<const char*, const char*>, 3> protocolToDBus{
62b0972a63SEd Tanous     {{"SSH", "dropbear"}, {"HTTPS", "bmcweb"}, {"IPMI", "phosphor-ipmi-net"}}};
633a8a0088SKowalski, Kamil 
64d24bfc7aSJennifer Lee inline void
6581ce609eSEd Tanous     extractNTPServersAndDomainNamesData(const GetManagedObjects& dbusData,
66d24bfc7aSJennifer Lee                                         std::vector<std::string>& ntpData,
67d24bfc7aSJennifer Lee                                         std::vector<std::string>& dnData)
6820e6ea5dSraviteja-b {
6981ce609eSEd Tanous     for (const auto& obj : dbusData)
7020e6ea5dSraviteja-b     {
7120e6ea5dSraviteja-b         for (const auto& ifacePair : obj.second)
7220e6ea5dSraviteja-b         {
7320e6ea5dSraviteja-b             if (obj.first == "/xyz/openbmc_project/network/eth0")
7420e6ea5dSraviteja-b             {
7520e6ea5dSraviteja-b                 if (ifacePair.first ==
7620e6ea5dSraviteja-b                     "xyz.openbmc_project.Network.EthernetInterface")
7720e6ea5dSraviteja-b                 {
7820e6ea5dSraviteja-b                     for (const auto& propertyPair : ifacePair.second)
7920e6ea5dSraviteja-b                     {
8020e6ea5dSraviteja-b                         if (propertyPair.first == "NTPServers")
8120e6ea5dSraviteja-b                         {
8220e6ea5dSraviteja-b                             const std::vector<std::string>* ntpServers =
838d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
8420e6ea5dSraviteja-b                                     &propertyPair.second);
8520e6ea5dSraviteja-b                             if (ntpServers != nullptr)
8620e6ea5dSraviteja-b                             {
87f23b7296SEd Tanous                                 ntpData = *ntpServers;
8820e6ea5dSraviteja-b                             }
8920e6ea5dSraviteja-b                         }
90d24bfc7aSJennifer Lee                         else if (propertyPair.first == "DomainName")
91d24bfc7aSJennifer Lee                         {
92d24bfc7aSJennifer Lee                             const std::vector<std::string>* domainNames =
938d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
94d24bfc7aSJennifer Lee                                     &propertyPair.second);
95d24bfc7aSJennifer Lee                             if (domainNames != nullptr)
96d24bfc7aSJennifer Lee                             {
97f23b7296SEd Tanous                                 dnData = *domainNames;
98d24bfc7aSJennifer Lee                             }
99d24bfc7aSJennifer Lee                         }
10020e6ea5dSraviteja-b                     }
10120e6ea5dSraviteja-b                 }
10220e6ea5dSraviteja-b             }
10320e6ea5dSraviteja-b         }
10420e6ea5dSraviteja-b     }
10520e6ea5dSraviteja-b }
10620e6ea5dSraviteja-b 
10720e6ea5dSraviteja-b template <typename CallbackFunc>
10820e6ea5dSraviteja-b void getEthernetIfaceData(CallbackFunc&& callback)
10920e6ea5dSraviteja-b {
11020e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
11120e6ea5dSraviteja-b         [callback{std::move(callback)}](
11281ce609eSEd Tanous             const boost::system::error_code errorCode,
11381ce609eSEd Tanous             const GetManagedObjects& dbusData) {
11420e6ea5dSraviteja-b             std::vector<std::string> ntpServers;
115d24bfc7aSJennifer Lee             std::vector<std::string> domainNames;
11620e6ea5dSraviteja-b 
11781ce609eSEd Tanous             if (errorCode)
11820e6ea5dSraviteja-b             {
119d24bfc7aSJennifer Lee                 callback(false, ntpServers, domainNames);
12020e6ea5dSraviteja-b                 return;
12120e6ea5dSraviteja-b             }
12220e6ea5dSraviteja-b 
12381ce609eSEd Tanous             extractNTPServersAndDomainNamesData(dbusData, ntpServers,
124d24bfc7aSJennifer Lee                                                 domainNames);
12520e6ea5dSraviteja-b 
126d24bfc7aSJennifer Lee             callback(true, ntpServers, domainNames);
12720e6ea5dSraviteja-b         },
12820e6ea5dSraviteja-b         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
12920e6ea5dSraviteja-b         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
130271584abSEd Tanous }
13120e6ea5dSraviteja-b 
132*4f48d5f6SEd Tanous inline void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
13372048780SAbhishek Patel                            const crow::Request& req)
1341abe55efSEd Tanous {
1350f74e643SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
13661932318SXiaochao Ma         "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol";
1370f74e643SEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
1380f74e643SEd Tanous         "/redfish/v1/Managers/bmc/NetworkProtocol";
1390f74e643SEd Tanous     asyncResp->res.jsonValue["Id"] = "NetworkProtocol";
1400f74e643SEd Tanous     asyncResp->res.jsonValue["Name"] = "Manager Network Protocol";
1410f74e643SEd Tanous     asyncResp->res.jsonValue["Description"] = "Manager Network Service";
1420f74e643SEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
1430f74e643SEd Tanous     asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
1440f74e643SEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
1450f74e643SEd Tanous 
14661932318SXiaochao Ma     // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0,
147818ea7b8SJoshi-Mansi     // but from security perspective it is not recommended to use.
148818ea7b8SJoshi-Mansi     // Hence using protocolEnabled as false to make it OCP and security-wise
149818ea7b8SJoshi-Mansi     // compliant
150818ea7b8SJoshi-Mansi     asyncResp->res.jsonValue["HTTP"]["Port"] = 0;
151818ea7b8SJoshi-Mansi     asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false;
152818ea7b8SJoshi-Mansi 
1530f74e643SEd Tanous     for (auto& protocol : protocolToDBus)
1540f74e643SEd Tanous     {
1550870f8c7SJayaprakash Mutyala         asyncResp->res.jsonValue[protocol.first]["Port"] =
1560870f8c7SJayaprakash Mutyala             nlohmann::detail::value_t::null;
1570f74e643SEd Tanous         asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false;
1580f74e643SEd Tanous     }
1590f74e643SEd Tanous 
160d24bfc7aSJennifer Lee     std::string hostName = getHostName();
161d24bfc7aSJennifer Lee 
162d24bfc7aSJennifer Lee     asyncResp->res.jsonValue["HostName"] = hostName;
1633a8a0088SKowalski, Kamil 
16420e6ea5dSraviteja-b     getNTPProtocolEnabled(asyncResp);
16520e6ea5dSraviteja-b 
16620e6ea5dSraviteja-b     // TODO Get eth0 interface data, and call the below callback for JSON
16720e6ea5dSraviteja-b     // preparation
168271584abSEd Tanous     getEthernetIfaceData(
169271584abSEd Tanous         [hostName, asyncResp](const bool& success,
170d24bfc7aSJennifer Lee                               const std::vector<std::string>& ntpServers,
171d24bfc7aSJennifer Lee                               const std::vector<std::string>& domainNames) {
17220e6ea5dSraviteja-b             if (!success)
17320e6ea5dSraviteja-b             {
1747e860f15SJohn Edward Broadbent                 messages::resourceNotFound(asyncResp->res, "EthernetInterface",
1757e860f15SJohn Edward Broadbent                                            "eth0");
17620e6ea5dSraviteja-b                 return;
17720e6ea5dSraviteja-b             }
17820e6ea5dSraviteja-b             asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers;
179d24bfc7aSJennifer Lee             if (hostName.empty() == false)
180d24bfc7aSJennifer Lee             {
181f23b7296SEd Tanous                 std::string fqdn = hostName;
182d24bfc7aSJennifer Lee                 if (domainNames.empty() == false)
183d24bfc7aSJennifer Lee                 {
184f23b7296SEd Tanous                     fqdn += ".";
185f23b7296SEd Tanous                     fqdn += domainNames[0];
186d24bfc7aSJennifer Lee                 }
1872c70f800SEd Tanous                 asyncResp->res.jsonValue["FQDN"] = std::move(fqdn);
188d24bfc7aSJennifer Lee             }
18920e6ea5dSraviteja-b         });
19020e6ea5dSraviteja-b 
19172048780SAbhishek Patel     Privileges effectiveUserPrivileges =
19272048780SAbhishek Patel         redfish::getUserPrivileges(req.userRole);
19372048780SAbhishek Patel 
194865fbb75SEd Tanous     crow::connections::systemBus->async_method_call(
19572048780SAbhishek Patel         [asyncResp,
19672048780SAbhishek Patel          &effectiveUserPrivileges](const boost::system::error_code e,
197271584abSEd Tanous                                    const std::vector<UnitStruct>& r) {
198271584abSEd Tanous             if (e)
1991abe55efSEd Tanous             {
2003a8a0088SKowalski, Kamil                 asyncResp->res.jsonValue = nlohmann::json::object();
201f12894f8SJason M. Bills                 messages::internalError(asyncResp->res);
202865fbb75SEd Tanous                 return;
2033a8a0088SKowalski, Kamil             }
20472048780SAbhishek Patel             // /redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates is
20572048780SAbhishek Patel             // something only ConfigureManager can access then only display when
20672048780SAbhishek Patel             // the user has permissions ConfigureManager
20772048780SAbhishek Patel             if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
20872048780SAbhishek Patel                                                  effectiveUserPrivileges))
20972048780SAbhishek Patel             {
2105968caeeSMarri Devender Rao                 asyncResp->res.jsonValue["HTTPS"]["Certificates"] = {
2115968caeeSMarri Devender Rao                     {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol/"
212659dd62eSJason M. Bills                                   "HTTPS/Certificates"}};
21372048780SAbhishek Patel             }
214271584abSEd Tanous             for (auto& unit : r)
2151abe55efSEd Tanous             {
216ec4974ddSAppaRao Puli                 /* Only traverse through <xyz>.socket units */
2173174e4dfSEd Tanous                 const std::string& unitName =
2183174e4dfSEd Tanous                     std::get<NET_PROTO_UNIT_NAME>(unit);
219ec4974ddSAppaRao Puli                 if (!boost::ends_with(unitName, ".socket"))
2201abe55efSEd Tanous                 {
221865fbb75SEd Tanous                     continue;
22270141561SBorawski.Lukasz                 }
22370141561SBorawski.Lukasz 
224ec4974ddSAppaRao Puli                 for (auto& kv : protocolToDBus)
225ec4974ddSAppaRao Puli                 {
226ec4974ddSAppaRao Puli                     // We are interested in services, which starts with
227ec4974ddSAppaRao Puli                     // mapped service name
228ec4974ddSAppaRao Puli                     if (!boost::starts_with(unitName, kv.second))
229ec4974ddSAppaRao Puli                     {
230ec4974ddSAppaRao Puli                         continue;
231ec4974ddSAppaRao Puli                     }
232ec4974ddSAppaRao Puli                     const char* rfServiceKey = kv.first;
2333174e4dfSEd Tanous                     const std::string& socketPath =
234ec4974ddSAppaRao Puli                         std::get<NET_PROTO_UNIT_OBJ_PATH>(unit);
2353174e4dfSEd Tanous                     const std::string& unitState =
236ec4974ddSAppaRao Puli                         std::get<NET_PROTO_UNIT_SUB_STATE>(unit);
237ec4974ddSAppaRao Puli 
2387e860f15SJohn Edward Broadbent                     asyncResp->res.jsonValue[rfServiceKey]["ProtocolEnabled"] =
2397e860f15SJohn Edward Broadbent                         (unitState == "running") || (unitState == "listening");
240ec4974ddSAppaRao Puli 
241865fbb75SEd Tanous                     crow::connections::systemBus->async_method_call(
2427e860f15SJohn Edward Broadbent                         [asyncResp, rfServiceKey{std::string(rfServiceKey)}](
243865fbb75SEd Tanous                             const boost::system::error_code ec,
2447e860f15SJohn Edward Broadbent                             const std::variant<std::vector<
2457e860f15SJohn Edward Broadbent                                 std::tuple<std::string, std::string>>>& resp) {
2461abe55efSEd Tanous                             if (ec)
2471abe55efSEd Tanous                             {
248a08b46ccSJason M. Bills                                 messages::internalError(asyncResp->res);
249865fbb75SEd Tanous                                 return;
2503a8a0088SKowalski, Kamil                             }
251abf2add6SEd Tanous                             const std::vector<
252abf2add6SEd Tanous                                 std::tuple<std::string, std::string>>*
253abf2add6SEd Tanous                                 responsePtr = std::get_if<std::vector<
254abf2add6SEd Tanous                                     std::tuple<std::string, std::string>>>(
2551b6b96c5SEd Tanous                                     &resp);
2561abe55efSEd Tanous                             if (responsePtr == nullptr ||
2571abe55efSEd Tanous                                 responsePtr->size() < 1)
2581abe55efSEd Tanous                             {
259865fbb75SEd Tanous                                 return;
26070141561SBorawski.Lukasz                             }
26170141561SBorawski.Lukasz 
262865fbb75SEd Tanous                             const std::string& listenStream =
2631abe55efSEd Tanous                                 std::get<NET_PROTO_LISTEN_STREAM>(
2641abe55efSEd Tanous                                     (*responsePtr)[0]);
2657e860f15SJohn Edward Broadbent                             std::size_t lastColonPos = listenStream.rfind(':');
2661abe55efSEd Tanous                             if (lastColonPos == std::string::npos)
2671abe55efSEd Tanous                             {
268865fbb75SEd Tanous                                 // Not a port
269865fbb75SEd Tanous                                 return;
270865fbb75SEd Tanous                             }
2711abe55efSEd Tanous                             std::string portStr =
2721abe55efSEd Tanous                                 listenStream.substr(lastColonPos + 1);
273ec4974ddSAppaRao Puli                             if (portStr.empty())
274ec4974ddSAppaRao Puli                             {
275ec4974ddSAppaRao Puli                                 return;
276ec4974ddSAppaRao Puli                             }
277865fbb75SEd Tanous                             char* endPtr = nullptr;
278ec4974ddSAppaRao Puli                             errno = 0;
2791abe55efSEd Tanous                             // Use strtol instead of stroi to avoid
2801abe55efSEd Tanous                             // exceptions
2811abe55efSEd Tanous                             long port =
2821abe55efSEd Tanous                                 std::strtol(portStr.c_str(), &endPtr, 10);
283ec4974ddSAppaRao Puli                             if ((errno == 0) && (*endPtr == '\0'))
2841abe55efSEd Tanous                             {
2857e860f15SJohn Edward Broadbent                                 asyncResp->res.jsonValue[rfServiceKey]["Port"] =
2867e860f15SJohn Edward Broadbent                                     port;
2871abe55efSEd Tanous                             }
288ec4974ddSAppaRao Puli                             return;
289865fbb75SEd Tanous                         },
290865fbb75SEd Tanous                         "org.freedesktop.systemd1", socketPath,
291865fbb75SEd Tanous                         "org.freedesktop.DBus.Properties", "Get",
292865fbb75SEd Tanous                         "org.freedesktop.systemd1.Socket", "Listen");
293ec4974ddSAppaRao Puli 
294ec4974ddSAppaRao Puli                     // We found service, break the inner loop.
295ec4974ddSAppaRao Puli                     break;
296865fbb75SEd Tanous                 }
297865fbb75SEd Tanous             }
298865fbb75SEd Tanous         },
299865fbb75SEd Tanous         "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
300865fbb75SEd Tanous         "org.freedesktop.systemd1.Manager", "ListUnits");
301865fbb75SEd Tanous }
302501be32bSraviteja-b 
3032db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH
304*4f48d5f6SEd Tanous inline void
305*4f48d5f6SEd Tanous     handleHostnamePatch(const std::string& hostName,
3068d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
307501be32bSraviteja-b {
308501be32bSraviteja-b     crow::connections::systemBus->async_method_call(
309501be32bSraviteja-b         [asyncResp](const boost::system::error_code ec) {
310501be32bSraviteja-b             if (ec)
311501be32bSraviteja-b             {
312501be32bSraviteja-b                 messages::internalError(asyncResp->res);
313501be32bSraviteja-b                 return;
314501be32bSraviteja-b             }
315501be32bSraviteja-b         },
3167e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/config",
317501be32bSraviteja-b         "org.freedesktop.DBus.Properties", "Set",
318501be32bSraviteja-b         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
319501be32bSraviteja-b         std::variant<std::string>(hostName));
320501be32bSraviteja-b }
3212db77d34SJohnathan Mantey #endif
322501be32bSraviteja-b 
323*4f48d5f6SEd Tanous inline void handleNTPProtocolEnabled(
3247e860f15SJohn Edward Broadbent     const bool& ntpEnabled, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
32520e6ea5dSraviteja-b {
32620e6ea5dSraviteja-b     std::string timeSyncMethod;
32720e6ea5dSraviteja-b     if (ntpEnabled)
32820e6ea5dSraviteja-b     {
3297e860f15SJohn Edward Broadbent         timeSyncMethod = "xyz.openbmc_project.Time.Synchronization.Method.NTP";
33020e6ea5dSraviteja-b     }
33120e6ea5dSraviteja-b     else
33220e6ea5dSraviteja-b     {
33320e6ea5dSraviteja-b         timeSyncMethod =
33420e6ea5dSraviteja-b             "xyz.openbmc_project.Time.Synchronization.Method.Manual";
33520e6ea5dSraviteja-b     }
33620e6ea5dSraviteja-b 
33720e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
33881ce609eSEd Tanous         [asyncResp](const boost::system::error_code errorCode) {
33981ce609eSEd Tanous             if (errorCode)
340cb13a392SEd Tanous             {
341cb13a392SEd Tanous                 messages::internalError(asyncResp->res);
342cb13a392SEd Tanous             }
343cb13a392SEd Tanous         },
3447e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method",
34520e6ea5dSraviteja-b         "org.freedesktop.DBus.Properties", "Set",
34620e6ea5dSraviteja-b         "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod",
34720e6ea5dSraviteja-b         std::variant<std::string>{timeSyncMethod});
34820e6ea5dSraviteja-b }
34920e6ea5dSraviteja-b 
350*4f48d5f6SEd Tanous inline void
351*4f48d5f6SEd Tanous     handleNTPServersPatch(const std::vector<std::string>& ntpServers,
3528d1b46d7Szhanghch05                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
35320e6ea5dSraviteja-b {
35420e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
355cf05f9dcSJohnathan Mantey         [asyncResp](const boost::system::error_code ec) {
35620e6ea5dSraviteja-b             if (ec)
35720e6ea5dSraviteja-b             {
35820e6ea5dSraviteja-b                 messages::internalError(asyncResp->res);
35920e6ea5dSraviteja-b                 return;
36020e6ea5dSraviteja-b             }
36120e6ea5dSraviteja-b         },
36220e6ea5dSraviteja-b         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0",
36320e6ea5dSraviteja-b         "org.freedesktop.DBus.Properties", "Set",
36420e6ea5dSraviteja-b         "xyz.openbmc_project.Network.EthernetInterface", "NTPServers",
36520e6ea5dSraviteja-b         std::variant<std::vector<std::string>>{ntpServers});
36620e6ea5dSraviteja-b }
36720e6ea5dSraviteja-b 
368*4f48d5f6SEd Tanous inline void
369*4f48d5f6SEd Tanous     handleProtocolEnabled(const bool protocolEnabled,
370e5a99777SAlbert Zhang                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
371e5a99777SAlbert Zhang                           const std::string_view netBasePath)
37267a78d87STom Joseph {
37367a78d87STom Joseph     crow::connections::systemBus->async_method_call(
374e5a99777SAlbert Zhang         [protocolEnabled, asyncResp,
375e5a99777SAlbert Zhang          netBasePath](const boost::system::error_code ec,
37667a78d87STom Joseph                       const crow::openbmc_mapper::GetSubTreeType& subtree) {
37767a78d87STom Joseph             if (ec)
37867a78d87STom Joseph             {
37967a78d87STom Joseph                 messages::internalError(asyncResp->res);
38067a78d87STom Joseph                 return;
38167a78d87STom Joseph             }
38267a78d87STom Joseph 
38367a78d87STom Joseph             for (const auto& entry : subtree)
38467a78d87STom Joseph             {
385e5a99777SAlbert Zhang                 if (boost::algorithm::starts_with(entry.first, netBasePath))
38667a78d87STom Joseph                 {
38767a78d87STom Joseph                     crow::connections::systemBus->async_method_call(
38823a21a1cSEd Tanous                         [asyncResp](const boost::system::error_code ec2) {
38923a21a1cSEd Tanous                             if (ec2)
39067a78d87STom Joseph                             {
39167a78d87STom Joseph                                 messages::internalError(asyncResp->res);
39267a78d87STom Joseph                                 return;
39367a78d87STom Joseph                             }
39467a78d87STom Joseph                         },
39567a78d87STom Joseph                         entry.second.begin()->first, entry.first,
39667a78d87STom Joseph                         "org.freedesktop.DBus.Properties", "Set",
39767a78d87STom Joseph                         "xyz.openbmc_project.Control.Service.Attributes",
398e5a99777SAlbert Zhang                         "Running", std::variant<bool>{protocolEnabled});
39967a78d87STom Joseph 
40067a78d87STom Joseph                     crow::connections::systemBus->async_method_call(
40123a21a1cSEd Tanous                         [asyncResp](const boost::system::error_code ec2) {
40223a21a1cSEd Tanous                             if (ec2)
40367a78d87STom Joseph                             {
40467a78d87STom Joseph                                 messages::internalError(asyncResp->res);
40567a78d87STom Joseph                                 return;
40667a78d87STom Joseph                             }
40767a78d87STom Joseph                         },
40867a78d87STom Joseph                         entry.second.begin()->first, entry.first,
40967a78d87STom Joseph                         "org.freedesktop.DBus.Properties", "Set",
41067a78d87STom Joseph                         "xyz.openbmc_project.Control.Service.Attributes",
411e5a99777SAlbert Zhang                         "Enabled", std::variant<bool>{protocolEnabled});
41267a78d87STom Joseph                 }
41367a78d87STom Joseph             }
41467a78d87STom Joseph         },
41567a78d87STom Joseph         "xyz.openbmc_project.ObjectMapper",
41667a78d87STom Joseph         "/xyz/openbmc_project/object_mapper",
41767a78d87STom Joseph         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
41867a78d87STom Joseph         "/xyz/openbmc_project/control/service", 0,
41967a78d87STom Joseph         std::array<const char*, 1>{
42067a78d87STom Joseph             "xyz.openbmc_project.Control.Service.Attributes"});
42167a78d87STom Joseph }
42267a78d87STom Joseph 
423*4f48d5f6SEd Tanous inline std::string getHostName()
424501be32bSraviteja-b {
4257e860f15SJohn Edward Broadbent     std::string hostName;
4268d1b46d7Szhanghch05 
4277e860f15SJohn Edward Broadbent     std::array<char, HOST_NAME_MAX> hostNameCStr;
4287e860f15SJohn Edward Broadbent     if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
4297e860f15SJohn Edward Broadbent     {
4307e860f15SJohn Edward Broadbent         hostName = hostNameCStr.data();
4317e860f15SJohn Edward Broadbent     }
4327e860f15SJohn Edward Broadbent     return hostName;
4337e860f15SJohn Edward Broadbent }
4347e860f15SJohn Edward Broadbent 
435*4f48d5f6SEd Tanous inline void
436*4f48d5f6SEd Tanous     getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
4377e860f15SJohn Edward Broadbent {
4387e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
4397e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code errorCode,
4407e860f15SJohn Edward Broadbent                     const std::variant<std::string>& timeSyncMethod) {
4417e860f15SJohn Edward Broadbent             if (errorCode)
4427e860f15SJohn Edward Broadbent             {
4437e860f15SJohn Edward Broadbent                 return;
4447e860f15SJohn Edward Broadbent             }
4457e860f15SJohn Edward Broadbent 
4467e860f15SJohn Edward Broadbent             const std::string* s = std::get_if<std::string>(&timeSyncMethod);
4477e860f15SJohn Edward Broadbent 
4487e860f15SJohn Edward Broadbent             if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP")
4497e860f15SJohn Edward Broadbent             {
4507e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true;
4517e860f15SJohn Edward Broadbent             }
4527e860f15SJohn Edward Broadbent             else if (*s == "xyz.openbmc_project.Time.Synchronization."
4537e860f15SJohn Edward Broadbent                            "Method.Manual")
4547e860f15SJohn Edward Broadbent             {
4557e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false;
4567e860f15SJohn Edward Broadbent             }
4577e860f15SJohn Edward Broadbent         },
4587e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method",
4597e860f15SJohn Edward Broadbent         "org.freedesktop.DBus.Properties", "Get",
4607e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod");
4617e860f15SJohn Edward Broadbent }
4627e860f15SJohn Edward Broadbent 
4637e860f15SJohn Edward Broadbent inline void requestRoutesNetworkProtocol(App& app)
4647e860f15SJohn Edward Broadbent {
4657e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
466ed398213SEd Tanous         .privileges(redfish::privileges::patchManagerNetworkProtocol)
4677e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
4687e860f15SJohn Edward Broadbent             [](const crow::Request& req,
4697e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
470501be32bSraviteja-b                 std::optional<std::string> newHostName;
471cf05f9dcSJohnathan Mantey                 std::optional<nlohmann::json> ntp;
47267a78d87STom Joseph                 std::optional<nlohmann::json> ipmi;
473e5a99777SAlbert Zhang                 std::optional<nlohmann::json> ssh;
474501be32bSraviteja-b 
4757e860f15SJohn Edward Broadbent                 if (!json_util::readJson(req, asyncResp->res, "NTP", ntp,
476e5a99777SAlbert Zhang                                          "HostName", newHostName, "IPMI", ipmi,
477e5a99777SAlbert Zhang                                          "SSH", ssh))
478501be32bSraviteja-b                 {
479501be32bSraviteja-b                     return;
480501be32bSraviteja-b                 }
481cf05f9dcSJohnathan Mantey 
4828d1b46d7Szhanghch05                 asyncResp->res.result(boost::beast::http::status::no_content);
483501be32bSraviteja-b                 if (newHostName)
484501be32bSraviteja-b                 {
4852db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH
486501be32bSraviteja-b                     handleHostnamePatch(*newHostName, asyncResp);
4872db77d34SJohnathan Mantey #else
4882db77d34SJohnathan Mantey                     messages::propertyNotWritable(asyncResp->res, "HostName");
4892db77d34SJohnathan Mantey #endif
490cf05f9dcSJohnathan Mantey                 }
491cf05f9dcSJohnathan Mantey 
492cf05f9dcSJohnathan Mantey                 if (ntp)
493cf05f9dcSJohnathan Mantey                 {
494cf05f9dcSJohnathan Mantey                     std::optional<std::vector<std::string>> ntpServers;
495cf05f9dcSJohnathan Mantey                     std::optional<bool> ntpEnabled;
4968d1b46d7Szhanghch05                     if (!json_util::readJson(*ntp, asyncResp->res, "NTPServers",
4977e860f15SJohn Edward Broadbent                                              ntpServers, "ProtocolEnabled",
4987e860f15SJohn Edward Broadbent                                              ntpEnabled))
499cf05f9dcSJohnathan Mantey                     {
500501be32bSraviteja-b                         return;
501501be32bSraviteja-b                     }
502cf05f9dcSJohnathan Mantey 
50320e6ea5dSraviteja-b                     if (ntpEnabled)
50420e6ea5dSraviteja-b                     {
50520e6ea5dSraviteja-b                         handleNTPProtocolEnabled(*ntpEnabled, asyncResp);
50620e6ea5dSraviteja-b                     }
507cf05f9dcSJohnathan Mantey 
50820e6ea5dSraviteja-b                     if (ntpServers)
50920e6ea5dSraviteja-b                     {
510dc3fbbd0STony Lee                         std::sort((*ntpServers).begin(), (*ntpServers).end());
511dc3fbbd0STony Lee                         (*ntpServers)
5127e860f15SJohn Edward Broadbent                             .erase(std::unique((*ntpServers).begin(),
5137e860f15SJohn Edward Broadbent                                                (*ntpServers).end()),
514dc3fbbd0STony Lee                                    (*ntpServers).end());
51520e6ea5dSraviteja-b                         handleNTPServersPatch(*ntpServers, asyncResp);
51620e6ea5dSraviteja-b                     }
517501be32bSraviteja-b                 }
51867a78d87STom Joseph 
51967a78d87STom Joseph                 if (ipmi)
52067a78d87STom Joseph                 {
52167a78d87STom Joseph                     std::optional<bool> ipmiProtocolEnabled;
5227e860f15SJohn Edward Broadbent                     if (!json_util::readJson(*ipmi, asyncResp->res,
5237e860f15SJohn Edward Broadbent                                              "ProtocolEnabled",
52467a78d87STom Joseph                                              ipmiProtocolEnabled))
52567a78d87STom Joseph                     {
52667a78d87STom Joseph                         return;
52767a78d87STom Joseph                     }
52867a78d87STom Joseph 
52967a78d87STom Joseph                     if (ipmiProtocolEnabled)
53067a78d87STom Joseph                     {
531e5a99777SAlbert Zhang                         handleProtocolEnabled(
532e5a99777SAlbert Zhang                             *ipmiProtocolEnabled, asyncResp,
533e5a99777SAlbert Zhang                             "/xyz/openbmc_project/control/service/"
534e5a99777SAlbert Zhang                             "phosphor_2dipmi_2dnet_40");
535e5a99777SAlbert Zhang                     }
536e5a99777SAlbert Zhang                 }
537e5a99777SAlbert Zhang 
538e5a99777SAlbert Zhang                 if (ssh)
539e5a99777SAlbert Zhang                 {
540e5a99777SAlbert Zhang                     std::optional<bool> sshProtocolEnabled;
541e5a99777SAlbert Zhang                     if (!json_util::readJson(*ssh, asyncResp->res,
542e5a99777SAlbert Zhang                                              "ProtocolEnabled",
543e5a99777SAlbert Zhang                                              sshProtocolEnabled))
544e5a99777SAlbert Zhang                     {
545e5a99777SAlbert Zhang                         return;
546e5a99777SAlbert Zhang                     }
547e5a99777SAlbert Zhang 
548e5a99777SAlbert Zhang                     if (sshProtocolEnabled)
549e5a99777SAlbert Zhang                     {
550e5a99777SAlbert Zhang                         handleProtocolEnabled(
551e5a99777SAlbert Zhang                             *sshProtocolEnabled, asyncResp,
552e5a99777SAlbert Zhang                             "/xyz/openbmc_project/control/service/dropbear");
55367a78d87STom Joseph                     }
55467a78d87STom Joseph                 }
5557e860f15SJohn Edward Broadbent             });
5567e860f15SJohn Edward Broadbent 
5577e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
558ed398213SEd Tanous         .privileges(redfish::privileges::getManagerNetworkProtocol)
5597e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
56072048780SAbhishek Patel             [](const crow::Request& req,
5617e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
56272048780SAbhishek Patel                 getNetworkData(asyncResp, req);
5637e860f15SJohn Edward Broadbent             });
564cf05f9dcSJohnathan Mantey }
56570141561SBorawski.Lukasz 
56670141561SBorawski.Lukasz } // namespace redfish
567