1*a2056e9cSWilly Tu // Copyright 2021 Google LLC 2*a2056e9cSWilly Tu // 3*a2056e9cSWilly Tu // Licensed under the Apache License, Version 2.0 (the "License"); 4*a2056e9cSWilly Tu // you may not use this file except in compliance with the License. 5*a2056e9cSWilly Tu // You may obtain a copy of the License at 6*a2056e9cSWilly Tu // 7*a2056e9cSWilly Tu // http://www.apache.org/licenses/LICENSE-2.0 8*a2056e9cSWilly Tu // 9*a2056e9cSWilly Tu // Unless required by applicable law or agreed to in writing, software 10*a2056e9cSWilly Tu // distributed under the License is distributed on an "AS IS" BASIS, 11*a2056e9cSWilly Tu // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*a2056e9cSWilly Tu // See the License for the specific language governing permissions and 13*a2056e9cSWilly Tu // limitations under the License. 144d49ae65SPatrick Venture 154d49ae65SPatrick Venture #include "cable.hpp" 164d49ae65SPatrick Venture 170e9aae5dSPatrick Venture #include "commands.hpp" 18d2037c6aSPatrick Venture #include "errors.hpp" 19d2037c6aSPatrick Venture #include "handler.hpp" 204d49ae65SPatrick Venture 214d49ae65SPatrick Venture #include <cstdint> 22ce07ee0aSPatrick Venture #include <cstring> 234d49ae65SPatrick Venture #include <string> 244d49ae65SPatrick Venture 254d49ae65SPatrick Venture namespace google 264d49ae65SPatrick Venture { 274d49ae65SPatrick Venture namespace ipmi 284d49ae65SPatrick Venture { 294d49ae65SPatrick Venture 304d49ae65SPatrick Venture struct CableRequest 314d49ae65SPatrick Venture { 324d49ae65SPatrick Venture uint8_t subcommand; 3345fad1bbSPatrick Venture uint8_t ifNameLength; 344d49ae65SPatrick Venture } __attribute__((packed)); 354d49ae65SPatrick Venture 3645fad1bbSPatrick Venture ipmi_ret_t cableCheck(const uint8_t* reqBuf, uint8_t* replyBuf, size_t* dataLen, 37d2037c6aSPatrick Venture const HandlerInterface* handler) 384d49ae65SPatrick Venture { 394d49ae65SPatrick Venture // There is an IPMI LAN channel statistics command which could be used for 404d49ae65SPatrick Venture // this type of check, however, we're not able to wait for the OpenBMC 414d49ae65SPatrick Venture // implementation to stabilize related to the network management. 424d49ae65SPatrick Venture // 434d49ae65SPatrick Venture // There is a link status file, but it is "unknown" to start with... 444d49ae65SPatrick Venture // The path we're checking: /sys/class/net/eth1/statistics/rx_packets 454d49ae65SPatrick Venture 4645fad1bbSPatrick Venture // This command is expecting: [0x00][len][ifName] 474d49ae65SPatrick Venture if ((*dataLen) < sizeof(struct CableRequest) + sizeof(uint8_t)) 484d49ae65SPatrick Venture { 49ce07ee0aSPatrick Venture std::fprintf(stderr, "Invalid command length: %u\n", 500dede335SPatrick Venture static_cast<uint32_t>(*dataLen)); 51fff98617SPatrick Venture return IPMI_CC_REQ_DATA_LEN_INVALID; 524d49ae65SPatrick Venture } 534d49ae65SPatrick Venture 544d49ae65SPatrick Venture const auto request = 554d49ae65SPatrick Venture reinterpret_cast<const struct CableRequest*>(&reqBuf[0]); 564d49ae65SPatrick Venture 574d49ae65SPatrick Venture // Sanity check the object contents. 5845fad1bbSPatrick Venture if (request->ifNameLength == 0) 594d49ae65SPatrick Venture { 60ce07ee0aSPatrick Venture std::fprintf(stderr, "Invalid string length: %d\n", 6145fad1bbSPatrick Venture request->ifNameLength); 62fff98617SPatrick Venture return IPMI_CC_REQ_DATA_LEN_INVALID; 634d49ae65SPatrick Venture } 644d49ae65SPatrick Venture 654d49ae65SPatrick Venture // Verify the request buffer contains the object and the string. 6645fad1bbSPatrick Venture if ((*dataLen) < (sizeof(struct CableRequest) + request->ifNameLength)) 674d49ae65SPatrick Venture { 68ce07ee0aSPatrick Venture std::fprintf(stderr, "*dataLen too small: %u\n", 690dede335SPatrick Venture static_cast<uint32_t>(*dataLen)); 70fff98617SPatrick Venture return IPMI_CC_REQ_DATA_LEN_INVALID; 714d49ae65SPatrick Venture } 724d49ae65SPatrick Venture 734d49ae65SPatrick Venture // Maximum length one can specify, plus null terminator. 744d49ae65SPatrick Venture char nameBuf[256] = {}; 754d49ae65SPatrick Venture // Copy the string out of the request buffer. 765d789734SWilliam A. Kennington III std::memcpy(&nameBuf[0], request + 1, request->ifNameLength); 774d49ae65SPatrick Venture std::string name = nameBuf; 78d2037c6aSPatrick Venture int64_t count; 794d49ae65SPatrick Venture 804d49ae65SPatrick Venture try 814d49ae65SPatrick Venture { 82d2037c6aSPatrick Venture count = handler->getRxPackets(name); 834d49ae65SPatrick Venture } 84d2037c6aSPatrick Venture catch (const IpmiException& e) 854d49ae65SPatrick Venture { 86d2037c6aSPatrick Venture return e.getIpmiError(); 874d49ae65SPatrick Venture } 884d49ae65SPatrick Venture 894d49ae65SPatrick Venture struct CableReply reply; 904d49ae65SPatrick Venture reply.subcommand = SysCableCheck; 914d49ae65SPatrick Venture 924d49ae65SPatrick Venture // If we have received packets then there is a cable present. 934d49ae65SPatrick Venture reply.value = (count > 0) ? 1 : 0; 944d49ae65SPatrick Venture 954d49ae65SPatrick Venture // Return the subcommand and the result. 96ce07ee0aSPatrick Venture std::memcpy(&replyBuf[0], &reply, sizeof(struct CableReply)); 974d49ae65SPatrick Venture (*dataLen) = sizeof(struct CableReply); 984d49ae65SPatrick Venture 994d49ae65SPatrick Venture return IPMI_CC_OK; 1004d49ae65SPatrick Venture } 1014d49ae65SPatrick Venture 1024d49ae65SPatrick Venture } // namespace ipmi 1034d49ae65SPatrick Venture } // namespace google 104