blob: fc82abcdec1f9ae01aecddd9b1e10d46cbe1b25e [file] [log] [blame]
Tom Joseph4e57ada2016-08-10 06:51:12 -05001#pragma once
2
3#include "message.hpp"
4#include "session.hpp"
5
6namespace message
7{
8
9namespace parser
10{
11
12constexpr size_t RMCP_VERSION = 6;
13
14// RMCP Messages with class=IPMI should be sent with an RMCP Sequence
15// Number of FFh to indicate that an RMCP ACK message should not be
16// generated by the message receiver.
17constexpr size_t RMCP_SEQ = 0xFF;
18
19// RMCP Message Class 7h is for IPMI
20constexpr size_t RMCP_MESSAGE_CLASS_IPMI = 7;
21
Tom Joseph64703f42017-01-10 17:03:48 +053022// RMCP Session Header Size
23constexpr size_t RMCP_SESSION_HEADER_SIZE = 4;
24
Tom Joseph1efcb492017-01-31 16:56:47 +053025// Maximum payload size
26constexpr size_t MAX_PAYLOAD_SIZE = 255;
27
Tom Joseph4e57ada2016-08-10 06:51:12 -050028enum class SessionHeader
29{
30 IPMI15 = 0x00,
31 IPMI20 = 0x06,
32 INVALID = 0xFF,
33};
34
35struct BasicHeader_t
36{
37 // RMCP Header
38 uint8_t version;
39 uint8_t reserved;
40 uint8_t rmcpSeqNum;
41 uint8_t classOfMsg;
42
43 // IPMI partial session header
44 union
45 {
46 uint8_t reserved1: 4;
47 uint8_t authType: 4;
48 uint8_t formatType;
49 } format;
50} __attribute__((packed));
51
52/*
53 * @brief Unflatten an incoming packet and prepare the IPMI message
54 *
55 * @param[in] inPacket - Incoming IPMI packet
56 *
57 * @return A tuple with IPMI message and the session header type to sent the
58 * response packet. In case of success incoming message and session
59 * header type. In case of failure nullptr and session header type
60 * would be invalid.
61 */
62std::tuple<std::unique_ptr<Message>, SessionHeader> unflatten(
63 std::vector<uint8_t>& inPacket);
64
65/*
66 * @brief Flatten an IPMI message and generate the IPMI packet with the
67 * session header
68 *
69 * @param[in] outMessage - IPMI message to be flattened
70 * @param[in] authType - Session header type to be added to the IPMI
71 * packet
72 *
73 * @return IPMI packet on success
74 */
75std::vector<uint8_t> flatten(Message& outMessage,
76 SessionHeader authType,
77 session::Session& session);
78
79} // namespace parser
80
81namespace ipmi15parser
82{
83
84struct SessionHeader_t
85{
86 struct parser::BasicHeader_t base;
87 uint32_t sessSeqNum;
88 uint32_t sessId;
89 // <Optional Field: AuthCode>
90 uint8_t payloadLength;
91} __attribute__((packed));
92
93struct SessionTrailer_t
94{
95 uint8_t legacyPad;
96} __attribute__((packed));
97
98/*
99 * @brief Unflatten an incoming packet and prepare the IPMI message
100 *
101 * @param[in] inPacket - Incoming IPMI packet
102 *
103 * @return IPMI message in the packet on success
104 */
105std::unique_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
106
107/*
108 * @brief Flatten an IPMI message and generate the IPMI packet with the
109 * session header
110 *
111 * @param[in] outMessage - IPMI message to be flattened
112 *
113 * @return IPMI packet on success
114 */
115std::vector<uint8_t> flatten(Message& outMessage, session::Session& session);
116
117} // namespace ipmi15parser
118
119namespace ipmi20parser
120{
121
122constexpr size_t MAX_INTEGRITY_DATA_LENGTH = 12;
123constexpr size_t PAYLOAD_ENCRYPT_MASK = 0x80;
124constexpr size_t PAYLOAD_AUTH_MASK = 0x40;
125
126struct SessionHeader_t
127{
128 struct parser::BasicHeader_t base;
129
130 uint8_t payloadType;
131
132 uint32_t sessId;
133 uint32_t sessSeqNum;
134 uint16_t payloadLength;
135} __attribute__((packed));
136
137struct SessionTrailer_t
138{
139 // Integrity Pad
140 uint8_t padLength;
141 uint8_t nextHeader;
Tom Joseph4e57ada2016-08-10 06:51:12 -0500142} __attribute__((packed));
143
144/*
145 * @brief Unflatten an incoming packet and prepare the IPMI message
146 *
147 * @param[in] inPacket - Incoming IPMI packet
148 *
149 * @return IPMI message in the packet on success
150 */
151std::unique_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
152
153/*
154 * @brief Flatten an IPMI message and generate the IPMI packet with the
155 * session header
156 *
157 * @param[in] outMessage - IPMI message to be flattened
158 *
159 * @return IPMI packet on success
160 */
161std::vector<uint8_t> flatten(Message& outMessage, session::Session& session);
162
163namespace internal
164{
165
166/*
167 * @brief Add sequence number to the message
168 *
169 * @param[in] packet - outgoing packet to which to add sequence number
170 * @param[in] session - session handle
171 *
172 */
173void addSequenceNumber(std::vector<uint8_t>& packet, session::Session& session);
174
Tom Joseph64703f42017-01-10 17:03:48 +0530175/*
176 * @brief Verify the integrity data of the incoming IPMI packet
177 *
178 * @param[in] packet - Incoming IPMI packet
Tom Joseph027dfc22017-01-26 13:30:53 +0530179 * @param[in] message - IPMI Message populated from the incoming packet
180 * @param[in] payloadLen - Length of the IPMI payload
Tom Joseph64703f42017-01-10 17:03:48 +0530181 *
182 */
183bool verifyPacketIntegrity(const std::vector<uint8_t>& packet,
Tom Joseph027dfc22017-01-26 13:30:53 +0530184 const Message& message,
185 size_t payloadLen);
Tom Joseph64703f42017-01-10 17:03:48 +0530186
187/*
188 * @brief Add Integrity data to the outgoing IPMI packet
189 *
190 * @param[in] packet - Outgoing IPMI packet
Tom Joseph1404bca2017-01-26 14:17:02 +0530191 * @param[in] message - IPMI Message populated for the outgoing packet
192 * @param[in] payloadLen - Length of the IPMI payload
Tom Joseph64703f42017-01-10 17:03:48 +0530193 */
Tom Joseph1404bca2017-01-26 14:17:02 +0530194void addIntegrityData(std::vector<uint8_t>& packet,
195 const Message& message,
196 size_t payloadLen);
Tom Joseph64703f42017-01-10 17:03:48 +0530197
Tom Joseph78478a82017-01-26 14:24:29 +0530198/*
199 * @brief Decrypt the encrypted payload in the incoming IPMI packet
200 *
201 * @param[in] packet - Incoming IPMI packet
202 * @param[in] message - IPMI Message populated from the incoming packet
203 * @param[in] payloadLen - Length of encrypted IPMI payload
204 *
205 * @return on successful completion, return the plain text payload
206 */
207std::vector<uint8_t> decryptPayload(const std::vector<uint8_t>& packet,
208 const Message& message,
209 size_t payloadLen);
210
Tom Joseph75362832017-01-26 15:17:04 +0530211/*
212 * @brief Encrypt the plain text payload for the outgoing IPMI packet
213 *
214 * @param[in] message - IPMI Message populated for the outgoing packet
215 *
216 * @return on successful completion, return the encrypted payload
217 */
218std::vector<uint8_t> encryptPayload(Message& message);
219
Tom Joseph4e57ada2016-08-10 06:51:12 -0500220} // namespace internal
221
222} // namespace ipmi20parser
223
224} // namespace message