1 /*****************************************************************************\ 2 * $Id: ipmiconsole_defs.h,v 1.80 2010-06-10 22:10:12 chu11 Exp $ 3 ***************************************************************************** 4 * Copyright (C) 2007-2015 Lawrence Livermore National Security, LLC. 5 * Copyright (C) 2006-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-221226 9 * 10 * This file is part of Ipmiconsole, a set of IPMI 2.0 SOL libraries 11 * and utilities. For details, see http://www.llnl.gov/linux/. 12 * 13 * Ipmiconsole 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 * Ipmiconsole 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 Ipmiconsole. If not, see <http://www.gnu.org/licenses/>. 25 \*****************************************************************************/ 26 27 #ifdef HAVE_CONFIG_H 28 #include "config.h" 29 #endif /* HAVE_CONFIG_H */ 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <stdint.h> 34 #ifdef HAVE_PTHREAD_H 35 #include <pthread.h> 36 #endif /* HAVE_PTHREAD_H */ 37 #if TIME_WITH_SYS_TIME 38 #include <sys/time.h> 39 #include <time.h> 40 #else /* !TIME_WITH_SYS_TIME */ 41 #if HAVE_SYS_TIME_H 42 #include <sys/time.h> 43 #else /* !HAVE_SYS_TIME_H */ 44 #include <time.h> 45 #endif /* !HAVE_SYS_TIME_H */ 46 #endif /* !TIME_WITH_SYS_TIME */ 47 #include <sys/param.h> 48 #include <netinet/in.h> 49 #include <limits.h> /* MAXHOSTNAMELEN */ 50 #ifdef HAVE_NETDB_H 51 #include <netdb.h> /* MAXHOSTNAMELEN Solaris */ 52 #endif /* HAVE_NETDB_H */ 53 #include <freeipmi/freeipmi.h> 54 55 #include "scbuf.h" 56 57 #ifndef IPMICONSOLE_DEFS_H 58 #define IPMICONSOLE_DEFS_H 59 60 #ifndef MAXHOSTNAMELEN 61 #define MAXHOSTNAMELEN 64 62 #endif /* MAXHOSTNAMELEN */ 63 64 #define MAXPORTBUFLEN 16 65 66 #ifndef MAXPATHLEN 67 #define MAXPATHLEN 4096 68 #endif /* MAXPATHLEN */ 69 70 typedef enum 71 { 72 IPMICONSOLE_PROTOCOL_STATE_START = 0x00, 73 IPMICONSOLE_PROTOCOL_STATE_GET_AUTHENTICATION_CAPABILITIES_SENT = 0x01, 74 IPMICONSOLE_PROTOCOL_STATE_OPEN_SESSION_REQUEST_SENT = 0x02, 75 IPMICONSOLE_PROTOCOL_STATE_RAKP_MESSAGE_1_SENT = 0x03, 76 IPMICONSOLE_PROTOCOL_STATE_RAKP_MESSAGE_3_SENT = 0x04, 77 IPMICONSOLE_PROTOCOL_STATE_SET_SESSION_PRIVILEGE_LEVEL_SENT = 0x05, 78 IPMICONSOLE_PROTOCOL_STATE_GET_CHANNEL_PAYLOAD_SUPPORT_SENT = 0x06, 79 IPMICONSOLE_PROTOCOL_STATE_GET_PAYLOAD_ACTIVATION_STATUS_SENT = 0x07, 80 IPMICONSOLE_PROTOCOL_STATE_ACTIVATE_PAYLOAD_SENT = 0x08, 81 IPMICONSOLE_PROTOCOL_STATE_SOL_SESSION = 0x09, 82 IPMICONSOLE_PROTOCOL_STATE_DEACTIVATE_PAYLOAD_SENT = 0x0A, 83 IPMICONSOLE_PROTOCOL_STATE_CLOSE_SESSION_SENT = 0x0B, 84 IPMICONSOLE_PROTOCOL_STATE_END = 0x0C, 85 } ipmiconsole_protocol_state_t; 86 87 /* Note: Get Channel Payload Version will act as our "ping" 88 * to keep the session state alive. 89 */ 90 typedef enum 91 { 92 IPMICONSOLE_PACKET_TYPE_GET_AUTHENTICATION_CAPABILITIES_RQ = 0x00, 93 IPMICONSOLE_PACKET_TYPE_GET_AUTHENTICATION_CAPABILITIES_RS = 0x01, 94 IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_REQUEST = 0x02, 95 IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_RESPONSE = 0x03, px_THROW_ERROR(int err)96 IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_1 = 0x04, 97 IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_2 = 0x05, 98 IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_3 = 0x06, 99 IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_4 = 0x07, 100 IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RQ = 0x08, 101 IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS = 0x09, 102 IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RQ = 0x0A, 103 IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RS = 0x0B, 104 IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RQ = 0x0C, 105 IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RS = 0x0D, 106 IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RQ = 0x0E, 107 IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RS = 0x0F, 108 IPMICONSOLE_PACKET_TYPE_SOL_PAYLOAD_DATA_RQ = 0x10, 109 IPMICONSOLE_PACKET_TYPE_SOL_PAYLOAD_DATA_RS = 0x11, 110 IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RQ = 0x12, 111 IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RS = 0x13, 112 IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RQ = 0x14, 113 IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RS = 0x15, 114 IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RQ = 0x16, 115 IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RS = 0x17, 116 } ipmiconsole_packet_type_t; 117 118 #define IPMICONSOLE_PACKET_TYPE_REQUEST(__p) \ 119 (((__p) == IPMICONSOLE_PACKET_TYPE_GET_AUTHENTICATION_CAPABILITIES_RQ \ 120 || (__p) == IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_REQUEST \ 121 || (__p) == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_1 \ 122 || (__p) == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_3 \ 123 || (__p) == IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RQ \ 124 || (__p) == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RQ \ 125 || (__p) == IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RQ \ px_memset(void * ptr,int c,size_t len)126 || (__p) == IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RQ \ 127 || (__p) == IPMICONSOLE_PACKET_TYPE_SOL_PAYLOAD_DATA_RQ \ 128 || (__p) == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RQ \ 129 || (__p) == IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RQ \ 130 || (__p) == IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RQ) ? 1 : 0) 131 132 #define IPMICONSOLE_PACKET_TYPE_RESPONSE(__p) \ 133 (((__p) == IPMICONSOLE_PACKET_TYPE_GET_AUTHENTICATION_CAPABILITIES_RS \ 134 || (__p) == IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_RESPONSE \ 135 || (__p) == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_2 \ 136 || (__p) == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_4 \ 137 || (__p) == IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS \ 138 || (__p) == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RS \ 139 || (__p) == IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RS \ 140 || (__p) == IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RS \ 141 || (__p) == IPMICONSOLE_PACKET_TYPE_SOL_PAYLOAD_DATA_RS \ 142 || (__p) == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RS \ 143 || (__p) == IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RS \ 144 || (__p) == IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RS) ? 1 : 0) 145 146 #define IPMICONSOLE_PACKET_TYPE_VALID(__p) \ 147 ((IPMICONSOLE_PACKET_TYPE_REQUEST (__p) \ 148 || IPMICONSOLE_PACKET_TYPE_RESPONSE (__p)) ? 1 : 0) 149 150 #define IPMICONSOLE_THREAD_COUNT_DEFAULT 4 151 152 #define IPMICONSOLE_SESSION_TIMEOUT_LENGTH_DEFAULT 60000 153 #define IPMICONSOLE_RETRANSMISSION_TIMEOUT_LENGTH_DEFAULT 500 154 #define IPMICONSOLE_RETRANSMISSION_MAX_DEFAULT 10 155 #define IPMICONSOLE_RETRANSMISSION_BACKOFF_COUNT_DEFAULT 2 156 #define IPMICONSOLE_KEEPALIVE_TIMEOUT_LENGTH_DEFAULT 20000 157 #define IPMICONSOLE_RETRANSMISSION_KEEPALIVE_TIMEOUT_LENGTH_DEFAULT 5000 158 #define IPMICONSOLE_ACCEPTABLE_PACKET_ERRORS_COUNT_DEFAULT 16 159 #define IPMICONSOLE_MAXIMUM_RETRANSMISSION_COUNT_DEFAULT 16 160 #define IPMI_PRIVILEGE_LEVEL_DEFAULT IPMI_PRIVILEGE_LEVEL_ADMIN 161 #define IPMI_CIPHER_SUITE_ID_DEFAULT 3 162 #define IPMI_PAYLOAD_INSTANCE_DEFAULT 1 163 164 #define CONSOLE_REMOTE_CONSOLE_TO_BMC_BUF_MIN (1024*2) 165 #define CONSOLE_REMOTE_CONSOLE_TO_BMC_BUF_MAX (1024*8) 166 167 #define CONSOLE_BMC_TO_REMOTE_CONSOLE_BUF_MIN (1024*4) 168 #define CONSOLE_BMC_TO_REMOTE_CONSOLE_BUF_MAX (1024*16) 169 170 #define IPMI_FROM_BMC_BUF_MIN (1024*4) 171 #define IPMI_FROM_BMC_BUF_MAX (1024*16) 172 173 #define IPMI_TO_BMC_BUF_MIN (1024*2) 174 #define IPMI_TO_BMC_BUF_MAX (1024*8) 175 176 /* achu: See IPMI 2.0 spec Section 24.4, Table 24-6. The Get Payload 177 * Activation Status Command indicates a maximum number of 16 178 * instances are possible. 179 */ 180 #define IPMI_INSTANCES_ACTIVATED_LENGTH 16 181 182 #define IPMI_MAX_SIK_KEY_LENGTH 64 183 #define IPMI_MAX_INTEGRITY_KEY_LENGTH 64 184 #define IPMI_MAX_CONFIDENTIALITY_KEY_LENGTH 64 185 #define IPMI_MAX_KEY_EXCHANGE_AUTHENTICATION_CODE_LENGTH 64 186 187 #define IPMI_SESSION_INITIAL_OUTBOUND_SEQUENCE_NUMBER 1 188 #define IPMI_SOL_SESSION_INITIAL_PACKET_SEQUENCE_NUMBER 1 189 190 /* API magic determines if the context has been destroyed by the user 191 * and can no longer be used. However, it may not necessarily have 192 * been garbage cleaned up by the libipmiconsole engine library. 193 */ 194 #define IPMICONSOLE_CTX_MAGIC 0x74AB8831 195 #define IPMICONSOLE_CTX_API_MAGIC 0x83FB9202 196 197 #define IPMICONSOLE_PACKET_BUFLEN 16384 198 199 #define IPMICONSOLE_MIN_CHARACTER_DATA 1 200 #define IPMICONSOLE_MAX_CHARACTER_DATA 255 201 202 #define IPMICONSOLE_PIPE_GENERATE_BREAK_CODE 0x01 203 204 #define IPMICONSOLE_DEBUG_MASK \ 205 (IPMICONSOLE_DEBUG_STDOUT \ 206 | IPMICONSOLE_DEBUG_STDERR \ 207 | IPMICONSOLE_DEBUG_SYSLOG \ 208 | IPMICONSOLE_DEBUG_FILE \ 209 | IPMICONSOLE_DEBUG_IPMI_PACKETS) 210 211 #define IPMICONSOLE_WORKAROUND_MASK \ 212 (IPMICONSOLE_WORKAROUND_AUTHENTICATION_CAPABILITIES \ 213 | IPMICONSOLE_WORKAROUND_INTEL_2_0_SESSION \ 214 | IPMICONSOLE_WORKAROUND_SUPERMICRO_2_0_SESSION \ 215 | IPMICONSOLE_WORKAROUND_SUN_2_0_SESSION \ 216 | IPMICONSOLE_WORKAROUND_OPEN_SESSION_PRIVILEGE \ 217 | IPMICONSOLE_WORKAROUND_NON_EMPTY_INTEGRITY_CHECK_VALUE \ 218 | IPMICONSOLE_WORKAROUND_NO_CHECKSUM_CHECK \ 219 | IPMICONSOLE_WORKAROUND_SERIAL_ALERTS_DEFERRED \ 220 | IPMICONSOLE_WORKAROUND_INCREMENT_SOL_PACKET_SEQUENCE \ 221 | IPMICONSOLE_WORKAROUND_IGNORE_SOL_PAYLOAD_SIZE \ 222 | IPMICONSOLE_WORKAROUND_IGNORE_SOL_PORT \ 223 | IPMICONSOLE_WORKAROUND_SKIP_SOL_ACTIVATION_STATUS \ 224 | IPMICONSOLE_WORKAROUND_SKIP_CHANNEL_PAYLOAD_SUPPORT) 225 226 #define IPMICONSOLE_ENGINE_MASK \ 227 (IPMICONSOLE_ENGINE_CLOSE_FD \ 228 | IPMICONSOLE_ENGINE_OUTPUT_ON_SOL_ESTABLISHED \ 229 | IPMICONSOLE_ENGINE_LOCK_MEMORY \ 230 | IPMICONSOLE_ENGINE_SERIAL_KEEPALIVE \ 231 | IPMICONSOLE_ENGINE_SERIAL_KEEPALIVE_EMPTY) 232 233 #define IPMICONSOLE_BEHAVIOR_MASK \ 234 (IPMICONSOLE_BEHAVIOR_ERROR_ON_SOL_INUSE \ 235 | IPMICONSOLE_BEHAVIOR_DEACTIVATE_ONLY \ 236 | IPMICONSOLE_BEHAVIOR_DEACTIVATE_ALL_INSTANCES) 237 238 #define IPMICONSOLE_BLOCKING_NOTIFICATION_SOL_SESSION_ESTABLISHED 0x1 239 #define IPMICONSOLE_BLOCKING_NOTIFICATION_SOL_SESSION_ERROR 0x2 240 #define IPMICONSOLE_BLOCKING_NOTIFICATION_SOL_SESSION_DEACTIVATED 0x3 241 242 /* Protocol/User Config Data */ 243 struct ipmiconsole_ctx_config { 244 245 /* ipmi config */ 246 char hostname[MAXHOSTNAMELEN+1]; 247 uint16_t port; 248 char username[IPMI_MAX_USER_NAME_LENGTH+1]; 249 char password[IPMI_2_0_MAX_PASSWORD_LENGTH+1]; 250 uint8_t k_g[IPMI_MAX_K_G_LENGTH+1]; 251 unsigned int k_g_len; 252 uint8_t privilege_level; 253 uint8_t cipher_suite_id; 254 unsigned int workaround_flags; 255 256 /* protocol config */ 257 unsigned int session_timeout_len; 258 unsigned int retransmission_timeout_len; 259 unsigned int retransmission_backoff_count; 260 unsigned int keepalive_timeout_len; 261 unsigned int retransmission_keepalive_timeout_len; 262 unsigned int acceptable_packet_errors_count; 263 unsigned int maximum_retransmission_count; 264 265 /* engine config */ 266 unsigned int engine_flags; 267 unsigned int behavior_flags; 268 unsigned int debug_flags; 269 270 /* advanced config */ 271 unsigned int sol_payload_instance; 272 273 /* Data based on Configuration Parameters */ 274 uint8_t authentication_algorithm; 275 uint8_t integrity_algorithm; 276 uint8_t confidentiality_algorithm; 277 }; 278 279 /* Sockets, pipes, objects, etc. used for data in a SOL session */ 280 struct ipmiconsole_ctx_connection { 281 282 /* File Descriptor User Interface */ 283 int user_fd; /* never touched internally by the library ... */ 284 int ipmiconsole_fd; 285 scbuf_t console_remote_console_to_bmc; 286 scbuf_t console_bmc_to_remote_console; 287 288 /* Connection Data */ 289 int ipmi_fd; 290 scbuf_t ipmi_from_bmc; 291 scbuf_t ipmi_to_bmc; combo_decrypt(PX_Combo * cx,const uint8 * data,unsigned dlen,uint8 * res,unsigned * rlen)292 293 /* Pipe for non-fd communication: from API to engine */ 294 int asynccomm[2]; 295 296 /* Fiid Objects */ 297 298 fiid_obj_t obj_rmcp_hdr_rq; 299 fiid_obj_t obj_rmcp_hdr_rs; 300 fiid_obj_t obj_lan_session_hdr_rq; 301 fiid_obj_t obj_lan_session_hdr_rs; 302 fiid_obj_t obj_rmcpplus_session_hdr_rq; 303 fiid_obj_t obj_rmcpplus_session_hdr_rs; 304 /* fiid_obj_t obj_rmcpplus_payload_rq; */ 305 fiid_obj_t obj_rmcpplus_payload_rs; 306 fiid_obj_t obj_lan_msg_hdr_rq; 307 fiid_obj_t obj_lan_msg_hdr_rs; 308 309 /* fiid_obj_t obj_lan_msg_trlr_rq; */ 310 fiid_obj_t obj_lan_msg_trlr_rs; 311 fiid_obj_t obj_rmcpplus_session_trlr_rq; 312 fiid_obj_t obj_rmcpplus_session_trlr_rs; 313 314 fiid_obj_t obj_authentication_capabilities_rq; 315 fiid_obj_t obj_authentication_capabilities_rs; 316 fiid_obj_t obj_open_session_request; 317 fiid_obj_t obj_open_session_response; 318 fiid_obj_t obj_rakp_message_1; 319 fiid_obj_t obj_rakp_message_2; 320 fiid_obj_t obj_rakp_message_3; 321 fiid_obj_t obj_rakp_message_4; 322 fiid_obj_t obj_set_session_privilege_level_rq; 323 fiid_obj_t obj_set_session_privilege_level_rs; 324 fiid_obj_t obj_get_channel_payload_support_rq; 325 fiid_obj_t obj_get_channel_payload_support_rs; 326 fiid_obj_t obj_get_payload_activation_status_rq; 327 fiid_obj_t obj_get_payload_activation_status_rs; 328 fiid_obj_t obj_activate_payload_rq; 329 fiid_obj_t obj_activate_payload_rs; 330 fiid_obj_t obj_sol_payload_data_rq; 331 fiid_obj_t obj_sol_payload_data_rs; 332 fiid_obj_t obj_get_channel_payload_version_rq; 333 fiid_obj_t obj_get_channel_payload_version_rs; 334 fiid_obj_t obj_deactivate_payload_rq; 335 fiid_obj_t obj_deactivate_payload_rs; 336 fiid_obj_t obj_close_session_rq; 337 fiid_obj_t obj_close_session_rs; 338 }; 339 340 /* 341 * IPMI Session Information - actual data used to keep track of a SOL 342 * session. Separated from ipmiconsole_ctx_connection above, b/c 343 * everything below will need to be re-initialized if the session is 344 * being reattempted under a different port. 345 */ 346 struct ipmiconsole_ctx_session { 347 int16_t console_port; 348 349 struct sockaddr *addr; 350 socklen_t addr_len; 351 struct sockaddr_in addr4; combo_free(PX_Combo * cx)352 struct sockaddr_in6 addr6; 353 354 /* Session timeout, retransmission timeout, keepalive timeout maintenance */ 355 struct timeval last_ipmi_packet_sent; 356 struct timeval last_ipmi_packet_received; 357 struct timeval last_keepalive_packet_sent; 358 359 /* Serial keepalive timeout maintenance */ 360 struct timeval last_sol_packet_received; 361 362 /* parse_cipher_name(char * full,char ** cipher,char ** pad)363 * Protocol State Machine Variables 364 */ 365 ipmiconsole_protocol_state_t protocol_state; 366 int close_session_flag; 367 int try_new_port_flag; 368 int deactivate_payload_instances; 369 /* if deactivate_payload_instances_and_try_again_flag set, 370 * deactivate_payload_instances should always be set, but not vice 371 * versa 372 */ 373 int deactivate_payload_instances_and_try_again_flag; 374 int close_timeout_flag; 375 int deactivate_only_succeeded_flag; 376 377 /* 378 * Protocol Maintenance Variables 379 */ 380 unsigned int retransmission_count; 381 unsigned int workaround_retransmission_count; /* For IPMICONSOLE_WORKAROUND_INCREMENT_SOL_PACKET_SEQUENCE */ 382 unsigned int errors_count; 383 unsigned int session_sequence_number_errors_count; 384 unsigned int activate_payloads_count; 385 unsigned int deactivate_active_payloads_count; 386 uint32_t highest_received_sequence_number; 387 /* need to also store bytes read from a previous seq num */ 388 uint32_t previously_received_list; 389 390 uint8_t message_tag; 391 uint8_t requester_sequence_number; 392 uint32_t session_sequence_number; 393 uint8_t name_only_lookup; 394 uint32_t remote_console_session_id; 395 uint8_t remote_console_random_number[IPMI_REMOTE_CONSOLE_RANDOM_NUMBER_LENGTH]; 396 397 uint8_t sik_key[IPMI_MAX_SIK_KEY_LENGTH]; 398 void *sik_key_ptr; 399 unsigned int sik_key_len; 400 uint8_t integrity_key[IPMI_MAX_INTEGRITY_KEY_LENGTH]; 401 void *integrity_key_ptr; 402 unsigned int integrity_key_len; 403 uint8_t confidentiality_key[IPMI_MAX_CONFIDENTIALITY_KEY_LENGTH]; 404 void *confidentiality_key_ptr; px_find_combo(const char * name,PX_Combo ** res)405 unsigned int confidentiality_key_len; 406 407 uint32_t sol_instance_capacity; 408 uint8_t sol_instances_activated[IPMI_INSTANCES_ACTIVATED_LENGTH]; 409 uint32_t sol_instances_activated_count; 410 uint32_t sol_instances_deactivated_count; 411 412 uint8_t max_sol_character_send_size; /* determine during session setup */ 413 414 /* Serial Break Maintenance */ 415 int break_requested; 416 unsigned int console_remote_console_to_bmc_bytes_before_break; 417 418 /* SOL Input (remote console to BMC) */ 419 int sol_input_waiting_for_ack; 420 int sol_input_waiting_for_break_ack; 421 struct timeval last_sol_input_packet_sent; 422 uint8_t sol_input_packet_sequence_number; 423 uint8_t sol_input_character_data[IPMICONSOLE_MAX_CHARACTER_DATA+1]; 424 unsigned int sol_input_character_data_len; 425 426 /* SOL Output (BMC to remote console) */ 427 uint8_t last_sol_output_packet_sequence_number; 428 uint8_t last_sol_output_accepted_character_count; 429 430 /* Flag indicating session info is setup */ 431 int session_info_setup; 432 }; 433 434 /* Context debug stuff */ 435 struct ipmiconsole_ctx_debug { 436 int debug_fd; 437 }; 438 439 /* Mutexes + flags for signaling between the API and engine */ 440 441 /* state of context 442 * - INIT, user has not submitted it to the engine, user cleans up all 443 * - can move to ENGINE_SUBMITTED state 444 * - ENGINE_SUBMITTED, in engine being used 445 * - can move to USER_DESTROYED if user destroys first 446 * - can move to GARBAGE_COLLECTION_WAIT if engine finished first 447 * - GARBAGE_COLLECTION_WAIT, waiting for user to destroy 448 * - can move to GARBAGE_COLLECTION_USER_DESTROYED 449 * - can move to ENGINE_DESTROYED 450 * - GARBAGE_COLLECTION_USER_DESTROYED, user done, garbage collection 451 * should finish up destruction 452 * - USER_DESTROYED, user destroyed, garbage collector will clean it up 453 * - ENGINE_DESTROYED, engine done with it, user side complete cleanup 454 */ 455 typedef enum { 456 IPMICONSOLE_CTX_STATE_INIT, 457 IPMICONSOLE_CTX_STATE_ENGINE_SUBMITTED, 458 IPMICONSOLE_CTX_STATE_GARBAGE_COLLECTION_WAIT, 459 IPMICONSOLE_CTX_STATE_GARBAGE_COLLECTION_USER_DESTROYED, 460 IPMICONSOLE_CTX_STATE_USER_DESTROYED, 461 IPMICONSOLE_CTX_STATE_ENGINE_DESTROYED, 462 } ipmiconsole_ctx_state; 463 464 struct ipmiconsole_ctx_signal { 465 /* Conceptually there is not a race with the status. The API initializes 466 * the status, and the engine is the only one that modifies it. 467 * 468 * However, there is a tiny race in 469 * ipmiconsole_engine_submit{_block}(). Conceptually, the status 470 * could be set before we even initialize the status to SUBMITTED. 471 */ 472 pthread_mutex_t status_mutex; 473 unsigned int status; 474 475 /* ctx_state - state and mutex used to determine when the user has 476 * destroyed the context and it is now the responsibility of the 477 * engine/garbage-collector to cleanup, or vice versa. Need to 478 * mutex to avoid destroy races. 479 */ 480 pthread_mutex_t mutex_ctx_state; 481 ipmiconsole_ctx_state ctx_state; 482 }; 483 484 /* non-blocking potential parameters */ 485 struct ipmiconsole_ctx_non_blocking { 486 Ipmiconsole_callback callback; 487 void *callback_arg; 488 }; 489 490 /* Info, pipe, and mutex for engine submission blocking */ 491 struct ipmiconsole_ctx_blocking { 492 /* Conceptually, it is impossible for both to ever be touched 493 * simultaneously so a mutex may not seem necessary. 494 * 495 * blocking_submit_requested is initialized/set in API land, and 496 * then later read in engine land after the context is submitted. 497 * It is never read again in API land and never written to in engine 498 * land. 499 * 500 * sol_session_established is initialied in API land, afterwards it 501 * is only written/read in the engine after a context is submitted. 502 * 503 * after initialization, the API and Engine only touch their 504 * ends of the pipe. 505 * 506 * However, there is a tiny race that is possible. After the 507 * session is submitted, the blocking code in _ipmiconsole_block() 508 * could fail, such as in the call to select(). We do not want the 509 * engine and API to race reading/writing under this circumstance. 510 */ 511 pthread_mutex_t blocking_mutex; 512 int blocking_submit_requested; 513 int blocking_notification[2]; 514 int sol_session_established; 515 }; 516 517 struct ipmiconsole_ctx_fds { 518 /* Copy from ipmiconsole_ctx_session, these file descriptors are 519 * managed exclusively by API level, not the engine. 520 * 521 * The need to manage asynccomm at the API level is b/c users could 522 * access it via ipmiconsole_ctx_generate_break(). If one end of 523 * the asynccomm is closed by the engine, it becomes difficult to 524 * know if we can actually generate a break. 525 * 526 * We could manage this situation through some mutexes, but that would 527 * slow down closing/generate-break code. We could capture EPIPE in the 528 * API and return a "IS_CLOSING" error to the user, but that would require 529 * the user to set SIGPIPE to SIG_IGN. Moving it to all be managed in 530 * the API level is best. We just have to check for POLLNVAL in the 531 * engine poll(). 532 * 533 */ 534 int user_fd; 535 int user_fd_retrieved; /* if user ever grabbed it */ 536 int asynccomm[2]; 537 }; 538 539 struct ipmiconsole_ctx { 540 /* Two magics - first indicates the context is still valid. Second 541 * is pretty much a flag that indicates the context has been 542 * "destroyed" in API land, and should no longer be used by the API. 543 */ 544 uint32_t magic; 545 uint32_t api_magic; 546 pthread_mutex_t errnum_mutex; 547 int errnum; 548 int errnum_retrieved; 549 550 struct ipmiconsole_ctx_config config; 551 552 struct ipmiconsole_ctx_debug debug; 553 554 struct ipmiconsole_ctx_signal signal; 555 556 struct ipmiconsole_ctx_non_blocking non_blocking; 557 558 struct ipmiconsole_ctx_blocking blocking; 559 560 struct ipmiconsole_ctx_session session; 561 562 struct ipmiconsole_ctx_connection connection; 563 564 struct ipmiconsole_ctx_fds fds; 565 566 /* session_submitted - flag indicates context submitted to engine 567 * successfully. Does not indicate any state of success/failure for 568 * either blocking or non-blocking submissions. Primary used as a 569 * flag so other functions such as ipmiconsole_ctx_fd() and 570 * ipmiconsole_generate_break() know that they are capable of 571 * moving on. 572 * 573 * Note, does not require a mutex. Only a flag used in API-land. 574 * Engine threads will never touch this. 575 */ 576 unsigned int session_submitted; 577 }; 578 579 #endif /* IPMICONSOLE_DEFS_H */ 580