void locate_set_locate_errnum_by_fiid_object (ipmi_locate_ctx_t ctx, fiid_obj_t obj) { assert (ctx && ctx->magic == IPMI_LOCATE_CTX_MAGIC); switch (fiid_obj_errnum (obj)) { case FIID_ERR_SUCCESS: ctx->errnum = IPMI_LOCATE_ERR_SUCCESS; break; case FIID_ERR_OUT_OF_MEMORY: ctx->errnum = IPMI_LOCATE_ERR_OUT_OF_MEMORY; break; case FIID_ERR_DATA_NOT_AVAILABLE: ctx->errnum = IPMI_LOCATE_ERR_SYSTEM_ERROR; break; case FIID_ERR_FIELD_NOT_FOUND: case FIID_ERR_DATA_NOT_BYTE_ALIGNED: case FIID_ERR_REQUIRED_FIELD_MISSING: case FIID_ERR_FIXED_LENGTH_FIELD_INVALID: case FIID_ERR_NOT_IDENTICAL: ctx->errnum = IPMI_LOCATE_ERR_PARAMETERS; break; default: ctx->errnum = IPMI_LOCATE_ERR_INTERNAL_ERROR; } }
static int _api_ipmi_cmd_post (ipmi_ctx_t ctx, fiid_obj_t obj_cmd_rs) { int ret; assert (ctx && ctx->magic == IPMI_CTX_MAGIC && fiid_obj_valid (obj_cmd_rs)); if (ctx->flags & IPMI_FLAGS_NO_LEGAL_CHECK) { uint64_t val; /* Do not check completion code if data not available * (i.e. FIID_ERR_DATA_NOT_AVAILABLE completion code). * * Fallthrough to normal error if it's an alternate fiid error * (invalid packet, field not found, etc.) */ if (FIID_OBJ_GET (obj_cmd_rs, "comp_code", &val) < 0) { if (fiid_obj_errnum (obj_cmd_rs) == FIID_ERR_DATA_NOT_AVAILABLE) goto skip_comp_code_check; } } if ((ret = ipmi_check_completion_code_success (obj_cmd_rs)) < 0) { API_ERRNO_TO_API_ERRNUM (ctx, errno); return (-1); } if (!ret) { API_BAD_RESPONSE_TO_API_ERRNUM (ctx, obj_cmd_rs); return (-1); } skip_comp_code_check: if (!(ctx->flags & IPMI_FLAGS_NO_VALID_CHECK) && !(ctx->flags & IPMI_FLAGS_NO_LEGAL_CHECK)) { if ((ret = fiid_obj_packet_valid (obj_cmd_rs)) < 0) { API_FIID_OBJECT_ERROR_TO_API_ERRNUM (ctx, obj_cmd_rs); return (-1); } if (!ret) { API_SET_ERRNUM (ctx, IPMI_ERR_IPMI_ERROR); return (-1); } } return (0); }
int32_t Fiid_obj_set_all(fiid_obj_t obj, uint8_t *data, uint32_t data_len) { int32_t rv; assert(fiid_obj_valid(obj) && data && data_len); if ((rv = fiid_obj_set_all(obj, data, data_len)) < 0) ierr_exit("Fiid_obj_set_all: %s", fiid_strerror(fiid_obj_errnum(obj))); return rv; }
int32_t Fiid_obj_set_data(fiid_obj_t obj, char *field, uint8_t *data, uint32_t data_len) { int32_t rv; assert(fiid_obj_valid(obj) && field && data && data_len); if ((rv = fiid_obj_set_data(obj, field, data, data_len)) < 0) ierr_exit("Fiid_obj_set_data: field=%s: %s", field, fiid_strerror(fiid_obj_errnum(obj))); return rv; }
void set_errno_by_fiid_object (fiid_obj_t obj) { if (fiid_obj_errnum (obj) == FIID_ERR_SUCCESS) errno = 0; else if (fiid_obj_errnum (obj) == FIID_ERR_OUT_OF_MEMORY) errno = ENOMEM; else if (fiid_obj_errnum (obj) == FIID_ERR_OVERFLOW) errno = ENOSPC; #if 0 else if (fiid_obj_errnum (obj) == FIID_ERR_DATA_NOT_AVAILABLE) errno = EINVAL; else if (fiid_obj_errnum (obj) == FIID_ERR_FIELD_NOT_FOUND || fiid_obj_errnum (obj) == FIID_ERR_DATA_NOT_BYTE_ALIGNED || fiid_obj_errnum (obj) == FIID_ERR_REQUIRED_FIELD_MISSING || fiid_obj_errnum (obj) == FIID_ERR_FIXED_LENGTH_FIELD_INVALID || fiid_obj_errnum (obj) == FIID_ERR_DATA_NOT_AVAILABLE || fiid_obj_errnum (obj) == FIID_ERR_NOT_IDENTICAL) errno = EINVAL; #endif else errno = EINVAL; }
void Fiid_obj_get(fiid_obj_t obj, char *field, uint64_t *val) { int8_t rv; assert(fiid_obj_valid(obj) && field && val); if ((rv = fiid_obj_get(obj, field, val)) < 0) ierr_exit("Fiid_obj_get: field=%s: %s", field, fiid_strerror(fiid_obj_errnum(obj))); if (!rv) ierr_exit("Fiid_obj_get: field=%s: No data set", field); return; }
static void _set_kcs_errnum_by_fiid_object (ipmi_kcs_ctx_t ctx, fiid_obj_t obj) { if (!ctx || ctx->magic != IPMI_KCS_CTX_MAGIC) return; if (!fiid_obj_valid (obj)) { KCS_SET_ERRNUM (ctx, IPMI_ERR_INTERNAL_ERROR); return; } if (fiid_obj_errnum (obj) == FIID_ERR_SUCCESS) ctx->errnum = IPMI_KCS_ERR_SUCCESS; else if (fiid_obj_errnum (obj) == FIID_ERR_OUT_OF_MEMORY) ctx->errnum = IPMI_KCS_ERR_OUT_OF_MEMORY; else if (fiid_obj_errnum (obj) == FIID_ERR_DATA_NOT_AVAILABLE) ctx->errnum = IPMI_KCS_ERR_SYSTEM_ERROR; else if (fiid_obj_errnum (obj) == FIID_ERR_NOT_IDENTICAL || fiid_obj_errnum (obj) == FIID_ERR_FIELD_NOT_FOUND) ctx->errnum = IPMI_KCS_ERR_PARAMETERS; else ctx->errnum = IPMI_KCS_ERR_INTERNAL_ERROR; }
static config_err_t _rmcpplus_cipher_suite_id_privilege_setup (bmc_config_state_data_t *state_data, const char *section_name) { fiid_obj_t obj_cmd_count_rs = NULL; fiid_obj_t obj_cmd_id_rs = NULL; fiid_obj_t obj_cmd_priv_rs = NULL; uint64_t val; config_err_t rv = CONFIG_ERR_FATAL_ERROR; config_err_t ret; uint8_t channel_number; unsigned int i; assert (state_data); assert (section_name); if ((ret = get_lan_channel_number (state_data, section_name, &channel_number)) != CONFIG_ERR_SUCCESS) { rv = ret; goto cleanup; } if (state_data->cipher_suite_entry_count_set && state_data->cipher_suite_id_supported_set && state_data->cipher_suite_priv_set && state_data->cipher_suite_channel_number == channel_number) return (CONFIG_ERR_SUCCESS); state_data->cipher_suite_entry_count = 0; state_data->cipher_suite_entry_count_set = 0; state_data->cipher_suite_id_supported_set = 0; state_data->cipher_suite_priv_set = 0; state_data->cipher_suite_channel_number = channel_number; memset (state_data->cipher_suite_id_supported, '\0', sizeof (state_data->cipher_suite_id_supported)); memset (state_data->cipher_suite_priv, '\0', sizeof (state_data->cipher_suite_priv)); if (!state_data->cipher_suite_entry_count_set) { if (!(obj_cmd_count_rs = fiid_obj_create (tmpl_cmd_get_lan_configuration_parameters_rmcpplus_messaging_cipher_suite_entry_support_rs))) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_create: %s\n", strerror (errno)); goto cleanup; } if (ipmi_cmd_get_lan_configuration_parameters_rmcpplus_messaging_cipher_suite_entry_support (state_data->ipmi_ctx, channel_number, IPMI_GET_LAN_PARAMETER, IPMI_LAN_CONFIGURATION_PARAMETERS_NO_SET_SELECTOR, IPMI_LAN_CONFIGURATION_PARAMETERS_NO_BLOCK_SELECTOR, obj_cmd_count_rs) < 0) { if (state_data->prog_data->args->config_args.common_args.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_get_lan_configuration_parameters_rmcpplus_messaging_cipher_suite_entry_support: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); if (config_is_config_param_non_fatal_error (state_data->ipmi_ctx, obj_cmd_count_rs, &ret)) rv = ret; goto cleanup; } if (FIID_OBJ_GET (obj_cmd_count_rs, "cipher_suite_entry_count", &val) < 0) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get: 'cipher_suite_entry_count': %s\n", fiid_obj_errormsg (obj_cmd_count_rs)); goto cleanup; } state_data->cipher_suite_entry_count = val; if (state_data->cipher_suite_entry_count > CIPHER_SUITE_LEN) state_data->cipher_suite_entry_count = CIPHER_SUITE_LEN; state_data->cipher_suite_entry_count_set++; } if (state_data->cipher_suite_entry_count && !state_data->cipher_suite_id_supported_set) { if (!(obj_cmd_id_rs = fiid_obj_create (tmpl_cmd_get_lan_configuration_parameters_rmcpplus_messaging_cipher_suite_entries_rs))) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_create: %s\n", strerror (errno)); goto cleanup; } if (ipmi_cmd_get_lan_configuration_parameters_rmcpplus_messaging_cipher_suite_entries (state_data->ipmi_ctx, channel_number, IPMI_GET_LAN_PARAMETER, IPMI_LAN_CONFIGURATION_PARAMETERS_NO_SET_SELECTOR, IPMI_LAN_CONFIGURATION_PARAMETERS_NO_BLOCK_SELECTOR, obj_cmd_id_rs) < 0) { if (state_data->prog_data->args->config_args.common_args.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_get_lan_configuration_parameters_rmcpplus_messaging_cipher_suite_entries: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); if (config_is_config_param_non_fatal_error (state_data->ipmi_ctx, obj_cmd_id_rs, &ret)) rv = ret; goto cleanup; } for (i = 0; i < state_data->cipher_suite_entry_count; i++) { char field[BMC_CONFIG_FIELD_LENGTH_MAX + 1]; memset (field, '\0', BMC_CONFIG_FIELD_LENGTH_MAX + 1); snprintf (field, BMC_CONFIG_FIELD_LENGTH_MAX, "cipher_suite_id_entry_%c", 'A' + i); if (FIID_OBJ_GET (obj_cmd_id_rs, field, &val) < 0) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get: '%s': %s\n", field, fiid_obj_errormsg (obj_cmd_id_rs)); goto cleanup; } state_data->cipher_suite_id_supported[i] = val; } /* IPMI Workaround (achu) * * Intel S2600JF/Appro 512X * * Motherboard incorrectly states that it supports Cipher Suites * 1-16 instead of 0-15. If this is specifically returned, adjust * appropriately. */ if (state_data->cipher_suite_entry_count == BMC_CONFIG_CIPHER_SUITE_INCORRECT_RANGE_LEN) { int workaround_condition_not_found = 0; for (i = 0; i < state_data->cipher_suite_entry_count; i++) { if (state_data->cipher_suite_id_supported[i] != (i + 1)) { workaround_condition_not_found++; break; } } if (!workaround_condition_not_found) { for (i = 0; i < state_data->cipher_suite_entry_count; i++) state_data->cipher_suite_id_supported[i] -= 1; } } state_data->cipher_suite_id_supported_set++; } if (state_data->cipher_suite_entry_count && !state_data->cipher_suite_priv_set) { if (!(obj_cmd_priv_rs = fiid_obj_create (tmpl_cmd_get_lan_configuration_parameters_rmcpplus_messaging_cipher_suite_privilege_levels_rs))) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_create: %s\n", strerror (errno)); goto cleanup; } if (ipmi_cmd_get_lan_configuration_parameters_rmcpplus_messaging_cipher_suite_privilege_levels (state_data->ipmi_ctx, channel_number, IPMI_GET_LAN_PARAMETER, IPMI_LAN_CONFIGURATION_PARAMETERS_NO_SET_SELECTOR, IPMI_LAN_CONFIGURATION_PARAMETERS_NO_BLOCK_SELECTOR, obj_cmd_priv_rs) < 0) { if (state_data->prog_data->args->config_args.common_args.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_get_lan_configuration_parameters_rmcpplus_messaging_cipher_suite_privilege_level: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); if (config_is_config_param_non_fatal_error (state_data->ipmi_ctx, obj_cmd_priv_rs, &ret)) rv = ret; goto cleanup; } for (i = 0; i < CIPHER_SUITE_LEN; i++) { char field[BMC_CONFIG_FIELD_LENGTH_MAX + 1]; memset (field, '\0', BMC_CONFIG_FIELD_LENGTH_MAX + 1); snprintf (field, BMC_CONFIG_FIELD_LENGTH_MAX, "maximum_privilege_for_cipher_suite_%u", i + 1); if (FIID_OBJ_GET (obj_cmd_priv_rs, field, &val) < 0) { int id_found = 0; /* IPMI Workaround (achu) * * HP DL145 * * The number of entries returned from a RMCP+ Messaging * Cipher Suite Privilege Levels request is not valid. Not * only is it not valid, the number of entries does not even * match the number of entries specified by a RMCP+ * Messaging Cipher Suite Entry Support Count request. * * Instead, indicate the privilege is illegal and have * the output indicated appropriately for this * situation. */ if (fiid_obj_errnum (obj_cmd_priv_rs) == FIID_ERR_DATA_NOT_AVAILABLE) { unsigned int j; for (j = 0; j < state_data->cipher_suite_entry_count; j++) { if (state_data->cipher_suite_id_supported[j] == i) { id_found++; break; } } } if (fiid_obj_errnum (obj_cmd_priv_rs) != FIID_ERR_DATA_NOT_AVAILABLE) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get: '%s': %s\n", field, fiid_obj_errormsg (obj_cmd_priv_rs)); goto cleanup; } else { if (id_found) val = BMC_CONFIG_PRIVILEGE_LEVEL_SUPPORTED_BUT_NOT_READABLE; else val = IPMI_PRIVILEGE_LEVEL_UNSPECIFIED; } } state_data->cipher_suite_priv[i] = val; } state_data->cipher_suite_priv_set++; } rv = CONFIG_ERR_SUCCESS; cleanup: fiid_obj_destroy (obj_cmd_count_rs); fiid_obj_destroy (obj_cmd_id_rs); fiid_obj_destroy (obj_cmd_priv_rs); return (rv); }
static ipmi_config_err_t _get_power_limit (ipmi_config_state_data_t *state_data, struct get_power_limit_data *gpld, int *no_set_power_limit_flag) { fiid_obj_t obj_cmd_rs = NULL; uint64_t val; int no_set_power_limit_error_flag = 0; ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR; assert (state_data); assert (gpld); if (no_set_power_limit_flag) (*no_set_power_limit_flag) = 0; if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_dcmi_get_power_limit_rs))) { pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_create: %s", strerror (errno)); goto cleanup; } /* IPMI Workaround/Interpretation * * The DCMI spec indicates a potential completion code for the "Get * Power Limit" command as "No Set Power Limit" (0x80). FreeIPMI * originally interpreted this to mean the "Set Power Limit" command * was not available. Atleast one vendor interpreted this to mean * "No Power Limit Set". One can consider this an English * interpretation issue of 'No set POWER LIMIT' vs. 'No SET POWER * LIMIT' (i.e. is "set" a verb or part of a proper noun referencing * the DCMI command). Confounding this issue is the fact that the * example implementation in Intel's DCMItool implements the former, * while the DCMI Conformance test suite implements the latter. In * addition to this, with the latter interpretation, it need not be * an indication of an error, but rather a flag. So the rest of the * packet can be completely full of legitimate data. * * So how do we handle this? * * If we hit "No Set Power Limit", try to read data. If we can't * read data (b/c it's not set), fail out, but preserve the "No Set * Power Limit" error message. */ if (ipmi_cmd_dcmi_get_power_limit (state_data->ipmi_ctx, obj_cmd_rs) < 0) { ipmi_config_err_t ret; if (ipmi_ctx_errnum (state_data->ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE && ipmi_check_completion_code (obj_cmd_rs, IPMI_COMP_CODE_DCMI_NO_SET_POWER_LIMIT) == 1) { if (state_data->prog_data->args->common_args.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_dcmi_get_power_limit: %s", IPMI_COMP_CODE_DCMI_NO_SET_POWER_LIMIT_STR); if (no_set_power_limit_flag) (*no_set_power_limit_flag) = 1; no_set_power_limit_error_flag++; goto read_data; } if (ipmi_config_param_errnum_is_non_fatal (state_data, obj_cmd_rs, &ret)) rv = ret; if (rv == IPMI_CONFIG_ERR_FATAL_ERROR || state_data->prog_data->args->common_args.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_get_pef_configuration_parameters_event_filter_table: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } read_data: if (FIID_OBJ_GET (obj_cmd_rs, "exception_actions", &val) < 0) { if (!no_set_power_limit_error_flag || fiid_obj_errnum (obj_cmd_rs) != FIID_ERR_DATA_NOT_AVAILABLE) pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get: 'exception_actions': %s", fiid_obj_errormsg (obj_cmd_rs)); if (no_set_power_limit_error_flag) rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } gpld->exception_actions = val; if (FIID_OBJ_GET (obj_cmd_rs, "power_limit_requested", &val) < 0) { if (!no_set_power_limit_error_flag || fiid_obj_errnum (obj_cmd_rs) != FIID_ERR_DATA_NOT_AVAILABLE) pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get: 'power_limit_requested': %s", fiid_obj_errormsg (obj_cmd_rs)); if (no_set_power_limit_error_flag) rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } gpld->power_limit_requested = val; if (FIID_OBJ_GET (obj_cmd_rs, "correction_time_limit", &val) < 0) { if (!no_set_power_limit_error_flag || fiid_obj_errnum (obj_cmd_rs) != FIID_ERR_DATA_NOT_AVAILABLE) pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get: 'correction_time_limit': %s", fiid_obj_errormsg (obj_cmd_rs)); if (no_set_power_limit_error_flag) rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } gpld->correction_time_limit = val; if (FIID_OBJ_GET (obj_cmd_rs, "management_application_statistics_sampling_period", &val) < 0) { if (!no_set_power_limit_error_flag || fiid_obj_errnum (obj_cmd_rs) != FIID_ERR_DATA_NOT_AVAILABLE) pstdout_fprintf (state_data->pstate, stderr, "fiid_obj_get: 'management_application_statistics_sampling_period': %s", fiid_obj_errormsg (obj_cmd_rs)); if (no_set_power_limit_error_flag) rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } gpld->management_application_statistics_sampling_period = val; rv = IPMI_CONFIG_ERR_SUCCESS; cleanup: fiid_obj_destroy (obj_cmd_rs); return (rv); }