1*70141561SBorawski.Lukasz /* 2*70141561SBorawski.Lukasz // Copyright (c) 2018 Intel Corporation 3*70141561SBorawski.Lukasz // 4*70141561SBorawski.Lukasz // Licensed under the Apache License, Version 2.0 (the "License"); 5*70141561SBorawski.Lukasz // you may not use this file except in compliance with the License. 6*70141561SBorawski.Lukasz // You may obtain a copy of the License at 7*70141561SBorawski.Lukasz // 8*70141561SBorawski.Lukasz // http://www.apache.org/licenses/LICENSE-2.0 9*70141561SBorawski.Lukasz // 10*70141561SBorawski.Lukasz // Unless required by applicable law or agreed to in writing, software 11*70141561SBorawski.Lukasz // distributed under the License is distributed on an "AS IS" BASIS, 12*70141561SBorawski.Lukasz // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*70141561SBorawski.Lukasz // See the License for the specific language governing permissions and 14*70141561SBorawski.Lukasz // limitations under the License. 15*70141561SBorawski.Lukasz */ 16*70141561SBorawski.Lukasz #pragma once 17*70141561SBorawski.Lukasz 18*70141561SBorawski.Lukasz #include "node.hpp" 19*70141561SBorawski.Lukasz 20*70141561SBorawski.Lukasz namespace redfish { 21*70141561SBorawski.Lukasz 22*70141561SBorawski.Lukasz static OperationMap managerNetworkProtocolOpMap = { 23*70141561SBorawski.Lukasz {crow::HTTPMethod::GET, {{"Login"}}}, 24*70141561SBorawski.Lukasz {crow::HTTPMethod::HEAD, {{"Login"}}}, 25*70141561SBorawski.Lukasz {crow::HTTPMethod::PATCH, {{"ConfigureManager"}}}, 26*70141561SBorawski.Lukasz {crow::HTTPMethod::PUT, {{"ConfigureManager"}}}, 27*70141561SBorawski.Lukasz {crow::HTTPMethod::DELETE, {{"ConfigureManager"}}}, 28*70141561SBorawski.Lukasz {crow::HTTPMethod::POST, {{"ConfigureManager"}}}}; 29*70141561SBorawski.Lukasz 30*70141561SBorawski.Lukasz class NetworkProtocol : public Node { 31*70141561SBorawski.Lukasz public: 32*70141561SBorawski.Lukasz NetworkProtocol(CrowApp& app) 33*70141561SBorawski.Lukasz : Node(app, EntityPrivileges(std::move(managerNetworkProtocolOpMap)), 34*70141561SBorawski.Lukasz "/redfish/v1/Managers/openbmc/NetworkProtocol") { 35*70141561SBorawski.Lukasz Node::json["@odata.type"] = 36*70141561SBorawski.Lukasz "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol"; 37*70141561SBorawski.Lukasz Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc/NetworkProtocol"; 38*70141561SBorawski.Lukasz Node::json["@odata.context"] = 39*70141561SBorawski.Lukasz "/redfish/v1/$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol"; 40*70141561SBorawski.Lukasz Node::json["Id"] = "NetworkProtocol"; 41*70141561SBorawski.Lukasz Node::json["Name"] = "Manager Network Protocol"; 42*70141561SBorawski.Lukasz Node::json["Description"] = "Manager Network Service"; 43*70141561SBorawski.Lukasz Node::json["Status"]["Health"] = "OK"; 44*70141561SBorawski.Lukasz Node::json["Status"]["HealthRollup"] = "OK"; 45*70141561SBorawski.Lukasz Node::json["Status"]["State"] = "Enabled"; 46*70141561SBorawski.Lukasz } 47*70141561SBorawski.Lukasz 48*70141561SBorawski.Lukasz private: 49*70141561SBorawski.Lukasz void doGet(crow::response& res, const crow::request& req, 50*70141561SBorawski.Lukasz const std::vector<std::string>& params) override { 51*70141561SBorawski.Lukasz refreshProtocolsState(); 52*70141561SBorawski.Lukasz Node::json["HostName"] = getHostName(); 53*70141561SBorawski.Lukasz res.json_value = Node::json; 54*70141561SBorawski.Lukasz res.end(); 55*70141561SBorawski.Lukasz } 56*70141561SBorawski.Lukasz 57*70141561SBorawski.Lukasz std::string getHostName() const { 58*70141561SBorawski.Lukasz std::string hostName; 59*70141561SBorawski.Lukasz 60*70141561SBorawski.Lukasz std::array<char, HOST_NAME_MAX> hostNameCStr; 61*70141561SBorawski.Lukasz if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) { 62*70141561SBorawski.Lukasz hostName = hostNameCStr.data(); 63*70141561SBorawski.Lukasz } 64*70141561SBorawski.Lukasz return hostName; 65*70141561SBorawski.Lukasz } 66*70141561SBorawski.Lukasz 67*70141561SBorawski.Lukasz void refreshProtocolsState() { 68*70141561SBorawski.Lukasz refreshListeningPorts(); 69*70141561SBorawski.Lukasz for (auto& kv : portToProtocolMap) { 70*70141561SBorawski.Lukasz Node::json[kv.second]["Port"] = kv.first; 71*70141561SBorawski.Lukasz if (listeningPorts.find(kv.first) != listeningPorts.end()) { 72*70141561SBorawski.Lukasz Node::json[kv.second]["ProtocolEnabled"] = true; 73*70141561SBorawski.Lukasz } else { 74*70141561SBorawski.Lukasz Node::json[kv.second]["ProtocolEnabled"] = false; 75*70141561SBorawski.Lukasz } 76*70141561SBorawski.Lukasz } 77*70141561SBorawski.Lukasz } 78*70141561SBorawski.Lukasz 79*70141561SBorawski.Lukasz void refreshListeningPorts() { 80*70141561SBorawski.Lukasz listeningPorts.clear(); 81*70141561SBorawski.Lukasz std::array<char, 128> netstatLine; 82*70141561SBorawski.Lukasz FILE* p = popen("netstat -tuln | awk '{ print $4 }'", "r"); 83*70141561SBorawski.Lukasz if (p != nullptr) { 84*70141561SBorawski.Lukasz while (fgets(netstatLine.data(), netstatLine.size(), p) != nullptr) { 85*70141561SBorawski.Lukasz auto s = std::string(netstatLine.data()); 86*70141561SBorawski.Lukasz 87*70141561SBorawski.Lukasz // get port num from strings such as: ".*:.*:.*:port" 88*70141561SBorawski.Lukasz s.erase(0, s.find_last_of(":") + strlen(":")); 89*70141561SBorawski.Lukasz 90*70141561SBorawski.Lukasz auto port = atoi(s.c_str()); 91*70141561SBorawski.Lukasz if (port != 0 && 92*70141561SBorawski.Lukasz portToProtocolMap.find(port) != portToProtocolMap.end()) { 93*70141561SBorawski.Lukasz listeningPorts.insert(port); 94*70141561SBorawski.Lukasz } 95*70141561SBorawski.Lukasz } 96*70141561SBorawski.Lukasz } 97*70141561SBorawski.Lukasz } 98*70141561SBorawski.Lukasz 99*70141561SBorawski.Lukasz std::map<int, std::string> portToProtocolMap{ 100*70141561SBorawski.Lukasz {22, "SSH"}, {80, "HTTP"}, {443, "HTTPS"}, {623, "IPMI"}, {1900, "SSDP"}}; 101*70141561SBorawski.Lukasz 102*70141561SBorawski.Lukasz std::set<int> listeningPorts; 103*70141561SBorawski.Lukasz }; 104*70141561SBorawski.Lukasz 105*70141561SBorawski.Lukasz } // namespace redfish 106