static config_err_t _get_sol_sol_authentication (bmc_config_state_data_t *state_data, struct sol_authentication *sa) { fiid_obj_t obj_cmd_rs = NULL; uint64_t val; config_err_t rv = CONFIG_ERR_FATAL_ERROR; config_err_t ret; uint8_t channel_number; assert(state_data); assert(sa); _FIID_OBJ_CREATE(obj_cmd_rs, tmpl_cmd_get_sol_configuration_parameters_sol_authentication_rs); if ((ret = get_sol_channel_number (state_data, &channel_number)) != CONFIG_ERR_SUCCESS) { rv = ret; goto cleanup; } if (ipmi_cmd_get_sol_configuration_parameters_sol_authentication (state_data->ipmi_ctx, channel_number, IPMI_GET_SOL_PARAMETER, SET_SELECTOR, BLOCK_SELECTOR, obj_cmd_rs) < 0) { if (state_data->prog_data->args->config_args.common.debug) pstdout_fprintf(state_data->pstate, stderr, "ipmi_cmd_get_sol_configuration_parameters_sol_authentication: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx))); if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR(state_data->ipmi_ctx)) rv = CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } _FIID_OBJ_GET (obj_cmd_rs, "sol_privilege_level", &val); sa->sol_privilege_level = val; _FIID_OBJ_GET (obj_cmd_rs, "force_sol_payload_authentication", &val); sa->force_sol_payload_authentication = val; _FIID_OBJ_GET (obj_cmd_rs, "force_sol_payload_encryption", &val); sa->force_sol_payload_encryption = val; rv = CONFIG_ERR_SUCCESS; cleanup: _FIID_OBJ_DESTROY(obj_cmd_rs); return (rv); }
static config_err_t sol_payload_port_checkout (const char *section_name, struct config_keyvalue *kv, void *arg) { bmc_config_state_data_t *state_data = (bmc_config_state_data_t *)arg; fiid_obj_t obj_cmd_rs = NULL; uint64_t val; config_err_t rv = CONFIG_ERR_FATAL_ERROR; config_err_t ret; uint8_t channel_number; _FIID_OBJ_CREATE(obj_cmd_rs, tmpl_cmd_get_sol_configuration_parameters_sol_payload_port_number_rs); if ((ret = get_sol_channel_number (state_data, &channel_number)) != CONFIG_ERR_SUCCESS) { rv = ret; goto cleanup; } if (ipmi_cmd_get_sol_configuration_parameters_sol_payload_port_number (state_data->ipmi_ctx, channel_number, IPMI_GET_SOL_PARAMETER, SET_SELECTOR, BLOCK_SELECTOR, obj_cmd_rs) < 0) { if (state_data->prog_data->args->config_args.common.debug) pstdout_fprintf(state_data->pstate, stderr, "ipmi_cmd_get_sol_configuration_parameters_sol_payload_port_number: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx))); if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR(state_data->ipmi_ctx)) rv = CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } _FIID_OBJ_GET (obj_cmd_rs, "port_number", &val); if (config_section_update_keyvalue_output_int(state_data->pstate, kv, val) < 0) return CONFIG_ERR_FATAL_ERROR; rv = CONFIG_ERR_SUCCESS; cleanup: _FIID_OBJ_DESTROY(obj_cmd_rs); return (rv); }
static config_err_t _get_sol_character_accumulate_interval_and_send_threshold (bmc_config_state_data_t *state_data, struct interval_and_threshold *it) { fiid_obj_t obj_cmd_rs = NULL; uint64_t val; config_err_t rv = CONFIG_ERR_FATAL_ERROR; config_err_t ret; uint8_t channel_number; assert(state_data); assert(it); _FIID_OBJ_CREATE(obj_cmd_rs, tmpl_cmd_get_sol_configuration_parameters_character_accumulate_interval_and_send_threshold_rs); if ((ret = get_sol_channel_number (state_data, &channel_number)) != CONFIG_ERR_SUCCESS) { rv = ret; goto cleanup; } if (ipmi_cmd_get_sol_configuration_parameters_character_accumulate_interval_and_send_threshold (state_data->ipmi_ctx, channel_number, IPMI_GET_SOL_PARAMETER, SET_SELECTOR, BLOCK_SELECTOR, obj_cmd_rs) < 0) { if (state_data->prog_data->args->config_args.common.debug) pstdout_fprintf(state_data->pstate, stderr, "ipmi_cmd_get_sol_configuration_parameters_character_accumulate_interval_and_send_threshold: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx))); if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR(state_data->ipmi_ctx)) rv = CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } _FIID_OBJ_GET (obj_cmd_rs, "character_accumulate_interval", &val); it->character_accumulate_interval = val; _FIID_OBJ_GET (obj_cmd_rs, "character_send_threshold", &val); it->character_send_threshold = val; rv = CONFIG_ERR_SUCCESS; cleanup: _FIID_OBJ_DESTROY(obj_cmd_rs); return (rv); }
static config_err_t _set_key(bmc_config_state_data_t *state_data, uint8_t key_type, uint8_t *key, uint32_t key_len) { fiid_obj_t obj_cmd_rs = NULL; config_err_t rv = CONFIG_ERR_FATAL_ERROR; config_err_t ret; uint8_t channel_number; assert(key_type == IPMI_CHANNEL_SECURITY_KEYS_KEY_ID_K_R || key_type == IPMI_CHANNEL_SECURITY_KEYS_KEY_ID_K_G); _FIID_OBJ_CREATE(obj_cmd_rs, tmpl_cmd_set_channel_security_keys_rs); if ((ret = get_lan_channel_number (state_data, &channel_number)) != CONFIG_ERR_SUCCESS) { rv = ret; goto cleanup; } if (ipmi_cmd_set_channel_security_keys (state_data->ipmi_ctx, channel_number, IPMI_CHANNEL_SECURITY_KEYS_OPERATION_SET_KEY, key_type, key, key_len, obj_cmd_rs) < 0) { if (state_data->prog_data->args->config_args.common.debug) pstdout_fprintf(state_data->pstate, stderr, "ipmi_cmd_set_channel_security_keys: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx))); if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR(state_data->ipmi_ctx)) rv = CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } rv = CONFIG_ERR_SUCCESS; cleanup: _FIID_OBJ_DESTROY(obj_cmd_rs); return (rv); }
static config_err_t sol_payload_port_commit (const char *section_name, const struct config_keyvalue *kv, void *arg) { bmc_config_state_data_t *state_data = (bmc_config_state_data_t *)arg; fiid_obj_t obj_cmd_rs = NULL; config_err_t rv = CONFIG_ERR_FATAL_ERROR; config_err_t ret; uint8_t channel_number; _FIID_OBJ_CREATE(obj_cmd_rs, tmpl_cmd_set_sol_configuration_parameters_rs); if ((ret = get_sol_channel_number (state_data, &channel_number)) != CONFIG_ERR_SUCCESS) { rv = ret; goto cleanup; } if (ipmi_cmd_set_sol_configuration_parameters_sol_payload_port_number (state_data->ipmi_ctx, channel_number, atoi (kv->value_input), obj_cmd_rs) < 0) { if (state_data->prog_data->args->config_args.common.debug) pstdout_fprintf(state_data->pstate, stderr, "ipmi_cmd_set_sol_configuration_parameters_sol_payload_port_number: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx))); if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR(state_data->ipmi_ctx)) rv = CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } rv = CONFIG_ERR_SUCCESS; cleanup: _FIID_OBJ_DESTROY(obj_cmd_rs); return (rv); }
static config_err_t _set_sol_sol_retry(bmc_config_state_data_t *state_data, struct sol_retry *sr) { fiid_obj_t obj_cmd_rs = NULL; config_err_t rv = CONFIG_ERR_FATAL_ERROR; config_err_t ret; uint8_t channel_number; _FIID_OBJ_CREATE(obj_cmd_rs, tmpl_cmd_set_sol_configuration_parameters_rs); if ((ret = get_sol_channel_number (state_data, &channel_number)) != CONFIG_ERR_SUCCESS) { rv = ret; goto cleanup; } if (ipmi_cmd_set_sol_configuration_parameters_sol_retry (state_data->ipmi_ctx, channel_number, sr->retry_count, sr->retry_interval, obj_cmd_rs) < 0) { if (state_data->prog_data->args->config_args.common.debug) pstdout_fprintf(state_data->pstate, stderr, "ipmi_cmd_set_sol_configuration_parameters_sol_retry: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx))); if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR(state_data->ipmi_ctx)) rv = CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } rv = CONFIG_ERR_SUCCESS; cleanup: _FIID_OBJ_DESTROY(obj_cmd_rs); return (rv); }
static config_err_t _get_alert_policy_table (struct pef_config_state_data *state_data, const char *section_name, struct alert_policy_table *apt) { fiid_obj_t obj_cmd_rs = NULL; uint64_t val; config_err_t rv = CONFIG_ERR_FATAL_ERROR; uint8_t alert_policy_entry_number; assert(state_data); assert(section_name); assert(apt); alert_policy_entry_number = atoi (section_name + strlen ("Alert_Policy_")); _FIID_OBJ_CREATE(obj_cmd_rs, tmpl_cmd_get_pef_configuration_parameters_alert_policy_table_rs); if (ipmi_cmd_get_pef_configuration_parameters_alert_policy_table (state_data->ipmi_ctx, IPMI_GET_PEF_PARAMETER, alert_policy_entry_number, BLOCK_SELECTOR, obj_cmd_rs) < 0) { if (state_data->prog_data->args->config_args.common.debug) pstdout_fprintf(state_data->pstate, stderr, "ipmi_cmd_get_pef_configuration_parameters_alert_policy_table: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx))); if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR(state_data->ipmi_ctx)) rv = CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } #if 0 _FIID_OBJ_GET (obj_cmd_rs, "alert_policy_entry_number", &val); #endif _FIID_OBJ_GET (obj_cmd_rs, "policy_number.policy_type", &val); apt->policy_type = val; _FIID_OBJ_GET (obj_cmd_rs, "policy_number.enabled", &val); apt->policy_enabled = val; _FIID_OBJ_GET (obj_cmd_rs, "policy_number.policy_number", &val); apt->policy_number = val; _FIID_OBJ_GET (obj_cmd_rs, "channel_destination.destination_selector", &val); apt->destination_selector = val; _FIID_OBJ_GET (obj_cmd_rs, "channel_destination.channel_number", &val); apt->channel_number = val; _FIID_OBJ_GET (obj_cmd_rs, "alert_string_key.alert_string_set_selector", &val); apt->alert_string_set_selector = val; _FIID_OBJ_GET (obj_cmd_rs, "alert_string_key.event_specific_alert_string", &val); apt->event_specific_alert_string = val; rv = CONFIG_ERR_SUCCESS; cleanup: _FIID_OBJ_DESTROY(obj_cmd_rs); return (rv); }
static config_err_t _set_alert_policy_table (struct pef_config_state_data *state_data, const char *section_name, struct alert_policy_table *apt) { fiid_obj_t obj_cmd_rs = NULL; config_err_t rv = CONFIG_ERR_FATAL_ERROR; uint8_t alert_policy_entry_number; assert(state_data); assert(section_name); assert(apt); alert_policy_entry_number = atoi (section_name + strlen ("Alert_Policy_")); _FIID_OBJ_CREATE(obj_cmd_rs, tmpl_cmd_set_pef_configuration_parameters_rs); if (ipmi_cmd_set_pef_configuration_parameters_alert_policy_table (state_data->ipmi_ctx, alert_policy_entry_number, apt->policy_type, apt->policy_enabled, apt->policy_number, apt->destination_selector, apt->channel_number, apt->alert_string_set_selector, apt->event_specific_alert_string, obj_cmd_rs) < 0) { if (state_data->prog_data->args->config_args.common.debug) pstdout_fprintf(state_data->pstate, stderr, "ipmi_cmd_set_pef_configuration_parameters_alert_policy_table: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx))); /* IPMI Workaround * * Fujitsu RX 100 S5 * * All fields have to be applied simultaneously, the motherboard * does not appear to like configuration of one field of a time, * always leading to invalid input errors. */ if (ipmi_ctx_errnum (state_data->ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE_REQUEST_DATA_INVALID && (ipmi_check_completion_code (obj_cmd_rs, IPMI_COMP_CODE_REQUEST_INVALID_DATA_FIELD) == 1)) { struct config_section *section = NULL; struct config_keyvalue *kv; unsigned int i; for (i = 0; i < state_data->alert_policy_sections_len; i++) { if (!strcasecmp (section_name, state_data->alert_policy_sections[i]->section_name)) { section = state_data->alert_policy_sections[i]; break; } } /* shouldn't be possible */ if (!section) goto cleanup; if ((kv = config_find_keyvalue (state_data->pstate, section, "Policy_Type"))) apt->policy_type = policy_type_number (kv->value_input); if ((kv = config_find_keyvalue (state_data->pstate, section, "Policy_Enabled"))) apt->policy_enabled = same (kv->value_input, "yes"); if ((kv = config_find_keyvalue (state_data->pstate, section, "Policy_Number"))) apt->policy_number = atoi (kv->value_input); if ((kv = config_find_keyvalue (state_data->pstate, section, "Destination_Selector"))) apt->destination_selector = atoi (kv->value_input); if ((kv = config_find_keyvalue (state_data->pstate, section, "Channel_Number"))) apt->channel_number = atoi (kv->value_input); if ((kv = config_find_keyvalue (state_data->pstate, section, "Alert_String_Set_Selector"))) apt->alert_string_set_selector = atoi (kv->value_input); if ((kv = config_find_keyvalue (state_data->pstate, section, "Event_Specific_Alert_String"))) apt->event_specific_alert_string = same (kv->value_input, "yes"); if (state_data->prog_data->args->config_args.common.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_set_pef_configuration_parameters_alert_policy_table: attempting workaround\n"); if (ipmi_cmd_set_pef_configuration_parameters_alert_policy_table (state_data->ipmi_ctx, alert_policy_entry_number, apt->policy_type, apt->policy_enabled, apt->policy_number, apt->destination_selector, apt->channel_number, apt->alert_string_set_selector, apt->event_specific_alert_string, obj_cmd_rs) < 0) { if (state_data->prog_data->args->config_args.common.debug) pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_set_pef_configuration_parameters_alert_policy_table: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx))); if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR(state_data->ipmi_ctx)) rv = CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } /* success */ goto out; } else if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR(state_data->ipmi_ctx)) rv = CONFIG_ERR_NON_FATAL_ERROR; goto cleanup; } out: rv = CONFIG_ERR_SUCCESS; cleanup: _FIID_OBJ_DESTROY(obj_cmd_rs); return (rv); }
static int ipmi_free_open(struct ipmi_intf * intf) { if (getuid() != 0) { fprintf(stderr, "Permission denied, must be root\n"); return -1; } #if IPMI_INTF_FREE_0_3_0 if (!(dev = ipmi_open_inband (IPMI_DEVICE_KCS, 0, 0, 0, NULL, IPMI_FLAGS_DEFAULT))) { if (!(dev = ipmi_open_inband (IPMI_DEVICE_SSIF, 0, 0, 0, NULL, IPMI_FLAGS_DEFAULT))) { perror("ipmi_open_inband()"); goto cleanup; } } #elif IPMI_INTF_FREE_0_4_0 if (!(dev = ipmi_device_create())) { perror("ipmi_device_create"); goto cleanup; } if (ipmi_open_inband (dev, IPMI_DEVICE_KCS, 0, 0, 0, NULL, IPMI_FLAGS_DEFAULT) < 0) { if (ipmi_open_inband (dev, IPMI_DEVICE_SSIF, 0, 0, 0, NULL, IPMI_FLAGS_DEFAULT) < 0) { fprintf(stderr, "ipmi_open_inband(): %s\n", ipmi_device_strerror(ipmi_device_errnum(dev))); goto cleanup; } } #elif IPMI_INTF_FREE_0_5_0 if (!(dev = ipmi_device_create())) { perror("ipmi_device_create"); goto cleanup; } if (ipmi_open_inband (dev, IPMI_DEVICE_KCS, 0, 0, 0, NULL, 0, IPMI_FLAGS_DEFAULT) < 0) { if (ipmi_open_inband (dev, IPMI_DEVICE_SSIF, 0, 0, 0, NULL, 0, IPMI_FLAGS_DEFAULT) < 0) { fprintf(stderr, "ipmi_open_inband(): %s\n", ipmi_device_strerror(ipmi_device_errnum(dev))); goto cleanup; } } #elif IPMI_INTF_FREE_0_6_0 if (!(dev = ipmi_ctx_create())) { perror("ipmi_ctx_create"); goto cleanup; } if (ipmi_ctx_open_inband (dev, IPMI_DEVICE_KCS, 0, 0, 0, NULL, 0, IPMI_FLAGS_DEFAULT) < 0) { if (ipmi_ctx_open_inband (dev, IPMI_DEVICE_SSIF, 0, 0, 0, NULL, 0, IPMI_FLAGS_DEFAULT) < 0) { fprintf(stderr, "ipmi_open_inband(): %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); goto cleanup; } } #endif intf->opened = 1; return 0; cleanup: if (dev) { #if IPMI_INTF_FREE_0_3_0 ipmi_close_device(dev); #elif IPMI_INTF_FREE_0_4_0 || IPMI_INTF_FREE_0_5_0 ipmi_close_device(dev); ipmi_device_destroy(dev); #elif IPMI_INTF_FREE_0_6_0 ipmi_ctx_close(dev); ipmi_ctx_destroy(dev); #endif } return -1; }
static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) { u_int8_t lun = 0; u_int8_t cmd = req->msg.cmd; u_int8_t netfn = req->msg.netfn; u_int8_t rq_buf[IPMI_BUF_SIZE]; u_int8_t rs_buf[IPMI_BUF_SIZE]; u_int32_t rs_buf_len = IPMI_BUF_SIZE; int32_t rs_len; static struct ipmi_rs rsp; /* achu: FreeIPMI requests have the cmd as the first byte of * the data. Responses have cmd as the first byte and * completion code as the second byte. This differs from some * other APIs, so it must be compensated for within the ipmitool * interface. */ if (!intf || !req) return NULL; if (!intf->opened && intf->open && intf->open(intf) < 0) return NULL; if (req->msg.data_len > IPMI_BUF_SIZE) return NULL; memset(rq_buf, '\0', IPMI_BUF_SIZE); memset(rs_buf, '\0', IPMI_BUF_SIZE); memcpy(rq_buf, &cmd, 1); if (req->msg.data) memcpy(rq_buf + 1, req->msg.data, req->msg.data_len); if ((rs_len = ipmi_cmd_raw(dev, lun, netfn, rq_buf, req->msg.data_len + 1, rs_buf, rs_buf_len)) < 0) { #if IPMI_INTF_FREE_0_3_0 perror("ipmi_cmd_raw"); #elif IPMI_INTF_FREE_0_4_0 || IPMI_INTF_FREE_0_5_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_device_strerror(ipmi_device_errnum(dev))); #elif IPMI_INTF_FREE_0_6_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); #endif return NULL; } memset(&rsp, 0, sizeof(struct ipmi_rs)); rsp.ccode = (unsigned char)rs_buf[1]; rsp.data_len = (int)rs_len - 2; if (!rsp.ccode && rsp.data_len) memcpy(rsp.data, rs_buf + 2, rsp.data_len); return &rsp; }
ipmi_ctx_t ipmi_open (const char *progname, const char *hostname, struct common_cmd_args *common_args, pstdout_state_t pstate) { ipmi_ctx_t ipmi_ctx = NULL; unsigned int workaround_flags = 0; assert (progname); assert (common_args); if (!(ipmi_ctx = ipmi_ctx_create ())) { PSTDOUT_FPRINTF (pstate, stderr, "ipmi_ctx_create: %s", strerror (errno)); goto cleanup; } if (hostname && strcasecmp (hostname, "localhost") != 0 && strcmp (hostname, "127.0.0.1") != 0) { if (common_args->driver_type == IPMI_DEVICE_LAN_2_0) { parse_get_freeipmi_outofband_2_0_flags (common_args->workaround_flags_outofband_2_0, &workaround_flags); if (ipmi_ctx_open_outofband_2_0 (ipmi_ctx, hostname, common_args->username, common_args->password, (common_args->k_g_len) ? common_args->k_g : NULL, (common_args->k_g_len) ? common_args->k_g_len : 0, common_args->privilege_level, common_args->cipher_suite_id, common_args->session_timeout, common_args->retransmission_timeout, workaround_flags, (common_args->debug) ? IPMI_FLAGS_DEBUG_DUMP : IPMI_FLAGS_DEFAULT) < 0) { if (ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_USERNAME_INVALID || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PASSWORD_INVALID || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_K_G_INVALID || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_INSUFFICIENT || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_AUTHENTICATION_TYPE_UNAVAILABLE || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_CIPHER_SUITE_ID_UNAVAILABLE || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PASSWORD_VERIFICATION_TIMEOUT || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_HOSTNAME_INVALID || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_IPMI_2_0_UNAVAILABLE || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_CONNECTION_TIMEOUT) PSTDOUT_FPRINTF (pstate, stderr, "%s: %s\n", progname, ipmi_ctx_errormsg (ipmi_ctx)); else PSTDOUT_FPRINTF (pstate, stderr, "ipmi_ctx_open_outofband_2_0: %s\n", ipmi_ctx_errormsg (ipmi_ctx)); goto cleanup; } } else { parse_get_freeipmi_outofband_flags (common_args->workaround_flags_outofband, &workaround_flags); if (ipmi_ctx_open_outofband (ipmi_ctx, hostname, common_args->username, common_args->password, common_args->authentication_type, common_args->privilege_level, common_args->session_timeout, common_args->retransmission_timeout, workaround_flags, (common_args->debug) ? IPMI_FLAGS_DEBUG_DUMP : IPMI_FLAGS_DEFAULT) < 0) { if (ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_USERNAME_INVALID || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PASSWORD_INVALID || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_INSUFFICIENT || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_AUTHENTICATION_TYPE_UNAVAILABLE || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PASSWORD_VERIFICATION_TIMEOUT || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_HOSTNAME_INVALID || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_CONNECTION_TIMEOUT) PSTDOUT_FPRINTF (pstate, stderr, "%s: %s\n", progname, ipmi_ctx_errormsg (ipmi_ctx)); else PSTDOUT_FPRINTF (pstate, stderr, "ipmi_ctx_open_outofband: %s\n", ipmi_ctx_errormsg (ipmi_ctx)); goto cleanup; } } } else { if (!ipmi_is_root ()) { PSTDOUT_FPRINTF (pstate, stderr, "%s: %s\n", progname, ipmi_ctx_strerror (IPMI_ERR_PERMISSION)); goto cleanup; } parse_get_freeipmi_inband_flags (common_args->workaround_flags_inband, &workaround_flags); if (common_args->driver_type == IPMI_DEVICE_UNKNOWN) { int ret; if ((ret = ipmi_ctx_find_inband (ipmi_ctx, NULL, common_args->disable_auto_probe, common_args->driver_address, common_args->register_spacing, common_args->driver_device, workaround_flags, (common_args->debug) ? IPMI_FLAGS_DEBUG_DUMP : IPMI_FLAGS_DEFAULT)) < 0) { PSTDOUT_FPRINTF (pstate, stderr, "ipmi_ctx_find_inband: %s\n", ipmi_ctx_errormsg (ipmi_ctx)); goto cleanup; } if (!ret) { PSTDOUT_FPRINTF (pstate, stderr, "could not find inband device"); goto cleanup; } } else { if (ipmi_ctx_open_inband (ipmi_ctx, common_args->driver_type, common_args->disable_auto_probe, common_args->driver_address, common_args->register_spacing, common_args->driver_device, workaround_flags, (common_args->debug) ? IPMI_FLAGS_DEBUG_DUMP : IPMI_FLAGS_DEFAULT) < 0) { if (ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_DEVICE_NOT_FOUND) PSTDOUT_FPRINTF (pstate, stderr, "%s: %s\n", progname, ipmi_ctx_errormsg (ipmi_ctx)); else PSTDOUT_FPRINTF (pstate, stderr, "ipmi_ctx_open_inband: %s\n", ipmi_ctx_errormsg (ipmi_ctx)); goto cleanup; } } } if (common_args->target_channel_number_is_set || common_args->target_slave_address_is_set) { if (ipmi_ctx_set_target (ipmi_ctx, common_args->target_channel_number_is_set ? &common_args->target_channel_number : NULL, common_args->target_slave_address_is_set ? &common_args->target_slave_address : NULL) < 0) { PSTDOUT_FPRINTF (pstate, stderr, "ipmi_ctx_set_target: %s\n", ipmi_ctx_errormsg (ipmi_ctx)); goto cleanup; } } return (ipmi_ctx); cleanup: ipmi_ctx_close (ipmi_ctx); ipmi_ctx_destroy (ipmi_ctx); return (NULL); }
int ipmi_sensors_get_thresholds (ipmi_sensors_state_data_t *state_data, uint8_t *sdr_record, unsigned int sdr_record_len, double **lower_non_critical_threshold, double **lower_critical_threshold, double **lower_non_recoverable_threshold, double **upper_non_critical_threshold, double **upper_critical_threshold, double **upper_non_recoverable_threshold) { int8_t r_exponent, b_exponent; int16_t m, b; uint8_t linearization, analog_data_format; uint8_t sensor_number; fiid_obj_t obj_cmd_rs = NULL; double *tmp_lower_non_critical_threshold = NULL; double *tmp_lower_critical_threshold = NULL; double *tmp_lower_non_recoverable_threshold = NULL; double *tmp_upper_non_critical_threshold = NULL; double *tmp_upper_critical_threshold = NULL; double *tmp_upper_non_recoverable_threshold = NULL; double threshold; uint8_t threshold_access_support; uint64_t val; int rv = -1; assert(state_data); assert(sdr_record); assert(sdr_record_len); if (lower_non_critical_threshold) *lower_non_critical_threshold = NULL; if (lower_critical_threshold) *lower_critical_threshold = NULL; if (lower_non_recoverable_threshold) *lower_non_recoverable_threshold = NULL; if (upper_non_critical_threshold) *upper_non_critical_threshold = NULL; if (upper_critical_threshold) *upper_critical_threshold = NULL; if (upper_non_recoverable_threshold) *upper_non_recoverable_threshold = NULL; /* achu: first lets check if we have anything to output */ if (sdr_cache_get_sensor_capabilities (state_data->pstate, sdr_record, sdr_record_len, NULL, &threshold_access_support, NULL, NULL, NULL) < 0) goto cleanup; if (threshold_access_support == IPMI_SDR_NO_THRESHOLDS_SUPPORT || threshold_access_support == IPMI_SDR_FIXED_UNREADABLE_THRESHOLDS_SUPPORT) { rv = 0; goto cleanup; } /* achu: * * I will admit I'm not entirely sure what the best way is * to get thresholds. It seems the information is * stored/retrievable in the SDR and through an IPMI command. * * Since the readable_threshold_mask in the SDR record indicates the * mask is for the "Get Sensor Thresholds" command, it suggests the * best/right way is to get the values via that command. Sounds * good to me. Also, I suppose its possible that changes to the * thresholds may not be written to the SDR. * * Also, because the results from the get_sensor_thresholds include * readability flags, we can ignore the readability flags in the * SDR. * */ if (sdr_cache_get_sensor_number (state_data->pstate, sdr_record, sdr_record_len, &sensor_number) < 0) goto cleanup; if (sdr_cache_get_sensor_decoding_data(state_data->pstate, sdr_record, sdr_record_len, &r_exponent, &b_exponent, &m, &b, &linearization, &analog_data_format) < 0) goto cleanup; /* if the sensor is not analog, this is most likely a bug in the * SDR, since we shouldn't be decoding a non-threshold sensor. * * Don't return an error. Allow code to output "NA" or something. */ if (!IPMI_SDR_ANALOG_DATA_FORMAT_VALID(analog_data_format)) { if (state_data->prog_data->args->common.debug) pstdout_fprintf(state_data->pstate, stderr, "Attempting to decode non-analog sensor\n"); rv = 0; goto cleanup; } /* if the sensor is non-linear, I just don't know what to do * * Don't return an error. Allow code to output "NA" or something. */ if (!IPMI_SDR_LINEARIZATION_IS_LINEAR(linearization)) { if (state_data->prog_data->args->common.debug) pstdout_fprintf(state_data->pstate, stderr, "Cannot decode non-linear sensor\n"); rv = 0; goto cleanup; } _FIID_OBJ_CREATE(obj_cmd_rs, tmpl_cmd_get_sensor_thresholds_rs); if (ipmi_cmd_get_sensor_thresholds (state_data->ipmi_ctx, sensor_number, obj_cmd_rs) < 0) { if (state_data->prog_data->args->common.debug) pstdout_fprintf(state_data->pstate, stderr, "ipmi_cmd_get_sensor_thresholds: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx))); if ((ipmi_ctx_errnum(state_data->ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE_REQUEST_DATA_INVALID) && (ipmi_check_completion_code(obj_cmd_rs, IPMI_COMP_CODE_COMMAND_ILLEGAL_FOR_SENSOR_OR_RECORD_TYPE) == 1 || ipmi_check_completion_code(obj_cmd_rs, IPMI_COMP_CODE_REQUEST_SENSOR_DATA_OR_RECORD_NOT_PRESENT) == 1)) { /* The thresholds cannot be gathered for one reason or * another, maybe b/c its a OEM sensor or something. We can * return 0 gracefully. */ rv = 0; goto cleanup; } /* * IPMI Workaround (achu) * * Discovered on HP DL585 * * Seems that the HP machine doesn't support the "Get Sensor * Thresholds" command. When this occurs, we assume the * information in the SDR is legit and up to date. Go get it * and fill in the object respectively. */ if ((ipmi_ctx_errnum(state_data->ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE_INVALID_COMMAND) && (ipmi_check_completion_code(obj_cmd_rs, IPMI_COMP_CODE_COMMAND_INVALID) == 1)) { if (state_data->prog_data->args->common.debug) pstdout_fprintf(state_data->pstate, stderr, "Get Sensor Thresholds failed, using SDR information\n"); if (_get_sdr_sensor_thresholds (state_data, sdr_record, sdr_record_len, obj_cmd_rs) < 0) goto cleanup; goto continue_get_sensor_thresholds; } goto cleanup; } continue_get_sensor_thresholds: if (lower_non_critical_threshold) { _FIID_OBJ_GET (obj_cmd_rs, "readable_thresholds.lower_non_critical_threshold", &val); if (val) { _FIID_OBJ_GET(obj_cmd_rs, "lower_non_critical_threshold", &val); if (ipmi_sensor_decode_value (r_exponent, b_exponent, m, b, linearization, analog_data_format, val, &threshold) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sensor_decode_value: %s\n", strerror(errno)); goto cleanup; } if (!(tmp_lower_non_critical_threshold = (double *)malloc(sizeof(double)))) { pstdout_perror(state_data->pstate, "malloc"); goto cleanup; } *tmp_lower_non_critical_threshold = threshold; } } if (lower_critical_threshold) { _FIID_OBJ_GET (obj_cmd_rs, "readable_thresholds.lower_critical_threshold", &val); if (val) { _FIID_OBJ_GET(obj_cmd_rs, "lower_critical_threshold", &val); if (ipmi_sensor_decode_value (r_exponent, b_exponent, m, b, linearization, analog_data_format, val, &threshold) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sensor_decode_value: %s\n", strerror(errno)); goto cleanup; } if (!(tmp_lower_critical_threshold = (double *)malloc(sizeof(double)))) { pstdout_perror(state_data->pstate, "malloc"); goto cleanup; } *tmp_lower_critical_threshold = threshold; } } if (lower_non_recoverable_threshold) { _FIID_OBJ_GET (obj_cmd_rs, "readable_thresholds.lower_non_recoverable_threshold", &val); if (val) { _FIID_OBJ_GET(obj_cmd_rs, "lower_non_recoverable_threshold", &val); if (ipmi_sensor_decode_value (r_exponent, b_exponent, m, b, linearization, analog_data_format, val, &threshold) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sensor_decode_value: %s\n", strerror(errno)); goto cleanup; } if (!(tmp_lower_non_recoverable_threshold = (double *)malloc(sizeof(double)))) { pstdout_perror(state_data->pstate, "malloc"); goto cleanup; } *tmp_lower_non_recoverable_threshold = threshold; } } if (upper_non_critical_threshold) { _FIID_OBJ_GET (obj_cmd_rs, "readable_thresholds.upper_non_critical_threshold", &val); if (val) { _FIID_OBJ_GET(obj_cmd_rs, "upper_non_critical_threshold", &val); if (ipmi_sensor_decode_value (r_exponent, b_exponent, m, b, linearization, analog_data_format, val, &threshold) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sensor_decode_value: %s\n", strerror(errno)); goto cleanup; } if (!(tmp_upper_non_critical_threshold = (double *)malloc(sizeof(double)))) { pstdout_perror(state_data->pstate, "malloc"); goto cleanup; } *tmp_upper_non_critical_threshold = threshold; } } if (upper_critical_threshold) { _FIID_OBJ_GET (obj_cmd_rs, "readable_thresholds.upper_critical_threshold", &val); if (val) { _FIID_OBJ_GET(obj_cmd_rs, "upper_critical_threshold", &val); if (ipmi_sensor_decode_value (r_exponent, b_exponent, m, b, linearization, analog_data_format, val, &threshold) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sensor_decode_value: %s\n", strerror(errno)); goto cleanup; } if (!(tmp_upper_critical_threshold = (double *)malloc(sizeof(double)))) { pstdout_perror(state_data->pstate, "malloc"); goto cleanup; } *tmp_upper_critical_threshold = threshold; } } if (upper_non_recoverable_threshold) { _FIID_OBJ_GET (obj_cmd_rs, "readable_thresholds.upper_non_recoverable_threshold", &val); if (val) { _FIID_OBJ_GET(obj_cmd_rs, "upper_non_recoverable_threshold", &val); if (ipmi_sensor_decode_value (r_exponent, b_exponent, m, b, linearization, analog_data_format, val, &threshold) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sensor_decode_value: %s\n", strerror(errno)); goto cleanup; } if (!(tmp_upper_non_recoverable_threshold = (double *)malloc(sizeof(double)))) { pstdout_perror(state_data->pstate, "malloc"); goto cleanup; } *tmp_upper_non_recoverable_threshold = threshold; } } if (lower_non_critical_threshold) *lower_non_critical_threshold = tmp_lower_non_critical_threshold; if (lower_critical_threshold) *lower_critical_threshold = tmp_lower_critical_threshold; if (lower_non_recoverable_threshold) *lower_non_recoverable_threshold = tmp_lower_non_recoverable_threshold; if (upper_non_critical_threshold) *upper_non_critical_threshold = tmp_upper_non_critical_threshold; if (upper_critical_threshold) *upper_critical_threshold = tmp_upper_critical_threshold; if (upper_non_recoverable_threshold) *upper_non_recoverable_threshold = tmp_upper_non_recoverable_threshold; rv = 0; cleanup: _FIID_OBJ_DESTROY(obj_cmd_rs); if (rv < 0) { if (tmp_lower_non_critical_threshold) free(tmp_lower_non_critical_threshold); if (tmp_lower_critical_threshold) free(tmp_lower_critical_threshold); if (tmp_lower_non_recoverable_threshold) free(tmp_lower_non_recoverable_threshold); if (tmp_upper_non_critical_threshold) free(tmp_upper_non_critical_threshold); if (tmp_upper_critical_threshold) free(tmp_upper_critical_threshold); if (tmp_upper_non_recoverable_threshold) free(tmp_upper_non_recoverable_threshold); } return rv; }
static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) { u_int8_t lun = req->msg.lun; u_int8_t cmd = req->msg.cmd; u_int8_t netfn = req->msg.netfn; u_int8_t rq_buf[IPMI_BUF_SIZE]; u_int8_t rs_buf[IPMI_BUF_SIZE]; u_int32_t rs_buf_len = IPMI_BUF_SIZE; int32_t rs_len; static struct ipmi_rs rsp; /* achu: FreeIPMI requests have the cmd as the first byte of * the data. Responses have cmd as the first byte and * completion code as the second byte. This differs from some * other APIs, so it must be compensated for within the ipmitool * interface. */ if (!intf || !req) return NULL; if (!intf->opened && intf->open && intf->open(intf) < 0) return NULL; if (req->msg.data_len > IPMI_BUF_SIZE) return NULL; memset(rq_buf, '\0', IPMI_BUF_SIZE); memset(rs_buf, '\0', IPMI_BUF_SIZE); memcpy(rq_buf, &cmd, 1); if (req->msg.data) memcpy(rq_buf + 1, req->msg.data, req->msg.data_len); if (intf->target_addr != 0 && intf->target_addr != IPMI_BMC_SLAVE_ADDR) { #if IPMI_INTF_FREE_BRIDGING if ((rs_len = ipmi_cmd_raw_ipmb(dev, intf->target_channel, intf->target_addr, lun, netfn, rq_buf, req->msg.data_len + 1, rs_buf, rs_buf_len)) < 0) { if (verbose > 3) fprintf(stderr, "ipmi_cmd_raw_ipmb: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); /* Compared to FreeIPMI, user is expected to input * the target channel on the command line, it is not automatically * discovered. So that is the likely cause of an error. * * Instead of returning an error, return a bad response so output * of ipmitool commands looks like other interfaces */ rs_len = 2; rs_buf[0] = 0; rs_buf[1] = 0xC1; /* invalid command */ } #else /* !IPMI_INTF_FREE_BRIDGING */ if (verbose > 3) fprintf(stderr, "sensor bridging not supported in this driver version"); /* instead of returning an error, return a bad response so output * of ipmitool commands looks like other interfaces */ rs_len = 2; rs_buf[0] = 0; rs_buf[1] = 0xC1; /* invalid command */ #endif /* !IPMI_INTF_FREE_BRIDGING */ } else { if ((rs_len = ipmi_cmd_raw(dev, lun, netfn, rq_buf, req->msg.data_len + 1, rs_buf, rs_buf_len)) < 0) { #if IPMI_INTF_FREE_0_3_0 perror("ipmi_cmd_raw"); #elif IPMI_INTF_FREE_0_4_0 || IPMI_INTF_FREE_0_5_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_device_strerror(ipmi_device_errnum(dev))); #elif IPMI_INTF_FREE_0_6_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); #endif return NULL; } } memset(&rsp, 0, sizeof(struct ipmi_rs)); rsp.ccode = (unsigned char)rs_buf[1]; rsp.data_len = (int)rs_len - 2; if (!rsp.ccode && rsp.data_len) memcpy(rsp.data, rs_buf + 2, rsp.data_len); return &rsp; }