blob: 49a0c5de901ef94b24965857042a9f06a4f19f32 [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
22// Maximum packet size that we'll handle
23constexpr uint32_t MESSAGE_MAX_PACKET_LENGTH = 512;
24
25enum class SessionHeader
26{
27 IPMI15 = 0x00,
28 IPMI20 = 0x06,
29 INVALID = 0xFF,
30};
31
32struct BasicHeader_t
33{
34 // RMCP Header
35 uint8_t version;
36 uint8_t reserved;
37 uint8_t rmcpSeqNum;
38 uint8_t classOfMsg;
39
40 // IPMI partial session header
41 union
42 {
43 uint8_t reserved1: 4;
44 uint8_t authType: 4;
45 uint8_t formatType;
46 } format;
47} __attribute__((packed));
48
49/*
50 * @brief Unflatten an incoming packet and prepare the IPMI message
51 *
52 * @param[in] inPacket - Incoming IPMI packet
53 *
54 * @return A tuple with IPMI message and the session header type to sent the
55 * response packet. In case of success incoming message and session
56 * header type. In case of failure nullptr and session header type
57 * would be invalid.
58 */
59std::tuple<std::unique_ptr<Message>, SessionHeader> unflatten(
60 std::vector<uint8_t>& inPacket);
61
62/*
63 * @brief Flatten an IPMI message and generate the IPMI packet with the
64 * session header
65 *
66 * @param[in] outMessage - IPMI message to be flattened
67 * @param[in] authType - Session header type to be added to the IPMI
68 * packet
69 *
70 * @return IPMI packet on success
71 */
72std::vector<uint8_t> flatten(Message& outMessage,
73 SessionHeader authType,
74 session::Session& session);
75
76} // namespace parser
77
78namespace ipmi15parser
79{
80
81struct SessionHeader_t
82{
83 struct parser::BasicHeader_t base;
84 uint32_t sessSeqNum;
85 uint32_t sessId;
86 // <Optional Field: AuthCode>
87 uint8_t payloadLength;
88} __attribute__((packed));
89
90struct SessionTrailer_t
91{
92 uint8_t legacyPad;
93} __attribute__((packed));
94
95/*
96 * @brief Unflatten an incoming packet and prepare the IPMI message
97 *
98 * @param[in] inPacket - Incoming IPMI packet
99 *
100 * @return IPMI message in the packet on success
101 */
102std::unique_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
103
104/*
105 * @brief Flatten an IPMI message and generate the IPMI packet with the
106 * session header
107 *
108 * @param[in] outMessage - IPMI message to be flattened
109 *
110 * @return IPMI packet on success
111 */
112std::vector<uint8_t> flatten(Message& outMessage, session::Session& session);
113
114} // namespace ipmi15parser
115
116namespace ipmi20parser
117{
118
119constexpr size_t MAX_INTEGRITY_DATA_LENGTH = 12;
120constexpr size_t PAYLOAD_ENCRYPT_MASK = 0x80;
121constexpr size_t PAYLOAD_AUTH_MASK = 0x40;
122
123struct SessionHeader_t
124{
125 struct parser::BasicHeader_t base;
126
127 uint8_t payloadType;
128
129 uint32_t sessId;
130 uint32_t sessSeqNum;
131 uint16_t payloadLength;
132} __attribute__((packed));
133
134struct SessionTrailer_t
135{
136 // Integrity Pad
137 uint8_t padLength;
138 uint8_t nextHeader;
139 // AuthCode (Integrity Data)
140 uint8_t authCode[MAX_INTEGRITY_DATA_LENGTH];
141} __attribute__((packed));
142
143/*
144 * @brief Unflatten an incoming packet and prepare the IPMI message
145 *
146 * @param[in] inPacket - Incoming IPMI packet
147 *
148 * @return IPMI message in the packet on success
149 */
150std::unique_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
151
152/*
153 * @brief Flatten an IPMI message and generate the IPMI packet with the
154 * session header
155 *
156 * @param[in] outMessage - IPMI message to be flattened
157 *
158 * @return IPMI packet on success
159 */
160std::vector<uint8_t> flatten(Message& outMessage, session::Session& session);
161
162namespace internal
163{
164
165/*
166 * @brief Add sequence number to the message
167 *
168 * @param[in] packet - outgoing packet to which to add sequence number
169 * @param[in] session - session handle
170 *
171 */
172void addSequenceNumber(std::vector<uint8_t>& packet, session::Session& session);
173
174} // namespace internal
175
176} // namespace ipmi20parser
177
178} // namespace message