blob: b26f9a32af8d8b4c5d1438b3fcdb12cf1e770a56 [file] [log] [blame]
Tom Joseph4e57ada2016-08-10 06:51:12 -05001#pragma once
2
3#include "message.hpp"
4#include "session.hpp"
5
Andrew Geissler9d9b7632020-05-17 09:18:05 -05006#include <cstddef>
7
Tom Joseph4e57ada2016-08-10 06:51:12 -05008namespace message
9{
10
11namespace parser
12{
13
14constexpr size_t RMCP_VERSION = 6;
15
16// RMCP Messages with class=IPMI should be sent with an RMCP Sequence
17// Number of FFh to indicate that an RMCP ACK message should not be
18// generated by the message receiver.
19constexpr size_t RMCP_SEQ = 0xFF;
20
21// RMCP Message Class 7h is for IPMI
22constexpr size_t RMCP_MESSAGE_CLASS_IPMI = 7;
23
Tom Joseph64703f42017-01-10 17:03:48 +053024// RMCP Session Header Size
25constexpr size_t RMCP_SESSION_HEADER_SIZE = 4;
26
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030027// RMCP/ASF Pong Message ASF Header Data Length
28// as per IPMI spec 13.2.4
29constexpr size_t RMCP_ASF_PONG_DATA_LEN = 16;
30
31// ASF IANA
32constexpr uint32_t ASF_IANA = 4542;
33
34// ASF Supported Entities
35constexpr uint32_t ASF_SUPP_ENT = 0x81;
36
37// ASF Supported Entities
38constexpr uint32_t ASF_SUPP_INT = 0x00;
39
Tom Joseph1efcb492017-01-31 16:56:47 +053040// Maximum payload size
41constexpr size_t MAX_PAYLOAD_SIZE = 255;
42
Tom Joseph4e57ada2016-08-10 06:51:12 -050043enum class SessionHeader
44{
45 IPMI15 = 0x00,
46 IPMI20 = 0x06,
47 INVALID = 0xFF,
48};
49
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030050// RMCP Header
51struct RmcpHeader_t
Tom Joseph4e57ada2016-08-10 06:51:12 -050052{
53 // RMCP Header
54 uint8_t version;
55 uint8_t reserved;
56 uint8_t rmcpSeqNum;
57 uint8_t classOfMsg;
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +030058} __attribute__((packed));
59
60struct BasicHeader_t
61{
62 // RMCP Header
63 struct RmcpHeader_t rmcp;
Tom Joseph4e57ada2016-08-10 06:51:12 -050064
65 // IPMI partial session header
66 union
67 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070068 uint8_t reserved1 : 4;
69 uint8_t authType : 4;
Tom Joseph4e57ada2016-08-10 06:51:12 -050070 uint8_t formatType;
71 } format;
72} __attribute__((packed));
73
Tom Joseph3563f8f2017-05-08 15:42:54 +053074/**
Tom Joseph4e57ada2016-08-10 06:51:12 -050075 * @brief Unflatten an incoming packet and prepare the IPMI message
76 *
77 * @param[in] inPacket - Incoming IPMI packet
78 *
79 * @return A tuple with IPMI message and the session header type to sent the
80 * response packet. In case of success incoming message and session
81 * header type. In case of failure nullptr and session header type
82 * would be invalid.
83 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -070084std::tuple<std::shared_ptr<Message>, SessionHeader>
Vernon Mauery9e801a22018-10-12 13:20:49 -070085 unflatten(std::vector<uint8_t>& inPacket);
Tom Joseph4e57ada2016-08-10 06:51:12 -050086
Tom Joseph3563f8f2017-05-08 15:42:54 +053087/**
Tom Joseph4e57ada2016-08-10 06:51:12 -050088 * @brief Flatten an IPMI message and generate the IPMI packet with the
89 * session header
90 *
91 * @param[in] outMessage - IPMI message to be flattened
92 * @param[in] authType - Session header type to be added to the IPMI
93 * packet
94 *
95 * @return IPMI packet on success
96 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -070097std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -070098 SessionHeader authType,
99 std::shared_ptr<session::Session> session);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500100
101} // namespace parser
102
103namespace ipmi15parser
104{
105
106struct SessionHeader_t
107{
108 struct parser::BasicHeader_t base;
109 uint32_t sessSeqNum;
110 uint32_t sessId;
111 // <Optional Field: AuthCode>
112 uint8_t payloadLength;
113} __attribute__((packed));
114
115struct SessionTrailer_t
116{
117 uint8_t legacyPad;
118} __attribute__((packed));
119
Tom Joseph3563f8f2017-05-08 15:42:54 +0530120/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500121 * @brief Unflatten an incoming packet and prepare the IPMI message
122 *
123 * @param[in] inPacket - Incoming IPMI packet
124 *
125 * @return IPMI message in the packet on success
126 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700127std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500128
Tom Joseph3563f8f2017-05-08 15:42:54 +0530129/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500130 * @brief Flatten an IPMI message and generate the IPMI packet with the
131 * session header
132 *
133 * @param[in] outMessage - IPMI message to be flattened
134 *
135 * @return IPMI packet on success
136 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700137std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -0700138 std::shared_ptr<session::Session> session);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500139
140} // namespace ipmi15parser
141
142namespace ipmi20parser
143{
144
145constexpr size_t MAX_INTEGRITY_DATA_LENGTH = 12;
146constexpr size_t PAYLOAD_ENCRYPT_MASK = 0x80;
147constexpr size_t PAYLOAD_AUTH_MASK = 0x40;
148
149struct SessionHeader_t
150{
151 struct parser::BasicHeader_t base;
152
153 uint8_t payloadType;
154
155 uint32_t sessId;
156 uint32_t sessSeqNum;
157 uint16_t payloadLength;
158} __attribute__((packed));
159
160struct SessionTrailer_t
161{
162 // Integrity Pad
163 uint8_t padLength;
164 uint8_t nextHeader;
Tom Joseph4e57ada2016-08-10 06:51:12 -0500165} __attribute__((packed));
166
Tom Joseph3563f8f2017-05-08 15:42:54 +0530167/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500168 * @brief Unflatten an incoming packet and prepare the IPMI message
169 *
170 * @param[in] inPacket - Incoming IPMI packet
171 *
172 * @return IPMI message in the packet on success
173 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700174std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500175
Tom Joseph3563f8f2017-05-08 15:42:54 +0530176/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500177 * @brief Flatten an IPMI message and generate the IPMI packet with the
178 * session header
179 *
180 * @param[in] outMessage - IPMI message to be flattened
181 *
182 * @return IPMI packet on success
183 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700184std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
Vernon Mauery224f36a2018-10-25 08:52:23 -0700185 std::shared_ptr<session::Session> session);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500186
187namespace internal
188{
189
Tom Joseph3563f8f2017-05-08 15:42:54 +0530190/**
Tom Joseph4e57ada2016-08-10 06:51:12 -0500191 * @brief Add sequence number to the message
192 *
193 * @param[in] packet - outgoing packet to which to add sequence number
194 * @param[in] session - session handle
195 *
196 */
Vernon Mauery224f36a2018-10-25 08:52:23 -0700197void addSequenceNumber(std::vector<uint8_t>& packet,
198 std::shared_ptr<session::Session> session);
Tom Joseph4e57ada2016-08-10 06:51:12 -0500199
Tom Joseph3563f8f2017-05-08 15:42:54 +0530200/**
Tom Joseph64703f42017-01-10 17:03:48 +0530201 * @brief Verify the integrity data of the incoming IPMI packet
202 *
203 * @param[in] packet - Incoming IPMI packet
Tom Joseph027dfc22017-01-26 13:30:53 +0530204 * @param[in] message - IPMI Message populated from the incoming packet
205 * @param[in] payloadLen - Length of the IPMI payload
Tom Joseph64703f42017-01-10 17:03:48 +0530206 *
207 */
208bool verifyPacketIntegrity(const std::vector<uint8_t>& packet,
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700209 const std::shared_ptr<Message> message,
210 size_t payloadLen);
Tom Joseph64703f42017-01-10 17:03:48 +0530211
Tom Joseph3563f8f2017-05-08 15:42:54 +0530212/**
Tom Joseph64703f42017-01-10 17:03:48 +0530213 * @brief Add Integrity data to the outgoing IPMI packet
214 *
215 * @param[in] packet - Outgoing IPMI packet
Tom Joseph1404bca2017-01-26 14:17:02 +0530216 * @param[in] message - IPMI Message populated for the outgoing packet
217 * @param[in] payloadLen - Length of the IPMI payload
Tom Joseph64703f42017-01-10 17:03:48 +0530218 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700219void addIntegrityData(std::vector<uint8_t>& packet,
220 const std::shared_ptr<Message> message,
Tom Joseph1404bca2017-01-26 14:17:02 +0530221 size_t payloadLen);
Tom Joseph64703f42017-01-10 17:03:48 +0530222
Tom Joseph3563f8f2017-05-08 15:42:54 +0530223/**
Tom Joseph78478a82017-01-26 14:24:29 +0530224 * @brief Decrypt the encrypted payload in the incoming IPMI packet
225 *
226 * @param[in] packet - Incoming IPMI packet
227 * @param[in] message - IPMI Message populated from the incoming packet
228 * @param[in] payloadLen - Length of encrypted IPMI payload
229 *
230 * @return on successful completion, return the plain text payload
231 */
232std::vector<uint8_t> decryptPayload(const std::vector<uint8_t>& packet,
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700233 const std::shared_ptr<Message> message,
234 size_t payloadLen);
Tom Joseph78478a82017-01-26 14:24:29 +0530235
Tom Joseph3563f8f2017-05-08 15:42:54 +0530236/**
Tom Joseph75362832017-01-26 15:17:04 +0530237 * @brief Encrypt the plain text payload for the outgoing IPMI packet
238 *
239 * @param[in] message - IPMI Message populated for the outgoing packet
240 *
241 * @return on successful completion, return the encrypted payload
242 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700243std::vector<uint8_t> encryptPayload(std::shared_ptr<Message> message);
Tom Joseph75362832017-01-26 15:17:04 +0530244
Tom Joseph4e57ada2016-08-10 06:51:12 -0500245} // namespace internal
246
247} // namespace ipmi20parser
248
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300249#ifdef RMCP_PING
250namespace asfparser
251{
252
253// ASF message fields for RMCP Ping message
254struct AsfMessagePing_t
255{
256 struct parser::RmcpHeader_t rmcp;
257
258 uint32_t iana;
259 uint8_t msgType;
260 uint8_t msgTag;
261 uint8_t reserved;
262 uint8_t dataLen;
263} __attribute__((packed));
264
265// ASF message fields for RMCP Pong message
266struct AsfMessagePong_t
267{
268 struct AsfMessagePing_t ping;
269
270 uint32_t iana;
271 uint32_t oemDefined;
272 uint8_t suppEntities;
273 uint8_t suppInteract;
274 uint32_t reserved1;
275 uint16_t reserved2;
276} __attribute__((packed));
277
278/**
279 * @brief Unflatten an incoming packet and prepare the ASF message
280 *
281 * @param[in] inPacket - Incoming ASF packet
282 *
283 * @return ASF message in the packet on success
284 */
285std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
286
287/**
288 * @brief Generate the ASF packet with the RMCP header
289 *
290 * @param[in] asfMsgTag - ASF Message Tag from Ping request
291 *
292 * @return ASF packet on success
293 */
294std::vector<uint8_t> flatten(uint8_t asfMsgTag);
295
296} // namespace asfparser
297#endif // RMCP_PING
298
Tom Joseph4e57ada2016-08-10 06:51:12 -0500299} // namespace message