1 /*
2  * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * Redistribution of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * Redistribution in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * Neither the name of Sun Microsystems, Inc. or the names of
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * This software is provided "AS IS," without a warranty of any kind.
20  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
26  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  */
32 
33 #ifndef IPMI_H
34 #define IPMI_H
35 
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <inttypes.h>
39 #include <sys/types.h>
40 #include <netinet/in.h>
41 #include <ipmitool/helper.h>
42 #include <ipmitool/ipmi_cc.h>
43 
44 #if HAVE_CONFIG_H
45 # include <config.h>
46 #endif
47 
48 #define IPMI_BUF_SIZE 1024
49 #define IPMI_MAX_MD_SIZE 0x20
50 
51 #if HAVE_PRAGMA_PACK
52 #define ATTRIBUTE_PACKING
53 #else
54 #define ATTRIBUTE_PACKING __attribute__ ((packed))
55 #endif
56 
57 
58 /* From table 13.16 of the IPMI v2 specification */
59 #define IPMI_PAYLOAD_TYPE_IPMI               0x00
60 #define IPMI_PAYLOAD_TYPE_SOL                0x01
61 #define IPMI_PAYLOAD_TYPE_OEM                0x02
62 #define IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST  0x10
63 #define IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE 0x11
64 #define IPMI_PAYLOAD_TYPE_RAKP_1             0x12
65 #define IPMI_PAYLOAD_TYPE_RAKP_2             0x13
66 #define IPMI_PAYLOAD_TYPE_RAKP_3             0x14
67 #define IPMI_PAYLOAD_TYPE_RAKP_4             0x15
68 
69 extern int verbose;
70 extern int csv_output;
71 
72 struct ipmi_rq {
73 	struct {
74 		uint8_t netfn:6;
75 		uint8_t lun:2;
76 		uint8_t cmd;
77 		uint8_t target_cmd;
78 		uint16_t data_len;
79 		uint8_t *data;
80 	} msg;
81 };
82 
83 /*
84  * This is what the sendrcv_v2() function would take as an argument. The common case
85  * is for payload_type to be IPMI_PAYLOAD_TYPE_IPMI.
86  */
87 struct ipmi_v2_payload {
88 	uint16_t payload_length;
89 	uint8_t payload_type;
90 
91 	union {
92 
93 		struct {
94 			uint8_t rq_seq;
95 			struct ipmi_rq *request;
96 		} ipmi_request;
97 
98 		struct {
99 			uint8_t rs_seq;
100 			struct ipmi_rs *response;
101 		} ipmi_response;
102 
103 		/* Only used internally by the lanplus interface */
104 		struct {
105 			uint8_t *request;
106 		} open_session_request;
107 
108 		/* Only used internally by the lanplus interface */
109 		struct {
110 			uint8_t *message;
111 		} rakp_1_message;
112 
113 		/* Only used internally by the lanplus interface */
114 		struct {
115 			uint8_t *message;
116 		} rakp_2_message;
117 
118 		/* Only used internally by the lanplus interface */
119 		struct {
120 			uint8_t *message;
121 		} rakp_3_message;
122 
123 		/* Only used internally by the lanplus interface */
124 		struct {
125 			uint8_t *message;
126 		} rakp_4_message;
127 
128 		struct {
129 			uint8_t data[IPMI_BUF_SIZE];
130 			uint16_t character_count;
131 			uint8_t packet_sequence_number;
132 			uint8_t acked_packet_number;
133 			uint8_t accepted_character_count;
134 			uint8_t is_nack;	/* bool */
135 			uint8_t assert_ring_wor;	/* bool */
136 			uint8_t generate_break;	/* bool */
137 			uint8_t deassert_cts;	/* bool */
138 			uint8_t deassert_dcd_dsr;	/* bool */
139 			uint8_t flush_inbound;	/* bool */
140 			uint8_t flush_outbound;	/* bool */
141 		} sol_packet;
142 
143 	} payload;
144 };
145 
146 struct ipmi_rq_entry {
147 	struct ipmi_rq req;
148 	struct ipmi_intf *intf;
149 	uint8_t rq_seq;
150 	uint8_t *msg_data;
151 	int msg_len;
152 	int bridging_level;
153 	struct ipmi_rq_entry *next;
154 };
155 
156 struct ipmi_rs {
157 	uint8_t ccode;
158 	uint8_t data[IPMI_BUF_SIZE];
159 
160 	/*
161 	 * Looks like this is the length of the entire packet, including the RMCP
162 	 * stuff, then modified to be the length of the extra IPMI message data
163 	 */
164 	int data_len;
165 
166 	struct {
167 		uint8_t netfn;
168 		uint8_t cmd;
169 		uint8_t seq;
170 		uint8_t lun;
171 	} msg;
172 
173 	struct {
174 		uint8_t authtype;
175 		uint32_t seq;
176 		uint32_t id;
177 		uint8_t bEncrypted;	/* IPMI v2 only */
178 		uint8_t bAuthenticated;	/* IPMI v2 only */
179 		uint8_t payloadtype;	/* IPMI v2 only */
180 		/* This is the total length of the payload or
181 		   IPMI message.  IPMI v2.0 requires this to
182 		   be 2 bytes.  Not really used for much. */
183 		uint16_t msglen;
184 	} session;
185 
186 	/*
187 	 * A union of the different possible payload meta-data
188 	 */
189 	union {
190 		struct {
191 			uint8_t rq_addr;
192 			uint8_t netfn;
193 			uint8_t rq_lun;
194 			uint8_t rs_addr;
195 			uint8_t rq_seq;
196 			uint8_t rs_lun;
197 			uint8_t cmd;
198 		} ipmi_response;
199 		struct {
200 			uint8_t message_tag;
201 			uint8_t rakp_return_code;
202 			uint8_t max_priv_level;
203 			uint32_t console_id;
204 			uint32_t bmc_id;
205 			uint8_t auth_alg;
206 			uint8_t integrity_alg;
207 			uint8_t crypt_alg;
208 		} open_session_response;
209 		struct {
210 			uint8_t message_tag;
211 			uint8_t rakp_return_code;
212 			uint32_t console_id;
213 			uint8_t bmc_rand[16];	/* Random number generated by the BMC */
214 			uint8_t bmc_guid[16];
215 			uint8_t key_exchange_auth_code[IPMI_MAX_MD_SIZE];
216 		} rakp2_message;
217 		struct {
218 			uint8_t message_tag;
219 			uint8_t rakp_return_code;
220 			uint32_t console_id;
221 			uint8_t integrity_check_value[IPMI_MAX_MD_SIZE];
222 		} rakp4_message;
223 		struct {
224 			uint8_t packet_sequence_number;
225 			uint8_t acked_packet_number;
226 			uint8_t accepted_character_count;
227 			uint8_t is_nack;	/* bool */
228 			uint8_t transfer_unavailable;	/* bool */
229 			uint8_t sol_inactive;	/* bool */
230 			uint8_t transmit_overrun;	/* bool */
231 			uint8_t break_detected;	/* bool */
232 		} sol_packet;
233 
234 	} payload;
235 };
236 
237 #define IPMI_NETFN_CHASSIS		0x0
238 #define IPMI_NETFN_BRIDGE		0x2
239 #define IPMI_NETFN_SE			0x4
240 #define IPMI_NETFN_APP			0x6
241 #define IPMI_NETFN_FIRMWARE		0x8
242 #define IPMI_NETFN_STORAGE		0xa
243 #define IPMI_NETFN_TRANSPORT	0xc
244 #define IPMI_NETFN_PICMG		0x2C
245 #define IPMI_NETFN_DCGRP		0x2C
246 #define IPMI_NETFN_OEM		0x2E
247 #define IPMI_NETFN_ISOL			0x34
248 #define IPMI_NETFN_TSOL			0x30
249 
250 #define IPMI_BMC_SLAVE_ADDR		0x20
251 #define IPMI_REMOTE_SWID		0x81
252 
253 
254 /* These values are IANA numbers */
255 /************************************************************************
256 * Add ID String for IANA Enterprise Number of IBM & ADLINK
257 * https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
258 ************************************************************************/
259 
260 typedef enum IPMI_OEM {
261      IPMI_OEM_UNKNOWN    = 0,
262      /* 2 for [IBM] */
263      IPMI_OEM_IBM_2      = 2,
264      IPMI_OEM_HP         = 11,
265      IPMI_OEM_SUN        = 42,
266      IPMI_OEM_NOKIA      = 94,
267      IPMI_OEM_BULL       = 107,
268      IPMI_OEM_HITACHI_116 = 116,
269      IPMI_OEM_NEC        = 119,
270      IPMI_OEM_TOSHIBA    = 186,
271      IPMI_OEM_ERICSSON   = 193,
272      IPMI_OEM_INTEL      = 343,
273      IPMI_OEM_TATUNG     = 373,
274      IPMI_OEM_HITACHI_399 = 399,
275      IPMI_OEM_DELL       = 674,
276      IPMI_OEM_LMC        = 2168,
277      IPMI_OEM_RADISYS    = 4337,
278      IPMI_OEM_BROADCOM   = 4413,
279      /* 4769 for [IBM Corporation] */
280      IPMI_OEM_IBM_4769   = 4769,
281      IPMI_OEM_MAGNUM     = 5593,
282      IPMI_OEM_TYAN       = 6653,
283      IPMI_OEM_QUANTA     = 7244,
284      IPMI_OEM_NEWISYS    = 9237,
285      IPMI_OEM_ADVANTECH  = 10297,
286      IPMI_OEM_FUJITSU_SIEMENS = 10368,
287      IPMI_OEM_AVOCENT    = 10418,
288      IPMI_OEM_PEPPERCON  = 10437,
289      IPMI_OEM_SUPERMICRO = 10876,
290      IPMI_OEM_OSA        = 11102,
291      IPMI_OEM_GOOGLE     = 11129,
292      IPMI_OEM_PICMG      = 12634,
293      IPMI_OEM_RARITAN    = 13742,
294      IPMI_OEM_KONTRON    = 15000,
295      IPMI_OEM_PPS        = 16394,
296      /* 20301 for [IBM eServer X] */
297      IPMI_OEM_IBM_20301  = 20301,
298      IPMI_OEM_AMI        = 20974,
299      /* 24339 for [ADLINK TECHNOLOGY INC.] */
300      IPMI_OEM_ADLINK_24339 = 24339,
301      IPMI_OEM_NOKIA_SOLUTIONS_AND_NETWORKS = 28458,
302      IPMI_OEM_VITA       = 33196,
303      IPMI_OEM_SUPERMICRO_47488 = 47488
304 } IPMI_OEM;
305 
306 extern const struct valstr completion_code_vals[];
307 
308 #endif				/* IPMI_H */
309