1 /* 2 * Copyright (C) 2003-2015 FreeIPMI Core Team 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * 17 */ 18 19 #ifndef IPMI_API_H 20 #define IPMI_API_H 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 #include <stdint.h> 27 #include <freeipmi/api/ipmi-api.h> 28 #include <freeipmi/fiid/fiid.h> 29 30 /* ERROR CODE NOTES 31 * 32 * IPMI_ERR_BMC_BUSY vs IPMI_ERR_DRIVER_BUSY 33 * 34 * BMC_BUSY indicates the BMC cannot handle more requests, it is an 35 * error typically from a completion code returned from the BMC. The 36 * DRIVER_BUSY error indicates a driver is too busy to handle 37 * additional requests, the error does not come from the BMC. 38 * 39 * IPMI_ERR_MESSAGE_TIMEOUT 40 * 41 * message timeout is typical of bridging commands. The 42 * session/connection has not timed out and is fine, but a 43 * bridging command could not get its bridged response back in a 44 * reasonable timeframe. 45 */ 46 47 /* IPMI COMPLETION CODE / RMCPPLUS CODE MAPPING 48 * 49 * For most users, the high level error codes listed below will 50 * suffice. However, for those who want/need to see deeper IPMI 51 * completion code or RMCPPlus errors, the following are mappings of 52 * IPMI completion codes and RMCPPlus codes to their respective error 53 * codes. 54 * 55 * Not that other factors outside of completion codes/RMCPPlus codes 56 * could also lead to these IPMI errors. For example, depending on 57 * motherboard support of username types, a IPMI_ERR_USERNAME_INVALID 58 * could be returned even though no IPMI error occurred. In addition, 59 * completion codes/RMCPPlus codes could map to different error codes, 60 * depending on when the error occurred (such as during session 61 * authentication vs. after authentication). 62 * 63 * (*) - Completion code is specific to an IPMI command 64 * 65 * IPMI_ERR_USERNAME_INVALID 66 * - IPMI_COMP_CODE_GET_SESSION_CHALLENGE_INVALID_USERNAME (*) 67 * - IPMI_COMP_CODE_GET_SESSION_CHALLENGE_NULL_USERNAME_NOT_ENABLED (*) 68 * 69 * IPMI_ERR_PASSWORD_INVALID 70 * - RMCPPLUS_STATUS_INVALID_INTEGRITY_CHECK_VALUE 71 * 72 * IPMI_ERR_PRIVILEGE_LEVEL_INSUFFICIENT 73 * - IPMI_COMP_CODE_INSUFFICIENT_PRIVILEGE_LEVEL 74 * 75 * IPMI_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED 76 * - IPMI_COMP_CODE_ACTIVATE_SESSION_EXCEEDS_PRIVILEGE_LEVEL (*) 77 * - IPMI_COMP_CODE_INSUFFICIENT_PRIVILEGE_LEVEL 78 * - IPMI_COMP_CODE_SET_SESSION_PRIVILEGE_LEVEL_REQUESTED_LEVEL_NOT_AVAILABLE_FOR_USER (*) 79 * - IPMI_COMP_CODE_SET_SESSION_PRIVILEGE_LEVEL_REQUESTED_LEVEL_EXCEEDS_USER_PRIVILEGE_LIMIT (*) 80 * - RMCPPLUS_STATUS_INVALID_ROLE 81 * - RMCPPLUS_STATUS_UNAUTHORIZED_ROLE_OR_PRIVILEGE_LEVEL_REQUESTED 82 * 83 * IPMI_ERR_CIPHER_SUITE_ID_UNAVAILABLE 84 * - RMCPPLUS_STATUS_NO_CIPHER_SUITE_MATCH_WITH_PROPOSED_SECURITY_ALGORITHMS 85 * 86 * IPMI_ERR_MESSAGE_TIMEOUT 87 * - IPMI_COMP_CODE_COMMAND_TIMEOUT 88 * 89 * IPMI_ERR_COMMAND_INVALID_OR_UNSUPPORTED 90 * - IPMI_COMP_CODE_INVALID_COMMAND 91 * - IPMI_COMP_CODE_COMMAND_INVALID_FOR_LUN 92 * - IPMI_COMP_CODE_REQUEST_DATA_LENGTH_INVALID 93 * - IPMI_COMP_CODE_REQUEST_DATA_LENGTH_LIMIT_EXCEEDED 94 * - IPMI_COMP_CODE_PARAMETER_OUT_OF_RANGE 95 * - IPMI_COMP_CODE_INVALID_DATA_FIELD_IN_REQUEST 96 * 97 * IPMI_ERR_BMC_BUSY 98 * - IPMI_COMP_CODE_NODE_BUSY 99 * - IPMI_COMP_CODE_OUT_OF_SPACE 100 * - IPMI_COMP_CODE_SDR_REPOSITORY_IN_UPDATE_MODE 101 * - IPMI_COMP_CODE_DEVICE_IN_FIRMWARE_UPDATE_MODE 102 * - IPMI_COMP_CODE_BMC_INITIALIZATION_IN_PROGRESS 103 * 104 * All other IPMI completion codes will map to IPMI_ERR_BAD_COMPLETION_CODE. 105 * All other RMCPPlus codes will map to IPMI_ERR_BAD_RMCPPLUS_STATUS_CODE. 106 */ 107 108 enum ipmi_errnum 109 { 110 IPMI_ERR_SUCCESS = 0, 111 IPMI_ERR_CTX_NULL = 1, 112 IPMI_ERR_CTX_INVALID = 2, 113 IPMI_ERR_PERMISSION = 3, 114 IPMI_ERR_USERNAME_INVALID = 4, 115 IPMI_ERR_PASSWORD_INVALID = 5, 116 IPMI_ERR_K_G_INVALID = 6, 117 IPMI_ERR_PRIVILEGE_LEVEL_INSUFFICIENT = 7, 118 IPMI_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED = 8, 119 IPMI_ERR_AUTHENTICATION_TYPE_UNAVAILABLE = 9, 120 IPMI_ERR_CIPHER_SUITE_ID_UNAVAILABLE = 10, 121 IPMI_ERR_PASSWORD_VERIFICATION_TIMEOUT = 11, 122 IPMI_ERR_IPMI_2_0_UNAVAILABLE = 12, 123 IPMI_ERR_CONNECTION_TIMEOUT = 13, 124 IPMI_ERR_SESSION_TIMEOUT = 14, 125 IPMI_ERR_DEVICE_ALREADY_OPEN = 15, 126 IPMI_ERR_DEVICE_NOT_OPEN = 16, 127 IPMI_ERR_DEVICE_NOT_SUPPORTED = 17, 128 IPMI_ERR_DEVICE_NOT_FOUND = 18, 129 IPMI_ERR_DRIVER_BUSY = 19, 130 IPMI_ERR_DRIVER_TIMEOUT = 20, 131 IPMI_ERR_MESSAGE_TIMEOUT = 21, 132 IPMI_ERR_COMMAND_INVALID_FOR_SELECTED_INTERFACE = 22, 133 IPMI_ERR_COMMAND_INVALID_OR_UNSUPPORTED = 23, 134 IPMI_ERR_BAD_COMPLETION_CODE = 24, 135 IPMI_ERR_BAD_RMCPPLUS_STATUS_CODE = 25, 136 IPMI_ERR_NOT_FOUND = 26, 137 IPMI_ERR_BMC_BUSY = 27, 138 IPMI_ERR_OUT_OF_MEMORY = 28, 139 IPMI_ERR_HOSTNAME_INVALID = 29, 140 IPMI_ERR_PARAMETERS = 30, 141 IPMI_ERR_DRIVER_PATH_REQUIRED = 31, 142 IPMI_ERR_IPMI_ERROR = 32, 143 IPMI_ERR_SYSTEM_ERROR = 33, 144 IPMI_ERR_INTERNAL_ERROR = 34, 145 IPMI_ERR_ERRNUMRANGE = 35, 146 }; 147 typedef enum ipmi_errnum ipmi_errnum_type_t; 148 149 enum ipmi_driver_type 150 { 151 IPMI_DEVICE_UNKNOWN = 0, 152 IPMI_DEVICE_LAN = 1, 153 IPMI_DEVICE_LAN_2_0 = 2, 154 IPMI_DEVICE_KCS = 3, 155 IPMI_DEVICE_SMIC = 4, 156 IPMI_DEVICE_BT = 5, 157 IPMI_DEVICE_SSIF = 6, 158 IPMI_DEVICE_OPENIPMI = 7, 159 IPMI_DEVICE_SUNBMC = 8, 160 IPMI_DEVICE_INTELDCMI = 9, 161 }; 162 typedef enum ipmi_driver_type ipmi_driver_type_t; 163 164 #define IPMI_SESSION_TIMEOUT_DEFAULT 20000 165 #define IPMI_RETRANSMISSION_TIMEOUT_DEFAULT 1000 166 167 #define IPMI_WORKAROUND_FLAGS_DEFAULT 0x00000000 168 169 /* For use w/ ipmi_ctx_open_outofband() */ 170 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_AUTHENTICATION_CAPABILITIES 0x00000001 171 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_ACCEPT_SESSION_ID_ZERO 0x00000002 172 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_FORCE_PERMSG_AUTHENTICATION 0x00000004 173 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_CHECK_UNEXPECTED_AUTHCODE 0x00000008 174 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_BIG_ENDIAN_SEQUENCE_NUMBER 0x00000010 175 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_NO_AUTH_CODE_CHECK 0x00000020 176 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_NO_CHECKSUM_CHECK 0x00000040 177 178 /* For use w/ ipmi_ctx_open_outofband_2_0() */ 179 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_AUTHENTICATION_CAPABILITIES 0x00000001 180 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION 0x00000002 181 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUPERMICRO_2_0_SESSION 0x00000004 182 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUN_2_0_SESSION 0x00000008 183 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE 0x00000010 184 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_NON_EMPTY_INTEGRITY_CHECK_VALUE 0x00000020 185 #define IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_NO_CHECKSUM_CHECK 0x00000040 186 187 /* For use w/ ipmi_ctx_open_inband() or ipmi_ctx_find_inband() */ 188 #define IPMI_WORKAROUND_FLAGS_INBAND_ASSUME_IO_BASE_ADDRESS 0x00000001 189 #define IPMI_WORKAROUND_FLAGS_INBAND_SPIN_POLL 0x00000002 190 191 /* NONBLOCKING - for inband only, do no block if device busy. 192 * 193 * NOSESSION - for outofband only, do not create an IPMI session. 194 * Useful for the few IPMI payloads that do not require a session for 195 * an IPMI command to be sent (e.g. Get Channel Authentication 196 * Capabilities, Get System GUID, PET Acknowledge). Can only be set 197 * during opening, not later using ipmi_ctx_set_flags(). If set, you 198 * cannot call most IPMI payload functions, only those few that send 199 * data without a session. 200 * 201 * DEBUG_DUMP - for all interfaces 202 * 203 * NO_VALID_CHECK - do not check if IPMI response payloads are valid 204 * (i.e. all required fields set). Useful to workaround non-compliant 205 * motherboards. For example, if an IPMI payload did not return a 206 * required flag in the payload, an error would be returned. The 207 * error might possibly be a session timeout, as no valid response 208 * packet was ever received. This flag would skip the checks for 209 * valid fields and return the packet to the user. 210 * 211 * NO_LEGAL_CHECK - do no check if IPMI response payloads have 212 * sufficient data (i.e. completion code fields) to be legal. Useful 213 * to work around non-compliant motherboards. This flag is ignores 214 * the legality of IPMI payloads greater than the NO_VALID_CHECK 215 * option. For example, NO_VALID_CHECK would still return an error if 216 * an IPMI payload did not return a completion code in an IPMI 217 * response. The NO_LEGAL_CHECK would return such a packet to the 218 * user without an error. If the payload did not return a completion 219 * code, the completion code will not be checked for. 220 * 221 * IGNORE_AUTHENTICATION_CODE - for IPMI 1.5 packets, do not check the 222 * authentication code on response packets. Useful to workaround 223 * around non-compliant motherboards implementing invalid code/hashes. 224 * Note that this is different than 225 * IPMI_WORKAROUND_FLAGS_OUTOFBAND_NO_AUTH_CODE_CHECK above. With the 226 * workaround flag, all authentication codes will be ignored during 227 * the entire IPMI session. With this flag, specific packets can have 228 * their authentication codes ignored. 229 */ 230 231 #define IPMI_FLAGS_DEFAULT 0x00000000 232 #define IPMI_FLAGS_NONBLOCKING 0x00000001 233 #define IPMI_FLAGS_NOSESSION 0x00000002 234 #define IPMI_FLAGS_DEBUG_DUMP 0x00000010 235 #define IPMI_FLAGS_NO_VALID_CHECK 0x00000100 236 #define IPMI_FLAGS_NO_LEGAL_CHECK 0x00000200 237 #define IPMI_FLAGS_IGNORE_AUTHENTICATION_CODE 0x00000400 238 239 typedef struct ipmi_ctx *ipmi_ctx_t; 240 241 ipmi_ctx_t ipmi_ctx_create (void); 242 243 int ipmi_ctx_errnum (ipmi_ctx_t ctx); 244 245 char *ipmi_ctx_strerror (int errnum); 246 247 char *ipmi_ctx_errormsg (ipmi_ctx_t ctx); 248 249 int ipmi_ctx_get_flags (ipmi_ctx_t ctx, unsigned int *flags); 250 251 /* for changing flags mid-operation for corner cases */ 252 int ipmi_ctx_set_flags (ipmi_ctx_t ctx, unsigned int flags); 253 254 /* For IPMI 1.5 sessions */ 255 /* For session_timeout and retransmission_timeout, specify 0 for default */ 256 int ipmi_ctx_open_outofband (ipmi_ctx_t ctx, 257 const char *hostname, 258 const char *username, 259 const char *password, 260 uint8_t authentication_type, 261 uint8_t privilege_level, 262 unsigned int session_timeout, 263 unsigned int retransmission_timeout, 264 unsigned int workaround_flags, 265 unsigned int flags); 266 267 /* For IPMI 2.0 sessions */ 268 /* For session_timeout and retransmission_timeout, specify 0 for default */ 269 int ipmi_ctx_open_outofband_2_0 (ipmi_ctx_t ctx, 270 const char *hostname, 271 const char *username, 272 const char *password, 273 const unsigned char *k_g, 274 unsigned int k_g_len, 275 uint8_t privilege_level, 276 uint8_t cipher_suite_id, 277 unsigned int session_timeout, 278 unsigned int retransmission_timeout, 279 unsigned int workaround_flags, 280 unsigned int flags); 281 282 /* For inband sessions */ 283 int ipmi_ctx_open_inband (ipmi_ctx_t ctx, 284 ipmi_driver_type_t driver_type, 285 int disable_auto_probe, 286 uint16_t driver_address, 287 uint8_t register_spacing, 288 const char *driver_device, 289 unsigned int workaround_flags, 290 unsigned int flags); 291 292 /* like ipmi_ctx_open_inband, but finds probes/discovers an inband device */ 293 /* returns 1 on driver found, 0 on not found, -1 on error */ 294 /* if specified, driver type returned in 'driver_type' */ 295 int ipmi_ctx_find_inband (ipmi_ctx_t ctx, 296 ipmi_driver_type_t *driver_type, 297 int disable_auto_probe, 298 uint16_t driver_address, 299 uint8_t register_spacing, 300 const char *driver_device, 301 unsigned int workaround_flags, 302 unsigned int flags); 303 304 /* Set target channel and slave address so all ipmi_cmd() calls and 305 * library API calls use ipmb. 306 * 307 * To set only one parameter, pass in NULL for the other parameter. 308 * When only one parameter is passed, the other will be the default 309 * target channel of IPMI_CHANNEL_NUMBER_PRIMARY_IPMB (0x0) or the 310 * default rs_addr of IPMI_SLAVE_ADDRESS_BMC (0x20). 311 * 312 * To reset to defaults, pass in NULL for both parameters. 313 * 314 * Can only be called after device opened. 315 */ 316 int ipmi_ctx_set_target (ipmi_ctx_t ctx, 317 uint8_t *channel_number, 318 uint8_t *rs_addr); 319 320 int ipmi_ctx_get_target (ipmi_ctx_t ctx, 321 uint8_t *channel_number, 322 uint8_t *rs_addr); 323 324 int ipmi_cmd (ipmi_ctx_t ctx, 325 uint8_t lun, 326 uint8_t net_fn, 327 fiid_obj_t obj_cmd_rq, 328 fiid_obj_t obj_cmd_rs); 329 330 /* convenience function to perform a single bridged IPMI command. 331 * Will effectively call ipmi_ctx_set_target(), then ipmi_cmd(), then 332 * will set targets back to prior originals. 333 */ 334 int ipmi_cmd_ipmb (ipmi_ctx_t ctx, 335 uint8_t channel_number, 336 uint8_t rs_addr, 337 uint8_t lun, 338 uint8_t net_fn, 339 fiid_obj_t obj_cmd_rq, 340 fiid_obj_t obj_cmd_rs); 341 342 /* for request/response, byte #1 = cmd */ 343 /* for response, byte #2 (typically) = completion code */ 344 /* returns length written into buf_fs on success, -1 on error */ 345 int ipmi_cmd_raw (ipmi_ctx_t ctx, 346 uint8_t lun, 347 uint8_t net_fn, 348 const void *buf_rq, 349 unsigned int buf_rq_len, 350 void *buf_rs, 351 unsigned int buf_rs_len); 352 353 /* convenience function to perform a single bridged IPMI raw command. 354 * Will effectively call ipmi_ctx_set_target(), then ipmi_cmd_raw(), 355 * then will set targets back to prior originals. 356 */ 357 int ipmi_cmd_raw_ipmb (ipmi_ctx_t ctx, 358 uint8_t channel_number, 359 uint8_t rs_addr, 360 uint8_t lun, 361 uint8_t net_fn, 362 const void *buf_rq, 363 unsigned int buf_rq_len, 364 void *buf_rs, 365 unsigned int buf_rs_len); 366 367 int ipmi_ctx_close (ipmi_ctx_t ctx); 368 369 void ipmi_ctx_destroy (ipmi_ctx_t ctx); 370 371 #ifdef __cplusplus 372 } 373 #endif 374 375 #endif /* IPMI_API_H */ 376