summaryrefslogtreecommitdiffstats
path: root/app/channel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/channel.cpp')
-rw-r--r--app/channel.cpp87
1 files changed, 50 insertions, 37 deletions
diff --git a/app/channel.cpp b/app/channel.cpp
index 6ea25c4..51e953d 100644
--- a/app/channel.cpp
+++ b/app/channel.cpp
@@ -1,6 +1,5 @@
#include "channel.hpp"
-#include "transporthandler.hpp"
#include "user_channel/channel_layer.hpp"
#include <arpa/inet.h>
@@ -97,26 +96,44 @@ std::pair<std::vector<uint8_t>, std::vector<uint8_t>> getCipherRecords()
} // namespace cipher
-ipmi_ret_t getChannelCipherSuites(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request,
- ipmi_response_t response,
- ipmi_data_len_t data_len,
- ipmi_context_t context)
+/** @brief this command is used to look up what authentication, integrity,
+ * confidentiality algorithms are supported.
+ *
+ * @ param ctx - context pointer
+ * @ param channelNumber - channel number
+ * @ param payloadType - payload type
+ * @ param listIndex - list index
+ * @ param algoSelectBit - list algorithms
+ *
+ * @returns ipmi completion code plus response data
+ * - rspChannel - channel number for authentication algorithm.
+ * - rspRecords - cipher suite records.
+ **/
+ipmi::RspType<uint8_t, // Channel Number
+ std::vector<uint8_t> // Cipher Records
+ >
+ getChannelCipherSuites(ipmi::Context::ptr ctx, uint4_t channelNumber,
+ uint4_t reserved1, uint8_t payloadType,
+ uint6_t listIndex, uint1_t reserved2,
+ uint1_t algoSelectBit)
{
static std::vector<uint8_t> cipherRecords;
static std::vector<uint8_t> supportedAlgorithms;
static auto recordInit = false;
- auto requestData =
- reinterpret_cast<const GetChannelCipherRequest*>(request);
+ uint8_t rspChannel = ipmi::convertCurrentChannelNum(
+ static_cast<uint8_t>(channelNumber), ctx->channel);
- if (*data_len < sizeof(GetChannelCipherRequest))
+ if (!ipmi::isValidChannel(rspChannel) || reserved1 != 0 || reserved2 != 0)
{
- *data_len = 0;
- return IPMI_CC_REQ_DATA_LEN_INVALID;
+ return ipmi::responseInvalidFieldRequest();
+ }
+ if (!ipmi::isValidPayloadType(static_cast<ipmi::PayloadType>(payloadType)))
+ {
+ log<level::DEBUG>("Get channel cipher suites - Invalid payload type");
+ constexpr uint8_t ccPayloadTypeNotSupported = 0x80;
+ return ipmi::response(ccPayloadTypeNotSupported);
}
-
- *data_len = 0;
if (!recordInit)
{
@@ -128,41 +145,37 @@ ipmi_ret_t getChannelCipherSuites(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
}
catch (const std::exception& e)
{
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
}
- const auto& records = (cipher::listCipherSuite ==
- (requestData->listIndex & cipher::listTypeMask))
- ? cipherRecords
- : supportedAlgorithms;
+ const std::vector<uint8_t>& records =
+ algoSelectBit ? cipherRecords : supportedAlgorithms;
+ static constexpr auto respSize = 16;
+
+ // Session support is available in active LAN channels.
+ if ((ipmi::getChannelSessionSupport(rspChannel) ==
+ ipmi::EChannelSessSupported::none) ||
+ !(ipmi::doesDeviceExist(rspChannel)))
+ {
+ log<level::DEBUG>("Get channel cipher suites - Device does not exist");
+ return ipmi::responseInvalidFieldRequest();
+ }
// List index(00h-3Fh), 0h selects the first set of 16, 1h selects the next
// set of 16 and so on.
- auto index =
- static_cast<size_t>(requestData->listIndex & cipher::listIndexMask);
// Calculate the number of record data bytes to be returned.
- auto start = std::min(index * cipher::respSize, records.size());
- auto end =
- std::min((index * cipher::respSize) + cipher::respSize, records.size());
+ auto start =
+ std::min(static_cast<size_t>(listIndex) * respSize, records.size());
+ auto end = std::min((static_cast<size_t>(listIndex) * respSize) + respSize,
+ records.size());
auto size = end - start;
- auto responseData = reinterpret_cast<GetChannelCipherRespHeader*>(response);
- responseData->channelNumber = cipher::defaultChannelNumber;
-
- if (!size)
- {
- *data_len = sizeof(GetChannelCipherRespHeader);
- }
- else
- {
- std::copy_n(records.data() + start, size,
- static_cast<uint8_t*>(response) + 1);
- *data_len = size + sizeof(GetChannelCipherRespHeader);
- }
+ std::vector<uint8_t> rspRecords;
+ std::copy_n(records.data() + start, size, std::back_inserter(rspRecords));
- return IPMI_CC_OK;
+ return ipmi::responseSuccess(rspChannel, rspRecords);
}
template <typename... ArgTypes>
OpenPOWER on IntegriCloud