示例#1
0
int
fill_ipmb_msg_hdr (uint8_t rs_addr,
                   uint8_t net_fn,
                   uint8_t rs_lun,
                   uint8_t rq_addr,
                   uint8_t rq_lun,
                   uint8_t rq_seq,
                   fiid_obj_t obj_ipmb_msg_hdr)
{
  uint8_t checksum_buf[1024];
  int checksum_len;
  uint8_t checksum;

  if (!IPMI_NET_FN_VALID (net_fn)
      || !IPMI_BMC_LUN_VALID (rs_lun)
      || !IPMI_BMC_LUN_VALID (rq_lun)
      || (rq_seq > IPMI_IPMB_REQUESTER_SEQUENCE_NUMBER_MAX)
      || !fiid_obj_valid (obj_ipmb_msg_hdr))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (FIID_OBJ_TEMPLATE_COMPARE (obj_ipmb_msg_hdr, tmpl_ipmb_msg_hdr_rq) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  FILL_FIID_OBJ_CLEAR (obj_ipmb_msg_hdr);
  FILL_FIID_OBJ_SET (obj_ipmb_msg_hdr, "rs_addr", rs_addr);
  FILL_FIID_OBJ_SET (obj_ipmb_msg_hdr, "net_fn", net_fn);
  FILL_FIID_OBJ_SET (obj_ipmb_msg_hdr, "rs_lun", rs_lun);

  if ((checksum_len = fiid_obj_get_block (obj_ipmb_msg_hdr,
                                          "rs_addr",
                                          "net_fn",
                                          checksum_buf,
                                          1024)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_hdr);
      return (-1);
    }

  checksum = ipmi_checksum (checksum_buf, checksum_len);
  FILL_FIID_OBJ_SET (obj_ipmb_msg_hdr, "checksum1", checksum);
  FILL_FIID_OBJ_SET (obj_ipmb_msg_hdr, "rq_addr", rq_addr);
  FILL_FIID_OBJ_SET (obj_ipmb_msg_hdr, "rq_lun", rq_lun);
  FILL_FIID_OBJ_SET (obj_ipmb_msg_hdr, "rq_seq", rq_seq);

  return (0);
}
int
fill_hdr_ipmi_kcs (uint8_t lun,
                   uint8_t fn,
                   fiid_obj_t obj_kcs_hdr)
{
  if (!IPMI_BMC_LUN_VALID (lun)
      || !IPMI_NET_FN_VALID (fn)
      || !fiid_obj_valid (obj_kcs_hdr))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (FIID_OBJ_TEMPLATE_COMPARE (obj_kcs_hdr, tmpl_hdr_kcs) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  FILL_FIID_OBJ_CLEAR (obj_kcs_hdr);
  FILL_FIID_OBJ_SET (obj_kcs_hdr, "lun", lun);
  FILL_FIID_OBJ_SET (obj_kcs_hdr, "net_fn", fn);

  return (0);
}
int
fill_cmd_set_command_enables (uint8_t channel_number,
                              uint8_t net_fn,
                              uint8_t operation,
                              uint8_t lun,
                              uint8_t *enable_disable_bitmask,
                              unsigned int enable_disable_bitmask_len,
                              uint32_t net_fn_data,
                              fiid_obj_t obj_cmd_rq)
{
  if (!IPMI_CHANNEL_NUMBER_VALID (channel_number)
      || !IPMI_NET_FN_VALID (net_fn)
      || !IPMI_FIRMWARE_FIREWALL_COMMAND_DISCOVERY_OPERATION_VALID (operation)
      || !IPMI_BMC_LUN_VALID (lun)
      || !enable_disable_bitmask
      || enable_disable_bitmask_len < IPMI_FIRMWARE_FIREWALL_COMMAND_DISCOVERY_ENABLE_DISABLE_BITMASK_LEN
      || !fiid_obj_valid (obj_cmd_rq))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }
  
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_cmd_rq, tmpl_cmd_set_command_enables_rq) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  FILL_FIID_OBJ_CLEAR (obj_cmd_rq);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "cmd", IPMI_CMD_SET_COMMAND_ENABLES);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "channel_number", channel_number);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "reserved1", 0);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "net_fn", net_fn);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "operation", operation);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "lun", lun);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "reserved2", 0);
  FILL_FIID_OBJ_SET_DATA (obj_cmd_rq,
                          "enable_disable_mask",
                          enable_disable_bitmask,
                          IPMI_FIRMWARE_FIREWALL_COMMAND_DISCOVERY_ENABLE_DISABLE_BITMASK_LEN);
  if (net_fn == IPMI_NET_FN_GROUP_EXTENSION_RQ
      || net_fn == IPMI_NET_FN_GROUP_EXTENSION_RS)
    {
      uint8_t tmp = net_fn_data;
      FILL_FIID_OBJ_SET_DATA (obj_cmd_rq, "net_fn_data", &tmp, 1);
    }
  else if (net_fn == IPMI_NET_FN_OEM_GROUP_RQ
           || net_fn == IPMI_NET_FN_OEM_GROUP_RS)
    FILL_FIID_OBJ_SET (obj_cmd_rq, "net_fn_data", net_fn_data);
  
  return (0);
}
示例#4
0
int
ipmi_openipmi_cmd_ipmb (ipmi_openipmi_ctx_t ctx,
                        uint8_t channel_number,
                        uint8_t rs_addr,
                        uint8_t lun,
                        uint8_t net_fn,
                        fiid_obj_t obj_cmd_rq,
                        fiid_obj_t obj_cmd_rs)
{
  if (!ctx || ctx->magic != IPMI_OPENIPMI_CTX_MAGIC)
    {
      ERR_TRACE (ipmi_openipmi_ctx_errormsg (ctx), ipmi_openipmi_ctx_errnum (ctx));
      return (-1);
    }

  if (!IPMI_CHANNEL_NUMBER_VALID (channel_number)
      || !IPMI_BMC_LUN_VALID (lun)
      || !IPMI_NET_FN_RQ_VALID (net_fn)
      || !fiid_obj_valid (obj_cmd_rq)
      || !fiid_obj_valid (obj_cmd_rs)
      || fiid_obj_packet_valid (obj_cmd_rq) <= 0)
    {
      OPENIPMI_SET_ERRNUM (ctx, IPMI_OPENIPMI_ERR_PARAMETERS);
      return (-1);
    }

  if (!ctx->io_init)
    {
      OPENIPMI_SET_ERRNUM (ctx, IPMI_OPENIPMI_ERR_IO_NOT_INITIALIZED);
      return (-1);
    }

  if (_openipmi_write (ctx,
                       channel_number,
                       rs_addr,
                       lun,
                       net_fn,
                       obj_cmd_rq,
                       1) < 0)
    return (-1);

  if (_openipmi_read (ctx,
                      obj_cmd_rs) < 0)
    return (-1);

  return (0);
}
int
fill_cmd_get_command_sub_function_enables (uint8_t channel_number,
                                           uint8_t net_fn,
                                           uint8_t lun,
                                           uint8_t command,
                                           uint32_t net_fn_data,
                                           fiid_obj_t obj_cmd_rq)
{
  if (!IPMI_CHANNEL_NUMBER_VALID (channel_number)
      || !IPMI_NET_FN_VALID (net_fn)
      || !IPMI_BMC_LUN_VALID (lun)
      || !fiid_obj_valid (obj_cmd_rq))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }
  
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_cmd_rq, tmpl_cmd_get_command_sub_function_enables_rq) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  FILL_FIID_OBJ_CLEAR (obj_cmd_rq);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "cmd", IPMI_CMD_GET_COMMAND_SUB_FUNCTION_ENABLES);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "channel_number", channel_number);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "reserved1", 0);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "net_fn", net_fn);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "reserved2", 0);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "lun", lun);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "reserved3", 0);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "command", command);
  if (net_fn == IPMI_NET_FN_GROUP_EXTENSION_RQ
      || net_fn == IPMI_NET_FN_GROUP_EXTENSION_RS)
    {
      uint8_t tmp = net_fn_data;
      FILL_FIID_OBJ_SET_DATA (obj_cmd_rq, "net_fn_data", &tmp, 1);
    }
  else if (net_fn == IPMI_NET_FN_OEM_GROUP_RQ
           || net_fn == IPMI_NET_FN_OEM_GROUP_RS)
    FILL_FIID_OBJ_SET (obj_cmd_rq, "net_fn_data", net_fn_data);
  
  return (0);
}
int
fill_cmd_get_configurable_commands (uint8_t channel_number,
                                    uint8_t net_fn,
                                    uint8_t operation,
                                    uint8_t lun,
                                    uint32_t net_fn_data,
                                    fiid_obj_t obj_cmd_rq)
{
  if (!IPMI_CHANNEL_NUMBER_VALID (channel_number)
      || !IPMI_NET_FN_VALID (net_fn)
      || !IPMI_FIRMWARE_FIREWALL_COMMAND_DISCOVERY_OPERATION_VALID (operation)
      || !IPMI_BMC_LUN_VALID (lun)
      || !fiid_obj_valid (obj_cmd_rq))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }
  
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_cmd_rq, tmpl_cmd_get_configurable_commands_rq) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  FILL_FIID_OBJ_CLEAR (obj_cmd_rq);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "cmd", IPMI_CMD_GET_CONFIGURABLE_COMMANDS);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "channel_number", channel_number);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "reserved1", 0);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "net_fn", net_fn);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "operation", operation);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "lun", lun);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "reserved2", 0);
  if (net_fn == IPMI_NET_FN_GROUP_EXTENSION_RQ
      || net_fn == IPMI_NET_FN_GROUP_EXTENSION_RS)
    {
      uint8_t tmp = net_fn_data;
      FILL_FIID_OBJ_SET_DATA (obj_cmd_rq, "net_fn_data", &tmp, 1);
    }
  else if (net_fn == IPMI_NET_FN_OEM_GROUP_RQ
           || net_fn == IPMI_NET_FN_OEM_GROUP_RS)
    FILL_FIID_OBJ_SET (obj_cmd_rq, "net_fn_data", net_fn_data);
  
  return (0);
}
int
fill_cmd_set_command_sub_function_enables_oem_iana (uint8_t channel_number,
                                                    uint8_t net_fn,
                                                    uint8_t lun,
                                                    uint8_t command,
                                                    uint32_t oem_iana,
                                                    uint32_t sub_function_enables1,
                                                    uint32_t *sub_function_enables2,
                                                    fiid_obj_t obj_cmd_rq)
{
  if (!IPMI_CHANNEL_NUMBER_VALID (channel_number)
      || (net_fn != IPMI_NET_FN_OEM_GROUP_RQ
          && net_fn != IPMI_NET_FN_OEM_GROUP_RS)
      || !IPMI_BMC_LUN_VALID (lun)
      || !fiid_obj_valid (obj_cmd_rq))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }
  
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_cmd_rq, tmpl_cmd_set_command_sub_function_enables_rq) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  FILL_FIID_OBJ_CLEAR (obj_cmd_rq);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "cmd", IPMI_CMD_SET_COMMAND_SUB_FUNCTION_ENABLES);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "channel_number", channel_number);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "reserved1", 0);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "net_fn", net_fn);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "reserved2", 0);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "lun", lun);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "reserved3", 0);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "command", command);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "oem_iana", oem_iana);
  FILL_FIID_OBJ_SET (obj_cmd_rq, "sub_function_enables1", sub_function_enables1);
  if (sub_function_enables2)
    FILL_FIID_OBJ_SET (obj_cmd_rq, "sub_function_enables2", *sub_function_enables2);
  
  return (0);
}
示例#8
0
int
ipmi_kcs_cmd (ipmi_kcs_ctx_t ctx,
              uint8_t lun,
              uint8_t net_fn,
              fiid_obj_t obj_cmd_rq,
              fiid_obj_t obj_cmd_rs)
{
  if (!ctx || ctx->magic != IPMI_KCS_CTX_MAGIC)
    {
      ERR_TRACE (ipmi_kcs_ctx_errormsg (ctx), ipmi_kcs_ctx_errnum (ctx));
      return (-1);
    }

  if (!IPMI_BMC_LUN_VALID (lun)
      || !IPMI_NET_FN_RQ_VALID (net_fn)
      || !fiid_obj_valid (obj_cmd_rq)
      || !fiid_obj_valid (obj_cmd_rs)
      || fiid_obj_packet_valid (obj_cmd_rq) <= 0)
    {
      KCS_SET_ERRNUM (ctx, IPMI_KCS_ERR_PARAMETERS);
      return (-1);
    }

  if (!ctx->io_init)
    {
      KCS_SET_ERRNUM (ctx, IPMI_KCS_ERR_IO_NOT_INITIALIZED);
      return (-1);
    }

  if (_ipmi_kcs_cmd_write (ctx, lun, net_fn, obj_cmd_rq) < 0)
    return (-1);

  if (_ipmi_kcs_cmd_read (ctx, obj_cmd_rs) < 0)
    return (-1);

  return (0);
}
示例#9
0
int
ipmi_sunbmc_cmd (ipmi_sunbmc_ctx_t ctx,
                 uint8_t lun,
                 uint8_t net_fn,
                 fiid_obj_t obj_cmd_rq,
                 fiid_obj_t obj_cmd_rs)
{
  if (!ctx || ctx->magic != IPMI_SUNBMC_CTX_MAGIC)
    {
      ERR_TRACE (ipmi_sunbmc_ctx_errormsg (ctx), ipmi_sunbmc_ctx_errnum (ctx));
      return (-1);
    }

  if (!IPMI_BMC_LUN_VALID (lun)
      || !IPMI_NET_FN_RQ_VALID (net_fn)
      || !fiid_obj_valid (obj_cmd_rq)
      || !fiid_obj_valid (obj_cmd_rs)
      || fiid_obj_packet_valid (obj_cmd_rq) <= 0)
    {
      SUNBMC_SET_ERRNUM (ctx, IPMI_SUNBMC_ERR_PARAMETERS);
      return (-1);
    }

  if (!ctx->io_init)
    {
      SUNBMC_SET_ERRNUM (ctx, IPMI_SUNBMC_ERR_IO_NOT_INITIALIZED);
      return (-1);
    }

  if (ctx->putmsg_intf)
    {
      if (_sunbmc_write (ctx,
                         lun,
                         net_fn,
                         obj_cmd_rq) < 0)
        return (-1);

      if (_sunbmc_read (ctx,
                        obj_cmd_rs) < 0)
        return (-1);
    }
  else
    {
#if defined(HAVE_SYS_STROPTS_H)
      struct strioctl istr;
      bmc_reqrsp_t reqrsp;
      uint8_t rq_buf_temp[IPMI_SUNBMC_BUFLEN];
      uint8_t rq_buf[IPMI_SUNBMC_BUFLEN];
      uint8_t rq_cmd;
      unsigned int rq_buf_len;
      uint8_t rs_buf[IPMI_SUNBMC_BUFLEN];
      int len;

      memset (&istr, '\0', sizeof (struct strioctl));
      memset (&reqrsp, '\0', sizeof (bmc_reqrsp_t));

      /* Due to API differences, we need to extract the cmd out of the
       * request.
       */
      memset (rq_buf_temp, '\0', IPMI_SUNBMC_BUFLEN);

      if ((len = fiid_obj_get_all (obj_cmd_rq,
                                   rq_buf_temp,
                                   IPMI_SUNBMC_BUFLEN)) <= 0)
        {
          SUNBMC_SET_ERRNUM (ctx, IPMI_SUNBMC_ERR_INTERNAL_ERROR);
          return (-1);
        }

      rq_cmd = rq_buf_temp[0];
      if (len > 1)
        {
          /* -1 b/c of cmd */
          memcpy (rq_buf, &rq_buf_temp[1], len - 1);
          rq_buf_len = len - 1;
        }
      else
        rq_buf_len = 0;

      reqrsp.req.fn = net_fn;
      reqrsp.req.lun = lun;
      reqrsp.req.cmd = rq_cmd;

      istr.ic_cmd = IOCTL_IPMI_KCS_ACTION;
      istr.ic_timout = 0;       /* spelled 'timout', not a typo */
      istr.ic_len = sizeof (struct bmc_reqrsp);
      istr.ic_dp = (char *)&reqrsp;

      if (ioctl (ctx->device_fd,
                 I_STR,
                 &istr) < 0)
        {
          SUNBMC_ERRNO_TO_SUNBMC_ERRNUM (ctx, errno);
          return (-1);
        }

      rs_buf[0] = reqrsp.rsp.cmd;
      rs_buf[1] = reqrsp.rsp.ccode;
      /* -2 b/c of cmd and ccode */
#if 0
      /* achu: to remove warnings, IPMI_SUNBMC_BUFLEN > amount uint8_t can hold */
      if (reqrsp.rsp.datalength >= (IPMI_SUNBMC_BUFLEN - 2))
        reqrsp.rsp.datalength = IPMI_SUNBMC_BUFLEN - 2;
#endif
      /* remove header data stuff in front we don't care about */
      if (reqrsp.rsp.datalength > 3)
        reqrsp.rsp.datalength -= 3;
      else
        reqrsp.rsp.datalength = 0;
      memcpy (rs_buf + 2, reqrsp.rsp.data, reqrsp.rsp.datalength);

      if (fiid_obj_set_all (obj_cmd_rs,
                            rs_buf,
                            reqrsp.rsp.datalength + 2) < 0)
        {
          SUNBMC_SET_ERRNUM (ctx, IPMI_SUNBMC_ERR_INTERNAL_ERROR);
          return (-1);
        }
#else /* !defined(HAVE_SYS_STROPTS_H) */
      /* otherwise, device is not supported */
      SUNBMC_SET_ERRNUM (ctx, IPMI_SUNBMC_ERR_DEVICE_NOT_SUPPORTED);
      return (-1);
#endif /* !defined(HAVE_SYS_STROPTS_H) */
    }

  return (0);
}
示例#10
0
static int
_sunbmc_write (ipmi_sunbmc_ctx_t ctx,
               uint8_t lun,
               uint8_t net_fn,
               fiid_obj_t obj_cmd_rq)
{
#if defined(HAVE_SYS_STROPTS_H)
  struct strbuf sbuf;
  bmc_msg_t *msg = NULL;
  bmc_req_t *req = NULL;
  unsigned int msg_len;
  uint8_t rq_buf_temp[IPMI_SUNBMC_BUFLEN];
  uint8_t rq_buf[IPMI_SUNBMC_BUFLEN];
  uint8_t rq_cmd;
  unsigned int rq_buf_len;
  int len;
#endif /* !defined(HAVE_SYS_STROPTS_H) */
  int rv = -1;

  assert (ctx);
  assert (ctx->magic == IPMI_SUNBMC_CTX_MAGIC);
  assert (IPMI_BMC_LUN_VALID (lun));
  assert (IPMI_NET_FN_RQ_VALID (net_fn));
  assert (fiid_obj_valid (obj_cmd_rq));
  assert (fiid_obj_packet_valid (obj_cmd_rq) == 1);
  assert (ctx->io_init);
  assert (ctx->putmsg_intf);

#if defined(HAVE_SYS_STROPTS_H)
  memset (&sbuf, '\0', sizeof (struct strbuf));

  /* Due to API differences, we need to extract the cmd out of the
   * request.
   */
  memset (rq_buf_temp, '\0', IPMI_SUNBMC_BUFLEN);

  if ((len = fiid_obj_get_all (obj_cmd_rq,
                               rq_buf_temp,
                               IPMI_SUNBMC_BUFLEN)) <= 0)
    {
      SUNBMC_SET_ERRNUM (ctx, IPMI_SUNBMC_ERR_INTERNAL_ERROR);
      goto cleanup;
    }

  rq_cmd = rq_buf_temp[0];
  if (len > 1)
    {
      memcpy (rq_buf, &rq_buf_temp[1], len - 1);
      rq_buf_len = len - 1;
    }
  else
    rq_buf_len = 0;

  /* achu: see header for for how this is calculated */
  msg_len = offsetof (bmc_msg_t, msg);
  msg_len += sizeof (bmc_req_t);
  msg_len += (rq_buf_len > SEND_MAX_PAYLOAD_SIZE) ? (rq_buf_len - SEND_MAX_PAYLOAD_SIZE) : 0;

  if (!(msg = (bmc_msg_t *)malloc (msg_len)))
    {
      SUNBMC_SET_ERRNUM (ctx, IPMI_SUNBMC_ERR_OUT_OF_MEMORY);
      goto cleanup;
    }

  msg->m_type = BMC_MSG_REQUEST;
  msg->m_id = ctx->putmsg_intf_msg_id;

  req = (bmc_req_t *)&(msg->msg[0]);
  req->fn = net_fn;
  req->lun = lun;
  req->cmd = rq_cmd;
  req->datalength = rq_buf_len;
  memcpy (req->data, rq_buf, rq_buf_len);

  sbuf.len = msg_len;
  sbuf.buf = (char *)msg;

  if (putmsg (ctx->device_fd, NULL, &sbuf, 0) < 0)
    {
      SUNBMC_ERRNO_TO_SUNBMC_ERRNUM (ctx, errno);
      goto cleanup;
    }

#else /* !defined(HAVE_SYS_STROPTS_H) */
  /* otherwise, device is not supported */
  SUNBMC_SET_ERRNUM (ctx, IPMI_SUNBMC_ERR_DEVICE_NOT_SUPPORTED);
  goto cleanup;
#endif /* !(defined(HAVE_BMC_INTF_H) && defined(HAVE_SYS_STROPTS_H)) */

  rv = 0;
 cleanup:
#if defined(HAVE_SYS_STROPTS_H)
  free (msg);
#endif /* !defined(HAVE_SYS_STROPTS_H) */
  return (rv);
}
示例#11
0
static int
_openipmi_write (ipmi_openipmi_ctx_t ctx,
                 uint8_t channel_number,
                 uint8_t rs_addr,
                 uint8_t lun,
                 uint8_t net_fn,
                 fiid_obj_t obj_cmd_rq,
                 unsigned int is_ipmb)
{
  uint8_t rq_buf_temp[IPMI_OPENIPMI_BUFLEN];
  uint8_t rq_buf[IPMI_OPENIPMI_BUFLEN];
  uint8_t rq_cmd;
  unsigned int rq_buf_len;
  int len;
  struct ipmi_system_interface_addr system_interface_addr;
  struct ipmi_ipmb_addr ipmb_addr;
  struct ipmi_req rq_packet;

  assert (ctx);
  assert (ctx->magic == IPMI_OPENIPMI_CTX_MAGIC);
  assert (IPMI_CHANNEL_NUMBER_VALID (channel_number));
  assert (IPMI_BMC_LUN_VALID (lun));
  assert (IPMI_NET_FN_RQ_VALID (net_fn));
  assert (fiid_obj_valid (obj_cmd_rq));
  assert (fiid_obj_packet_valid (obj_cmd_rq) == 1);

  /* Due to API differences, we need to extract the cmd out of the
   * request.
   */
  memset (rq_buf_temp, '\0', IPMI_OPENIPMI_BUFLEN);

  if ((len = fiid_obj_get_all (obj_cmd_rq,
                               rq_buf_temp,
                               IPMI_OPENIPMI_BUFLEN)) <= 0)
    {
      OPENIPMI_SET_ERRNUM (ctx, IPMI_OPENIPMI_ERR_INTERNAL_ERROR);
      return (-1);
    }

  rq_cmd = rq_buf_temp[0];
  if (len > 1)
    {
      /* -1 b/c of cmd */
      memcpy (rq_buf, &rq_buf_temp[1], len - 1);
      rq_buf_len = len - 1;
    }
  else
    rq_buf_len = 0;

  if (!is_ipmb)
    {
      system_interface_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; /* openipmi macro */
      system_interface_addr.channel = IPMI_CHANNEL_NUMBER_SYSTEM_INTERFACE; /* freeipmi macro */
      system_interface_addr.lun = lun;

      rq_packet.addr = (unsigned char *)&system_interface_addr;
      rq_packet.addr_len = sizeof (struct ipmi_system_interface_addr);
    }
  else
    {
      ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE; /* openipmi macro */
      ipmb_addr.channel = channel_number;
      ipmb_addr.slave_addr = rs_addr;
      ipmb_addr.lun = lun;

      rq_packet.addr = (unsigned char *)&ipmb_addr;
      rq_packet.addr_len = sizeof (struct ipmi_ipmb_addr);
    }

  rq_packet.msgid = 0;
  rq_packet.msg.netfn = net_fn;
  rq_packet.msg.cmd = rq_cmd;
  rq_packet.msg.data_len = rq_buf_len;
  rq_packet.msg.data = rq_buf;

  if (ioctl (ctx->device_fd,
             IPMICTL_SEND_COMMAND,
             &rq_packet) < 0)
    {
      OPENIPMI_ERRNO_TO_OPENIPMI_ERRNUM (ctx, errno);
      return (-1);
    }

  return (0);
}
示例#12
0
static int
_ipmi_kcs_cmd_write (ipmi_kcs_ctx_t ctx,
                     uint8_t lun,
                     uint8_t net_fn,
                     fiid_obj_t obj_cmd_rq)
{
  uint8_t *pkt = NULL;
  unsigned int pkt_len;
  int hdr_len, cmd_len, rv = -1;
  fiid_obj_t obj_hdr = NULL;

  assert (ctx);
  assert (ctx->magic == IPMI_KCS_CTX_MAGIC);
  assert (IPMI_BMC_LUN_VALID (lun));
  assert (IPMI_NET_FN_RQ_VALID (net_fn));
  assert (fiid_obj_valid (obj_cmd_rq));
  assert (fiid_obj_packet_valid (obj_cmd_rq) == 1);

  if ((hdr_len = fiid_template_len_bytes (tmpl_hdr_kcs)) < 0)
    {
      KCS_ERRNO_TO_KCS_ERRNUM (ctx, errno);
      goto cleanup;
    }

  if ((cmd_len = fiid_obj_len_bytes (obj_cmd_rq)) < 0)
    {
      KCS_FIID_OBJECT_ERROR_TO_KCS_ERRNUM (ctx, obj_cmd_rq);
      goto cleanup;
    }

  if (!(obj_hdr = fiid_obj_create (tmpl_hdr_kcs)))
    {
      KCS_ERRNO_TO_KCS_ERRNUM (ctx, errno);
      goto cleanup;
    }

  pkt_len = hdr_len + cmd_len;

  if (!(pkt = (uint8_t *)malloc (pkt_len)))
    {
      KCS_SET_ERRNUM (ctx, IPMI_KCS_ERR_OUT_OF_MEMORY);
      goto cleanup;
    }

  if (fill_hdr_ipmi_kcs (lun,
                         net_fn,
                         obj_hdr) < 0)
    {
      KCS_SET_ERRNUM (ctx, IPMI_KCS_ERR_INTERNAL_ERROR);
      goto cleanup;
    }

  if (assemble_ipmi_kcs_pkt (obj_hdr,
                             obj_cmd_rq,
                             pkt,
                             pkt_len,
                             IPMI_INTERFACE_FLAGS_DEFAULT) < 0)
    {
      KCS_SET_ERRNUM (ctx, IPMI_KCS_ERR_INTERNAL_ERROR);
      goto cleanup;
    }

  if (ipmi_kcs_write (ctx, pkt, pkt_len) < 0)
    goto cleanup;

  rv = 0;
 cleanup:
  fiid_obj_destroy (obj_hdr);
  free (pkt);
  return (rv);
}