1 /* 2 * Copyright 2018 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "eth.hpp" 18 19 #include "commands.hpp" 20 #include "handler.hpp" 21 22 #include <cstdint> 23 #include <cstring> 24 #include <string> 25 #include <tuple> 26 27 namespace google 28 { 29 namespace ipmi 30 { 31 32 struct EthDeviceRequest 33 { 34 uint8_t subcommand; 35 } __attribute__((packed)); 36 37 // TOOD(venture): The ipmid.h has this macro, which is a header we 38 // can't normally access. 39 #ifndef MAX_IPMI_BUFFER 40 #define MAX_IPMI_BUFFER 64 41 #endif 42 43 ipmi_ret_t getEthDevice(const uint8_t*, uint8_t* replyBuf, size_t* dataLen, 44 const HandlerInterface* handler) 45 { 46 if ((*dataLen) < sizeof(struct EthDeviceRequest)) 47 { 48 std::fprintf(stderr, "Invalid command length: %u\n", 49 static_cast<uint32_t>(*dataLen)); 50 return IPMI_CC_REQ_DATA_LEN_INVALID; 51 } 52 53 std::tuple<std::uint8_t, std::string> details = handler->getEthDetails(); 54 55 std::string device = std::get<1>(details); 56 if (device.length() == 0) 57 { 58 std::fprintf(stderr, "Invalid eth string\n"); 59 return IPMI_CC_REQ_DATA_LEN_INVALID; 60 } 61 62 if ((sizeof(struct EthDeviceReply) + device.length()) > MAX_IPMI_BUFFER) 63 { 64 std::fprintf(stderr, "Response would overflow response buffer\n"); 65 return IPMI_CC_REQUESTED_TOO_MANY_BYTES; 66 } 67 68 // Fill in the response buffer. 69 auto reply = reinterpret_cast<struct EthDeviceReply*>(&replyBuf[0]); 70 reply->subcommand = SysGetEthDevice; 71 reply->channel = std::get<0>(details); 72 reply->ifNameLength = device.length(); 73 std::memcpy(reply + 1, device.c_str(), device.length()); 74 75 (*dataLen) = sizeof(struct EthDeviceReply) + device.length(); 76 77 return IPMI_CC_OK; 78 } 79 80 } // namespace ipmi 81 } // namespace google 82