Example #1
0
static void emu_msg_handler(void)
{
    uint8_t msg[100];
    unsigned int msg_len = sizeof(msg);

    get_emu_msg(msg, &msg_len);
    g_assert(msg_len >= 5);
    g_assert(msg[msg_len - 1] == 0xa0);
    msg_len--;
    g_assert(ipmb_checksum(msg, msg_len, 0) == 0);
    msg_len--;
    if ((msg[1] == get_dev_id_cmd[0]) && (msg[2] == get_dev_id_cmd[1])) {
        memcpy(msg + 1, get_dev_id_rsp, sizeof(get_dev_id_rsp));
        msg_len = sizeof(get_dev_id_rsp) + 1;
        msg[msg_len] = -ipmb_checksum(msg, msg_len, 0);
        msg_len++;
        msg[msg_len++] = 0xa0;
        write_emu_msg(msg, msg_len);
    } else if ((msg[1] == set_bmc_globals_cmd[0]) &&
               (msg[2] == set_bmc_globals_cmd[1])) {
        memcpy(msg + 1, set_bmc_globals_rsp, sizeof(set_bmc_globals_rsp));
        msg_len = sizeof(set_bmc_globals_rsp) + 1;
        msg[msg_len] = -ipmb_checksum(msg, msg_len, 0);
        msg_len++;
        msg[msg_len++] = 0xa0;
        write_emu_msg(msg, msg_len);
        write_emu_msg(enable_irq_cmd, sizeof(enable_irq_cmd));
    } else {
        g_assert(0);
    }
}
Example #2
0
static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
                                       uint8_t *cmd, unsigned int cmd_len,
                                       unsigned int max_cmd_len,
                                       uint8_t msg_id)
{
    IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(b);
    IPMIInterface *s = ibe->parent.intf;
    uint8_t err = 0, csum;
    unsigned int i;

    if (ibe->outlen) {
        /* We already have a command queued.  Shouldn't ever happen. */
        fprintf(stderr, "IPMI KCS: Got command when not finished with the"
                " previous commmand\n");
        abort();
    }

    /* If it's too short or it was truncated, return an error. */
    if (cmd_len < 2) {
        err = IPMI_CC_REQUEST_DATA_LENGTH_INVALID;
    } else if ((cmd_len > max_cmd_len) || (cmd_len > MAX_IPMI_MSG_SIZE)) {
        err = IPMI_CC_REQUEST_DATA_TRUNCATED;
    } else if (!ibe->connected) {
        err = IPMI_CC_BMC_INIT_IN_PROGRESS;
    }
    if (err) {
        IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
        unsigned char rsp[3];
        rsp[0] = cmd[0] | 0x04;
        rsp[1] = cmd[1];
        rsp[2] = err;
        ibe->waiting_rsp = false;
        k->handle_rsp(s, msg_id, rsp, 3);
        goto out;
    }

    addchar(ibe, msg_id);
    for (i = 0; i < cmd_len; i++) {
        addchar(ibe, cmd[i]);
    }
    csum = ipmb_checksum(&msg_id, 1, 0);
    addchar(ibe, -ipmb_checksum(cmd, cmd_len, csum));

    ibe->outbuf[ibe->outlen] = VM_MSG_CHAR;
    ibe->outlen++;

    /* Start the transmit */
    continue_send(ibe);

 out:
    return;
}
Example #3
0
static void
format_ipmb_rsp(msg_t *msg, unsigned char *msgd,
		unsigned int *msgd_len, serserv_data_t *mi)
{
    msgd[0] = msg->rs_addr;
    msgd[1] = (msg->netfn << 2) | msg->rs_lun;
    msgd[2] = -ipmb_checksum(msgd, 2, 0);
    msgd[3] = msg->rq_addr;
    msgd[4] = (msg->rq_seq << 2) | msg->rq_lun;
    msgd[5] = msg->cmd;
    memcpy(msgd + 6, msg->data, msg->len);
    *msgd_len = msg->len + 6;
    msgd[*msgd_len] = -ipmb_checksum(msgd + 3, (*msgd_len) - 3, 0);
    (*msgd_len)++;
}
Example #4
0
static void handle_msg(IPMIBmcExtern *ibe)
{
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(ibe->parent.intf);

    if (ibe->in_escape) {
        ipmi_debug("msg escape not ended\n");
        return;
    }
    if (ibe->inpos < 5) {
        ipmi_debug("msg too short\n");
        return;
    }
    if (ibe->in_too_many) {
        ibe->inbuf[3] = IPMI_CC_REQUEST_DATA_TRUNCATED;
        ibe->inpos = 4;
    } else if (ipmb_checksum(ibe->inbuf, ibe->inpos, 0) != 0) {
        ipmi_debug("msg checksum failure\n");
        return;
    } else {
        ibe->inpos--; /* Remove checkum */
    }

    timer_del(ibe->extern_timer);
    ibe->waiting_rsp = false;
    k->handle_rsp(ibe->parent.intf, ibe->inbuf[0], ibe->inbuf + 1, ibe->inpos - 1);
}
Example #5
0
static int
unformat_ipmb_msg(msg_t *msg, unsigned char *msgd, unsigned int len,
		  serserv_data_t *si)
{
    if (len < 7) {
	fprintf(stderr, "Message too short\n");
	return -1;
    }

    if (ipmb_checksum(msgd, len, 0) != 0) {
	fprintf(stderr, "Message checksum failure\n");
	return -1;
    }
    len--;

    msg->rs_addr = msgd[0];
    msg->netfn = msgd[1] >> 2;
    msg->rs_lun = msgd[1] & 3;
    msg->rq_addr = msgd[3];
    msg->rq_seq = msgd[4] >> 2;
    msg->rq_lun = msgd[4] & 3;
    msg->cmd = msgd[5];

    msg->len = len - 6;
    msg->data = msgd + 6;

    msg->src_addr = NULL;
    msg->src_len = 0;

    return 0;
}