Пример #1
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);
}
Пример #2
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);
}
Пример #3
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);
}
Пример #4
0
static int
_ssif_cmd_write (ipmi_ctx_t ctx,
		 uint8_t cmd,
		 uint8_t group_extension,
		 fiid_obj_t obj_cmd_rq)
{
  uint8_t *pkt = NULL;
  unsigned int pkt_len;
  int hdr_len, cmd_len, send_len;
  int rv = -1;
  
  assert (ctx
          && ctx->magic == IPMI_CTX_MAGIC
          && fiid_obj_valid (obj_cmd_rq));
  
  if ((hdr_len = fiid_template_len_bytes (tmpl_hdr_kcs)) < 0)
    {
      API_ERRNO_TO_API_ERRNUM (ctx, errno);
      goto cleanup;
    }
  
  if ((cmd_len = fiid_obj_len_bytes (obj_cmd_rq)) < 0)
    {
      API_FIID_OBJECT_ERROR_TO_API_ERRNUM (ctx, obj_cmd_rq);
      goto cleanup;
    }
  
  pkt_len = hdr_len + cmd_len;
  
  if (!(pkt = malloc (pkt_len)))
    {
      API_ERRNO_TO_API_ERRNUM (ctx, errno);
      goto cleanup;
    }
  memset (pkt, '\0', pkt_len);
  
  if (fill_hdr_ipmi_kcs (ctx->target.lun,
                         ctx->target.net_fn,
                         ctx->io.inband.rq.obj_hdr) < 0)
    {
      API_ERRNO_TO_API_ERRNUM (ctx, errno);
      goto cleanup;
    }
  
  if ((send_len = assemble_ipmi_kcs_pkt (ctx->io.inband.rq.obj_hdr,
                                         obj_cmd_rq,
                                         pkt,
                                         pkt_len,
					 IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
    {
      API_ERRNO_TO_API_ERRNUM (ctx, errno);
      goto cleanup;
    }

  if (ctx->flags & IPMI_FLAGS_DEBUG_DUMP && send_len)
    _api_ssif_dump_rq (ctx,
		       pkt,
		       send_len,
		       cmd,
		       ctx->target.net_fn,
		       group_extension,
		       obj_cmd_rq);

  if (ipmi_ssif_write (ctx->io.inband.ssif_ctx, pkt, send_len) < 0)
    {
      API_SSIF_ERRNUM_TO_API_ERRNUM (ctx, ipmi_ssif_ctx_errnum (ctx->io.inband.ssif_ctx));
      goto cleanup;
    }

  rv = 0;
 cleanup:
  free (pkt);
  return (rv);
}
Пример #5
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);
}
Пример #6
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);
}