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); } }
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; }
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)++; }
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); }
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; }