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 1870141561SBorawski.Lukasz #include "node.hpp" 1970141561SBorawski.Lukasz 2070141561SBorawski.Lukasz namespace redfish { 2170141561SBorawski.Lukasz 2270141561SBorawski.Lukasz class NetworkProtocol : public Node { 2370141561SBorawski.Lukasz public: 2470141561SBorawski.Lukasz NetworkProtocol(CrowApp& app) 253ebd75f7SEd Tanous : Node(app, 2670141561SBorawski.Lukasz "/redfish/v1/Managers/openbmc/NetworkProtocol") { 2770141561SBorawski.Lukasz Node::json["@odata.type"] = 2870141561SBorawski.Lukasz "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol"; 2970141561SBorawski.Lukasz Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc/NetworkProtocol"; 3070141561SBorawski.Lukasz Node::json["@odata.context"] = 3170141561SBorawski.Lukasz "/redfish/v1/$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol"; 3270141561SBorawski.Lukasz Node::json["Id"] = "NetworkProtocol"; 3370141561SBorawski.Lukasz Node::json["Name"] = "Manager Network Protocol"; 3470141561SBorawski.Lukasz Node::json["Description"] = "Manager Network Service"; 3570141561SBorawski.Lukasz Node::json["Status"]["Health"] = "OK"; 3670141561SBorawski.Lukasz Node::json["Status"]["HealthRollup"] = "OK"; 3770141561SBorawski.Lukasz Node::json["Status"]["State"] = "Enabled"; 383ebd75f7SEd Tanous 39*e0d918bcSEd Tanous entityPrivileges = {{boost::beast::http::verb::get, {{"Login"}}}, 40*e0d918bcSEd Tanous {boost::beast::http::verb::head, {{"Login"}}}, 41*e0d918bcSEd Tanous {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 42*e0d918bcSEd Tanous {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 43*e0d918bcSEd Tanous {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 44*e0d918bcSEd Tanous {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 4570141561SBorawski.Lukasz } 4670141561SBorawski.Lukasz 4770141561SBorawski.Lukasz private: 4870141561SBorawski.Lukasz void doGet(crow::response& res, const crow::request& req, 4970141561SBorawski.Lukasz const std::vector<std::string>& params) override { 5070141561SBorawski.Lukasz refreshProtocolsState(); 5170141561SBorawski.Lukasz Node::json["HostName"] = getHostName(); 5270141561SBorawski.Lukasz res.json_value = Node::json; 5370141561SBorawski.Lukasz res.end(); 5470141561SBorawski.Lukasz } 5570141561SBorawski.Lukasz 5670141561SBorawski.Lukasz std::string getHostName() const { 5770141561SBorawski.Lukasz std::string hostName; 5870141561SBorawski.Lukasz 5970141561SBorawski.Lukasz std::array<char, HOST_NAME_MAX> hostNameCStr; 6070141561SBorawski.Lukasz if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) { 6170141561SBorawski.Lukasz hostName = hostNameCStr.data(); 6270141561SBorawski.Lukasz } 6370141561SBorawski.Lukasz return hostName; 6470141561SBorawski.Lukasz } 6570141561SBorawski.Lukasz 6670141561SBorawski.Lukasz void refreshProtocolsState() { 6770141561SBorawski.Lukasz refreshListeningPorts(); 6870141561SBorawski.Lukasz for (auto& kv : portToProtocolMap) { 6970141561SBorawski.Lukasz Node::json[kv.second]["Port"] = kv.first; 7070141561SBorawski.Lukasz if (listeningPorts.find(kv.first) != listeningPorts.end()) { 7170141561SBorawski.Lukasz Node::json[kv.second]["ProtocolEnabled"] = true; 7270141561SBorawski.Lukasz } else { 7370141561SBorawski.Lukasz Node::json[kv.second]["ProtocolEnabled"] = false; 7470141561SBorawski.Lukasz } 7570141561SBorawski.Lukasz } 7670141561SBorawski.Lukasz } 7770141561SBorawski.Lukasz 7870141561SBorawski.Lukasz void refreshListeningPorts() { 7970141561SBorawski.Lukasz listeningPorts.clear(); 8070141561SBorawski.Lukasz std::array<char, 128> netstatLine; 8170141561SBorawski.Lukasz FILE* p = popen("netstat -tuln | awk '{ print $4 }'", "r"); 8270141561SBorawski.Lukasz if (p != nullptr) { 8370141561SBorawski.Lukasz while (fgets(netstatLine.data(), netstatLine.size(), p) != nullptr) { 8470141561SBorawski.Lukasz auto s = std::string(netstatLine.data()); 8570141561SBorawski.Lukasz 8670141561SBorawski.Lukasz // get port num from strings such as: ".*:.*:.*:port" 8770141561SBorawski.Lukasz s.erase(0, s.find_last_of(":") + strlen(":")); 8870141561SBorawski.Lukasz 8970141561SBorawski.Lukasz auto port = atoi(s.c_str()); 9070141561SBorawski.Lukasz if (port != 0 && 9170141561SBorawski.Lukasz portToProtocolMap.find(port) != portToProtocolMap.end()) { 9270141561SBorawski.Lukasz listeningPorts.insert(port); 9370141561SBorawski.Lukasz } 9470141561SBorawski.Lukasz } 9570141561SBorawski.Lukasz } 9670141561SBorawski.Lukasz } 9770141561SBorawski.Lukasz 98aa2e59c1SEd Tanous boost::container::flat_map<int, std::string> portToProtocolMap{ 9970141561SBorawski.Lukasz {22, "SSH"}, {80, "HTTP"}, {443, "HTTPS"}, {623, "IPMI"}, {1900, "SSDP"}}; 10070141561SBorawski.Lukasz 101aa2e59c1SEd Tanous boost::container::flat_set<int> listeningPorts; 10270141561SBorawski.Lukasz }; 10370141561SBorawski.Lukasz 10470141561SBorawski.Lukasz } // namespace redfish 105