int
ipmiconsole_check_requester_sequence_number (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint8_t req_seq, expected_req_seq;
    uint64_t val;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (IPMICONSOLE_PACKET_TYPE_RESPONSE (p));
    assert (p == IPMICONSOLE_PACKET_TYPE_GET_AUTHENTICATION_CAPABILITIES_RS
            || p == IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RS
            || p == IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RS
            || p == IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RS);

    if (FIID_OBJ_GET (c->connection.obj_lan_msg_hdr_rs,
                      "rq_seq",
                      &val) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'rq_seq': %s",
                                   fiid_obj_errormsg (c->connection.obj_lan_msg_hdr_rs)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }
    req_seq = val;
    expected_req_seq = c->session.requester_sequence_number;

    if (req_seq != expected_req_seq)
        IPMICONSOLE_CTX_DEBUG (c, ("requester sequence number check failed; p = %d; req_seq = %Xh; expected_req_seq = %Xh", p, req_seq, expected_req_seq));

    return ((req_seq == expected_req_seq) ? 1 : 0);
}
int
ipmiconsole_check_message_tag (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint8_t message_tag, expected_message_tag;
    fiid_obj_t obj_cmd;
    uint64_t val;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (IPMICONSOLE_PACKET_TYPE_RESPONSE (p));
    assert (p == IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_RESPONSE
            || p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_2
            || p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_4);

    obj_cmd = ipmiconsole_packet_object (c, p);
    if (FIID_OBJ_GET (obj_cmd,
                      "message_tag",
                      &val) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'message_tag': %s",
                                   fiid_obj_errormsg (obj_cmd)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }
    message_tag = val;
    expected_message_tag = c->session.message_tag;

    if (message_tag != expected_message_tag)
        IPMICONSOLE_CTX_DEBUG (c, ("message tag check failed; p = %d", p));

    return ((message_tag == expected_message_tag) ? 1 : 0);
}
int
ipmiconsole_check_network_function (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint8_t netfn, expected_netfn;
    uint64_t val;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (IPMICONSOLE_PACKET_TYPE_RESPONSE (p));
    assert (p == IPMICONSOLE_PACKET_TYPE_GET_AUTHENTICATION_CAPABILITIES_RS
            || p == IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RS
            || p == IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RS
            || p == IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RS);

    if (FIID_OBJ_GET (c->connection.obj_lan_msg_hdr_rs,
                      "net_fn",
                      &val) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'net_fn': %s",
                                   fiid_obj_errormsg (c->connection.obj_lan_msg_hdr_rs)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }
    netfn = val;
    expected_netfn = IPMI_NET_FN_APP_RS;

    if (netfn != expected_netfn)
        IPMICONSOLE_CTX_DEBUG (c, ("network function check failed; p = %d; netfn = %Xh; expected_netfn = %Xh", p, netfn, expected_netfn));

    return ((netfn == expected_netfn) ? 1 : 0);
}
int
ipmiconsole_check_rmcpplus_status_code (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint8_t rmcpplus_status_code;
    uint64_t val;
    fiid_obj_t obj_cmd;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (IPMICONSOLE_PACKET_TYPE_RESPONSE (p));
    assert (p == IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_RESPONSE
            || p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_2
            || p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_4);

    obj_cmd = ipmiconsole_packet_object (c, p);
    if (FIID_OBJ_GET (obj_cmd,
                      "rmcpplus_status_code",
                      &val) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'rmcpplus_status_code': %s",
                                   fiid_obj_errormsg (obj_cmd)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }
    rmcpplus_status_code = val;

    if (rmcpplus_status_code != RMCPPLUS_STATUS_NO_ERRORS)
        IPMICONSOLE_CTX_DEBUG (c, ("rmcpplus status code check failed; p = %d", p));

    return ((rmcpplus_status_code == RMCPPLUS_STATUS_NO_ERRORS) ? 1 : 0);
}
int
ipmiconsole_check_outbound_sequence_number (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint32_t session_sequence_number;
    uint64_t val;
    int rv = 0;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (IPMICONSOLE_PACKET_TYPE_RESPONSE (p));
    assert (p == IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RS
            || p == IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_SOL_PAYLOAD_DATA_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RS
            || p == IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RS);

    if (FIID_OBJ_GET (c->connection.obj_rmcpplus_session_hdr_rs,
                      "session_sequence_number",
                      &val) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'session_sequence_number': %s",
                                   fiid_obj_errormsg (c->connection.obj_rmcpplus_session_hdr_rs)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }
    session_sequence_number = val;

    if ((rv = ipmi_check_session_sequence_number_2_0 (session_sequence_number,
              &(c->session.highest_received_sequence_number),
              &(c->session.previously_received_list),
              0)) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("ipmi_check_session_sequence_number_2_0: 'session_sequence_number': %s",
                                   fiid_obj_errormsg (c->connection.obj_rmcpplus_session_hdr_rs)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }

    if (!rv)
        IPMICONSOLE_CTX_DEBUG (c, ("session sequence number check failed; p = %d; session_sequence_number = %u; highest_received_sequence_number = %u", p, session_sequence_number, c->session.highest_received_sequence_number));

    return (rv);
}
Exemple #6
0
static void
_fiid_obj_get(fiid_obj_t obj_cmd_rs, const char *field, uint64_t *val)
{
  uint64_t valtemp;

  if (FIID_OBJ_GET (obj_cmd_rs, field, &valtemp) < 0)
    err_exit ("fiid_obj_get: '%s': %s", field, fiid_obj_errormsg (obj_cmd_rs));

  (*val) = valtemp;
}
int
ipmiconsole_check_payload_type (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint8_t payload_type, expected_payload_type;
    uint64_t val;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (IPMICONSOLE_PACKET_TYPE_RESPONSE (p));
    assert (p == IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_RESPONSE
            || p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_2
            || p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_4
            || p == IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RS
            || p == IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_SOL_PAYLOAD_DATA_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RS
            || p == IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RS);

    if (FIID_OBJ_GET (c->connection.obj_rmcpplus_session_hdr_rs,
                      "payload_type",
                      &val) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'payload_type': %s",
                                   fiid_obj_errormsg (c->connection.obj_rmcpplus_session_hdr_rs)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }
    payload_type = val;

    if (p == IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_RESPONSE)
        expected_payload_type = IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_RESPONSE;
    else if (p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_2)
        expected_payload_type = IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_2;
    else if (p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_4)
        expected_payload_type = IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_4;
    else if (p == IPMICONSOLE_PACKET_TYPE_SOL_PAYLOAD_DATA_RS)
        expected_payload_type = IPMI_PAYLOAD_TYPE_SOL;
    else
        expected_payload_type = IPMI_PAYLOAD_TYPE_IPMI;

    if (payload_type != expected_payload_type)
        IPMICONSOLE_CTX_DEBUG (c, ("payload type check failed; p = %d; payload_type = %Xh; expected_payload_type = %Xh", p, payload_type, expected_payload_type));

    return ((payload_type == expected_payload_type) ? 1 : 0);
}
int
ipmiconsole_check_open_session_response_privilege (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    int rv;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (p == IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_RESPONSE);

    /* IPMI Workaround
     *
     * Intel IPMI 2.0 implementations don't support the highest level privilege.
     */
    if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_INTEL_2_0_SESSION)
    {
        uint8_t maximum_privilege_level;
        uint64_t val;

        if (FIID_OBJ_GET (c->connection.obj_open_session_response,
                          "maximum_privilege_level",
                          &val) < 0)
        {
            IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'maximum_privilege_level': %s",
                                       fiid_obj_errormsg (c->connection.obj_open_session_response)));
            ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
            return (-1);
        }
        maximum_privilege_level = val;

        rv = (maximum_privilege_level == c->config.privilege_level) ? 1 : 0;
    }
    else
    {
        if ((rv = ipmi_check_open_session_maximum_privilege (c->config.privilege_level,
                  c->connection.obj_open_session_response)) < 0)
        {
            IPMICONSOLE_CTX_DEBUG (c, ("ipmi_check_open_session_maximum_privilege: %s",
                                       strerror (errno)));
            ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
            return (-1);
        }
    }

    if (!rv)
        IPMICONSOLE_CTX_DEBUG (c, ("open session response privilege check failed; p = %d", p));

    return (rv);
}
int
ipmiconsole_check_packet (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    fiid_obj_t obj_cmd;
    int rv;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (IPMICONSOLE_PACKET_TYPE_RESPONSE (p));

    obj_cmd = ipmiconsole_packet_object (c, p);
    if ((rv = fiid_obj_packet_valid (obj_cmd)) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_packet_valid: %s",
                                   fiid_obj_errormsg (obj_cmd)));
        return (-1);
    }

    if (!rv)
        IPMICONSOLE_CTX_DEBUG (c, ("invalid packet received; p = %d", p));

    return (rv);
}
int
ipmiconsole_check_completion_code (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint8_t comp_code;
    fiid_obj_t obj_cmd;
    uint64_t val;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (IPMICONSOLE_PACKET_TYPE_RESPONSE (p));
    assert (p == IPMICONSOLE_PACKET_TYPE_GET_AUTHENTICATION_CAPABILITIES_RS
            || p == IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RS
            || p == IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RS
            || p == IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RS);

    obj_cmd = ipmiconsole_packet_object (c, p);
    if (FIID_OBJ_GET (obj_cmd,
                      "comp_code",
                      &val) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'comp_code': %s",
                                   fiid_obj_errormsg (obj_cmd)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }
    comp_code = val;

    if (comp_code != IPMI_COMP_CODE_COMMAND_SUCCESS)
        IPMICONSOLE_CTX_DEBUG (c, ("completion code check failed; p = %d; comp_code = %Xh", p, comp_code));

    return ((comp_code == IPMI_COMP_CODE_COMMAND_SUCCESS) ? 1 : 0);
}
static ipmi_config_err_t
_get_connection_mode (ipmi_config_state_data_t *state_data,
                      const char *section_name,
                      struct connection_mode *cm)
{
  fiid_obj_t obj_cmd_rs = NULL;
  uint64_t val;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
  ipmi_config_err_t ret;
  uint8_t channel_number;

  assert (state_data);
  assert (section_name);
  assert (cm);

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_serial_modem_configuration_connection_mode_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  if ((ret = get_serial_channel_number (state_data, section_name, &channel_number)) != IPMI_CONFIG_ERR_SUCCESS)
    {
      rv = ret;
      goto cleanup;
    }

  if (ipmi_cmd_get_serial_modem_configuration_connection_mode (state_data->ipmi_ctx,
                                                               channel_number,
                                                               IPMI_GET_SERIAL_MODEM_PARAMETER,
                                                               IPMI_SERIAL_MODEM_CONFIGURATION_NO_SET_SELECTOR,
                                                               IPMI_SERIAL_MODEM_CONFIGURATION_NO_BLOCK_SELECTOR,
                                                               obj_cmd_rs) < 0)
    {
      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_serial_modem_configuration_connection_mode: %s\n",
                         ipmi_ctx_errormsg (state_data->ipmi_ctx));

      goto cleanup;
    }

  if (FIID_OBJ_GET (obj_cmd_rs, "basic_mode", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'basic_mode': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  cm->basic_mode = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "ppp_mode", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'ppp_mode': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  cm->ppp_mode = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "terminal_mode", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'terminal_mode': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  cm->terminal_mode = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "connect_mode", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'connect_mode': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  cm->connect_mode = val;

  rv = IPMI_CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}
Exemple #12
0
void
ipmipower_ping_process_pings (int *timeout)
{
  int i, send_pings_flag = 0;
  struct timeval cur_time, result;
  unsigned int ms_time;

  assert (timeout);

  if (!cmd_args.common_args.hostname)
    return;

  if (!cmd_args.ping_interval)
    return;

  if (gettimeofday (&cur_time, NULL) < 0)
    {
      IPMIPOWER_ERROR (("gettimeofday: %s", strerror (errno)));
      exit (EXIT_FAILURE);
    }

  if (timeval_gt (&cur_time, &next_ping_sends_time) || force_discovery_sweep)
    {
      force_discovery_sweep = 0;
      timeval_add_ms (&cur_time, cmd_args.ping_interval, &next_ping_sends_time);
      send_pings_flag++;
    }

  for (i = 0; i < ics_len; i++)
    {
      uint8_t buf[IPMIPOWER_PACKET_BUFLEN];
      int ret, len;

      if (send_pings_flag)
        {
          int dropped = 0;
          
          memset (buf, '\0', IPMIPOWER_PACKET_BUFLEN);

          /* deal with packet heuristics */
          if (cmd_args.ping_packet_count && cmd_args.ping_percent)
            {
              if (ics[i].ping_packet_count_send == cmd_args.ping_packet_count)
                {
                  if ((((double)(ics[i].ping_packet_count_send - ics[i].ping_packet_count_recv))/ics[i].ping_packet_count_send) > ((double)cmd_args.ping_percent/100))
                    ics[i].link_state = IPMIPOWER_LINK_STATE_BAD;
                  else
                    ics[i].link_state = IPMIPOWER_LINK_STATE_GOOD;

                  ics[i].ping_packet_count_send = 0;
                  ics[i].ping_packet_count_recv = 0;
                }
            }

          if (cmd_args.ping_consec_count)
            {
              if (!ics[i].ping_last_packet_recv_flag)
                ics[i].ping_consec_count = 0;
              ics[i].ping_last_packet_recv_flag = 0;
            }

          /* must increment count before setting message tag, so we
           * can check sequence number correctly later on
           */
          ics[i].ping_sequence_number_counter++;

	  /* Workaround
	   *
	   * Some motherboards don't support RMCP ping/pong :-(
	   *
	   * Discovered on Intel Windmill, Quanta Winterfell, and Wiwynn Windmill
	   */
	  if (cmd_args.common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING)
	    {
	      fiid_obj_t obj_rmcp_hdr = NULL;
	      fiid_obj_t obj_lan_session_hdr = NULL;
	      fiid_obj_t obj_lan_msg_hdr = NULL;
	      fiid_obj_t obj_cmd = NULL;

	      if (!(obj_rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (!(obj_lan_session_hdr = fiid_obj_create (tmpl_lan_session_hdr)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (!(obj_lan_msg_hdr = fiid_obj_create (tmpl_lan_msg_hdr_rq)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (!(obj_cmd = fiid_obj_create (tmpl_cmd_get_channel_authentication_capabilities_rq)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (fill_rmcp_hdr_ipmi (obj_rmcp_hdr) < 0)
		{
		  IPMIPOWER_ERROR (("fill_rmcp_hdr_ipmi: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (fill_lan_session_hdr (IPMI_AUTHENTICATION_TYPE_NONE,
					0,
					0,
					obj_lan_session_hdr) < 0)
		{
		  IPMIPOWER_ERROR (("fill_lan_session_hdr: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (fill_lan_msg_hdr (IPMI_SLAVE_ADDRESS_BMC,
				    IPMI_NET_FN_APP_RQ,
				    IPMI_BMC_IPMB_LUN_BMC,
				    (ics[i].ping_sequence_number_counter % (IPMI_RQ_SEQ_MAX + 1)),
				    obj_lan_msg_hdr) < 0)
		{
		  IPMIPOWER_ERROR (("fill_lan_msg_hdr: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (fill_cmd_get_channel_authentication_capabilities (IPMI_CHANNEL_NUMBER_CURRENT_CHANNEL,
								    IPMI_PRIVILEGE_LEVEL_USER,
								    IPMI_GET_IPMI_V15_DATA,
								    obj_cmd) < 0)
		{
		  IPMIPOWER_ERROR (("fill_cmd_get_channel_authentication_capabilities: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if ((len = assemble_ipmi_lan_pkt (obj_rmcp_hdr,
						obj_lan_session_hdr,
						obj_lan_msg_hdr,
						obj_cmd,
						NULL,
						0,
						buf,
						IPMIPOWER_PACKET_BUFLEN,
						IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
		{
		  IPMIPOWER_ERROR (("assemble_ipmi_lan_pkt: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

#ifndef NDEBUG
	      if (cmd_args.rmcpdump)
		{
		  char hdrbuf[DEBUG_UTIL_HDR_BUFLEN];
		  const char *str_cmd = NULL;

		  str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES);

		  debug_hdr_str (DEBUG_UTIL_TYPE_IPMI_1_5,
				 DEBUG_UTIL_DIRECTION_REQUEST,
				 DEBUG_UTIL_FLAGS_DEFAULT,
				 str_cmd,
				 hdrbuf,
				 DEBUG_UTIL_HDR_BUFLEN);
		  
		  if (ipmi_dump_lan_packet (STDERR_FILENO,
					    ics[i].hostname,
					    hdrbuf,
					    NULL,
					    buf,
					    len,
					    tmpl_lan_msg_hdr_rq,
					    tmpl_cmd_get_channel_authentication_capabilities_rq) < 0)
		    IPMIPOWER_DEBUG (("ipmi_dump_lan_packet: %s", strerror (errno)));
		}
#endif /* NDEBUG */

	      fiid_obj_destroy (obj_rmcp_hdr);
	      fiid_obj_destroy (obj_lan_session_hdr);
	      fiid_obj_destroy (obj_lan_msg_hdr);
	      fiid_obj_destroy (obj_cmd);
	    }
	  else			/* !IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING */
	    {
	      fiid_obj_t rmcp_hdr = NULL;
	      fiid_obj_t rmcp_ping = NULL;

	      if (!(rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (!(rmcp_ping = fiid_obj_create (tmpl_cmd_asf_presence_ping)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (fill_rmcp_hdr_asf (rmcp_hdr) < 0)
		{
		  IPMIPOWER_ERROR (("fill_rmcp_hdr_asf: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (fill_cmd_asf_presence_ping ((ics[i].ping_sequence_number_counter %
					       (RMCP_ASF_MESSAGE_TAG_MAX + 1)),
					      rmcp_ping) < 0)
		{
		  IPMIPOWER_ERROR (("fill_cmd_asf_presence_ping: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if ((len = assemble_rmcp_pkt (rmcp_hdr,
					    rmcp_ping,
					    buf,
					    IPMIPOWER_PACKET_BUFLEN,
					    IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
		{
		  IPMIPOWER_ERROR (("assemble_rmcp_pkt: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

#ifndef NDEBUG
	      if (cmd_args.rmcpdump)
		{
		  char hdrbuf[DEBUG_UTIL_HDR_BUFLEN];
		  
		  debug_hdr_str (DEBUG_UTIL_TYPE_NONE,
				 DEBUG_UTIL_DIRECTION_NONE,
				 DEBUG_UTIL_FLAGS_DEFAULT,
				 DEBUG_UTIL_RMCPPING_STR,
				 hdrbuf,
				 DEBUG_UTIL_HDR_BUFLEN);
		  
		  if (ipmi_dump_rmcp_packet (STDERR_FILENO,
					     ics[i].hostname,
					     hdrbuf,
					     NULL,
					     buf,
					     len,
					     tmpl_cmd_asf_presence_ping) < 0)
		    IPMIPOWER_DEBUG (("ipmi_dump_rmcp_packet: %s", strerror (errno)));
		}
#endif /* NDEBUG */

	      fiid_obj_destroy (rmcp_hdr);
	      fiid_obj_destroy (rmcp_ping);
	    } /* !IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING */

          if ((ret = cbuf_write (ics[i].ping_out, buf, len, &dropped)) < 0)
            {
              IPMIPOWER_ERROR (("cbuf_write: %s", strerror (errno)));
              exit (EXIT_FAILURE);
            }

          if (ret != len)
            {
              IPMIPOWER_ERROR (("cbuf_write: incorrect bytes written %d", ret));
              exit (EXIT_FAILURE);
            }

          if (dropped)
            IPMIPOWER_DEBUG (("cbuf_write: dropped %d bytes", dropped));

          ics[i].last_ping_send.tv_sec = cur_time.tv_sec;
          ics[i].last_ping_send.tv_usec = cur_time.tv_usec;

          if (cmd_args.ping_packet_count && cmd_args.ping_percent)
            ics[i].ping_packet_count_send++;
        }

      /* Did we receive something? */
      memset (buf, '\0', IPMIPOWER_PACKET_BUFLEN);
      len = ipmipower_cbuf_peek_and_drop (ics[i].ping_in, buf, IPMIPOWER_PACKET_BUFLEN);
      if (len > 0)
        {
          uint8_t message_type = 0, ipmi_supported = 0;
          uint64_t val;

	  /* Workaround
	   *
	   * Some motherboards don't support RMCP ping/pong :-(
	   *
	   * Discovered on Intel Windmill, Quanta Winterfell, and Wiwynn Windmill
	   */
	  if (cmd_args.common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING)
	    {
	      fiid_obj_t obj_rmcp_hdr = NULL;
	      fiid_obj_t obj_lan_session_hdr = NULL;
	      fiid_obj_t obj_lan_msg_hdr = NULL;
	      fiid_obj_t obj_cmd = NULL;
	      fiid_obj_t obj_lan_msg_trlr = NULL;
	      int checksum_ret = 0;
	      int unassemble_ret = 0;
	      int cmd_ret = 0;

	      if (!(obj_rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (!(obj_lan_session_hdr = fiid_obj_create (tmpl_lan_session_hdr)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (!(obj_lan_msg_hdr = fiid_obj_create (tmpl_lan_msg_hdr_rs)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (!(obj_cmd = fiid_obj_create (tmpl_cmd_get_channel_authentication_capabilities_rs)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (!(obj_lan_msg_trlr = fiid_obj_create (tmpl_lan_msg_trlr)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

#ifndef NDEBUG
	      if (cmd_args.rmcpdump)
		{
		  char hdrbuf[DEBUG_UTIL_HDR_BUFLEN];
		  const char *str_cmd = NULL;

		  str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES);

		  debug_hdr_str (DEBUG_UTIL_TYPE_IPMI_1_5,
				 DEBUG_UTIL_DIRECTION_RESPONSE,
				 DEBUG_UTIL_FLAGS_DEFAULT,
				 str_cmd,
				 hdrbuf,
				 DEBUG_UTIL_HDR_BUFLEN);
		  
		  if (ipmi_dump_lan_packet (STDERR_FILENO,
					    ics[i].hostname,
					    hdrbuf,
					    NULL,
					    buf,
					    len,
					    tmpl_lan_msg_hdr_rs,
					    tmpl_cmd_get_channel_authentication_capabilities_rs) < 0)
		    IPMIPOWER_DEBUG (("ipmi_dump_lan_packet: %s", strerror (errno)));
		}
#endif /* NDEBUG */

	      if ((checksum_ret = ipmi_lan_check_packet_checksum (buf, len)) < 0)
		{
		  IPMIPOWER_ERROR (("ipmi_lan_check_packet_checksum: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (checksum_ret
		  && ((unassemble_ret = unassemble_ipmi_lan_pkt (buf,
								 len,
								 obj_rmcp_hdr,
								 obj_lan_session_hdr,
								 obj_lan_msg_hdr,
								 obj_cmd,
								 obj_lan_msg_trlr,
								 IPMI_INTERFACE_FLAGS_DEFAULT)) < 0))
		{
		  IPMIPOWER_ERROR (("unassemble_ipmi_lan_pkt: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      /* achu: check for cmd type, but don't bother checking
	       * sequence numbers or completion code.  The fact it
	       * returns is sufficient.  We just need to make sure we
	       * get something back from the BMC to ensure the machine
	       * is still there.
	       */

	      if (checksum_ret
		  && unassemble_ret
		  && ((cmd_ret = ipmi_check_cmd (obj_cmd, IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES)) < 0))
		{
		  IPMIPOWER_ERROR (("ipmi_check_cmd: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}
	      
	      if (checksum_ret && unassemble_ret && cmd_ret)
		{
		  /* We'll say this is equivalent to what pong response from RMCP */
		  message_type = RMCP_ASF_MESSAGE_TYPE_PRESENCE_PONG;
		  ipmi_supported = 1;
		}

	      fiid_obj_destroy (obj_rmcp_hdr);
	      fiid_obj_destroy (obj_lan_session_hdr);
	      fiid_obj_destroy (obj_lan_msg_hdr);
	      fiid_obj_destroy (obj_cmd);
	      fiid_obj_destroy (obj_lan_msg_trlr);
	    }
	  else			/* !IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING */
	    {
	      fiid_obj_t rmcp_hdr = NULL;
	      fiid_obj_t rmcp_pong = NULL;

	      if (!(rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (!(rmcp_pong = fiid_obj_create (tmpl_cmd_asf_presence_pong)))
		{
		  IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

#ifndef NDEBUG
	      if (cmd_args.rmcpdump)
		{
		  char hdrbuf[DEBUG_UTIL_HDR_BUFLEN];
		  
		  debug_hdr_str (DEBUG_UTIL_TYPE_NONE,
				 DEBUG_UTIL_DIRECTION_NONE,
				 DEBUG_UTIL_FLAGS_DEFAULT,
				 DEBUG_UTIL_RMCPPING_STR,
				 hdrbuf,
				 DEBUG_UTIL_HDR_BUFLEN);
		  
		  if (ipmi_dump_rmcp_packet (STDERR_FILENO,
					     ics[i].hostname,
					     hdrbuf,
					     NULL,
					     buf,
					     len,
					     tmpl_cmd_asf_presence_pong) < 0)
		    IPMIPOWER_DEBUG (("ipmi_dump_rmcp_packet: %s", strerror (errno)));
		}
#endif /* NDEBUG */

	      if ((ret = unassemble_rmcp_pkt (buf,
					      len,
					      rmcp_hdr,
					      rmcp_pong,
					      IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
		{
		  IPMIPOWER_ERROR (("unassemble_rmcp_pkt: %s", strerror (errno)));
		  exit (EXIT_FAILURE);
		}

	      if (ret)
		{
		  /* achu: check for ipmi_support and pong type, but don't
		   * check for message tag.  On occassion, I have witnessed
		   * BMCs send message tags "out of sync".  For example, you
		   * send 8, BMC returns 7.  You send 9, BMC returns 8.  We
		   * really don't care if the BMC is out of sync.  We just
		   * need to make sure we get something back from the BMC to
		   * ensure the machine is still there.
		   */
		  
		  if (FIID_OBJ_GET (rmcp_pong,
				    "message_type",
				    &val) < 0)
		    {
		      IPMIPOWER_ERROR (("FIID_OBJ_GET: 'message_type': %s",
					fiid_obj_errormsg (rmcp_pong)));
		      exit (EXIT_FAILURE);
		    }
		  message_type = val;
		  
		  if (FIID_OBJ_GET (rmcp_pong,
				    "supported_entities.ipmi_supported",
				    &val) < 0)
		    {
		      IPMIPOWER_ERROR (("FIID_OBJ_GET: 'supported_entities.ipmi_supported': %s",
					fiid_obj_errormsg (rmcp_pong)));
		      exit (EXIT_FAILURE);
		    }
		  ipmi_supported = val;
		}

	      fiid_obj_destroy (rmcp_hdr);
	      fiid_obj_destroy (rmcp_pong);
	    }

	  if (message_type == RMCP_ASF_MESSAGE_TYPE_PRESENCE_PONG && ipmi_supported)
	    {
	      if (cmd_args.ping_packet_count && cmd_args.ping_percent)
		ics[i].ping_packet_count_recv++;
	      
	      if (cmd_args.ping_consec_count)
		{
		  /* Don't increment twice, its possible a previous pong
		   * response was late, and we quickly receive two
		   * pong responses
		   */
		  if (!ics[i].ping_last_packet_recv_flag)
		    ics[i].ping_consec_count++;
		  
		  ics[i].ping_last_packet_recv_flag++;
		}
	      
	      if (cmd_args.ping_packet_count && cmd_args.ping_percent)
		{
		  if (ics[i].link_state == IPMIPOWER_LINK_STATE_GOOD)
		    ics[i].discover_state = IPMIPOWER_DISCOVER_STATE_DISCOVERED;
		  else
		    {
		      if (cmd_args.ping_consec_count
			  && ics[i].ping_consec_count >= cmd_args.ping_consec_count)
			ics[i].discover_state = IPMIPOWER_DISCOVER_STATE_DISCOVERED;
		      else
			ics[i].discover_state = IPMIPOWER_DISCOVER_STATE_BADCONNECTION;
		    }
		}
	      else
		{
		  ics[i].discover_state = IPMIPOWER_DISCOVER_STATE_DISCOVERED;
		}
	      ics[i].last_ping_recv.tv_sec = cur_time.tv_sec;
	      ics[i].last_ping_recv.tv_usec = cur_time.tv_usec;
	      
	    }
     	} /* !IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING */

      /* Is the node gone?? */
      timeval_sub (&cur_time, &ics[i].last_ping_recv, &result);
      timeval_millisecond_calc (&result, &ms_time);
      if (ms_time >= cmd_args.ping_timeout)
        ics[i].discover_state = IPMIPOWER_DISCOVER_STATE_UNDISCOVERED;
    }

  timeval_sub (&next_ping_sends_time, &cur_time, &result);
  timeval_millisecond_calc (&result, &ms_time);
  *timeout = ms_time;
}
static config_err_t
community_string_checkout (const char *section_name,
                           struct config_keyvalue *kv,
                           void *arg)
{
  ipmi_pef_config_state_data_t *state_data;
  char community_string[IPMI_MAX_COMMUNITY_STRING_LENGTH+1] = { 0, };
  fiid_obj_t obj_cmd_rs = NULL;
  config_err_t rv = CONFIG_ERR_FATAL_ERROR;
  config_err_t ret;
  uint8_t channel_number;

  assert (section_name);
  assert (kv);
  assert (arg);
  
  state_data = (ipmi_pef_config_state_data_t *)arg;

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_lan_configuration_parameters_community_string_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  if ((ret = get_lan_channel_number (state_data, section_name, &channel_number)) != CONFIG_ERR_SUCCESS)
    {
      rv = ret;
      goto cleanup;
    }

  if (ipmi_cmd_get_lan_configuration_parameters_community_string (state_data->ipmi_ctx,
                                                                  channel_number,
                                                                  IPMI_GET_LAN_PARAMETER,
                                                                  IPMI_PEF_CONFIGURATION_PARAMETERS_NO_SET_SELECTOR,
                                                                  IPMI_PEF_CONFIGURATION_PARAMETERS_NO_BLOCK_SELECTOR,
                                                                  obj_cmd_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_community_string: %s\n",
                         ipmi_ctx_errormsg (state_data->ipmi_ctx));

      if (config_is_config_param_non_fatal_error (state_data->ipmi_ctx,
                                                  obj_cmd_rs,
                                                  &ret))
        rv = ret;

      goto cleanup;
    }

  memset (community_string,'\0', IPMI_MAX_COMMUNITY_STRING_LENGTH+1);
  if (fiid_obj_get_data (obj_cmd_rs,
                         "community_string",
                         community_string,
                         IPMI_MAX_COMMUNITY_STRING_LENGTH+1) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get_data: 'obj_cmd_rs': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (config_section_update_keyvalue_output (state_data->pstate,
                                             kv,
                                             community_string) < 0)
    return (CONFIG_ERR_FATAL_ERROR);

  rv = CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}
int
ipmiconsole_check_rakp_2_key_exchange_authentication_code (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint8_t managed_system_random_number[IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH];
    int managed_system_random_number_len;
    uint8_t managed_system_guid[IPMI_MANAGED_SYSTEM_GUID_LENGTH];
    int managed_system_guid_len;
    char username_buf[IPMI_MAX_USER_NAME_LENGTH+1];
    char *username;
    unsigned int username_len;
    char *password;
    unsigned int password_len;
    uint32_t managed_system_session_id;
    uint64_t val;
    int rv;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_2);

    /* IPMI Workaround
     *
     * Intel IPMI 2.0 implementations pad their usernames.
     */
    if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_INTEL_2_0_SESSION)
    {
        memset (username_buf, '\0', IPMI_MAX_USER_NAME_LENGTH+1);
        if (strlen (c->config.username))
            strcpy (username_buf, c->config.username);
        username = username_buf;
        username_len = IPMI_MAX_USER_NAME_LENGTH;
    }
    else
    {
        if (strlen (c->config.username))
            username = c->config.username;
        else
            username = NULL;
        username_len = (username) ? strlen (username) : 0;
    }

    /* IPMI Workaround
     *
     * Supermicro IPMI 2.0 implementations may have invalid payload lengths
     * on the RAKP response packet.
     */
    if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_SUPERMICRO_2_0_SESSION)
    {
        uint8_t keybuf[IPMICONSOLE_PACKET_BUFLEN];
        int keybuf_len;

        if ((keybuf_len = fiid_obj_get_data (c->connection.obj_rakp_message_2,
                                             "key_exchange_authentication_code",
                                             keybuf,
                                             IPMICONSOLE_PACKET_BUFLEN)) < 0)
        {
            IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: 'key_exchange_authentication_code': %s",
                                       fiid_obj_errormsg (c->connection.obj_rakp_message_2)));
            ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
            return (-1);
        }

        if (c->config.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE
                && keybuf_len == 1)
        {
            if (fiid_obj_clear_field (c->connection.obj_rakp_message_2,
                                      "key_exchange_authentication_code") < 0)
            {
                IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_clear_field: 'key_exchange_authentication_code': %s",
                                           fiid_obj_errormsg (c->connection.obj_rakp_message_2)));
                ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
                return (-1);
            }
        }
        else if (c->config.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1
                 && keybuf_len == (IPMI_HMAC_SHA1_DIGEST_LENGTH + 1))
        {
            if (fiid_obj_set_data (c->connection.obj_rakp_message_2,
                                   "key_exchange_authentication_code",
                                   keybuf,
                                   IPMI_HMAC_SHA1_DIGEST_LENGTH) < 0)
            {
                IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_set_data: 'key_exchange_authentication_code': %s",
                                           fiid_obj_errormsg (c->connection.obj_rakp_message_2)));
                ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
                return (-1);
            }
        }
        else if (c->config.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5
                 && keybuf_len == (IPMI_HMAC_MD5_DIGEST_LENGTH + 1))
        {
            if (fiid_obj_set_data (c->connection.obj_rakp_message_2,
                                   "key_exchange_authentication_code",
                                   keybuf,
                                   IPMI_HMAC_MD5_DIGEST_LENGTH) < 0)
            {
                IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_set_data: 'key_exchange_authentication_code': %s",
                                           fiid_obj_errormsg (c->connection.obj_rakp_message_2)));
                ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
                return (-1);
            }
        }
    }

    if (strlen (c->config.password))
        password = c->config.password;
    else
        password = NULL;
    password_len = (password) ? strlen (password) : 0;

    /* IPMI Workaround
     *
     * Intel IPMI 2.0 implementations improperly calculate HMAC-MD5-128 hashes
     * when the passwords are > 16 bytes long.  The BMCs probably assume
     * all keys are <= 16 bytes in length.  So we have to adjust.
     */
    if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_INTEL_2_0_SESSION
            && c->config.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5
            && password_len > IPMI_1_5_MAX_PASSWORD_LENGTH)
        password_len = IPMI_1_5_MAX_PASSWORD_LENGTH;

    /* IPMI Workaround
     *
     * Discovered on Sun Fire 4100.
     *
     * The key exchange authentication code is the wrong length.  We
     * need to shorten it.
     */
    if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_SUN_2_0_SESSION
            && c->config.authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1)
    {
        uint8_t buf[IPMI_MAX_KEY_EXCHANGE_AUTHENTICATION_CODE_LENGTH];
        int buf_len;

        /* trace, but do not return potential error */

        if ((buf_len = fiid_obj_get_data (c->connection.obj_rakp_message_2,
                                          "key_exchange_authentication_code",
                                          buf,
                                          IPMI_MAX_KEY_EXCHANGE_AUTHENTICATION_CODE_LENGTH)) < 0)
            IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: 'key_exchange_authentication_code': %s",
                                       fiid_obj_errormsg (c->connection.obj_rakp_message_2)));

        if (buf_len == (IPMI_HMAC_SHA1_DIGEST_LENGTH + 1))
        {
            /* trace, but do not return potential error */

            if (fiid_obj_clear_field (c->connection.obj_rakp_message_2,
                                      "key_exchange_authentication_code") < 0)
                IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_clear_field: 'key_exchange_authentication_code': %s",
                                           fiid_obj_errormsg (c->connection.obj_rakp_message_2)));

            if (fiid_obj_set_data (c->connection.obj_rakp_message_2,
                                   "key_exchange_authentication_code",
                                   buf,
                                   IPMI_HMAC_SHA1_DIGEST_LENGTH) < 0)
                IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_set_data: 'key_exchange_authentication_code': %s",
                                           fiid_obj_errormsg (c->connection.obj_rakp_message_2)));
        }
    }


    if (FIID_OBJ_GET (c->connection.obj_open_session_response,
                      "managed_system_session_id",
                      &val) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'managed_system_session_id': %s",
                                   fiid_obj_errormsg (c->connection.obj_open_session_response)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }
    managed_system_session_id = val;

    if ((managed_system_random_number_len = fiid_obj_get_data (c->connection.obj_rakp_message_2,
                                            "managed_system_random_number",
                                            managed_system_random_number,
                                            IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH)) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: 'managed_system_random_number': %s",
                                   fiid_obj_errormsg (c->connection.obj_rakp_message_2)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }

    if (managed_system_random_number_len != IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: invalid managed system random number length: %d",
                                   managed_system_random_number_len));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }

    if ((managed_system_guid_len = fiid_obj_get_data (c->connection.obj_rakp_message_2,
                                   "managed_system_guid",
                                   managed_system_guid,
                                   IPMI_MANAGED_SYSTEM_GUID_LENGTH)) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: 'managed_system_guid': %s",
                                   fiid_obj_errormsg (c->connection.obj_rakp_message_2)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }

    if (managed_system_guid_len != IPMI_MANAGED_SYSTEM_GUID_LENGTH)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: invalid managed system guid length: %d",
                                   managed_system_guid_len));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }

    if ((rv = ipmi_rmcpplus_check_rakp_2_key_exchange_authentication_code (c->config.authentication_algorithm,
              password,
              password_len,
              c->session.remote_console_session_id,
              managed_system_session_id,
              c->session.remote_console_random_number,
              IPMI_REMOTE_CONSOLE_RANDOM_NUMBER_LENGTH,
              managed_system_random_number,
              managed_system_random_number_len,
              managed_system_guid,
              managed_system_guid_len,
              c->session.name_only_lookup,
              c->config.privilege_level,
              username,
              username_len,
              c->connection.obj_rakp_message_2)) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("ipmi_rmcpplus_check_rakp_2_key_exchange_authentication_code: p = %d; %s", p, strerror (errno)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }

    if (!rv)
        IPMICONSOLE_CTX_DEBUG (c, ("rakp 2 key exchanged authentication code check failed; p = %d", p));

    return (rv);
}
static config_err_t
_get_alert_policy_table (struct ipmi_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_"));

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_pef_configuration_parameters_alert_policy_table_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  if (ipmi_cmd_get_pef_configuration_parameters_alert_policy_table (state_data->ipmi_ctx,
                                                                    IPMI_GET_PEF_PARAMETER,
                                                                    alert_policy_entry_number,
                                                                    IPMI_PEF_CONFIGURATION_PARAMETERS_NO_BLOCK_SELECTOR,
                                                                    obj_cmd_rs) < 0)
    {
      config_err_t ret;

      if (state_data->prog_data->args->config_args.common_args.debug)
        pstdout_fprintf (state_data->pstate,
                         stderr,
                         "ipmi_cmd_get_pef_configuration_parameters_alert_policy_table: %s\n",
                         ipmi_ctx_errormsg (state_data->ipmi_ctx));

      if (config_is_config_param_non_fatal_error (state_data->ipmi_ctx,
                                                  obj_cmd_rs,
                                                  &ret))
        rv = ret;

      goto cleanup;
    }

#if 0
  if (FIID_OBJ_GET (obj_cmd_rs, "alert_policy_entry_number", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'alert_policy_entry_number': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
#endif
  if (FIID_OBJ_GET (obj_cmd_rs, "policy_number.policy_type", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'policy_number.policy_type': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  apt->policy_type = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "policy_number.enabled", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'policy_number.enabled': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  apt->policy_enabled = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "policy_number.policy_number", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'policy_number.policy_number': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  apt->policy_number = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "channel_destination.destination_selector", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'channel_destination.destination_selector': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  apt->destination_selector = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "channel_destination.channel_number", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'channel_destination.channel_number': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  apt->channel_number = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "alert_string_key.alert_string_set_selector", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'alert_string_key.alert_string_set_selector': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  apt->alert_string_set_selector = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "alert_string_key.event_specific_alert_string", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'alert_string_key.event_specific_alert_string': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  apt->event_specific_alert_string = val;

  rv = CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}
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 config_err_t
_get_authentication_type_support (bmc_config_state_data_t *state_data,
				  const char *section_name)
{
  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 (section_name);

  if ((ret = get_lan_channel_number (state_data, section_name, &channel_number)) != CONFIG_ERR_SUCCESS)
    {
      rv = ret;
      goto cleanup;
    }
  
  if (state_data->authentication_type_initialized
      && state_data->authentication_type_channel_number == channel_number)
    goto out;
  
  state_data->authentication_type_initialized = 0;
  state_data->authentication_type_channel_number = 0;

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_lan_configuration_parameters_authentication_type_support_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  if (ipmi_cmd_get_lan_configuration_parameters_authentication_type_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_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_authentication_type_support: %s\n",
                         ipmi_ctx_errormsg (state_data->ipmi_ctx));

      if (config_is_config_param_non_fatal_error (state_data->ipmi_ctx,
                                                  obj_cmd_rs,
                                                  &ret))
        rv = ret;

      goto cleanup;
    }

  if (FIID_OBJ_GET (obj_cmd_rs, "none", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'none': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  state_data->authentication_type_none = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "md2", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'md2': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  state_data->authentication_type_md2 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "md5", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'md5': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  state_data->authentication_type_md5 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "straight_password", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'straight_password': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  state_data->authentication_type_straight_password = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "oem_proprietary", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'oem_proprietary': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  state_data->authentication_type_oem_proprietary = val;

  state_data->authentication_type_initialized++;
 out:
  rv = CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}
static config_err_t
_get_authentication_type_enables (bmc_config_state_data_t *state_data,
				  const char *section_name,
                                  struct bmc_authentication_level *al)
{
  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 (section_name);
  assert (al);

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_lan_configuration_parameters_authentication_type_enables_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  if ((ret = get_lan_channel_number (state_data, section_name, &channel_number)) != CONFIG_ERR_SUCCESS)
    {
      rv = ret;
      goto cleanup;
    }

  if (ipmi_cmd_get_lan_configuration_parameters_authentication_type_enables (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_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_authentication_type_enables: %s\n",
                         ipmi_ctx_errormsg (state_data->ipmi_ctx));

      if (config_is_config_param_non_fatal_error (state_data->ipmi_ctx,
                                                  obj_cmd_rs,
                                                  &ret))
        rv = ret;

      goto cleanup;
    }

  if (FIID_OBJ_GET (obj_cmd_rs, "callback_level.none", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'callback_level.none': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->callback_level_none = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "callback_level.md2", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'callback_level.md2': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->callback_level_md2 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "callback_level.md5", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'callback_level.md5': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->callback_level_md5 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "callback_level.straight_password", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'callback_level.straight_password': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->callback_level_straight_password = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "callback_level.oem_proprietary", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'callback_level.oem_proprietary': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->callback_level_oem_proprietary = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "user_level.none", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'user_level.none': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->user_level_none = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "user_level.md2", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'user_level.md2': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->user_level_md2 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "user_level.md5", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'user_level.md5': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->user_level_md5 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "user_level.straight_password", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'user_level.straight_password': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->user_level_straight_password = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "user_level.oem_proprietary", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'user_level.oem_proprietary': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->user_level_oem_proprietary = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "operator_level.none", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'operator_level.none': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->operator_level_none = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "operator_level.md2", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'operator_level.md2': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->operator_level_md2 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "operator_level.md5", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'operator_level.md5': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->operator_level_md5 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "operator_level.straight_password", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'operator_level.straight_password': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->operator_level_straight_password = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "operator_level.oem_proprietary", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'operator_level.oem_proprietary': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->operator_level_oem_proprietary = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "admin_level.none", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'admin_level.none': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->admin_level_none = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "admin_level.md2", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'admin_level.md2': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->admin_level_md2 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "admin_level.md5", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'admin_level.md5': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->admin_level_md5 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "admin_level.straight_password", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'admin_level.straight_password': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->admin_level_straight_password = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "admin_level.oem_proprietary", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'admin_level.oem_proprietary': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->admin_level_oem_proprietary = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "oem_level.none", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'oem_level.none': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->oem_level_none = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "oem_level.md2", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'oem_level.md2': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->oem_level_md2 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "oem_level.md5", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'oem_level.md5': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->oem_level_md5 = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "oem_level.straight_password", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'oem_level.straight_password': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->oem_level_straight_password = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "oem_level.oem_proprietary", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'oem_level.oem_proprietary': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  al->oem_level_oem_proprietary = val;

  rv = CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}
static ipmi_config_err_t
_get_bad_password_threshold (ipmi_config_state_data_t *state_data,
                             const char *section_name,
                             struct bad_password_threshold *bpt)
{
  fiid_obj_t obj_cmd_rs = NULL;
  uint64_t val;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
  ipmi_config_err_t ret;
  uint8_t channel_number;

  assert (state_data);
  assert (section_name);
  assert (bpt);

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_lan_configuration_parameters_bad_password_threshold_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }
  
  if ((ret = get_lan_channel_number (state_data, section_name, &channel_number)) != IPMI_CONFIG_ERR_SUCCESS)
    {
      rv = ret;
      goto cleanup;
    }
  
  if (ipmi_cmd_get_lan_configuration_parameters_bad_password_threshold (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_rs) < 0)
    {
      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_lan_configuration_parameters_bad_password_threshold: %s\n",
                         ipmi_ctx_errormsg (state_data->ipmi_ctx));

      goto cleanup;
    }
  
  if (FIID_OBJ_GET (obj_cmd_rs, "user_disabled_event_message", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'user_disabled_event_message': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  bpt->user_disabled_event_message = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "bad_password_threshold_number", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'bad_password_threshold_number': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  bpt->bad_password_threshold_number = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "attempt_count_reset_interval", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'attempt_count_reset_interval': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  bpt->attempt_count_reset_interval = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "user_lockout_interval", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'user_lockout_interval': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  bpt->user_lockout_interval = val;

  rv = IPMI_CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}
Exemple #20
0
int
parsepacket (const char *destination,
             const void *buf,
             unsigned int buflen,
             const char *from,
             unsigned int sequence_number,
             int verbose,
             int version,
             int debug)
{
  fiid_obj_t obj_rmcp_hdr = NULL;
  fiid_obj_t obj_lan_session_hdr = NULL;
  fiid_obj_t obj_lan_msg_hdr = NULL;
  fiid_obj_t obj_cmd = NULL;
  fiid_obj_t obj_lan_msg_trlr = NULL;
  uint8_t req_seq, none, md2, md5, straight_password_key, oem,
    anonymous_login, null_username, non_null_username,
    user_level_authentication, per_message_authentication,
    k_g, ipmi_v20_extended_capabilities_available, ipmi_v15, ipmi_v20;
  uint64_t val;
  int ret, rv = -1;

  assert (destination);
  assert (buf);
  assert (from);
  assert (version == IPMI_PING_VERSION_1_5 || version == IPMI_PING_VERSION_2_0);

  if (!buflen)
    return (0);

  if (!(obj_rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr)))
    ipmi_ping_err_exit ("fiid_obj_create: %s", strerror (errno));
  if (!(obj_lan_session_hdr = fiid_obj_create (tmpl_lan_session_hdr)))
    ipmi_ping_err_exit ("fiid_obj_create: %s", strerror (errno));
  if (!(obj_lan_msg_hdr = fiid_obj_create (tmpl_lan_msg_hdr_rs)))
    ipmi_ping_err_exit ("fiid_obj_create: %s", strerror (errno));
  if (!(obj_cmd = fiid_obj_create (tmpl_cmd_get_channel_authentication_capabilities_rs)))
    ipmi_ping_err_exit ("fiid_obj_create: %s", strerror (errno));
  if (!(obj_lan_msg_trlr = fiid_obj_create (tmpl_lan_msg_trlr)))
    ipmi_ping_err_exit ("fiid_obj_create: %s", strerror (errno));

  if (debug)
    {
      char hdrbuf[DEBUG_UTIL_HDR_BUFLEN];

      debug_hdr_cmd ((version == IPMI_PING_VERSION_1_5) ? DEBUG_UTIL_TYPE_IPMI_1_5 : DEBUG_UTIL_TYPE_IPMI_2_0,
                     DEBUG_UTIL_DIRECTION_RESPONSE,
                     IPMI_NET_FN_APP_RQ,
                     IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES,
		     0,
                     hdrbuf,
                     DEBUG_UTIL_HDR_BUFLEN);

      if (ipmi_dump_lan_packet (STDERR_FILENO,
                                destination,
                                hdrbuf,
                                NULL,
                                buf,
                                buflen,
                                tmpl_lan_msg_hdr_rs,
                                tmpl_cmd_get_channel_authentication_capabilities_rs) < 0)
        ipmi_ping_err_exit ("ipmi_dump_lan_packet: %s", strerror (errno));
    }

  if ((ret = ipmi_lan_check_packet_checksum (buf, buflen)) < 0)
    ipmi_ping_err_exit ("ipmi_lan_check_checksum: %s", strerror (errno));

  if (!ret)
    {
      if (debug)
        fprintf (stderr, "%s(%d): checksum failed\n", __FUNCTION__, __LINE__);
      rv = 0;
      goto cleanup;
    }

  if ((ret = unassemble_ipmi_lan_pkt (buf,
                                      buflen,
                                      obj_rmcp_hdr,
                                      obj_lan_session_hdr,
                                      obj_lan_msg_hdr,
                                      obj_cmd,
                                      obj_lan_msg_trlr,
				      IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
    ipmi_ping_err_exit ("unassemble_ipmi_lan_pkt: %s", strerror (errno));

  if (!ret)
    {
      if (debug)
        fprintf (stderr, "%s(%d): Could not unassemble packet\n", __FUNCTION__, __LINE__);
      rv = 0;
      goto cleanup;
    }

  if ((ret = ipmi_lan_check_net_fn (obj_lan_msg_hdr, IPMI_NET_FN_APP_RS)) < 0)
    ipmi_ping_err_exit ("ipmi_lan_check_net_fn: %s", strerror (errno));

  if (!ret)
    {
      if (debug)
        fprintf (stderr, "%s(%d): net_fn failed\n", __FUNCTION__, __LINE__);
      rv = 0;
      goto cleanup;
    }

  if ((ret = ipmi_check_cmd (obj_cmd, IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES)) < 0)
    ipmi_ping_err_exit ("ipmi_check_cmd: %s", strerror (errno));

  if (!ret)
    {
      if (debug)
        fprintf (stderr, "%s(%d): cmd failed\n", __FUNCTION__, __LINE__);
      rv = 0;
      goto cleanup;
    }

  if ((ret = ipmi_check_completion_code_success (obj_cmd)) < 0)
    ipmi_ping_err_exit ("ipmi_check_comp_code: %s", strerror (errno));

  if (!ret)
    {
      if (debug)
        fprintf (stderr, "%s(%d): comp_code failed\n", __FUNCTION__, __LINE__);
      rv = 0;
      goto cleanup;
    }

  if (FIID_OBJ_GET (obj_lan_msg_hdr,
                    "rq_seq",
                    &val) < 0)
    ipmi_ping_err_exit ("fiid_obj_get: 'rq_seq': %s",
                        fiid_obj_errormsg (obj_lan_msg_hdr));
  req_seq = val;

  if (req_seq != sequence_number % (IPMI_RQ_SEQ_MAX + 1))
    {
      if (debug)
        fprintf (stderr, "%s(%d): req_seq failed\n", __FUNCTION__, __LINE__);
      rv = 0;
      goto cleanup;
    }

  printf ("response received from %s: rq_seq=%u", from, req_seq);
  if (verbose)
    {
      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_type.none",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_type.none': %s",
                            fiid_obj_errormsg (obj_cmd));
      none = val;

      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_type.md2",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_type.md2': %s",
                            fiid_obj_errormsg (obj_cmd));
      md2 = val;

      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_type.md5",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_type.md5': %s",
                            fiid_obj_errormsg (obj_cmd));
      md5 = val;

      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_type.straight_password_key",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_type.straight_password_key': %s",
                            fiid_obj_errormsg (obj_cmd));
      straight_password_key = val;

      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_type.oem_prop",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_type.oem_prop': %s",
                            fiid_obj_errormsg (obj_cmd));
      oem = val;

      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_status.anonymous_login",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_status.anonymous_login': %s",
                            fiid_obj_errormsg (obj_cmd));
      anonymous_login = val;

      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_status.null_username",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_status.null_username': %s",
                            fiid_obj_errormsg (obj_cmd));
      null_username = val;

      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_status.non_null_username",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_status.non_null_username': %s",
                            fiid_obj_errormsg (obj_cmd));
      non_null_username = val;

      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_status.user_level_authentication",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_status.user_level_authentication': %s",
                            fiid_obj_errormsg (obj_cmd));
      user_level_authentication = val;

      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_status.per_message_authentication",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_status.per_message_authentication': %s",
                            fiid_obj_errormsg (obj_cmd));
      per_message_authentication = val;

      if (FIID_OBJ_GET (obj_cmd,
                        "authentication_status.per_message_authentication",
                        &val) < 0)
        ipmi_ping_err_exit ("fiid_obj_get: 'authentication_status.per_message_authentication': %s",
                            fiid_obj_errormsg (obj_cmd));
      per_message_authentication = val;

      printf (", auth: none=%s md2=%s md5=%s password=%s oem=%s anon=%s null=%s non-null=%s user=%s permsg=%s ",
              _setstr (none), _setstr (md2), _setstr (md5),
              _setstr (straight_password_key),_setstr (oem),
              _setstr (anonymous_login), _setstr (null_username),
              _setstr (non_null_username), _setstr (user_level_authentication),
              _setstr (per_message_authentication));

      if (version == IPMI_PING_VERSION_2_0)
        {
          if (FIID_OBJ_GET (obj_cmd,
                            "authentication_type.ipmi_v2.0_extended_capabilities_available",
                            &val) < 0)
            ipmi_ping_err_exit ("fiid_obj_get: 'authentication_type.ipmi_v2.0_extended_capabilities_available': %s",
                                fiid_obj_errormsg (obj_cmd));
          ipmi_v20_extended_capabilities_available = val;

          if (FIID_OBJ_GET (obj_cmd,
                            "authentication_status.k_g",
                            &val) < 0)
            ipmi_ping_err_exit ("fiid_obj_get: 'authentication_status.k_g': %s",
                                fiid_obj_errormsg (obj_cmd));
          k_g = val;

          printf ("k_g=%s ipmi_v2.0_extended_capabilities_available=%s ",
                  _setstr (k_g),
                  _setstr (ipmi_v20_extended_capabilities_available));

          if (ipmi_v20_extended_capabilities_available)
            {
              if (FIID_OBJ_GET (obj_cmd,
                                "channel_supports_ipmi_v1.5_connections",
                                &val) < 0)
                ipmi_ping_err_exit ("fiid_obj_get: 'channel_supports_ipmi_v1.5_connections': %s",
                                    fiid_obj_errormsg (obj_cmd));
              ipmi_v15 = val;

              if (FIID_OBJ_GET (obj_cmd,
                                "channel_supports_ipmi_v2.0_connections",
                                &val) < 0)
                ipmi_ping_err_exit ("fiid_obj_get: 'channel_supports_ipmi_v2.0_connections': %s",
                                    fiid_obj_errormsg (obj_cmd));
              ipmi_v20 = val;

              printf ("ipmi_v1.5=%s ipmi_v2.0=%s ", _setstr (ipmi_v15), _setstr (ipmi_v20));
            }
        }
    }
  printf ("\n");

  rv = 1;
 cleanup:
  fiid_obj_destroy (obj_rmcp_hdr);
  fiid_obj_destroy (obj_lan_session_hdr);
  fiid_obj_destroy (obj_lan_msg_hdr);
  fiid_obj_destroy (obj_cmd);
  fiid_obj_destroy (obj_lan_msg_trlr);
  return (rv);
}
static ipmi_config_err_t
_get_front_panel_buttons (ipmi_config_state_data_t *state_data,
                          struct front_panel_buttons *data)
{
  fiid_obj_t obj_cmd_rs = NULL;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
  uint64_t val;
  int flag;

  assert (state_data);
  assert (data);

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_chassis_status_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  if (ipmi_cmd_get_chassis_status (state_data->ipmi_ctx, obj_cmd_rs) < 0)
    {
      ipmi_config_err_t ret;

      if (ipmi_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_chassis_status: %s\n",
                         ipmi_ctx_errormsg (state_data->ipmi_ctx));

      goto cleanup;
    }

  if ((flag = fiid_obj_get (obj_cmd_rs,
                            "front_panel.standby_button_disabled",
                            &val)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'front_panel.standby_button_disabled': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (flag)
    data->standby = val;
  else
    data->standby = BUTTON_UNKNOWN;

  if ((flag = fiid_obj_get (obj_cmd_rs,
                            "front_panel.diagnostic_interrupt_button_disabled",
                            &val)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'front_panel.diagnostic_interrupt_button_disabled': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (flag)
    data->diagnostic_interrupt = val;
  else
    data->diagnostic_interrupt = BUTTON_UNKNOWN;

  if ((flag = fiid_obj_get (obj_cmd_rs,
                            "front_panel.reset_button_disabled",
                            &val)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'front_panel.reset_button_disabled': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (flag)
    data->reset = val;
  else
    data->reset = BUTTON_UNKNOWN;

  if ((flag = fiid_obj_get (obj_cmd_rs,
                            "front_panel.power_off_button_disabled",
                            &val)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'front_panel.power_off_button_disabled': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (flag)
    data->power_off = val;
  else
    data->power_off = BUTTON_UNKNOWN;

  if ((flag = fiid_obj_get (obj_cmd_rs,
                            "front_panel.standby_button_disable_allowed",
                            &val)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'front_panel.standby_button_disable_allowed': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (flag)
    data->standby_disable_allowed = val;
  else
    data->standby_disable_allowed = BUTTON_DISABLE_UNKNOWN;

  if ((flag = fiid_obj_get (obj_cmd_rs,
                            "front_panel.diagnostic_interrupt_button_disable_allowed",
                            &val)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'front_panel.diagnostic_interrupt_button_disable_allowed': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (flag)
    data->diagnostic_interrupt_disable_allowed = val;
  else
    data->diagnostic_interrupt_disable_allowed = BUTTON_DISABLE_UNKNOWN;

  if ((flag = fiid_obj_get (obj_cmd_rs,
                            "front_panel.reset_button_disable_allowed",
                            &val)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'front_panel.reset_button_disable_allowed': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (flag)
    data->reset_disable_allowed = val;
  else
    data->reset_disable_allowed = BUTTON_DISABLE_UNKNOWN;

  if ((flag = fiid_obj_get (obj_cmd_rs,
                            "front_panel.power_off_button_disable_allowed",
                            &val)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'front_panel.power_off_button_disable_allowed': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (flag)
    data->power_off_disable_allowed = val;
  else
    data->power_off_disable_allowed = BUTTON_DISABLE_UNKNOWN;

  rv = IPMI_CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}
static ipmi_config_err_t
call_retry_interval_checkout (ipmi_config_state_data_t *state_data,
			      const char *section_name,
                              struct ipmi_config_keyvalue *kv)
{
  fiid_obj_t obj_cmd_rs = NULL;
  uint8_t call_retry_interval;
  uint64_t val;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
  ipmi_config_err_t ret;
  uint8_t channel_number;

  assert (state_data);
  assert (section_name);
  assert (kv);

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_serial_modem_configuration_call_retry_interval_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  if ((ret = get_serial_channel_number (state_data, section_name, &channel_number)) != IPMI_CONFIG_ERR_SUCCESS)
    {
      rv = ret;
      goto cleanup;
    }

  if (ipmi_cmd_get_serial_modem_configuration_call_retry_interval (state_data->ipmi_ctx,
                                                                   channel_number,
                                                                   IPMI_GET_SERIAL_MODEM_PARAMETER,
                                                                   IPMI_SERIAL_MODEM_CONFIGURATION_NO_SET_SELECTOR,
                                                                   IPMI_SERIAL_MODEM_CONFIGURATION_NO_BLOCK_SELECTOR,
                                                                   obj_cmd_rs) < 0)
    {
      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_serial_modem_configuration_call_retry_interval: %s\n",
                         ipmi_ctx_errormsg (state_data->ipmi_ctx));

      goto cleanup;
    }

  if (FIID_OBJ_GET (obj_cmd_rs, "call_retry_interval", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'call_retry_interval': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  call_retry_interval = val;

  if (ipmi_config_section_update_keyvalue_output_unsigned_int (state_data,
                                                               kv,
                                                               call_retry_interval) < 0)
    return (IPMI_CONFIG_ERR_FATAL_ERROR);

  rv = IPMI_CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_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);
}
static ipmi_config_err_t
asset_tag_checkout (ipmi_config_state_data_t *state_data,
                    const char *section_name,
                    struct ipmi_config_keyvalue *kv)
{
  fiid_obj_t obj_cmd_rs = NULL;
  char asset_tag_data[IPMI_DCMI_MAX_ASSET_TAG_LENGTH + 1];
  int data_len;
  unsigned int offset = 0;
  uint8_t total_asset_tag_length = 0;
  uint8_t bytes_to_read = IPMI_DCMI_ASSET_TAG_NUMBER_OF_BYTES_TO_READ_MAX;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
  ipmi_config_err_t ret;

  assert (state_data);
  assert (section_name);
  assert (kv);

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_dcmi_get_asset_tag_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  memset (asset_tag_data, '\0', IPMI_DCMI_MAX_ASSET_TAG_LENGTH + 1);

  while (1)
    {
      uint64_t val;

      if (!offset
          || ((total_asset_tag_length - offset) >= IPMI_DCMI_ASSET_TAG_NUMBER_OF_BYTES_TO_READ_MAX))
        bytes_to_read = IPMI_DCMI_ASSET_TAG_NUMBER_OF_BYTES_TO_READ_MAX;
      else 
        bytes_to_read = total_asset_tag_length - offset;
      
      if (ipmi_cmd_dcmi_get_asset_tag (state_data->ipmi_ctx,
                                       offset,
                                       bytes_to_read,
                                       obj_cmd_rs) < 0)
        {
          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_dcmi_get_asset_tag: %s\n",
                             ipmi_ctx_errormsg (state_data->ipmi_ctx));
          
          goto cleanup;
        }

      if (FIID_OBJ_GET (obj_cmd_rs,
                        "total_asset_tag_length",
                        &val) < 0)
        {
          pstdout_fprintf (state_data->pstate,
                           stderr,
                           "fiid_obj_get: 'total_asset_tag_length': %s\n",
                           fiid_obj_errormsg (obj_cmd_rs));
          goto cleanup;
        }
      total_asset_tag_length = val;

      if (!total_asset_tag_length)
        break;

      if ((data_len = fiid_obj_get_data (obj_cmd_rs,
                                         "data",
                                         asset_tag_data + offset,
                                         IPMI_DCMI_MAX_ASSET_TAG_LENGTH - offset)) < 0)
        {
          pstdout_fprintf (state_data->pstate,
                           stderr,
                           "fiid_obj_get_data: 'data': %s\n",
                           fiid_obj_errormsg (obj_cmd_rs));
          goto cleanup;
        }
      offset += data_len;

      if (offset >= total_asset_tag_length)
        break;
    }

  /* Handle special case UTF-8 encoding w/ BOM prefix */
  if (asset_tag_data[0] == IPMI_DCMI_ASSET_TAG_UTF8_BOM_BYTE0
      && asset_tag_data[1] == IPMI_DCMI_ASSET_TAG_UTF8_BOM_BYTE1
      && asset_tag_data[2] == IPMI_DCMI_ASSET_TAG_UTF8_BOM_BYTE2)
    {
      /* achu: I think this is right for UTF-8 in libc and is
       * portable, but I would bet some systems won't like this.
       */
      if (ipmi_config_section_update_keyvalue_output (state_data,
                                                      kv,
                                                      &asset_tag_data[3]) < 0)
        return (IPMI_CONFIG_ERR_FATAL_ERROR);
    }
  else
    {
      if (ipmi_config_section_update_keyvalue_output (state_data,
                                                      kv,
                                                      asset_tag_data) < 0)
        return (IPMI_CONFIG_ERR_FATAL_ERROR);
    }

  rv = IPMI_CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}
int
ipmiconsole_check_session_id (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint32_t session_id, expected_session_id;
    uint64_t val;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (IPMICONSOLE_PACKET_TYPE_RESPONSE (p));
    assert (p == IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_RESPONSE
            || p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_2
            || p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_4
            || p == IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RS
            || p == IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_SOL_PAYLOAD_DATA_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RS
            || p == IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RS);

    if (p == IPMICONSOLE_PACKET_TYPE_OPEN_SESSION_RESPONSE
            || p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_2
            || p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_4)
    {
        fiid_obj_t obj_cmd;

        obj_cmd = ipmiconsole_packet_object (c, p);

        if (FIID_OBJ_GET (obj_cmd,
                          "remote_console_session_id",
                          &val) < 0)
        {
            IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'remote_console_session_id': %s",
                                       fiid_obj_errormsg (obj_cmd)));
            ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
            return (-1);
        }
        session_id = val;
        expected_session_id = c->session.remote_console_session_id;
    }
    else
    {
        if (FIID_OBJ_GET (c->connection.obj_rmcpplus_session_hdr_rs,
                          "session_id",
                          &val) < 0)
        {
            IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'session_id': %s",
                                       fiid_obj_errormsg (c->connection.obj_rmcpplus_session_hdr_rs)));
            ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
            return (-1);
        }
        session_id = val;
        expected_session_id = c->session.remote_console_session_id;
    }

    if (session_id != expected_session_id)
        IPMICONSOLE_CTX_DEBUG (c, ("session id check failed; p = %d; session_id = %Xh; expected_session_id = %Xh", p, session_id, expected_session_id));

    return ((session_id == expected_session_id) ? 1 : 0);
}
static ipmi_config_err_t
_get_ipmi_messaging_comm_settings (ipmi_config_state_data_t *state_data,
                                   const char *section_name,
                                   struct ipmi_messaging_comm_settings *cs)
{
  fiid_obj_t obj_cmd_rs = NULL;
  uint64_t val;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
  ipmi_config_err_t ret;
  uint8_t channel_number;

  assert (state_data);
  assert (section_name);
  assert (cs);

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_serial_modem_configuration_ipmi_messaging_comm_settings_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  if ((ret = get_serial_channel_number (state_data, section_name, &channel_number)) != IPMI_CONFIG_ERR_SUCCESS)
    {
      rv = ret;
      goto cleanup;
    }

  if (ipmi_cmd_get_serial_modem_configuration_ipmi_messaging_comm_settings (state_data->ipmi_ctx,
                                                                            channel_number,
                                                                            IPMI_GET_SERIAL_MODEM_PARAMETER,
                                                                            IPMI_SERIAL_MODEM_CONFIGURATION_NO_SET_SELECTOR,
                                                                            IPMI_SERIAL_MODEM_CONFIGURATION_NO_BLOCK_SELECTOR,
                                                                            obj_cmd_rs) < 0)
    {
      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_serial_modem_configuration_ipmi_messaging_comm_settings: %s\n",
                         ipmi_ctx_errormsg (state_data->ipmi_ctx));

      goto cleanup;
    }

  if (FIID_OBJ_GET (obj_cmd_rs, "dtr_hangup", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'dtr_hangup': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  cs->dtr_hangup = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "flow_control", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'flow_control': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  cs->flow_control = val;

  if (FIID_OBJ_GET (obj_cmd_rs, "bit_rate", &val) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get: 'bit_rate': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }
  cs->bit_rate = val;

  rv = IPMI_CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}
int
ipmiconsole_check_rakp_4_integrity_check_value (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint8_t managed_system_guid[IPMI_MANAGED_SYSTEM_GUID_LENGTH];
    int managed_system_guid_len;
    uint32_t managed_system_session_id;
    uint8_t authentication_algorithm = 0;
    uint64_t val;
    int rv;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (p == IPMICONSOLE_PACKET_TYPE_RAKP_MESSAGE_4);

    /* IPMI Workaround
     *
     * Intel IPMI 2.0 implementations respond with the integrity check
     * value based on the integrity algorithm rather than the
     * authentication algorithm.
     */
    if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_INTEL_2_0_SESSION)
    {
        if (c->config.integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE)
            authentication_algorithm = IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE;
        else if (c->config.integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96)
            authentication_algorithm = IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1;
        else if (c->config.integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128)
            authentication_algorithm = IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5;
        else if (c->config.integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128)
        {
            /* achu: I have thus far been unable to reverse engineer this
             * corner case.  Since we cannot provide a reasonable two
             * part authentication, we're going to error out.
             */
            IPMICONSOLE_CTX_DEBUG (c, ("Intel Non-Compliance: Cannot Reverse Engineer"));
            ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_BMC_ERROR);
            return (0);
        }
    }
    else
        authentication_algorithm = c->config.authentication_algorithm;

    if (FIID_OBJ_GET (c->connection.obj_open_session_response,
                      "managed_system_session_id",
                      &val) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'managed_system_session_id': %s",
                                   fiid_obj_errormsg (c->connection.obj_open_session_response)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }
    managed_system_session_id = val;

    if ((managed_system_guid_len = fiid_obj_get_data (c->connection.obj_rakp_message_2,
                                   "managed_system_guid",
                                   managed_system_guid,
                                   IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH)) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: 'managed_system_guid': %s",
                                   fiid_obj_errormsg (c->connection.obj_rakp_message_2)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }

    if (managed_system_guid_len != IPMI_MANAGED_SYSTEM_GUID_LENGTH)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_get_data: invalid managed system guid length: %d",
                                   managed_system_guid_len));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }

    /* IPMI Workaround (achu)
     *
     * Discovered on Supermicro X8DTG, Supermicro X8DTU, Intel
     * S5500WBV/Penguin Relion 700
     *
     * For whatever reason, with cipher suite 0, the RAKP 4 response
     * returns with an Integrity Check Value when it should be empty.
     */

    if (c->config.workaround_flags & IPMICONSOLE_WORKAROUND_NON_EMPTY_INTEGRITY_CHECK_VALUE
            && !c->config.cipher_suite_id)
    {
        if (fiid_obj_clear_field (c->connection.obj_rakp_message_4,
                                  "integrity_check_value") < 0)
        {
            IPMICONSOLE_CTX_DEBUG (c, ("fiid_obj_clear_field: 'integrity_check_value': %s",
                                       fiid_obj_errormsg (c->connection.obj_rakp_message_4)));
            ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
            return (-1);
        }
    }

    if ((rv = ipmi_rmcpplus_check_rakp_4_integrity_check_value (authentication_algorithm,
              c->session.sik_key_ptr,
              c->session.sik_key_len,
              c->session.remote_console_random_number,
              IPMI_REMOTE_CONSOLE_RANDOM_NUMBER_LENGTH,
              managed_system_session_id,
              managed_system_guid,
              managed_system_guid_len,
              c->connection.obj_rakp_message_4)) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("ipmi_rmcpplus_check_rakp_4_integrity_check_value: p = %d; %s", p, strerror (errno)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }

    if (!rv)
        IPMICONSOLE_CTX_DEBUG (c, ("rakp 4 integrity check value check failed; p = %d", p));

    return (rv);
}
int
ipmiconsole_check_command (ipmiconsole_ctx_t c, ipmiconsole_packet_type_t p)
{
    uint8_t cmd, expected_cmd;
    fiid_obj_t obj_cmd;
    uint64_t val;

    assert (c);
    assert (c->magic == IPMICONSOLE_CTX_MAGIC);
    assert (IPMICONSOLE_PACKET_TYPE_RESPONSE (p));
    assert (p == IPMICONSOLE_PACKET_TYPE_GET_AUTHENTICATION_CAPABILITIES_RS
            || p == IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RS
            || p == IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RS
            || p == IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RS
            || p == IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RS);

    obj_cmd = ipmiconsole_packet_object (c, p);
    if (FIID_OBJ_GET (obj_cmd,
                      "cmd",
                      &val) < 0)
    {
        IPMICONSOLE_CTX_DEBUG (c, ("FIID_OBJ_GET: 'cmd': %s",
                                   fiid_obj_errormsg (obj_cmd)));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }
    cmd = val;

    switch (p)
    {
    case IPMICONSOLE_PACKET_TYPE_GET_AUTHENTICATION_CAPABILITIES_RS:
        expected_cmd = IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES;
        break;
    case IPMICONSOLE_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS:
        expected_cmd = IPMI_CMD_SET_SESSION_PRIVILEGE_LEVEL;
        break;
    case IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_SUPPORT_RS:
        expected_cmd = IPMI_CMD_GET_CHANNEL_PAYLOAD_SUPPORT;
        break;
    case IPMICONSOLE_PACKET_TYPE_GET_PAYLOAD_ACTIVATION_STATUS_RS:
        expected_cmd = IPMI_CMD_GET_PAYLOAD_ACTIVATION_STATUS;
        break;
    case IPMICONSOLE_PACKET_TYPE_ACTIVATE_PAYLOAD_RS:
        expected_cmd = IPMI_CMD_ACTIVATE_PAYLOAD;
        break;
    case IPMICONSOLE_PACKET_TYPE_GET_CHANNEL_PAYLOAD_VERSION_RS:
        expected_cmd = IPMI_CMD_GET_CHANNEL_PAYLOAD_VERSION;
        break;
    case IPMICONSOLE_PACKET_TYPE_DEACTIVATE_PAYLOAD_RS:
        expected_cmd = IPMI_CMD_DEACTIVATE_PAYLOAD;
        break;
    case IPMICONSOLE_PACKET_TYPE_CLOSE_SESSION_RS:
        expected_cmd = IPMI_CMD_CLOSE_SESSION;
        break;
    default:
        IPMICONSOLE_CTX_DEBUG (c, ("invalid packet type: p = %d", p));
        ipmiconsole_ctx_set_errnum (c, IPMICONSOLE_ERR_INTERNAL_ERROR);
        return (-1);
    }

    if (cmd != expected_cmd)
        IPMICONSOLE_CTX_DEBUG (c, ("command check failed; p = %d; cmd = %Xh; expected_cmd = %Xh", p, cmd, expected_cmd));

    return ((cmd == expected_cmd) ? 1 : 0);
}
int
ipmi_oem_get_system_info_string (ipmi_oem_state_data_t *state_data,
				 uint8_t parameter_selector,
				 uint8_t set_selector,
				 uint8_t block_selector,
				 char *string,
				 unsigned int string_len,
				 unsigned int *string_len_ret)
{
  fiid_obj_t obj_cmd_rs = NULL;
  uint8_t configuration_parameter_data[IPMI_OEM_MAX_BYTES];
  int len;
  int rv = -1;

  assert (state_data);
  assert (string);
  assert (string_len);

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_system_info_parameters_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  if (ipmi_cmd_get_system_info_parameters (state_data->ipmi_ctx,
                                           IPMI_GET_SYSTEM_INFO_PARAMETER,
                                           parameter_selector,
					   set_selector,
					   block_selector,
                                           obj_cmd_rs) < 0)
    {
      if ((ipmi_ctx_errnum (state_data->ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE
	   && ipmi_check_completion_code (obj_cmd_rs,
					  IPMI_COMP_CODE_GET_SYSTEM_INFO_PARAMETERS_PARAMETER_NOT_SUPPORTED) == 1)
	  || (ipmi_ctx_errnum (state_data->ipmi_ctx) == IPMI_ERR_COMMAND_INVALID_OR_UNSUPPORTED
	      && ipmi_check_completion_code (obj_cmd_rs,
					     IPMI_COMP_CODE_INVALID_DATA_FIELD_IN_REQUEST) == 1))
	{
	  pstdout_fprintf (state_data->pstate,
			   stderr,
			   "%s:%s '%s' option not supported on this system\n",
			   state_data->prog_data->args->oem_id,
			   state_data->prog_data->args->oem_command,
			   state_data->prog_data->args->oem_options[0]);
	  goto cleanup;
	}
      
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_cmd_get_system_info_parameters: %s\n",
                       ipmi_ctx_errormsg (state_data->ipmi_ctx));
      goto cleanup;
    }

  if ((len = fiid_obj_get_data (obj_cmd_rs,
                                "configuration_parameter_data",
                                configuration_parameter_data,
                                IPMI_OEM_MAX_BYTES)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get_data: 'configuration_parameter_data': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (len > string_len)
    {
      pstdout_fprintf (state_data->pstate,
		       stderr,
		       "buffer overflow\n");
      goto cleanup;
    }
  
  memcpy (string,
	  &(configuration_parameter_data[0]),
	  len);

  if (string_len_ret)
    (*string_len_ret) = len;

  rv = 0;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}
static ipmi_config_err_t
_get_key (ipmi_config_state_data_t *state_data,
          const char *section_name,
          uint8_t key_type,
          void *key,
          unsigned int key_len)
{
  fiid_obj_t obj_cmd_rs = NULL;
  uint8_t buf[IPMI_CONFIG_PARSE_BUFLEN];
  int buf_len;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
  ipmi_config_err_t ret;
  uint8_t channel_number;

  assert (state_data);
  assert (section_name);
  assert (key_type == IPMI_CHANNEL_SECURITY_KEYS_KEY_ID_K_R
          || key_type == IPMI_CHANNEL_SECURITY_KEYS_KEY_ID_K_G);
  assert (key);
  assert (key_len);

  if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_set_channel_security_keys_rs)))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_create: %s\n",
                       strerror (errno));
      goto cleanup;
    }

  if ((ret = get_lan_channel_number (state_data, section_name, &channel_number)) != IPMI_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_READ_KEY,
                                          key_type,
                                          NULL,
                                          0,
                                          obj_cmd_rs) < 0)
    {
      if (!IPMI_CTX_ERRNUM_IS_FATAL_ERROR (state_data->ipmi_ctx))
        rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;

      if (rv == IPMI_CONFIG_ERR_FATAL_ERROR
	  || state_data->prog_data->args->common_args.debug)
        pstdout_fprintf (state_data->pstate,
                         stderr,
                         "ipmi_cmd_set_channel_security_keys: %s\n",
                         ipmi_ctx_errormsg (state_data->ipmi_ctx));

      goto cleanup;
    }

  if ((buf_len = fiid_obj_get_data (obj_cmd_rs,
                                    "key_value",
                                    buf,
                                    IPMI_CONFIG_PARSE_BUFLEN)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "fiid_obj_get_data: 'key_value': %s\n",
                       fiid_obj_errormsg (obj_cmd_rs));
      goto cleanup;
    }

  if (key_len < buf_len)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_cmd_set_channel_security_keys: short buffer\n");
      goto cleanup;
    }
  memcpy (key, buf, buf_len);

  rv = IPMI_CONFIG_ERR_SUCCESS;
 cleanup:
  fiid_obj_destroy (obj_cmd_rs);
  return (rv);
}