Esempio n. 1
0
int
ipmi_check_completion_code (fiid_obj_t obj_cmd, uint8_t completion_code)
{
  uint8_t completion_code_recv;
  uint64_t val;

  if (!fiid_obj_valid (obj_cmd))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (FIID_OBJ_FIELD_LOOKUP (obj_cmd, "comp_code") < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if (FIID_OBJ_GET (obj_cmd, "comp_code", &val) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }
  completion_code_recv = val;

  return ((completion_code_recv == completion_code) ? 1 : 0);
}
Esempio n. 2
0
int
ipmi_check_cmd (fiid_obj_t obj_cmd, uint8_t cmd)
{
  uint8_t cmd_recv;
  uint64_t val;

  if (!fiid_obj_valid (obj_cmd))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (FIID_OBJ_FIELD_LOOKUP (obj_cmd, "cmd") < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if (FIID_OBJ_GET (obj_cmd, "cmd", &val) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }
  cmd_recv = val;

  return ((cmd_recv == cmd) ? 1 : 0);
}
Esempio n. 3
0
int
ipmi_completion_code_strerror_cmd_r (fiid_obj_t obj_cmd,
                                     uint8_t netfn,
                                     char *errstr,
                                     size_t len)
{
    uint8_t cmd, comp_code;
    uint64_t val;

    /* The netfn need not be valid */
    if (!fiid_obj_valid (obj_cmd)
            || !errstr)
    {
        SET_ERRNO (EINVAL);
        return (-1);
    }

    if (FIID_OBJ_FIELD_LOOKUP (obj_cmd, "cmd") < 0)
    {
        FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
        return (-1);
    }

    if (FIID_OBJ_FIELD_LOOKUP (obj_cmd, "comp_code") < 0)
    {
        FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
        return (-1);
    }

    if (FIID_OBJ_GET (obj_cmd, "cmd", &val) < 0)
    {
        FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
        return (-1);
    }
    cmd = val;

    if (FIID_OBJ_GET (obj_cmd, "comp_code", &val) < 0)
    {
        FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
        return (-1);
    }
    comp_code = val;

    return (ipmi_completion_code_strerror_r (cmd, netfn, comp_code, errstr, len));
}
Esempio n. 4
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);
}
Esempio n. 5
0
int
unassemble_ipmi_ipmb_msg (fiid_obj_t obj_ipmb_msg,
                          fiid_obj_t obj_ipmb_msg_hdr,
                          fiid_obj_t obj_cmd,
                          fiid_obj_t obj_ipmb_msg_trlr,
			  unsigned int flags)
{
  uint8_t buf[IPMB_MAX_LEN+1];
  int buf_len, obj_ipmb_msg_trlr_len, len;
  unsigned int indx = 0;
  unsigned int ipmb_msg_len;
  unsigned int flags_mask = (IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK);

  if (!fiid_obj_valid (obj_ipmb_msg)
      || !fiid_obj_valid (obj_ipmb_msg_hdr)
      || !fiid_obj_valid (obj_cmd)
      || !fiid_obj_valid (obj_ipmb_msg_trlr)
      || (flags & ~flags_mask))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

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

  memset (buf, '\0', IPMB_MAX_LEN+1);

  if ((buf_len = fiid_obj_get_all (obj_ipmb_msg, buf, IPMB_MAX_LEN)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg);
      return (-1);
    }

  if (fiid_obj_clear (obj_ipmb_msg_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_hdr);
      return (-1);
    }

  if (fiid_obj_clear (obj_cmd) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }
  
  if (fiid_obj_clear (obj_ipmb_msg_trlr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_trlr);
      return (-1);
    }

  if ((len = fiid_obj_set_all (obj_ipmb_msg_hdr, buf + indx, buf_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_hdr);
      return (-1);
    }
  indx += len;
  
  if (buf_len <= indx)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }
  
  if ((obj_ipmb_msg_trlr_len = fiid_template_len_bytes (tmpl_ipmb_msg_trlr)) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  
  if ((buf_len - indx) <= obj_ipmb_msg_trlr_len)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  ipmb_msg_len = (buf_len - indx) - obj_ipmb_msg_trlr_len;

  if ((len = fiid_obj_set_all (obj_cmd, buf + indx, ipmb_msg_len)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }
  indx += len;
      
  if (buf_len <= indx)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if ((len = fiid_obj_set_all (obj_ipmb_msg_trlr, buf + indx, buf_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_trlr);
      return (-1);
    }
  indx += len;
  
  if (FIID_OBJ_PACKET_VALID (obj_ipmb_msg_hdr) == 1
      && ((flags & IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK) || FIID_OBJ_PACKET_SUFFICIENT (obj_cmd) == 1)
      && FIID_OBJ_PACKET_VALID (obj_ipmb_msg_trlr) == 1)
    return (1);

  return (0);
}
Esempio n. 6
0
int
assemble_ipmi_ipmb_msg (fiid_obj_t obj_ipmb_msg_hdr,
                        fiid_obj_t obj_cmd,
                        fiid_obj_t obj_ipmb_msg,
			unsigned int flags)
{
  uint8_t buf[IPMB_MAX_LEN+1];
  unsigned int indx = 0;
  uint8_t *checksum_data_ptr = NULL;
  unsigned int checksum_data_count = 0;
  unsigned int required_len = 0;
  fiid_obj_t obj_ipmb_msg_trlr = NULL;
  uint8_t checksum;
  int len, rv = -1;
  unsigned int flags_mask = 0;

  if (!fiid_obj_valid (obj_ipmb_msg_hdr)
      || !fiid_obj_valid (obj_cmd)
      || !fiid_obj_valid (obj_ipmb_msg)
      || (flags & ~flags_mask))
    {
      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);
    }
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_ipmb_msg, tmpl_ipmb_msg) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  if (FIID_OBJ_PACKET_VALID (obj_ipmb_msg_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_hdr);
      return (-1);
    }
  if (FIID_OBJ_PACKET_VALID (obj_cmd) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if ((len = fiid_template_len_bytes (tmpl_ipmb_msg_hdr_rq)) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  required_len += len;

  if ((len = fiid_obj_len_bytes (obj_cmd)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }
  required_len += len;

  if ((len = fiid_template_len_bytes (tmpl_ipmb_msg_trlr)) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  required_len += len;

  if (IPMB_MAX_LEN < required_len)
    {
      SET_ERRNO (EMSGSIZE);
      return (-1);
    }

  memset (buf, '\0', IPMB_MAX_LEN+1);

  if ((len = fiid_obj_get_block (obj_ipmb_msg_hdr,
                                 "rs_addr",
                                 "checksum1",
                                 buf + indx,
                                 IPMB_MAX_LEN - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_hdr);
      goto cleanup;
    }
  indx += len;

  checksum_data_ptr = (buf + indx);

  if ((len = fiid_obj_get_block (obj_ipmb_msg_hdr,
                                 "rq_addr",
                                 "rq_seq",
                                 buf + indx,
                                 IPMB_MAX_LEN - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_hdr);
      goto cleanup;
    }
  indx += len;
  checksum_data_count += len;

  if ((len = fiid_obj_get_all (obj_cmd, buf + indx, IPMB_MAX_LEN - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      goto cleanup;
    }
  indx += len;
  checksum_data_count += len;

  if (!(obj_ipmb_msg_trlr = fiid_obj_create (tmpl_ipmb_msg_trlr)))
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  checksum = ipmi_checksum (checksum_data_ptr, checksum_data_count);

  if (fiid_obj_set_all (obj_ipmb_msg_trlr, &checksum, sizeof (checksum)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_trlr);
      goto cleanup;
    }

  if ((len = fiid_obj_get_all (obj_ipmb_msg_trlr, buf + indx, IPMB_MAX_LEN - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_trlr);
      goto cleanup;
    }
  indx += len;

  if ((len = fiid_obj_set_all (obj_ipmb_msg, buf, indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg);
      goto cleanup;
    }

  rv = len;
 cleanup:
  fiid_obj_destroy (obj_ipmb_msg_trlr);
  return (rv);
}
Esempio n. 7
0
int
ipmi_dump_rmcp_packet (int fd,
                       const char *prefix,
                       const char *hdr,
                       const char *trlr,
                       const void *pkt,
                       unsigned int pkt_len,
                       fiid_template_t tmpl_cmd)
{
  unsigned int indx = 0;
  char prefix_buf[IPMI_DEBUG_MAX_PREFIX_LEN];
  char *rmcp_hdr =
    "RMCP Header:\n"
    "------------";
  char *rmcp_cmd =
    "RMCP Command Data:\n"
    "------------------";
  char *unexpected_hdr =
    "Unexpected Data:\n"
    "----------------";
  fiid_obj_t obj_rmcp_hdr = NULL;
  fiid_obj_t obj_cmd = NULL;
  fiid_obj_t obj_unexpected_data = NULL;
  int len, rv = -1;

  if (!pkt || !tmpl_cmd)
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (debug_set_prefix (prefix_buf, IPMI_DEBUG_MAX_PREFIX_LEN, prefix) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  if (debug_output_str (fd, prefix_buf, hdr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  /* Dump rmcp header */

  if (!(obj_rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr)))
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  if ((len = fiid_obj_set_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      goto cleanup;
    }
  indx += len;

  if (ipmi_obj_dump (fd, prefix, rmcp_hdr, NULL, obj_rmcp_hdr) < 0)
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  if (pkt_len <= indx)
    {
      rv = 0;
      goto cleanup;
    }

  /* Dump command data */

  if (!(obj_cmd = fiid_obj_create (tmpl_cmd)))
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  if ((len = fiid_obj_set_all (obj_cmd, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      goto cleanup;
    }
  indx += len;

  if (ipmi_obj_dump (fd, prefix, rmcp_cmd, NULL, obj_cmd) < 0)
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  /* Dump unexpected stuff */

  if ((pkt_len - indx) > 0)
    {
      if (!(obj_unexpected_data = fiid_obj_create (tmpl_unexpected_data)))
        {
          ERRNO_TRACE (errno);
          goto cleanup;
        }
      
      if ((len = fiid_obj_set_all (obj_unexpected_data, pkt + indx, pkt_len - indx)) < 0)
        {
          FIID_OBJECT_ERROR_TO_ERRNO (obj_unexpected_data);
          goto cleanup;
        }
      indx += len;
      
      if (ipmi_obj_dump (fd, prefix, unexpected_hdr, NULL, obj_unexpected_data) < 0)
        {
          ERRNO_TRACE (errno);
          goto cleanup;
        }
    }

  if (debug_output_str (fd, prefix_buf, trlr) < 0)
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }


#if WITH_RAWDUMPS
  /* For those vendors that get confused when they see the nice output
   * and want the hex output
   */
  if (ipmi_dump_hex (fd,
                     prefix,
                     hdr,
                     trlr,
                     pkt,
                     pkt_len) < 0)
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }
#endif
  
  rv = 0;
 cleanup:
  fiid_obj_destroy (obj_rmcp_hdr);
  fiid_obj_destroy (obj_cmd);
  fiid_obj_destroy (obj_unexpected_data);
  return (rv);
}
Esempio n. 8
0
int
assemble_rmcp_pkt (fiid_obj_t obj_rmcp_hdr,
                   fiid_obj_t obj_cmd,
                   void *pkt,
                   unsigned int pkt_len,
		   unsigned int flags)
{
  int obj_cmd_len, obj_rmcp_hdr_len;
  unsigned int flags_mask = 0;

  if (!fiid_obj_valid (obj_rmcp_hdr)
      || !fiid_obj_valid (obj_cmd)
      || !pkt
      || !pkt_len
      || (flags & ~flags_mask))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (FIID_OBJ_TEMPLATE_COMPARE (obj_rmcp_hdr, tmpl_rmcp_hdr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }
  if (FIID_OBJ_PACKET_VALID (obj_cmd) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if ((obj_rmcp_hdr_len = fiid_obj_len_bytes (obj_rmcp_hdr)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }
  if ((obj_cmd_len = fiid_obj_len_bytes (obj_cmd)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if (pkt_len < (obj_rmcp_hdr_len + obj_cmd_len))
    {
      SET_ERRNO (EMSGSIZE);
      return (-1);
    }

  memset (pkt, '\0', pkt_len);
  if ((obj_rmcp_hdr_len = fiid_obj_get_all (obj_rmcp_hdr,
                                            pkt,
                                            pkt_len)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }
  if ((obj_cmd_len = fiid_obj_get_all (obj_cmd,
                                       pkt + obj_rmcp_hdr_len,
                                       pkt_len - obj_rmcp_hdr_len)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  return (obj_rmcp_hdr_len + obj_cmd_len);
}
Esempio n. 9
0
int
unassemble_rmcp_pkt (const void *pkt,
                     unsigned int pkt_len,
                     fiid_obj_t obj_rmcp_hdr,
                     fiid_obj_t obj_cmd,
		     unsigned int flags)
{
  unsigned int indx = 0;
  int len;
  unsigned int flags_mask = (IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK);

  if (!pkt
      || !fiid_obj_valid (obj_rmcp_hdr)
      || !fiid_obj_valid (obj_cmd)
      || (flags & ~flags_mask))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (FIID_OBJ_TEMPLATE_COMPARE (obj_rmcp_hdr, tmpl_rmcp_hdr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  if (fiid_obj_clear (obj_rmcp_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }

  if (fiid_obj_clear (obj_cmd) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if ((len = fiid_obj_set_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }
  indx += len;

  if (pkt_len <= indx)
    {
      /* trace, but don't error out, cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if ((len = fiid_obj_set_all (obj_cmd, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }
  indx += len;

  if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) == 1
      && ((flags & IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK) || FIID_OBJ_PACKET_SUFFICIENT (obj_cmd) == 1))
    return (1);

  return (0);
}
Esempio n. 10
0
int
unassemble_ipmi_lan_pkt (const void *pkt,
                         unsigned int pkt_len,
                         fiid_obj_t obj_rmcp_hdr,
                         fiid_obj_t obj_lan_session_hdr,
                         fiid_obj_t obj_lan_msg_hdr,
                         fiid_obj_t obj_cmd,
                         fiid_obj_t obj_lan_msg_trlr,
			 unsigned int flags)
{
  uint8_t authentication_type;
  unsigned int indx = 0;
  unsigned int obj_cmd_len;
  int obj_lan_msg_trlr_len, len;
  uint64_t val;
  unsigned int flags_mask = (IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK);

  if (!pkt
      || !fiid_obj_valid (obj_rmcp_hdr)
      || !fiid_obj_valid (obj_lan_session_hdr)
      || !fiid_obj_valid (obj_lan_msg_hdr)
      || !fiid_obj_valid (obj_cmd)
      || !fiid_obj_valid (obj_lan_msg_trlr)
      || (flags & ~flags_mask))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (FIID_OBJ_TEMPLATE_COMPARE (obj_rmcp_hdr, tmpl_rmcp_hdr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_session_hdr, tmpl_lan_session_hdr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_msg_hdr, tmpl_lan_msg_hdr_rs) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_msg_trlr, tmpl_lan_msg_trlr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  indx = 0;
  if (fiid_obj_clear (obj_rmcp_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }

  if (fiid_obj_clear (obj_lan_session_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
      return (-1);
    }

  if (fiid_obj_clear (obj_lan_msg_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr);
      return (-1);
    }
  
  if (fiid_obj_clear (obj_cmd) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if (fiid_obj_clear (obj_lan_msg_trlr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr);
      return (-1);
    }

  if ((len = fiid_obj_set_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }
  indx += len;

  if (pkt_len <= indx)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if ((len = fiid_obj_set_block (obj_lan_session_hdr,
                                 "authentication_type",
                                 "session_id",
                                 pkt + indx,
                                 pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
      return (-1);
    }
  indx += len;

  if (FIID_OBJ_GET (obj_lan_session_hdr,
                    "authentication_type",
                    &val) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
      return (-1);
    }
  authentication_type = val;

  if (!IPMI_1_5_AUTHENTICATION_TYPE_VALID (authentication_type))
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE)
    {
      if ((len = fiid_obj_set_data (obj_lan_session_hdr,
                                    "authentication_code",
                                    pkt + indx,
                                    pkt_len - indx)) < 0)
        {
          FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
          return (-1);
        }
      indx += len;

      if (pkt_len <= indx)
        {
          /* cannot parse packet */
          ERR_TRACE ("malformed packet", EINVAL);
          return (0);
        }
    }

  if ((len = fiid_obj_set_data (obj_lan_session_hdr,
                                "ipmi_msg_len",
                                pkt + indx,
                                pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
      return (-1);
    }
  indx += len;

  if (pkt_len <= indx)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if ((len = fiid_obj_set_all (obj_lan_msg_hdr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr);
      return (-1);
    }
  indx += len;

  if (pkt_len <= indx)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if ((obj_lan_msg_trlr_len = fiid_template_len_bytes (tmpl_lan_msg_trlr)) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  if ((pkt_len - indx) <= obj_lan_msg_trlr_len)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  obj_cmd_len = (pkt_len - indx) - obj_lan_msg_trlr_len;

  if ((len = fiid_obj_set_all (obj_cmd, pkt + indx, obj_cmd_len)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }
  indx += len;

  if (pkt_len <= indx)
    {
      /* cannot parse packet */
      ERR_TRACE ("malformed packet", EINVAL);
      return (0);
    }

  if ((len = fiid_obj_set_all (obj_lan_msg_trlr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr);
      return (-1);
    }
  indx += len;
  
  if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) == 1
      && FIID_OBJ_PACKET_VALID (obj_lan_session_hdr) == 1
      && FIID_OBJ_PACKET_VALID (obj_lan_msg_hdr) == 1
      && ((flags & IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK) || FIID_OBJ_PACKET_SUFFICIENT (obj_cmd) == 1)
      && FIID_OBJ_PACKET_VALID (obj_lan_msg_trlr) == 1)
    return (1);

  return (0);
}
Esempio n. 11
0
int
assemble_ipmi_lan_pkt (fiid_obj_t obj_rmcp_hdr,
                       fiid_obj_t obj_lan_session_hdr,
                       fiid_obj_t obj_lan_msg_hdr,
                       fiid_obj_t obj_cmd,
                       const void *authentication_code_data,
                       unsigned int authentication_code_data_len,
                       void *pkt,
                       unsigned int pkt_len,
		       unsigned int flags)
{
  uint8_t authentication_type;
  uint64_t val;
  unsigned int indx = 0;
  int required_len;
  void *authentication_code_field_ptr = NULL;
  void *checksum_data_ptr = NULL;
  void *msg_data_ptr = NULL;
  void *ipmi_msg_len_ptr = NULL;
  unsigned int msg_data_count = 0;
  unsigned int checksum_data_count = 0;
  uint8_t ipmi_msg_len;
  fiid_obj_t obj_lan_msg_trlr = NULL;
  uint8_t pwbuf[IPMI_1_5_MAX_PASSWORD_LENGTH];
  uint8_t checksum;
  int len, rv = -1;
  unsigned int flags_mask = 0;

  if (!fiid_obj_valid (obj_rmcp_hdr)
      || !fiid_obj_valid (obj_lan_session_hdr)
      || !fiid_obj_valid (obj_lan_msg_hdr)
      || !fiid_obj_valid (obj_cmd)
      || (authentication_code_data && authentication_code_data_len > IPMI_1_5_MAX_PASSWORD_LENGTH)
      || !pkt
      || (flags & ~flags_mask))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (FIID_OBJ_TEMPLATE_COMPARE (obj_rmcp_hdr, tmpl_rmcp_hdr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_session_hdr, tmpl_lan_session_hdr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_msg_hdr, tmpl_lan_msg_hdr_rq) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }

  /*
   * ipmi_msg_len is calculated in this function, so we can't use
   * fiid_obj_packet_valid() on obj_lan_session_hdr b/c ipmi_msg_len
   * is probably not set yet.
   */

  if (FIID_OBJ_PACKET_VALID (obj_lan_msg_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr);
      return (-1);
    }
  if (FIID_OBJ_PACKET_VALID (obj_cmd) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if (FIID_OBJ_GET (obj_lan_session_hdr,
                    "authentication_type",
                    &val) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  authentication_type = val;

  if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE
      && authentication_type != IPMI_AUTHENTICATION_TYPE_MD2
      && authentication_type != IPMI_AUTHENTICATION_TYPE_MD5
      && authentication_type != IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY)
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  /* no need for overflow checks, handled w/ _ipmi_lan_pkt_rq_min_size check */

  required_len = _ipmi_lan_pkt_rq_min_size (authentication_type, obj_cmd);
  if (pkt_len < required_len)
    {
      SET_ERRNO (EMSGSIZE);
      return (-1);
    }

  memset (pkt, 0, pkt_len);

  if ((len = fiid_obj_get_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      goto cleanup;
    }
  indx += len;

  if ((len = fiid_obj_get_block (obj_lan_session_hdr,
                                 "authentication_type",
                                 "session_id",
                                 pkt + indx,
                                 pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
      goto cleanup;
    }

  indx += len;

  /* authentication_code generated last.  Save pointers for later calculation */
  if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE)
    {
      authentication_code_field_ptr = (pkt + indx);
      indx += IPMI_1_5_MAX_PASSWORD_LENGTH;
    }

  ipmi_msg_len_ptr = (pkt + indx);
  if ((len = fiid_template_field_len_bytes (tmpl_lan_session_hdr, "ipmi_msg_len")) < 0)
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }
  if (len != 1)
    {
      SET_ERRNO (EINVAL);
      goto cleanup;
    }
  indx += len;

  msg_data_ptr = (pkt + indx);

  if ((len = fiid_obj_get_block (obj_lan_msg_hdr,
                                 "rs_addr",
                                 "checksum1",
                                 pkt + indx,
                                 pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr);
      goto cleanup;
    }
  indx += len;
  msg_data_count += len;

  checksum_data_ptr = (pkt + indx);

  if ((len = fiid_obj_get_block (obj_lan_msg_hdr,
                                 "rq_addr",
                                 "rq_seq",
                                 pkt + indx,
                                 pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr);
      goto cleanup;
    }
  indx += len;
  msg_data_count += len;
  checksum_data_count += len;

  if ((len = fiid_obj_get_all (obj_cmd, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      goto cleanup;
    }
  indx += len;
  msg_data_count += len;
  checksum_data_count += len;

  if (!(obj_lan_msg_trlr = fiid_obj_create (tmpl_lan_msg_trlr)))
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  checksum = ipmi_checksum (checksum_data_ptr, checksum_data_count);

  if (fiid_obj_set_all (obj_lan_msg_trlr, &checksum, sizeof (checksum)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr);
      goto cleanup;
    }

  if ((len = fiid_obj_get_all (obj_lan_msg_trlr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr);
      goto cleanup;
    }
  indx += len;
  msg_data_count += len;

  /* ipmi_msg_len done after message length is computed */
  ipmi_msg_len = msg_data_count;
  memcpy (ipmi_msg_len_ptr,
          &ipmi_msg_len,
          sizeof (ipmi_msg_len));

  /* Auth code must be done last, some authentication like md2 and md5
   * require all fields, including checksums, to be calculated
   * beforehand
   */
  if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE)
    {
      int authentication_len;

      memset (pwbuf, '\0', IPMI_1_5_MAX_PASSWORD_LENGTH);

      if ((authentication_len = fiid_obj_field_len_bytes (obj_lan_session_hdr,
                                                          "authentication_code")) < 0)
        {
          FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
          goto cleanup;
        }

      if (authentication_len)
        {
          if (fiid_obj_get_data (obj_lan_session_hdr,
                                 "authentication_code",
                                 pwbuf,
                                 IPMI_1_5_MAX_PASSWORD_LENGTH) < 0)
            {
              FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
              goto cleanup;
            }

          memcpy (authentication_code_field_ptr,
                  pwbuf,
                  IPMI_1_5_MAX_PASSWORD_LENGTH);
        }
      else
        {
          if (authentication_code_data)
            memcpy (pwbuf,
                    authentication_code_data,
                    authentication_code_data_len);

          if (authentication_type == IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY)
            {
              memcpy (authentication_code_field_ptr,
                      pwbuf,
                      IPMI_1_5_MAX_PASSWORD_LENGTH);
            }
          else /* IPMI_AUTHENTICATION_TYPE_MD2 || IPMI_AUTHENTICATION_TYPE_MD5 */
            {
              uint8_t session_id_buf[1024];
              uint8_t session_sequence_number_buf[1024];
              int session_id_len, session_sequence_number_len;

              if ((session_id_len = fiid_obj_get_data (obj_lan_session_hdr,
                                                       "session_id",
                                                       session_id_buf,
                                                       1024)) < 0)
                {
                  FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
                  goto cleanup;
                }

              if ((session_sequence_number_len = fiid_obj_get_data (obj_lan_session_hdr,
                                                                    "session_sequence_number",
                                                                    session_sequence_number_buf,
                                                                    1024)) < 0)
                {
                  FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
                  goto cleanup;
                }

              if (authentication_type == IPMI_AUTHENTICATION_TYPE_MD2)
                {
                  md2_t ctx;
                  uint8_t digest[MD2_DIGEST_LENGTH];

                  assert (IPMI_1_5_MAX_PASSWORD_LENGTH == MD2_DIGEST_LENGTH);

                  md2_init (&ctx);
                  md2_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  md2_update_data (&ctx, session_id_buf, session_id_len);
                  md2_update_data (&ctx, msg_data_ptr, msg_data_count);
                  md2_update_data (&ctx, session_sequence_number_buf, session_sequence_number_len);
                  md2_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  md2_finish (&ctx, digest, MD2_DIGEST_LENGTH);
                  md2_init (&ctx);

                  memcpy (authentication_code_field_ptr, digest, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  secure_memset (digest, '\0', MD2_DIGEST_LENGTH);
                }
              else if (authentication_type == IPMI_AUTHENTICATION_TYPE_MD5)
                {
                  md5_t ctx;
                  uint8_t digest[MD5_DIGEST_LENGTH];

                  assert (IPMI_1_5_MAX_PASSWORD_LENGTH == MD5_DIGEST_LENGTH);

                  md5_init (&ctx);
                  md5_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  md5_update_data (&ctx, session_id_buf, session_id_len);
                  md5_update_data (&ctx, msg_data_ptr, msg_data_count);
                  md5_update_data (&ctx, session_sequence_number_buf, session_sequence_number_len);
                  md5_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  md5_finish (&ctx, digest, MD5_DIGEST_LENGTH);
                  md5_init (&ctx);

                  memcpy (authentication_code_field_ptr, digest, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  secure_memset (digest, '\0', MD5_DIGEST_LENGTH);
                }
            }
        }
    }

  if (indx > INT_MAX)
    {
      SET_ERRNO (EMSGSIZE);
      goto cleanup;
    }

  rv = indx;
 cleanup:
  if (rv < 0)
    secure_memset (pkt, '\0', pkt_len);
  fiid_obj_destroy (obj_lan_msg_trlr);
  secure_memset (pwbuf, '\0', IPMI_1_5_MAX_PASSWORD_LENGTH);
  return (rv);
}
Esempio n. 12
0
static int
_ipmi_lan_pkt_rq_min_size (uint8_t authentication_type, fiid_obj_t obj_cmd)
{
  unsigned int msg_len = 0;
  int len;

  assert (IPMI_1_5_AUTHENTICATION_TYPE_VALID (authentication_type) && fiid_obj_valid (obj_cmd));

  if ((len = fiid_template_len_bytes (tmpl_rmcp_hdr)) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  msg_len += len;

  if ((len = fiid_template_len_bytes (tmpl_lan_msg_hdr_rq)) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  msg_len += len;

  if ((len = fiid_template_len_bytes (tmpl_lan_msg_trlr)) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  msg_len += len;

  if ((len = fiid_template_block_len_bytes (tmpl_lan_session_hdr,
                                            "authentication_type",
                                            "session_id")) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  msg_len += len;

  if (authentication_type == IPMI_AUTHENTICATION_TYPE_MD2
      || authentication_type == IPMI_AUTHENTICATION_TYPE_MD5
      || authentication_type == IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY
      || authentication_type == IPMI_AUTHENTICATION_TYPE_OEM_PROP)
    msg_len += IPMI_1_5_MAX_PASSWORD_LENGTH;

  if ((len = fiid_template_field_len_bytes (tmpl_lan_session_hdr, "ipmi_msg_len")) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  msg_len += len;

  if ((len = fiid_obj_len_bytes (obj_cmd)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  msg_len += len;

  return (msg_len);
}
Esempio n. 13
0
int
assemble_ipmi_kcs_pkt (fiid_obj_t obj_kcs_hdr,
                       fiid_obj_t obj_cmd,
                       void *pkt,
                       unsigned int pkt_len,
		       unsigned int flags)
{
  int obj_cmd_len, obj_kcs_hdr_len;
  unsigned int utmp;
  unsigned int flags_mask = 0;

  if (!fiid_obj_valid (obj_kcs_hdr)
      || !fiid_obj_valid (obj_cmd)
      || !pkt
      || (flags & ~flags_mask))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

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

  if (FIID_OBJ_PACKET_VALID (obj_kcs_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_kcs_hdr);
      return (-1);
    }
  if (FIID_OBJ_PACKET_VALID (obj_cmd) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if ((obj_kcs_hdr_len = fiid_obj_len_bytes (obj_kcs_hdr)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_kcs_hdr);
      return (-1);
    }
  if ((obj_cmd_len = fiid_obj_len_bytes (obj_cmd)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  /* int overflow not possible here */
  if (pkt_len < (obj_kcs_hdr_len + obj_cmd_len))
    {
      SET_ERRNO (EMSGSIZE);
      return (-1);
    }

  memset (pkt, 0, pkt_len);
  if ((obj_kcs_hdr_len = fiid_obj_get_all (obj_kcs_hdr,
                                           pkt,
                                           pkt_len)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_kcs_hdr);
      return (-1);
    }
  if ((obj_cmd_len = fiid_obj_get_all (obj_cmd,
                                       pkt + obj_kcs_hdr_len,
                                       pkt_len - obj_kcs_hdr_len)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  utmp = obj_kcs_hdr_len + obj_cmd_len;
  if (utmp > INT_MAX)
    {
      SET_ERRNO (EMSGSIZE);
      return (-1);
    }

  return (obj_kcs_hdr_len + obj_cmd_len);
}
Esempio n. 14
0
int
debug_dump_ipmb (int fd,
		 const char *prefix,
		 const uint8_t *ipmb_buf,
		 unsigned int ipmb_buf_len,
		 fiid_template_t tmpl_ipmb_msg_hdr,
		 fiid_template_t tmpl_ipmb_cmd)
{
  char *ipmb_msg_hdr =
    "IPMB Message Header:\n"
    "--------------------";
  char *ipmb_cmd_hdr =
    "IPMB Message Data:\n"
    "------------------";
  char *ipmb_msg_trlr_hdr =
    "IPMB Message Trailer:\n"
    "---------------------";
  char *ipmb_unexpected_hdr =
    "IPMB Unexpected Data:\n"
    "---------------------";
  fiid_obj_t obj_ipmb_msg_hdr = NULL;
  fiid_obj_t obj_ipmb_cmd = NULL;
  fiid_obj_t obj_ipmb_msg_trlr = NULL;
  fiid_obj_t obj_ipmb_unexpected_data = NULL;
  int obj_ipmb_msg_trlr_len = 0;
  unsigned int obj_ipmb_cmd_len = 0;
  int ipmb_hdr_len = 0;
  int ipmb_cmd_len = 0;
  int ipmb_trlr_len = 0;
  int len;
  unsigned int ipmb_indx = 0;
  int rv = -1;

  assert (ipmb_buf);
  assert (ipmb_buf_len);
  assert (tmpl_ipmb_msg_hdr);
  assert (tmpl_ipmb_cmd);

  if (!(obj_ipmb_msg_hdr = fiid_obj_create (tmpl_ipmb_msg_hdr)))
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }
  if (!(obj_ipmb_cmd = fiid_obj_create (tmpl_ipmb_cmd)))
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }
  if (!(obj_ipmb_msg_trlr = fiid_obj_create (tmpl_ipmb_msg_trlr)))
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  if ((obj_ipmb_msg_trlr_len = fiid_template_len_bytes (tmpl_ipmb_msg_trlr)) < 0)
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  if ((ipmb_hdr_len = fiid_obj_set_all (obj_ipmb_msg_hdr,
                                        ipmb_buf,
                                        ipmb_buf_len)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_hdr);
      goto cleanup;
    }
  ipmb_indx += ipmb_hdr_len;

  if (ipmi_obj_dump (fd,
                     prefix,
                     ipmb_msg_hdr,
                     NULL,
                     obj_ipmb_msg_hdr) < 0)
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  if (ipmb_buf_len <= ipmb_indx)
    {
      rv = 0;
      goto cleanup;
    }

  if ((ipmb_buf_len - ipmb_hdr_len) <= obj_ipmb_msg_trlr_len)
    goto dump_ipmb_extra;

  obj_ipmb_cmd_len = (ipmb_buf_len - ipmb_hdr_len) - obj_ipmb_msg_trlr_len;

  if ((ipmb_cmd_len = fiid_obj_set_all (obj_ipmb_cmd,
                                        ipmb_buf + ipmb_hdr_len,
                                        obj_ipmb_cmd_len)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_cmd);
      goto cleanup;
    }
  ipmb_indx += ipmb_cmd_len;

  if (ipmi_obj_dump (fd,
                     prefix,
                     ipmb_cmd_hdr,
                     NULL,
                     obj_ipmb_cmd) < 0)
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  if (ipmb_buf_len <= ipmb_indx)
    {
      rv = 0;
      goto cleanup;
    }

  if ((ipmb_trlr_len = fiid_obj_set_all (obj_ipmb_msg_trlr,
                                         ipmb_buf + ipmb_hdr_len + ipmb_cmd_len,
                                         (ipmb_buf_len - ipmb_hdr_len - ipmb_cmd_len))) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_msg_trlr);
      goto cleanup;
    }
  ipmb_indx += ipmb_trlr_len;

  if (ipmi_obj_dump (fd,
                     prefix,
                     ipmb_msg_trlr_hdr,
                     NULL,
                     obj_ipmb_msg_trlr) < 0)
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }
  
  /* Dump IPMB unexpected stuff */
  
 dump_ipmb_extra:
  
  if ((ipmb_buf_len - ipmb_indx) > 0)
    {
      if (!(obj_ipmb_unexpected_data = fiid_obj_create (tmpl_unexpected_data)))
        {
          ERRNO_TRACE (errno);
          goto cleanup;
        }
      
      if ((len = fiid_obj_set_all (obj_ipmb_unexpected_data,
                                   ipmb_buf + ipmb_indx,
                                   ipmb_buf_len - ipmb_indx)) < 0)
        {
          FIID_OBJECT_ERROR_TO_ERRNO (obj_ipmb_unexpected_data);
          goto cleanup;
        }
      ipmb_indx += len;
      
      if (ipmi_obj_dump (fd,
                         prefix,
                         ipmb_unexpected_hdr,
                         NULL,
                         obj_ipmb_unexpected_data) < 0)
        {
          ERRNO_TRACE (errno);
          goto cleanup;
        }
    }
  
  rv = 0;
 cleanup:
  fiid_obj_destroy (obj_ipmb_msg_hdr);
  fiid_obj_destroy (obj_ipmb_cmd);
  fiid_obj_destroy (obj_ipmb_msg_trlr);
  fiid_obj_destroy (obj_ipmb_unexpected_data);
  return (rv);

}