1f085d91dSPatrick Venture /* 2f085d91dSPatrick Venture * Copyright 2019 Google Inc. 3f085d91dSPatrick Venture * 4f085d91dSPatrick Venture * Licensed under the Apache License, Version 2.0 (the "License"); 5f085d91dSPatrick Venture * you may not use this file except in compliance with the License. 6f085d91dSPatrick Venture * You may obtain a copy of the License at 7f085d91dSPatrick Venture * 8f085d91dSPatrick Venture * http://www.apache.org/licenses/LICENSE-2.0 9f085d91dSPatrick Venture * 10f085d91dSPatrick Venture * Unless required by applicable law or agreed to in writing, software 11f085d91dSPatrick Venture * distributed under the License is distributed on an "AS IS" BASIS, 12f085d91dSPatrick Venture * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f085d91dSPatrick Venture * See the License for the specific language governing permissions and 14f085d91dSPatrick Venture * limitations under the License. 15f085d91dSPatrick Venture */ 16f085d91dSPatrick Venture 17f085d91dSPatrick Venture #include "handler.hpp" 18f085d91dSPatrick Venture 19*d2037c6aSPatrick Venture #include "errors.hpp" 20*d2037c6aSPatrick Venture 21*d2037c6aSPatrick Venture #include <ipmid/api.h> 22*d2037c6aSPatrick Venture 23*d2037c6aSPatrick Venture #include <cstdio> 24*d2037c6aSPatrick Venture #include <filesystem> 25*d2037c6aSPatrick Venture #include <fstream> 26*d2037c6aSPatrick Venture #include <sstream> 27*d2037c6aSPatrick Venture #include <string> 28*d2037c6aSPatrick Venture #include <tuple> 29*d2037c6aSPatrick Venture 30f085d91dSPatrick Venture // The phosphor-host-ipmi daemon requires a configuration that maps 31f085d91dSPatrick Venture // the if_name to the IPMI LAN channel. However, that doesn't strictly 32f085d91dSPatrick Venture // define which is meant to be used for NCSI. 33f085d91dSPatrick Venture #ifndef NCSI_IPMI_CHANNEL 34f085d91dSPatrick Venture #define NCSI_IPMI_CHANNEL 1 35f085d91dSPatrick Venture #endif 36f085d91dSPatrick Venture 37f085d91dSPatrick Venture #ifndef NCSI_IF_NAME 38f085d91dSPatrick Venture #define NCSI_IF_NAME eth0 39f085d91dSPatrick Venture #endif 40f085d91dSPatrick Venture 41f085d91dSPatrick Venture // To deal with receiving a string without quotes. 42f085d91dSPatrick Venture #define QUOTE(name) #name 43f085d91dSPatrick Venture #define STR(macro) QUOTE(macro) 44f085d91dSPatrick Venture #define NCSI_IF_NAME_STR STR(NCSI_IF_NAME) 45f085d91dSPatrick Venture 46f085d91dSPatrick Venture namespace google 47f085d91dSPatrick Venture { 48f085d91dSPatrick Venture namespace ipmi 49f085d91dSPatrick Venture { 50*d2037c6aSPatrick Venture namespace fs = std::filesystem; 51f085d91dSPatrick Venture 52f085d91dSPatrick Venture std::tuple<std::uint8_t, std::string> Handler::getEthDetails() const 53f085d91dSPatrick Venture { 54f085d91dSPatrick Venture return std::make_tuple(NCSI_IPMI_CHANNEL, NCSI_IF_NAME_STR); 55f085d91dSPatrick Venture } 56f085d91dSPatrick Venture 57*d2037c6aSPatrick Venture std::int64_t Handler::getRxPackets(const std::string& name) const 58*d2037c6aSPatrick Venture { 59*d2037c6aSPatrick Venture std::ostringstream opath; 60*d2037c6aSPatrick Venture opath << "/sys/class/net/" << name << "/statistics/rx_packets"; 61*d2037c6aSPatrick Venture std::string path = opath.str(); 62*d2037c6aSPatrick Venture 63*d2037c6aSPatrick Venture // Minor sanity & security check (of course, I'm less certain if unicode 64*d2037c6aSPatrick Venture // comes into play here. 65*d2037c6aSPatrick Venture // 66*d2037c6aSPatrick Venture // Basically you can't easily inject ../ or /../ into the path below. 67*d2037c6aSPatrick Venture if (name.find("/") != std::string::npos) 68*d2037c6aSPatrick Venture { 69*d2037c6aSPatrick Venture std::fprintf(stderr, "Invalid or illegal name: '%s'\n", name.c_str()); 70*d2037c6aSPatrick Venture throw IpmiException(IPMI_CC_INVALID_FIELD_REQUEST); 71*d2037c6aSPatrick Venture } 72*d2037c6aSPatrick Venture 73*d2037c6aSPatrick Venture std::error_code ec; 74*d2037c6aSPatrick Venture if (!fs::exists(path, ec)) 75*d2037c6aSPatrick Venture { 76*d2037c6aSPatrick Venture std::fprintf(stderr, "Path: '%s' doesn't exist.\n", path.c_str()); 77*d2037c6aSPatrick Venture throw IpmiException(IPMI_CC_INVALID_FIELD_REQUEST); 78*d2037c6aSPatrick Venture } 79*d2037c6aSPatrick Venture // We're uninterested in the state of ec. 80*d2037c6aSPatrick Venture 81*d2037c6aSPatrick Venture int64_t count = 0; 82*d2037c6aSPatrick Venture std::ifstream ifs; 83*d2037c6aSPatrick Venture ifs.exceptions(std::ifstream::failbit); 84*d2037c6aSPatrick Venture try 85*d2037c6aSPatrick Venture { 86*d2037c6aSPatrick Venture ifs.open(path); 87*d2037c6aSPatrick Venture ifs >> count; 88*d2037c6aSPatrick Venture } 89*d2037c6aSPatrick Venture catch (std::ios_base::failure& fail) 90*d2037c6aSPatrick Venture { 91*d2037c6aSPatrick Venture throw IpmiException(IPMI_CC_UNSPECIFIED_ERROR); 92*d2037c6aSPatrick Venture } 93*d2037c6aSPatrick Venture 94*d2037c6aSPatrick Venture return count; 95*d2037c6aSPatrick Venture } 96*d2037c6aSPatrick Venture 97f085d91dSPatrick Venture Handler handlerImpl; 98f085d91dSPatrick Venture 99f085d91dSPatrick Venture } // namespace ipmi 100f085d91dSPatrick Venture } // namespace google 101