1 /*****************************************************************************\
2 * $Id: ipmipower_packet.c,v 1.127 2010-06-11 16:29:34 chu11 Exp $
3 *****************************************************************************
4 * Copyright (C) 2007-2015 Lawrence Livermore National Security, LLC.
5 * Copyright (C) 2003-2007 The Regents of the University of California.
6 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
7 * Written by Albert Chu <chu11@llnl.gov>
8 * UCRL-CODE-155698
9 *
10 * This file is part of Ipmipower, a remote power control utility.
11 * For details, see http://www.llnl.gov/linux/.
12 *
13 * Ipmipower is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 3 of the License, or (at your
16 * option) any later version.
17 *
18 * Ipmipower is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with Ipmipower. If not, see <http://www.gnu.org/licenses/>.
25 \*****************************************************************************/
26
27 #if HAVE_CONFIG_H
28 #include "config.h"
29 #endif /* HAVE_CONFIG_H */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #if STDC_HEADERS
34 #include <string.h>
35 #endif /* STDC_HEADERS */
36 #if HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif /* HAVE_UNISTD_H */
39 #include <errno.h>
40 #include <assert.h>
41 #include <stdint.h>
42
43 #include "ipmipower_packet.h"
44 #include "ipmipower_error.h"
45 #include "ipmipower_oem.h"
46 #include "ipmipower_util.h"
47
48 #include "freeipmi-portability.h"
49 #include "debug-util.h"
50
51 extern struct ipmipower_arguments cmd_args;
52
53 fiid_field_t *
ipmipower_packet_cmd_template(ipmipower_powercmd_t ip,ipmipower_packet_type_t pkt)54 ipmipower_packet_cmd_template (ipmipower_powercmd_t ip, ipmipower_packet_type_t pkt)
55 {
56 assert (ip);
57 assert (IPMIPOWER_PACKET_TYPE_VALID (pkt));
58
59 switch (pkt)
60 {
61 case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RQ:
62 return (&tmpl_cmd_get_channel_authentication_capabilities_rq[0]);
63 case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RS:
64 return (&tmpl_cmd_get_channel_authentication_capabilities_rs[0]);
65 case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ:
66 return (&tmpl_cmd_get_session_challenge_rq[0]);
67 case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RS:
68 return (&tmpl_cmd_get_session_challenge_rs[0]);
69 case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ:
70 return (&tmpl_cmd_activate_session_rq[0]);
71 case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS:
72 return (&tmpl_cmd_activate_session_rs[0]);
73 case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_REQUEST:
74 return (&tmpl_rmcpplus_open_session_request[0]);
75 case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_RESPONSE:
76 return (&tmpl_rmcpplus_open_session_response[0]);
77 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1:
78 return (&tmpl_rmcpplus_rakp_message_1[0]);
79 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_2:
80 return (&tmpl_rmcpplus_rakp_message_2[0]);
81 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3:
82 return (&tmpl_rmcpplus_rakp_message_3[0]);
83 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_4:
84 return (&tmpl_rmcpplus_rakp_message_4[0]);
85 case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RQ:
86 return (&tmpl_cmd_set_session_privilege_level_rq[0]);
87 case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS:
88 return (&tmpl_cmd_set_session_privilege_level_rs[0]);
89 case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RQ:
90 return (&tmpl_cmd_get_chassis_status_rq[0]);
91 case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RS:
92 return (&tmpl_cmd_get_chassis_status_rs[0]);
93 case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RQ:
94 return (&tmpl_cmd_chassis_control_rq[0]);
95 case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RS:
96 return (&tmpl_cmd_chassis_control_rs[0]);
97 case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RQ:
98 return (&tmpl_cmd_chassis_identify_rq[0]);
99 case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RS:
100 return (&tmpl_cmd_chassis_identify_rs[0]);
101 case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RQ:
102 return (&tmpl_cmd_get_sensor_reading_rq[0]);
103 case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RS:
104 return (&tmpl_cmd_get_sensor_reading_rs[0]);
105 case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RQ:
106 return (&tmpl_cmd_c410x_slot_power_control_rq[0]);
107 case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RS:
108 return (&tmpl_cmd_c410x_slot_power_control_rs[0]);
109 case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RQ:
110 return (&tmpl_cmd_close_session_rq[0]);
111 case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RS:
112 return (&tmpl_cmd_close_session_rs[0]);
113 default:
114 IPMIPOWER_ERROR (("ipmipower_packet_cmd_template: invalid packet type: %d", pkt));
115 exit (EXIT_FAILURE);
116 }
117
118 return (NULL); /* NOT REACHED */
119 }
120
121 fiid_obj_t
ipmipower_packet_cmd_obj(ipmipower_powercmd_t ip,ipmipower_packet_type_t pkt)122 ipmipower_packet_cmd_obj (ipmipower_powercmd_t ip, ipmipower_packet_type_t pkt)
123 {
124 assert (ip);
125 assert (IPMIPOWER_PACKET_TYPE_VALID (pkt));
126
127 switch (pkt)
128 {
129 case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RQ:
130 return (ip->obj_authentication_capabilities_rq);
131 case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RS:
132 return (ip->obj_authentication_capabilities_rs);
133 case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ:
134 return (ip->obj_get_session_challenge_rq);
135 case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RS:
136 return (ip->obj_get_session_challenge_rs);
137 case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ:
138 return (ip->obj_activate_session_rq);
139 case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS:
140 return (ip->obj_activate_session_rs);
141 case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_REQUEST:
142 return (ip->obj_open_session_rq);
143 case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_RESPONSE:
144 return (ip->obj_open_session_rs);
145 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1:
146 return (ip->obj_rakp_message_1_rq);
147 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_2:
148 return (ip->obj_rakp_message_2_rs);
149 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3:
150 return (ip->obj_rakp_message_3_rq);
151 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_4:
152 return (ip->obj_rakp_message_4_rs);
153 case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RQ:
154 return (ip->obj_set_session_privilege_level_rq);
155 case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS:
156 return (ip->obj_set_session_privilege_level_rs);
157 case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RQ:
158 return (ip->obj_get_chassis_status_rq);
159 case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RS:
160 return (ip->obj_get_chassis_status_rs);
161 case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RQ:
162 return (ip->obj_chassis_control_rq);
163 case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RS:
164 return (ip->obj_chassis_control_rs);
165 case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RQ:
166 return (ip->obj_chassis_identify_rq);
167 case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RS:
168 return (ip->obj_chassis_identify_rs);
169 case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RQ:
170 return (ip->obj_c410x_get_sensor_reading_rq);
171 case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RS:
172 return (ip->obj_c410x_get_sensor_reading_rs);
173 case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RQ:
174 return (ip->obj_c410x_slot_power_control_rq);
175 case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RS:
176 return (ip->obj_c410x_slot_power_control_rs);
177 case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RQ:
178 return (ip->obj_close_session_rq);
179 case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RS:
180 return (ip->obj_close_session_rs);
181 default:
182 IPMIPOWER_ERROR (("ipmipower_packet_cmd_obj: invalid packet type: %d", pkt));
183 exit (EXIT_FAILURE);
184 }
185
186 return (NULL); /* NOT REACHED */
187 }
188
189 void
ipmipower_packet_dump(ipmipower_powercmd_t ip,ipmipower_packet_type_t pkt,const void * buf,unsigned int buflen)190 ipmipower_packet_dump (ipmipower_powercmd_t ip,
191 ipmipower_packet_type_t pkt,
192 const void *buf,
193 unsigned int buflen)
194 {
195 assert (ip);
196 assert (IPMIPOWER_PACKET_TYPE_VALID (pkt));
197 assert (buf);
198
199 if (cmd_args.common_args.debug)
200 {
201 fiid_field_t *tmpl_lan_msg_hdr;
202 char hdrbuf[DEBUG_UTIL_HDR_BUFLEN + 1];
203 uint8_t packet_type;
204 uint8_t packet_direction;
205 const char *str_cmd = NULL;
206
207 if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN)
208 packet_type = DEBUG_UTIL_TYPE_IPMI_1_5;
209 else
210 packet_type = DEBUG_UTIL_TYPE_IPMI_2_0;
211
212 switch (pkt)
213 {
214 case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RQ:
215 case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RS:
216 str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES);
217 break;
218 case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ:
219 case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RS:
220 str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_GET_SESSION_CHALLENGE);
221 break;
222 case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ:
223 case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS:
224 str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_ACTIVATE_SESSION);
225 break;
226 case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_REQUEST:
227 case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_RESPONSE:
228 str_cmd = DEBUG_UTIL_OPEN_SESSION_STR;
229 break;
230 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1:
231 str_cmd = DEBUG_UTIL_RAKP_1_STR;
232 break;
233 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_2:
234 str_cmd = DEBUG_UTIL_RAKP_2_STR;
235 break;
236 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3:
237 str_cmd = DEBUG_UTIL_RAKP_3_STR;
238 break;
239 case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_4:
240 str_cmd = DEBUG_UTIL_RAKP_4_STR;
241 break;
242 case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RQ:
243 case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS:
244 str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_SET_SESSION_PRIVILEGE_LEVEL);
245 break;
246 case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RQ:
247 case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RS:
248 str_cmd = ipmi_cmd_str (IPMI_NET_FN_CHASSIS_RQ, IPMI_CMD_GET_CHASSIS_STATUS);
249 break;
250 case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RQ:
251 case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RS:
252 str_cmd = ipmi_cmd_str (IPMI_NET_FN_CHASSIS_RQ, IPMI_CMD_CHASSIS_CONTROL);
253 break;
254 case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RQ:
255 case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RS:
256 str_cmd = ipmi_cmd_str (IPMI_NET_FN_CHASSIS_RQ, IPMI_CMD_CHASSIS_IDENTIFY);
257 break;
258 case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RQ:
259 case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RS:
260 str_cmd = ipmi_cmd_str (IPMI_NET_FN_SENSOR_EVENT_RQ, IPMI_CMD_GET_SENSOR_READING);
261 break;
262 case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RQ:
263 case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RS:
264 str_cmd = "C410x Slot Power Control";
265 break;
266 case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RQ:
267 case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RS:
268 str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_CLOSE_SESSION);
269 break;
270 default:
271 IPMIPOWER_ERROR (("ipmipower_packet_dump: invalid packet type: %d", pkt));
272 exit (EXIT_FAILURE);
273 }
274
275 if (IPMIPOWER_PACKET_TYPE_RQ (pkt))
276 packet_direction = DEBUG_UTIL_DIRECTION_REQUEST;
277 else
278 packet_direction = DEBUG_UTIL_DIRECTION_RESPONSE;
279
280 memset (hdrbuf, '\0', DEBUG_UTIL_HDR_BUFLEN + 1);
281 debug_hdr_str (packet_type,
282 packet_direction,
283 DEBUG_UTIL_FLAGS_DEFAULT,
284 str_cmd,
285 hdrbuf,
286 DEBUG_UTIL_HDR_BUFLEN);
287
288 if (IPMIPOWER_PACKET_TYPE_RQ (pkt))
289 tmpl_lan_msg_hdr = &tmpl_lan_msg_hdr_rq[0];
290 else
291 tmpl_lan_msg_hdr = &tmpl_lan_msg_hdr_rs[0];
292
293 if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP (pkt))
294 {
295 if (ipmi_dump_rmcpplus_packet (STDERR_FILENO,
296 ip->ic->hostname,
297 hdrbuf,
298 NULL,
299 IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE,
300 IPMI_INTEGRITY_ALGORITHM_NONE,
301 IPMI_CONFIDENTIALITY_ALGORITHM_NONE,
302 NULL,
303 0,
304 NULL,
305 0,
306 buf,
307 buflen,
308 tmpl_lan_msg_hdr,
309 ipmipower_packet_cmd_template (ip, pkt)) < 0)
310 {
311 IPMIPOWER_ERROR (("ipmi_dump_rmcpplus_packet: %s", strerror (errno)));
312 exit (EXIT_FAILURE);
313 }
314 }
315 else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
316 && IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET (pkt))
317 {
318 if (ipmi_dump_rmcpplus_packet (STDERR_FILENO,
319 ip->ic->hostname,
320 hdrbuf,
321 NULL,
322 ip->authentication_algorithm,
323 ip->integrity_algorithm,
324 ip->confidentiality_algorithm,
325 ip->integrity_key_ptr,
326 ip->integrity_key_len,
327 ip->confidentiality_key_ptr,
328 ip->confidentiality_key_len,
329 buf,
330 buflen,
331 tmpl_lan_msg_hdr,
332 ipmipower_packet_cmd_template (ip, pkt)) < 0)
333 {
334 IPMIPOWER_ERROR (("ipmi_dump_rmcpplus_packet: %s", strerror (errno)));
335 exit (EXIT_FAILURE);
336 }
337 }
338 else /* cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
339 && IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET (pkt))
340 */
341 {
342 if (ipmi_dump_lan_packet (STDERR_FILENO,
343 ip->ic->hostname,
344 hdrbuf,
345 NULL,
346 buf,
347 buflen,
348 tmpl_lan_msg_hdr,
349 ipmipower_packet_cmd_template (ip, pkt)) < 0)
350 {
351 IPMIPOWER_ERROR (("ipmi_dump_lan_packet: %s", strerror (errno)));
352 exit (EXIT_FAILURE);
353 }
354 }
355 }
356 }
357
358 int
ipmipower_packet_store(ipmipower_powercmd_t ip,ipmipower_packet_type_t pkt,const void * buf,unsigned int buflen)359 ipmipower_packet_store (ipmipower_powercmd_t ip,
360 ipmipower_packet_type_t pkt,
361 const void *buf,
362 unsigned int buflen)
363 {
364 fiid_obj_t obj;
365 int rv = -1;
366
367 assert (ip);
368 assert (buf);
369 assert (buflen);
370 assert (IPMIPOWER_PACKET_TYPE_RS (pkt));
371
372 obj = ipmipower_packet_cmd_obj (ip, pkt);
373
374 if (IPMIPOWER_PACKET_TYPE_IPMI_1_5_SETUP_RS (pkt)
375 || cmd_args.common_args.driver_type == IPMI_DEVICE_LAN)
376 {
377 if ((rv = unassemble_ipmi_lan_pkt (buf,
378 buflen,
379 ip->obj_rmcp_hdr_rs,
380 ip->obj_lan_session_hdr_rs,
381 ip->obj_lan_msg_hdr_rs,
382 obj,
383 ip->obj_lan_msg_trlr_rs,
384 IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
385 {
386 IPMIPOWER_ERROR (("unassemble_ipmi_lan_pkt: %s", strerror (errno)));
387 exit (EXIT_FAILURE);
388 }
389 }
390 else
391 {
392 if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RS (pkt))
393 {
394 if ((rv = unassemble_ipmi_rmcpplus_pkt (IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE,
395 IPMI_INTEGRITY_ALGORITHM_NONE,
396 IPMI_CONFIDENTIALITY_ALGORITHM_NONE,
397 NULL,
398 0,
399 NULL,
400 0,
401 buf,
402 buflen,
403 ip->obj_rmcp_hdr_rs,
404 ip->obj_rmcpplus_session_hdr_rs,
405 ip->obj_rmcpplus_payload_rs,
406 ip->obj_lan_msg_hdr_rs,
407 obj,
408 ip->obj_lan_msg_trlr_rs,
409 ip->obj_rmcpplus_session_trlr_rs,
410 IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
411 {
412 IPMIPOWER_ERROR (("unassemble_ipmi_rmcpplus_pkt: %s", strerror (errno)));
413 exit (EXIT_FAILURE);
414 }
415 }
416 else
417 {
418 if ((rv = unassemble_ipmi_rmcpplus_pkt (ip->authentication_algorithm,
419 ip->integrity_algorithm,
420 ip->confidentiality_algorithm,
421 ip->integrity_key_ptr,
422 ip->integrity_key_len,
423 ip->confidentiality_key_ptr,
424 ip->confidentiality_key_len,
425 buf,
426 buflen,
427 ip->obj_rmcp_hdr_rs,
428 ip->obj_rmcpplus_session_hdr_rs,
429 ip->obj_rmcpplus_payload_rs,
430 ip->obj_lan_msg_hdr_rs,
431 obj,
432 ip->obj_lan_msg_trlr_rs,
433 ip->obj_rmcpplus_session_trlr_rs,
434 IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
435 {
436 IPMIPOWER_ERROR (("unassemble_ipmi_rmcpplus_pkt: %s", strerror (errno)));
437 exit (EXIT_FAILURE);
438 }
439 }
440 }
441
442 return (rv);
443 }
444
445 static int
_ipmi_1_5_packet_create(ipmipower_powercmd_t ip,ipmipower_packet_type_t pkt,uint8_t authentication_type,uint32_t inbound_sequence_number,uint32_t session_id,void * authentication_code_data,unsigned int authentication_code_data_len,uint8_t net_fn,fiid_obj_t obj_cmd_rq,void * buf,unsigned int buflen)446 _ipmi_1_5_packet_create (ipmipower_powercmd_t ip,
447 ipmipower_packet_type_t pkt,
448 uint8_t authentication_type,
449 uint32_t inbound_sequence_number,
450 uint32_t session_id,
451 void *authentication_code_data,
452 unsigned int authentication_code_data_len,
453 uint8_t net_fn,
454 fiid_obj_t obj_cmd_rq,
455 void *buf,
456 unsigned int buflen)
457 {
458 int len;
459
460 assert (ip);
461 assert (IPMIPOWER_PACKET_TYPE_RQ (pkt));
462 assert (fiid_obj_valid (obj_cmd_rq));
463 assert (buf);
464 assert (buflen);
465
466 if (fill_rmcp_hdr_ipmi (ip->obj_rmcp_hdr_rq) < 0)
467 {
468 IPMIPOWER_ERROR (("fill_rmcp_hdr_ipmi: %s", strerror (errno)));
469 exit (EXIT_FAILURE);
470 }
471
472 if (fill_lan_session_hdr (authentication_type,
473 inbound_sequence_number,
474 session_id,
475 ip->obj_lan_session_hdr_rq) < 0)
476 {
477 IPMIPOWER_ERROR (("fill_lan_session_hdr: %s", strerror (errno)));
478 exit (EXIT_FAILURE);
479 }
480
481 if (fill_lan_msg_hdr (IPMI_SLAVE_ADDRESS_BMC,
482 net_fn,
483 IPMI_BMC_IPMB_LUN_BMC,
484 (ip->ic->ipmi_requester_sequence_number_counter % (IPMI_LAN_REQUESTER_SEQUENCE_NUMBER_MAX + 1)),
485 ip->obj_lan_msg_hdr_rq) < 0)
486 {
487 IPMIPOWER_ERROR (("fill_lan_msg_hdr: %s", strerror (errno)));
488 exit (EXIT_FAILURE);
489 }
490
491 if ((len = assemble_ipmi_lan_pkt (ip->obj_rmcp_hdr_rq,
492 ip->obj_lan_session_hdr_rq,
493 ip->obj_lan_msg_hdr_rq,
494 obj_cmd_rq,
495 authentication_code_data,
496 authentication_code_data_len,
497 buf,
498 buflen,
499 IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
500 {
501 IPMIPOWER_ERROR (("assemble_ipmi_lan_pkt: %s", strerror (errno)));
502 exit (EXIT_FAILURE);
503 }
504
505 return (len);
506 }
507
508 static int
_ipmi_2_0_packet_create(ipmipower_powercmd_t ip,ipmipower_packet_type_t pkt,uint8_t payload_type,uint8_t payload_authenticated,uint8_t payload_encrypted,uint32_t session_id,uint32_t session_sequence_number,void * authentication_code_data,unsigned int authentication_code_data_len,uint8_t net_fn,uint8_t authentication_algorithm,uint8_t integrity_algorithm,uint8_t confidentiality_algorithm,void * integrity_key,unsigned int integrity_key_len,void * confidentiality_key,unsigned int confidentiality_key_len,fiid_obj_t obj_cmd_rq,void * buf,unsigned int buflen)509 _ipmi_2_0_packet_create (ipmipower_powercmd_t ip,
510 ipmipower_packet_type_t pkt,
511 uint8_t payload_type,
512 uint8_t payload_authenticated,
513 uint8_t payload_encrypted,
514 uint32_t session_id,
515 uint32_t session_sequence_number,
516 void *authentication_code_data,
517 unsigned int authentication_code_data_len,
518 uint8_t net_fn,
519 uint8_t authentication_algorithm,
520 uint8_t integrity_algorithm,
521 uint8_t confidentiality_algorithm,
522 void *integrity_key,
523 unsigned int integrity_key_len,
524 void *confidentiality_key,
525 unsigned int confidentiality_key_len,
526 fiid_obj_t obj_cmd_rq,
527 void *buf,
528 unsigned int buflen)
529 {
530 int len;
531
532 assert (ip);
533 assert (IPMIPOWER_PACKET_TYPE_RQ (pkt));
534 assert (fiid_obj_valid (obj_cmd_rq));
535 assert (buf);
536 assert (buflen);
537
538 if (fill_rmcp_hdr_ipmi (ip->obj_rmcp_hdr_rq) < 0)
539 {
540 IPMIPOWER_ERROR (("fill_rmcp_hdr_ipmi: %s", strerror (errno)));
541 exit (EXIT_FAILURE);
542 }
543
544 if (fill_rmcpplus_session_hdr (payload_type,
545 payload_authenticated,
546 payload_encrypted,
547 0, /* oem_iana */
548 0, /* oem_payload_id */
549 session_id,
550 session_sequence_number,
551 ip->obj_rmcpplus_session_hdr_rq) < 0)
552 {
553 IPMIPOWER_ERROR (("fill_rmcpplus_session_hdr: %s", strerror (errno)));
554 exit (EXIT_FAILURE);
555 }
556
557 if (fill_lan_msg_hdr (IPMI_SLAVE_ADDRESS_BMC,
558 net_fn,
559 IPMI_BMC_IPMB_LUN_BMC,
560 (ip->ic->ipmi_requester_sequence_number_counter % (IPMI_LAN_REQUESTER_SEQUENCE_NUMBER_MAX + 1)),
561 ip->obj_lan_msg_hdr_rq) < 0)
562 {
563 IPMIPOWER_ERROR (("fill_lan_msg_hdr: %s", strerror (errno)));
564 exit (EXIT_FAILURE);
565 }
566
567 if (fill_rmcpplus_session_trlr (ip->obj_rmcpplus_session_trlr_rq) < 0)
568 {
569 IPMIPOWER_ERROR (("fill_rmcpplus_session_trlr: %s", strerror (errno)));
570 exit (EXIT_FAILURE);
571 }
572
573 if ((len = assemble_ipmi_rmcpplus_pkt (authentication_algorithm,
574 integrity_algorithm,
575 confidentiality_algorithm,
576 integrity_key,
577 integrity_key_len,
578 confidentiality_key,
579 confidentiality_key_len,
580 authentication_code_data,
581 authentication_code_data_len,
582 ip->obj_rmcp_hdr_rq,
583 ip->obj_rmcpplus_session_hdr_rq,
584 ip->obj_lan_msg_hdr_rq,
585 obj_cmd_rq,
586 ip->obj_rmcpplus_session_trlr_rq,
587 buf,
588 buflen,
589 IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
590 {
591 IPMIPOWER_ERROR (("assemble_ipmi_rmcpplus_pkt: %s", strerror (errno)));
592 exit (EXIT_FAILURE);
593 }
594
595 return (len);
596 }
597
598 int
ipmipower_packet_create(ipmipower_powercmd_t ip,ipmipower_packet_type_t pkt,void * buf,unsigned int buflen)599 ipmipower_packet_create (ipmipower_powercmd_t ip,
600 ipmipower_packet_type_t pkt,
601 void *buf,
602 unsigned int buflen)
603 {
604 char *username = NULL;
605 char *password = NULL;
606 void *integrity_key = NULL;
607 void *confidentiality_key = NULL;
608 char username_buf[IPMI_MAX_USER_NAME_LENGTH+1];
609 unsigned int username_len;
610 uint32_t session_id, managed_system_session_id = 0;
611 uint32_t sequence_number = 0;
612 unsigned int integrity_key_len = 0;
613 unsigned int confidentiality_key_len = 0;
614 uint8_t authentication_type = 0;
615 uint8_t net_fn = 0;
616 uint8_t payload_authenticated = 0;
617 uint8_t payload_encrypted = 0;
618 uint8_t payload_type = 0;
619 uint8_t authentication_algorithm = 0;
620 uint8_t integrity_algorithm = 0;
621 uint8_t confidentiality_algorithm = 0;
622 fiid_obj_t obj_cmd_rq = NULL;
623 uint64_t val;
624 int rv = 0;
625
626 assert (ip);
627 assert (IPMIPOWER_PACKET_TYPE_RQ (pkt));
628 assert (buf);
629 assert (buflen);
630
631 if (pkt == IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ
632 || pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1
633 || pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3)
634 {
635 username = cmd_args.common_args.username;
636
637 /* IPMI Workaround (achu)
638 *
639 * Discovered on SE7520AF2 with Intel Server Management Module
640 * (Professional Edition)
641 *
642 * The username must be padded despite explicitly not being
643 * allowed. "No Null characters (00h) are allowed in the name".
644 * Table 13-11 in the IPMI 2.0 spec.
645 */
646 if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1
647 && (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION))
648 {
649 memset (username_buf, '\0', IPMI_MAX_USER_NAME_LENGTH+1);
650 if (username)
651 strcpy (username_buf, username);
652 username = username_buf;
653 username_len = IPMI_MAX_USER_NAME_LENGTH;
654 }
655 else
656 username_len = (username) ? strlen (username) : 0;
657 }
658 else
659 {
660 username = NULL;
661 username_len = 0;
662 }
663
664 /* Calculate Password */
665 if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ
666 || IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RQ (pkt)
667 || IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
668 password = cmd_args.common_args.password;
669 else
670 password = NULL;
671
672 /* Calculate Session ID */
673 if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ)
674 {
675 if (FIID_OBJ_GET (ip->obj_get_session_challenge_rs,
676 "temp_session_id",
677 &val) < 0)
678 {
679 IPMIPOWER_ERROR (("FIID_OBJ_GET: 'temp_session_id': %s",
680 fiid_obj_errormsg (ip->obj_get_session_challenge_rs)));
681 exit (EXIT_FAILURE);
682 }
683
684 session_id = val;
685 }
686 else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
687 && IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
688 {
689 if (FIID_OBJ_GET (ip->obj_activate_session_rs,
690 "session_id",
691 &val) < 0)
692 {
693 IPMIPOWER_ERROR (("FIID_OBJ_GET: 'session_id': %s",
694 fiid_obj_errormsg (ip->obj_activate_session_rs)));
695 exit (EXIT_FAILURE);
696 }
697 session_id = val;
698 }
699 else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
700 && IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
701 {
702 if (FIID_OBJ_GET (ip->obj_open_session_rs,
703 "managed_system_session_id",
704 &val) < 0)
705 {
706 IPMIPOWER_ERROR (("FIID_OBJ_GET: 'managed_system_session_id': %s",
707 fiid_obj_errormsg (ip->obj_open_session_rs)));
708 exit (EXIT_FAILURE);
709 }
710 session_id = val;
711 }
712 else
713 session_id = 0;
714
715 /* Calculate Sequence Number */
716 if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
717 && IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
718 {
719 uint32_t initial_inbound_sequence_number;
720
721 if (FIID_OBJ_GET (ip->obj_activate_session_rs,
722 "initial_inbound_sequence_number",
723 &val) < 0)
724 {
725 IPMIPOWER_ERROR (("FIID_OBJ_GET: 'initial_inbound_sequence_number': %s",
726 fiid_obj_errormsg (ip->obj_activate_session_rs)));
727 exit (EXIT_FAILURE);
728 }
729 initial_inbound_sequence_number = val;
730
731 sequence_number = initial_inbound_sequence_number + ip->session_inbound_count;
732 }
733 else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
734 && IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
735 sequence_number = ip->session_sequence_number;
736 else
737 sequence_number = 0;
738
739 /* Calculate Network Function */
740 if (pkt == IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RQ
741 || pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RQ
742 || pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RQ)
743 net_fn = IPMI_NET_FN_CHASSIS_RQ;
744 else if (pkt == IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RQ)
745 net_fn = IPMI_NET_FN_SENSOR_EVENT_RQ;
746 else if (pkt == IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RQ)
747 net_fn = IPMI_NET_FN_OEM_DELL_GENERIC_RQ;
748 else /* pkt == IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RQ
749 || pkt == IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ
750 || pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ
751 || pkt == IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RQ
752 */
753 net_fn = IPMI_NET_FN_APP_RQ;
754
755 /* Calculate Authentication Type */
756 if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ)
757 authentication_type = cmd_args.common_args.authentication_type;
758 else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
759 && IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
760 {
761 if (!ip->permsgauth_enabled)
762 authentication_type = IPMI_AUTHENTICATION_TYPE_NONE;
763 else
764 authentication_type = cmd_args.common_args.authentication_type;
765
766 if (authentication_type == IPMI_AUTHENTICATION_TYPE_NONE)
767 password = NULL;
768 }
769 else
770 authentication_type = IPMI_AUTHENTICATION_TYPE_NONE;
771
772 if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0)
773 {
774 /* Calculate Payload Type */
775 if (pkt == IPMIPOWER_PACKET_TYPE_OPEN_SESSION_REQUEST)
776 payload_type = IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST;
777 else if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1)
778 payload_type = IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1;
779 else if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3)
780 payload_type = IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3;
781 else
782 payload_type = IPMI_PAYLOAD_TYPE_IPMI;
783
784 /* achu: "session_id" above is for the session headers. This is
785 * for the RAKP session setup protocol. The values will be
786 * different.
787 */
788 if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1
789 || pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3)
790 {
791 if (FIID_OBJ_GET (ip->obj_open_session_rs,
792 "managed_system_session_id",
793 &val) < 0)
794 {
795 IPMIPOWER_ERROR (("FIID_OBJ_GET: 'managed_system_session_id': %s",
796 fiid_obj_errormsg (ip->obj_open_session_rs)));
797 exit (EXIT_FAILURE);
798 }
799 managed_system_session_id = val;
800 }
801
802 /* Setup authentication/integrity/confidentiality keys */
803 if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RQ (pkt))
804 {
805 authentication_algorithm = IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE;
806 integrity_algorithm = IPMI_INTEGRITY_ALGORITHM_NONE;
807 confidentiality_algorithm = IPMI_CONFIDENTIALITY_ALGORITHM_NONE;
808 integrity_key = NULL;
809 integrity_key_len = 0;
810 confidentiality_key = NULL;
811 confidentiality_key_len = 0;
812 }
813 else /* IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt) */
814 {
815 authentication_algorithm = ip->authentication_algorithm;
816 integrity_algorithm = ip->integrity_algorithm;
817 confidentiality_algorithm = ip->confidentiality_algorithm;
818 integrity_key = ip->integrity_key_ptr;
819 integrity_key_len = ip->integrity_key_len;
820 confidentiality_key = ip->confidentiality_key_ptr;
821 confidentiality_key_len = ip->confidentiality_key_len;
822 }
823
824 /* Calculate Payload Authenticated */
825 if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RQ (pkt)
826 || integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE)
827 payload_authenticated = IPMI_PAYLOAD_FLAG_UNAUTHENTICATED;
828 else
829 payload_authenticated = IPMI_PAYLOAD_FLAG_AUTHENTICATED;
830
831 /* Calculate Payload Encrypted */
832 if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RQ (pkt)
833 || confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE)
834 payload_encrypted = IPMI_PAYLOAD_FLAG_UNENCRYPTED;
835 else
836 payload_encrypted = IPMI_PAYLOAD_FLAG_ENCRYPTED;
837 }
838
839 /* Calculate/Fill Command Object */
840 if (pkt == IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RQ)
841 {
842 uint8_t get_ipmi_v20_extended_data;
843
844 if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0)
845 get_ipmi_v20_extended_data = IPMI_GET_IPMI_V20_EXTENDED_DATA;
846 else
847 get_ipmi_v20_extended_data = IPMI_GET_IPMI_V15_DATA;
848
849 if (fill_cmd_get_channel_authentication_capabilities (IPMI_CHANNEL_NUMBER_CURRENT_CHANNEL,
850 cmd_args.common_args.privilege_level,
851 get_ipmi_v20_extended_data,
852 ip->obj_authentication_capabilities_rq) < 0)
853 {
854 IPMIPOWER_ERROR (("fill_cmd_get_channel_authentication_capabilities: %s",
855 strerror (errno)));
856 exit (EXIT_FAILURE);
857 }
858 obj_cmd_rq = ip->obj_authentication_capabilities_rq;
859 }
860 else if (pkt == IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ)
861 {
862 /* Note: The session_authentication_type is none, this authentication type may be different.
863 */
864 if (fill_cmd_get_session_challenge (cmd_args.common_args.authentication_type,
865 username,
866 username_len,
867 ip->obj_get_session_challenge_rq) < 0)
868 {
869 IPMIPOWER_ERROR (("fill_cmd_get_session_challenge: %s", strerror (errno)));
870 exit (EXIT_FAILURE);
871 }
872 obj_cmd_rq = ip->obj_get_session_challenge_rq;
873 }
874 else if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ)
875 {
876 uint8_t challenge_string[IPMI_CHALLENGE_STRING_LENGTH];
877 int challenge_string_len;
878
879 if ((challenge_string_len = fiid_obj_get_data (ip->obj_get_session_challenge_rs,
880 "challenge_string",
881 challenge_string,
882 IPMI_CHALLENGE_STRING_LENGTH)) < 0)
883 {
884 IPMIPOWER_ERROR (("fiid_obj_get_data: 'challenge_string': %s",
885 fiid_obj_errormsg (ip->obj_get_session_challenge_rs)));
886 exit (EXIT_FAILURE);
887 }
888
889 if (!challenge_string_len)
890 {
891 IPMIPOWER_ERROR (("host = %s; p = %d; empty challenge string",
892 ip->ic->hostname, ip->protocol_state));
893 exit (EXIT_FAILURE);
894 }
895
896 if (fill_cmd_activate_session (authentication_type,
897 cmd_args.common_args.privilege_level,
898 challenge_string,
899 challenge_string_len,
900 IPMIPOWER_LAN_INITIAL_OUTBOUND_SEQUENCE_NUMBER,
901 ip->obj_activate_session_rq) < 0)
902 {
903 IPMIPOWER_ERROR (("fill_cmd_activate_session: %s", strerror (errno)));
904 exit (EXIT_FAILURE);
905 }
906 obj_cmd_rq = ip->obj_activate_session_rq;
907 }
908 else if (pkt == IPMIPOWER_PACKET_TYPE_OPEN_SESSION_REQUEST)
909 {
910 if (fill_rmcpplus_open_session (ip->initial_message_tag + ip->message_tag_count,
911 ip->requested_maximum_privilege_level,
912 ip->remote_console_session_id,
913 ip->authentication_algorithm,
914 ip->integrity_algorithm,
915 ip->confidentiality_algorithm,
916 ip->obj_open_session_rq) < 0)
917 {
918 IPMIPOWER_ERROR (("fill_rmcpplus_open_session: %s", strerror (errno)));
919 exit (EXIT_FAILURE);
920 }
921 obj_cmd_rq = ip->obj_open_session_rq;
922 }
923 else if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1)
924 {
925 if (fill_rmcpplus_rakp_message_1 (ip->initial_message_tag + ip->message_tag_count,
926 managed_system_session_id,
927 ip->remote_console_random_number,
928 IPMI_REMOTE_CONSOLE_RANDOM_NUMBER_LENGTH,
929 cmd_args.common_args.privilege_level,
930 ip->name_only_lookup,
931 username,
932 username_len,
933 ip->obj_rakp_message_1_rq) < 0)
934 {
935 IPMIPOWER_ERROR (("fill_rmcpplus_rakp_message_1: %s", strerror (errno)));
936 exit (EXIT_FAILURE);
937 }
938 obj_cmd_rq = ip->obj_rakp_message_1_rq;
939 }
940 else if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3)
941 {
942 uint8_t managed_system_random_number[IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH];
943 int managed_system_random_number_len;
944 uint8_t key_exchange_authentication_code[IPMI_MAX_KEY_EXCHANGE_AUTHENTICATION_CODE_LENGTH];
945 int key_exchange_authentication_code_len;
946 uint8_t name_only_lookup;
947 unsigned int password_len;
948
949 if ((managed_system_random_number_len = fiid_obj_get_data (ip->obj_rakp_message_2_rs,
950 "managed_system_random_number",
951 managed_system_random_number,
952 IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH)) < 0)
953 {
954 IPMIPOWER_ERROR (("fiid_obj_get_data: 'managed_system_random_number': %s",
955 fiid_obj_errormsg (ip->obj_rakp_message_2_rs)));
956 exit (EXIT_FAILURE);
957 }
958
959 /* IPMI Workaround (achu)
960 *
961 * Discovered on SE7520AF2 with Intel Server Management Module
962 * (Professional Edition)
963 *
964 * For some reason we have to create this key with the name only
965 * lookup turned off. I was skeptical about this actually being
966 * a bug until I saw that the ipmitool folks implemented the
967 * same workaround.
968 */
969
970 if (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION)
971 name_only_lookup = IPMI_USER_NAME_PRIVILEGE_LOOKUP;
972 else
973 name_only_lookup = ip->name_only_lookup;
974
975 password_len = (password) ? strlen (password) : 0;
976
977 /* IPMI Workaround (achu)
978 *
979 * Discovered on SE7520AF2 with Intel Server Management Module
980 * (Professional Edition)
981 *
982 * When the authentication algorithm is HMAC-MD5-128 and the
983 * password is greater than 16 bytes, the Intel BMC truncates the
984 * password to 16 bytes when generating keys, hashes, etc. So we
985 * have to do the same when generating keys, hashes, etc.
986 */
987 if ((cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION)
988 && ip->authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5
989 && password_len > IPMI_1_5_MAX_PASSWORD_LENGTH)
990 password_len = IPMI_1_5_MAX_PASSWORD_LENGTH;
991
992 if ((key_exchange_authentication_code_len = ipmi_calculate_rakp_3_key_exchange_authentication_code (ip->authentication_algorithm,
993 password,
994 password_len,
995 managed_system_random_number,
996 managed_system_random_number_len,
997 ip->remote_console_session_id,
998 name_only_lookup,
999 cmd_args.common_args.privilege_level,
1000 username,
1001 username_len,
1002 key_exchange_authentication_code,
1003 IPMI_MAX_KEY_EXCHANGE_AUTHENTICATION_CODE_LENGTH)) < 0)
1004 {
1005 IPMIPOWER_ERROR (("ipmi_calculate_rakp_3_key_exchange_authentication_code: %s",
1006 strerror (errno)));
1007 exit (EXIT_FAILURE);
1008 }
1009
1010 if (fill_rmcpplus_rakp_message_3 (ip->initial_message_tag + ip->message_tag_count,
1011 RMCPPLUS_STATUS_NO_ERRORS,
1012 managed_system_session_id,
1013 key_exchange_authentication_code,
1014 key_exchange_authentication_code_len,
1015 ip->obj_rakp_message_3_rq) < 0)
1016 {
1017 IPMIPOWER_ERROR (("fill_rmcpplus_rakp_message_3: %s", strerror (errno)));
1018 exit (EXIT_FAILURE);
1019 }
1020 obj_cmd_rq = ip->obj_rakp_message_3_rq;
1021 }
1022 else if (pkt == IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RQ)
1023 {
1024 if (fill_cmd_set_session_privilege_level (cmd_args.common_args.privilege_level,
1025 ip->obj_set_session_privilege_level_rq) < 0)
1026 {
1027 IPMIPOWER_ERROR (("fill_cmd_set_session_privilege_level: %s", strerror (errno)));
1028 exit (EXIT_FAILURE);
1029 }
1030 obj_cmd_rq = ip->obj_set_session_privilege_level_rq;
1031 }
1032 else if (pkt == IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RQ)
1033 {
1034 if (fill_cmd_get_chassis_status (ip->obj_get_chassis_status_rq) < 0)
1035 {
1036 IPMIPOWER_ERROR (("fill_cmd_get_chassis_status: %s", strerror (errno)));
1037 exit (EXIT_FAILURE);
1038 }
1039 obj_cmd_rq = ip->obj_get_chassis_status_rq;
1040 }
1041 else if (pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RQ)
1042 {
1043 uint8_t command = 0;
1044
1045 assert (ip->cmd == IPMIPOWER_POWER_CMD_POWER_OFF
1046 || ip->cmd == IPMIPOWER_POWER_CMD_POWER_ON
1047 || ip->cmd == IPMIPOWER_POWER_CMD_POWER_CYCLE
1048 || ip->cmd == IPMIPOWER_POWER_CMD_POWER_RESET
1049 || ip->cmd == IPMIPOWER_POWER_CMD_PULSE_DIAGNOSTIC_INTERRUPT
1050 || ip->cmd == IPMIPOWER_POWER_CMD_SOFT_SHUTDOWN_OS);
1051
1052 if (ip->cmd == IPMIPOWER_POWER_CMD_POWER_OFF)
1053 command = IPMI_CHASSIS_CONTROL_POWER_DOWN;
1054 else if (ip->cmd == IPMIPOWER_POWER_CMD_POWER_ON)
1055 command = IPMI_CHASSIS_CONTROL_POWER_UP;
1056 else if (ip->cmd == IPMIPOWER_POWER_CMD_POWER_CYCLE)
1057 command = IPMI_CHASSIS_CONTROL_POWER_CYCLE;
1058 else if (ip->cmd == IPMIPOWER_POWER_CMD_POWER_RESET)
1059 command = IPMI_CHASSIS_CONTROL_HARD_RESET;
1060 else if (ip->cmd == IPMIPOWER_POWER_CMD_PULSE_DIAGNOSTIC_INTERRUPT)
1061 command = IPMI_CHASSIS_CONTROL_PULSE_DIAGNOSTIC_INTERRUPT;
1062 else if (ip->cmd == IPMIPOWER_POWER_CMD_SOFT_SHUTDOWN_OS)
1063 command = IPMI_CHASSIS_CONTROL_INITIATE_SOFT_SHUTDOWN;
1064
1065 if (fill_cmd_chassis_control (command, ip->obj_chassis_control_rq) < 0)
1066 {
1067 IPMIPOWER_ERROR (("fill_cmd_chassis_control: %s", strerror (errno)));
1068 exit (EXIT_FAILURE);
1069 }
1070 obj_cmd_rq = ip->obj_chassis_control_rq;
1071 }
1072 else if (pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RQ)
1073 {
1074 uint8_t identify_interval;
1075 uint8_t force_identify;
1076 uint8_t *identify_interval_ptr = NULL;
1077 uint8_t *force_identify_ptr = NULL;
1078
1079 assert (ip->cmd == IPMIPOWER_POWER_CMD_IDENTIFY_ON
1080 || ip->cmd == IPMIPOWER_POWER_CMD_IDENTIFY_OFF);
1081
1082 if (ip->cmd == IPMIPOWER_POWER_CMD_IDENTIFY_ON)
1083 {
1084 /* must pass interval for force to be taken */
1085 identify_interval = 0xFF;
1086 identify_interval_ptr = &identify_interval;
1087
1088 force_identify = IPMI_CHASSIS_FORCE_IDENTIFY_ON;
1089 force_identify_ptr = &force_identify;
1090 }
1091 else
1092 {
1093 identify_interval = 0;
1094 identify_interval_ptr = &identify_interval;
1095 }
1096
1097 if (fill_cmd_chassis_identify (identify_interval_ptr,
1098 force_identify_ptr,
1099 ip->obj_chassis_identify_rq) < 0)
1100 {
1101 IPMIPOWER_ERROR (("fill_cmd_chassis_identify: %s", strerror (errno)));
1102 exit (EXIT_FAILURE);
1103 }
1104 obj_cmd_rq = ip->obj_chassis_identify_rq;
1105 }
1106 else if (pkt == IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RQ)
1107 {
1108 char *endptr;
1109 unsigned int slot_number;
1110
1111 assert (ip->extra_arg);
1112
1113 errno = 0;
1114 slot_number = strtol (ip->extra_arg, &endptr, 0);
1115
1116 /* tons of error checks by now, should not error out here */
1117 assert (!errno);
1118 assert (endptr[0] == '\0');
1119 assert (slot_number >= IPMI_OEM_DELL_SLOT_POWER_CONTROL_SLOT_NUMBER_MIN
1120 && slot_number <= IPMI_OEM_DELL_SLOT_POWER_CONTROL_SLOT_NUMBER_MAX);
1121
1122 if (fill_cmd_get_sensor_reading (IPMI_SENSOR_NUMBER_OEM_DELL_C410X_PCIE_1_WATT + (slot_number - 1),
1123 ip->obj_c410x_get_sensor_reading_rq) < 0)
1124 {
1125 IPMIPOWER_ERROR (("fill_cmd_get_sensor_reading: %s", strerror (errno)));
1126 exit (EXIT_FAILURE);
1127 }
1128
1129 obj_cmd_rq = ip->obj_c410x_get_sensor_reading_rq;
1130 }
1131 else if (pkt == IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RQ)
1132 {
1133 char *endptr;
1134 unsigned int slot_number;
1135 uint16_t slot_number_bitmask;
1136
1137 assert (ip->extra_arg);
1138
1139 errno = 0;
1140 slot_number = strtol (ip->extra_arg, &endptr, 0);
1141
1142 /* tons of error checks by now, should not error out here */
1143 assert (!errno);
1144 assert (endptr[0] == '\0');
1145 assert (slot_number >= IPMI_OEM_DELL_SLOT_POWER_CONTROL_SLOT_NUMBER_MIN
1146 && slot_number <= IPMI_OEM_DELL_SLOT_POWER_CONTROL_SLOT_NUMBER_MAX);
1147
1148 if (fiid_obj_set (ip->obj_c410x_slot_power_control_rq,
1149 "cmd",
1150 IPMI_CMD_OEM_DELL_SLOT_POWER_CONTROL) < 0)
1151 {
1152 IPMIPOWER_ERROR (("fiid_obj_set: 'cmd': %s",
1153 fiid_obj_errormsg (ip->obj_c410x_slot_power_control_rq)));
1154 exit (EXIT_FAILURE);
1155 }
1156
1157 slot_number_bitmask = (0x1 << (slot_number - 1));
1158 if (fiid_obj_set (ip->obj_c410x_slot_power_control_rq,
1159 "slot_number_bitmask",
1160 slot_number_bitmask) < 0)
1161 {
1162 IPMIPOWER_ERROR (("fiid_obj_set: 'slot_number_bitmask': %s",
1163 fiid_obj_errormsg (ip->obj_c410x_slot_power_control_rq)));
1164 exit (EXIT_FAILURE);
1165 }
1166
1167 obj_cmd_rq = ip->obj_c410x_slot_power_control_rq;
1168 }
1169 else if (pkt == IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RQ)
1170 {
1171 if (fill_cmd_close_session (session_id,
1172 NULL,
1173 ip->obj_close_session_rq) < 0)
1174 {
1175 IPMIPOWER_ERROR (("fill_cmd_close_session: %s", strerror (errno)));
1176 exit (EXIT_FAILURE);
1177 }
1178 obj_cmd_rq = ip->obj_close_session_rq;
1179 }
1180
1181 /* Construct packets */
1182 if (IPMIPOWER_PACKET_TYPE_IPMI_1_5_SETUP_RQ (pkt)
1183 || (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
1184 && IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt)))
1185 rv = _ipmi_1_5_packet_create (ip,
1186 pkt,
1187 authentication_type,
1188 sequence_number,
1189 session_id,
1190 password,
1191 (password) ? strlen (password) : 0,
1192 net_fn,
1193 obj_cmd_rq,
1194 buf,
1195 buflen);
1196 else if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RQ (pkt)
1197 || (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
1198 && IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt)))
1199 rv = _ipmi_2_0_packet_create (ip,
1200 pkt,
1201 payload_type,
1202 payload_authenticated,
1203 payload_encrypted,
1204 session_id,
1205 sequence_number,
1206 password,
1207 (password) ? strlen (password) : 0,
1208 net_fn,
1209 authentication_algorithm,
1210 integrity_algorithm,
1211 confidentiality_algorithm,
1212 integrity_key,
1213 integrity_key_len,
1214 confidentiality_key,
1215 confidentiality_key_len,
1216 obj_cmd_rq,
1217 buf,
1218 buflen);
1219 else
1220 {
1221 IPMIPOWER_ERROR (("host = %s; p = %d; invalid logic",
1222 ip->ic->hostname, ip->protocol_state));
1223 exit (EXIT_FAILURE);
1224 }
1225
1226 return (rv);
1227 }
1228
1229 ipmipower_msg_type_t
ipmipower_packet_errmsg(ipmipower_powercmd_t ip,ipmipower_packet_type_t pkt)1230 ipmipower_packet_errmsg (ipmipower_powercmd_t ip, ipmipower_packet_type_t pkt)
1231 {
1232 fiid_obj_t obj_cmd;
1233
1234 assert (ip);
1235 assert (IPMIPOWER_PACKET_TYPE_RS (pkt));
1236
1237 obj_cmd = ipmipower_packet_cmd_obj (ip, pkt);
1238
1239 if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RS (pkt))
1240 {
1241 uint8_t rmcpplus_status_code;
1242 uint64_t val;
1243
1244 if (FIID_OBJ_GET (obj_cmd,
1245 "rmcpplus_status_code",
1246 &val) < 0)
1247 {
1248 IPMIPOWER_ERROR (("FIID_OBJ_GET: 'rmcpplus_status_code': %s",
1249 fiid_obj_errormsg (obj_cmd)));
1250 exit (EXIT_FAILURE);
1251 }
1252 rmcpplus_status_code = val;
1253
1254 /* achu:
1255
1256 At this point in time, my belief is that the following RMCPPLUS
1257 Status Codes:
1258
1259 RMCPPLUS_STATUS_INVALID_AUTHENTICATION_ALGORITHM
1260 RMCPPLUS_STATUS_INVALID_INTEGRITY_ALGORITHM
1261 RMCPPLUS_STATUS_INVALID_CONFIDENTIALITY_ALGORITHM
1262 RMCPPLUS_STATUS_INVALID_ROLE
1263 RMCPPLUS_STATUS_NO_MATCHING_AUTHENTICATION_PAYLOAD
1264 RMCPPLUS_STATUS_NO_MATCHING_INTEGRITY_PAYLOAD
1265
1266 Imply that an incorrect algorithm/role/payload value was sent.
1267 *NOT* an unsupported algorithm/role/payload. I assume unsupported algorithm/role/payloads
1268 will get different error codes.
1269
1270 If my assumption is later proven incorrect, then I need to redo some of this.
1271
1272 */
1273
1274 if (rmcpplus_status_code == RMCPPLUS_STATUS_NO_ERRORS)
1275 {
1276 IPMIPOWER_ERROR (("host = %s; p = %d; pkt = %d; called with good rmcpplus_status_code",
1277 ip->ic->hostname, ip->protocol_state, pkt));
1278 exit (EXIT_FAILURE);
1279 }
1280 else if (rmcpplus_status_code == RMCPPLUS_STATUS_INSUFFICIENT_RESOURCES_TO_CREATE_A_SESSION
1281 || rmcpplus_status_code == RMCPPLUS_STATUS_INSUFFICIENT_RESOURCES_TO_CREATE_A_SESSION_AT_THE_REQUESTED_TIME)
1282 return (IPMIPOWER_MSG_TYPE_BMC_BUSY);
1283 else if (rmcpplus_status_code == RMCPPLUS_STATUS_UNAUTHORIZED_ROLE_OR_PRIVILEGE_LEVEL_REQUESTED
1284 || rmcpplus_status_code == RMCPPLUS_STATUS_INVALID_ROLE)
1285 return (IPMIPOWER_MSG_TYPE_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED);
1286 else if (rmcpplus_status_code == RMCPPLUS_STATUS_UNAUTHORIZED_NAME)
1287 return (IPMIPOWER_MSG_TYPE_USERNAME_INVALID);
1288 else if (rmcpplus_status_code == RMCPPLUS_STATUS_NO_CIPHER_SUITE_MATCH_WITH_PROPOSED_SECURITY_ALGORITHMS)
1289 return (IPMIPOWER_MSG_TYPE_CIPHER_SUITE_ID_UNAVAILABLE);
1290 }
1291 else
1292 {
1293 uint8_t comp_code;
1294 uint64_t val;
1295
1296 if (FIID_OBJ_GET (obj_cmd,
1297 "comp_code",
1298 &val) < 0)
1299 {
1300 IPMIPOWER_ERROR (("FIID_OBJ_GET: 'comp_code': %s",
1301 fiid_obj_errormsg (obj_cmd)));
1302 exit (EXIT_FAILURE);
1303 }
1304 comp_code = val;
1305
1306 if (comp_code == IPMI_COMP_CODE_COMMAND_SUCCESS)
1307 {
1308 IPMIPOWER_ERROR (("host = %s; p = %d; pkt = %d; called with good comp_code",
1309 ip->ic->hostname, ip->protocol_state, pkt));
1310 exit (EXIT_FAILURE);
1311 }
1312 else if (pkt == IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RS
1313 && cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
1314 && comp_code == IPMI_COMP_CODE_INVALID_DATA_FIELD_IN_REQUEST)
1315 return (IPMIPOWER_MSG_TYPE_IPMI_2_0_UNAVAILABLE);
1316 else if (pkt == IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RS
1317 && (comp_code == IPMI_COMP_CODE_GET_SESSION_CHALLENGE_INVALID_USERNAME
1318 || comp_code == IPMI_COMP_CODE_GET_SESSION_CHALLENGE_NULL_USERNAME_NOT_ENABLED))
1319 return (IPMIPOWER_MSG_TYPE_USERNAME_INVALID);
1320 else if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS
1321 && comp_code == IPMI_COMP_CODE_ACTIVATE_SESSION_EXCEEDS_PRIVILEGE_LEVEL)
1322 return (IPMIPOWER_MSG_TYPE_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED);
1323 else if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS
1324 && (comp_code == IPMI_COMP_CODE_ACTIVATE_SESSION_NO_SESSION_SLOT_AVAILABLE
1325 || comp_code == IPMI_COMP_CODE_ACTIVATE_SESSION_NO_SLOT_AVAILABLE_FOR_GIVEN_USER
1326 || comp_code == IPMI_COMP_CODE_ACTIVATE_SESSION_NO_SLOT_AVAILABLE_TO_SUPPORT_USER))
1327 return (IPMIPOWER_MSG_TYPE_BMC_BUSY);
1328 /*
1329 * IPMI Workaround
1330 *
1331 * Discovered on Xyratex HB-F8-SRAY
1332 *
1333 * For some reason on this system, if you do not specify a
1334 * privilege level of Admin, this completion code will always be
1335 * returned. Reason unknown. This isn't the best/right error
1336 * to return, but it will atleast point the user to a way to
1337 * work around the problem.
1338 */
1339 else if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS
1340 && comp_code == IPMI_COMP_CODE_INSUFFICIENT_PRIVILEGE_LEVEL)
1341 return (IPMIPOWER_MSG_TYPE_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED);
1342 else if (pkt == IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS
1343 && (comp_code == IPMI_COMP_CODE_SET_SESSION_PRIVILEGE_LEVEL_REQUESTED_LEVEL_NOT_AVAILABLE_FOR_USER
1344 || comp_code == IPMI_COMP_CODE_SET_SESSION_PRIVILEGE_LEVEL_REQUESTED_LEVEL_EXCEEDS_USER_PRIVILEGE_LIMIT
1345 || comp_code == IPMI_COMP_CODE_SET_SESSION_PRIVILEGE_LEVEL_CANNOT_DISABLE_USER_LEVEL_AUTHENTICATION))
1346 return (IPMIPOWER_MSG_TYPE_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED);
1347 #if 0
1348 /* Should not reach this point, should be handled by other code */
1349 else if (pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RS
1350 && comp_code == IPMI_COMP_CODE_INSUFFICIENT_PRIVILEGE_LEVEL)
1351 return (IPMIPOWER_MSG_TYPE_PRIVILEGE_LEVEL_INSUFFICIENT);
1352 #endif
1353 else if (pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RS
1354 && comp_code == IPMI_COMP_CODE_REQUEST_PARAMETER_NOT_SUPPORTED)
1355 return (IPMIPOWER_MSG_TYPE_OPERATION_INVALID);
1356 }
1357
1358 return (IPMIPOWER_MSG_TYPE_BMC_ERROR);
1359 }
1360