14d49ae65SPatrick Venture /* 24d49ae65SPatrick Venture * Copyright 2018 Google Inc. 34d49ae65SPatrick Venture * 44d49ae65SPatrick Venture * Licensed under the Apache License, Version 2.0 (the "License"); 54d49ae65SPatrick Venture * you may not use this file except in compliance with the License. 64d49ae65SPatrick Venture * You may obtain a copy of the License at 74d49ae65SPatrick Venture * 84d49ae65SPatrick Venture * http://www.apache.org/licenses/LICENSE-2.0 94d49ae65SPatrick Venture * 104d49ae65SPatrick Venture * Unless required by applicable law or agreed to in writing, software 114d49ae65SPatrick Venture * distributed under the License is distributed on an "AS IS" BASIS, 124d49ae65SPatrick Venture * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134d49ae65SPatrick Venture * See the License for the specific language governing permissions and 144d49ae65SPatrick Venture * limitations under the License. 154d49ae65SPatrick Venture */ 164d49ae65SPatrick Venture 174d49ae65SPatrick Venture #include "cable.hpp" 184d49ae65SPatrick Venture 19*d2037c6aSPatrick Venture #include "errors.hpp" 20*d2037c6aSPatrick Venture #include "handler.hpp" 214d49ae65SPatrick Venture #include "main.hpp" 224d49ae65SPatrick Venture 234d49ae65SPatrick Venture #include <cstdint> 24ce07ee0aSPatrick Venture #include <cstring> 254d49ae65SPatrick Venture #include <string> 264d49ae65SPatrick Venture 274d49ae65SPatrick Venture namespace google 284d49ae65SPatrick Venture { 294d49ae65SPatrick Venture namespace ipmi 304d49ae65SPatrick Venture { 314d49ae65SPatrick Venture 324d49ae65SPatrick Venture struct CableRequest 334d49ae65SPatrick Venture { 344d49ae65SPatrick Venture uint8_t subcommand; 354d49ae65SPatrick Venture uint8_t if_name_len; 364d49ae65SPatrick Venture uint8_t if_name[0]; 374d49ae65SPatrick Venture } __attribute__((packed)); 384d49ae65SPatrick Venture 39*d2037c6aSPatrick Venture ipmi_ret_t CableCheck(const uint8_t* reqBuf, uint8_t* replyBuf, size_t* dataLen, 40*d2037c6aSPatrick Venture const HandlerInterface* handler) 414d49ae65SPatrick Venture { 424d49ae65SPatrick Venture // There is an IPMI LAN channel statistics command which could be used for 434d49ae65SPatrick Venture // this type of check, however, we're not able to wait for the OpenBMC 444d49ae65SPatrick Venture // implementation to stabilize related to the network management. 454d49ae65SPatrick Venture // 464d49ae65SPatrick Venture // There is a link status file, but it is "unknown" to start with... 474d49ae65SPatrick Venture // The path we're checking: /sys/class/net/eth1/statistics/rx_packets 484d49ae65SPatrick Venture 494d49ae65SPatrick Venture // This command is expecting: [0x00][len][if_name] 504d49ae65SPatrick Venture if ((*dataLen) < sizeof(struct CableRequest) + sizeof(uint8_t)) 514d49ae65SPatrick Venture { 52ce07ee0aSPatrick Venture std::fprintf(stderr, "Invalid command length: %u\n", 530dede335SPatrick Venture static_cast<uint32_t>(*dataLen)); 54fff98617SPatrick Venture return IPMI_CC_REQ_DATA_LEN_INVALID; 554d49ae65SPatrick Venture } 564d49ae65SPatrick Venture 574d49ae65SPatrick Venture const auto request = 584d49ae65SPatrick Venture reinterpret_cast<const struct CableRequest*>(&reqBuf[0]); 594d49ae65SPatrick Venture 604d49ae65SPatrick Venture // Sanity check the object contents. 614d49ae65SPatrick Venture if (request->if_name_len == 0) 624d49ae65SPatrick Venture { 63ce07ee0aSPatrick Venture std::fprintf(stderr, "Invalid string length: %d\n", 64ce07ee0aSPatrick Venture request->if_name_len); 65fff98617SPatrick Venture return IPMI_CC_REQ_DATA_LEN_INVALID; 664d49ae65SPatrick Venture } 674d49ae65SPatrick Venture 684d49ae65SPatrick Venture // Verify the request buffer contains the object and the string. 694d49ae65SPatrick Venture if ((*dataLen) < (sizeof(struct CableRequest) + request->if_name_len)) 704d49ae65SPatrick Venture { 71ce07ee0aSPatrick Venture std::fprintf(stderr, "*dataLen too small: %u\n", 720dede335SPatrick Venture static_cast<uint32_t>(*dataLen)); 73fff98617SPatrick Venture return IPMI_CC_REQ_DATA_LEN_INVALID; 744d49ae65SPatrick Venture } 754d49ae65SPatrick Venture 764d49ae65SPatrick Venture // Maximum length one can specify, plus null terminator. 774d49ae65SPatrick Venture char nameBuf[256] = {}; 784d49ae65SPatrick Venture // Copy the string out of the request buffer. 79ce07ee0aSPatrick Venture std::memcpy(&nameBuf[0], request->if_name, request->if_name_len); 804d49ae65SPatrick Venture std::string name = nameBuf; 81*d2037c6aSPatrick Venture int64_t count; 824d49ae65SPatrick Venture 834d49ae65SPatrick Venture try 844d49ae65SPatrick Venture { 85*d2037c6aSPatrick Venture count = handler->getRxPackets(name); 864d49ae65SPatrick Venture } 87*d2037c6aSPatrick Venture catch (const IpmiException& e) 884d49ae65SPatrick Venture { 89*d2037c6aSPatrick Venture return e.getIpmiError(); 904d49ae65SPatrick Venture } 914d49ae65SPatrick Venture 924d49ae65SPatrick Venture struct CableReply reply; 934d49ae65SPatrick Venture reply.subcommand = SysCableCheck; 944d49ae65SPatrick Venture 954d49ae65SPatrick Venture // If we have received packets then there is a cable present. 964d49ae65SPatrick Venture reply.value = (count > 0) ? 1 : 0; 974d49ae65SPatrick Venture 984d49ae65SPatrick Venture // Return the subcommand and the result. 99ce07ee0aSPatrick Venture std::memcpy(&replyBuf[0], &reply, sizeof(struct CableReply)); 1004d49ae65SPatrick Venture (*dataLen) = sizeof(struct CableReply); 1014d49ae65SPatrick Venture 1024d49ae65SPatrick Venture return IPMI_CC_OK; 1034d49ae65SPatrick Venture } 1044d49ae65SPatrick Venture 1054d49ae65SPatrick Venture } // namespace ipmi 1064d49ae65SPatrick Venture } // namespace google 107