static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) { u_int8_t lun = 0; u_int8_t cmd = req->msg.cmd; u_int8_t netfn = req->msg.netfn; u_int8_t rq_buf[IPMI_BUF_SIZE]; u_int8_t rs_buf[IPMI_BUF_SIZE]; u_int32_t rs_buf_len = IPMI_BUF_SIZE; int32_t rs_len; static struct ipmi_rs rsp; /* achu: FreeIPMI requests have the cmd as the first byte of * the data. Responses have cmd as the first byte and * completion code as the second byte. This differs from some * other APIs, so it must be compensated for within the ipmitool * interface. */ if (!intf || !req) return NULL; if (!intf->opened && intf->open && intf->open(intf) < 0) return NULL; if (req->msg.data_len > IPMI_BUF_SIZE) return NULL; memset(rq_buf, '\0', IPMI_BUF_SIZE); memset(rs_buf, '\0', IPMI_BUF_SIZE); memcpy(rq_buf, &cmd, 1); if (req->msg.data) memcpy(rq_buf + 1, req->msg.data, req->msg.data_len); if ((rs_len = ipmi_cmd_raw(dev, lun, netfn, rq_buf, req->msg.data_len + 1, rs_buf, rs_buf_len)) < 0) { #if IPMI_INTF_FREE_0_3_0 perror("ipmi_cmd_raw"); #elif IPMI_INTF_FREE_0_4_0 || IPMI_INTF_FREE_0_5_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_device_strerror(ipmi_device_errnum(dev))); #elif IPMI_INTF_FREE_0_6_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); #endif return NULL; } memset(&rsp, 0, sizeof(struct ipmi_rs)); rsp.ccode = (unsigned char)rs_buf[1]; rsp.data_len = (int)rs_len - 2; if (!rsp.ccode && rsp.data_len) memcpy(rsp.data, rs_buf + 2, rsp.data_len); return &rsp; }
static int ipmi_free_open(struct ipmi_intf * intf) { if (getuid() != 0) { fprintf(stderr, "Permission denied, must be root\n"); return -1; } #if IPMI_INTF_FREE_0_3_0 if (!(dev = ipmi_open_inband (IPMI_DEVICE_KCS, 0, 0, 0, NULL, IPMI_FLAGS_DEFAULT))) { if (!(dev = ipmi_open_inband (IPMI_DEVICE_SSIF, 0, 0, 0, NULL, IPMI_FLAGS_DEFAULT))) { perror("ipmi_open_inband()"); goto cleanup; } } #elif IPMI_INTF_FREE_0_4_0 if (!(dev = ipmi_device_create())) { perror("ipmi_device_create"); goto cleanup; } if (ipmi_open_inband (dev, IPMI_DEVICE_KCS, 0, 0, 0, NULL, IPMI_FLAGS_DEFAULT) < 0) { if (ipmi_open_inband (dev, IPMI_DEVICE_SSIF, 0, 0, 0, NULL, IPMI_FLAGS_DEFAULT) < 0) { fprintf(stderr, "ipmi_open_inband(): %s\n", ipmi_device_strerror(ipmi_device_errnum(dev))); goto cleanup; } } #elif IPMI_INTF_FREE_0_5_0 if (!(dev = ipmi_device_create())) { perror("ipmi_device_create"); goto cleanup; } if (ipmi_open_inband (dev, IPMI_DEVICE_KCS, 0, 0, 0, NULL, 0, IPMI_FLAGS_DEFAULT) < 0) { if (ipmi_open_inband (dev, IPMI_DEVICE_SSIF, 0, 0, 0, NULL, 0, IPMI_FLAGS_DEFAULT) < 0) { fprintf(stderr, "ipmi_open_inband(): %s\n", ipmi_device_strerror(ipmi_device_errnum(dev))); goto cleanup; } } #elif IPMI_INTF_FREE_0_6_0 if (!(dev = ipmi_ctx_create())) { perror("ipmi_ctx_create"); goto cleanup; } if (ipmi_ctx_open_inband (dev, IPMI_DEVICE_KCS, 0, 0, 0, NULL, 0, IPMI_FLAGS_DEFAULT) < 0) { if (ipmi_ctx_open_inband (dev, IPMI_DEVICE_SSIF, 0, 0, 0, NULL, 0, IPMI_FLAGS_DEFAULT) < 0) { fprintf(stderr, "ipmi_open_inband(): %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); goto cleanup; } } #endif intf->opened = 1; return 0; cleanup: if (dev) { #if IPMI_INTF_FREE_0_3_0 ipmi_close_device(dev); #elif IPMI_INTF_FREE_0_4_0 || IPMI_INTF_FREE_0_5_0 ipmi_close_device(dev); ipmi_device_destroy(dev); #elif IPMI_INTF_FREE_0_6_0 ipmi_ctx_close(dev); ipmi_ctx_destroy(dev); #endif } return -1; }
static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) { u_int8_t lun = req->msg.lun; u_int8_t cmd = req->msg.cmd; u_int8_t netfn = req->msg.netfn; u_int8_t rq_buf[IPMI_BUF_SIZE]; u_int8_t rs_buf[IPMI_BUF_SIZE]; u_int32_t rs_buf_len = IPMI_BUF_SIZE; int32_t rs_len; static struct ipmi_rs rsp; /* achu: FreeIPMI requests have the cmd as the first byte of * the data. Responses have cmd as the first byte and * completion code as the second byte. This differs from some * other APIs, so it must be compensated for within the ipmitool * interface. */ if (!intf || !req) return NULL; if (!intf->opened && intf->open && intf->open(intf) < 0) return NULL; if (req->msg.data_len > IPMI_BUF_SIZE) return NULL; memset(rq_buf, '\0', IPMI_BUF_SIZE); memset(rs_buf, '\0', IPMI_BUF_SIZE); memcpy(rq_buf, &cmd, 1); if (req->msg.data) memcpy(rq_buf + 1, req->msg.data, req->msg.data_len); if (intf->target_addr != 0 && intf->target_addr != IPMI_BMC_SLAVE_ADDR) { #if IPMI_INTF_FREE_BRIDGING if ((rs_len = ipmi_cmd_raw_ipmb(dev, intf->target_channel, intf->target_addr, lun, netfn, rq_buf, req->msg.data_len + 1, rs_buf, rs_buf_len)) < 0) { if (verbose > 3) fprintf(stderr, "ipmi_cmd_raw_ipmb: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); /* Compared to FreeIPMI, user is expected to input * the target channel on the command line, it is not automatically * discovered. So that is the likely cause of an error. * * Instead of returning an error, return a bad response so output * of ipmitool commands looks like other interfaces */ rs_len = 2; rs_buf[0] = 0; rs_buf[1] = 0xC1; /* invalid command */ } #else /* !IPMI_INTF_FREE_BRIDGING */ if (verbose > 3) fprintf(stderr, "sensor bridging not supported in this driver version"); /* instead of returning an error, return a bad response so output * of ipmitool commands looks like other interfaces */ rs_len = 2; rs_buf[0] = 0; rs_buf[1] = 0xC1; /* invalid command */ #endif /* !IPMI_INTF_FREE_BRIDGING */ } else { if ((rs_len = ipmi_cmd_raw(dev, lun, netfn, rq_buf, req->msg.data_len + 1, rs_buf, rs_buf_len)) < 0) { #if IPMI_INTF_FREE_0_3_0 perror("ipmi_cmd_raw"); #elif IPMI_INTF_FREE_0_4_0 || IPMI_INTF_FREE_0_5_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_device_strerror(ipmi_device_errnum(dev))); #elif IPMI_INTF_FREE_0_6_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); #endif return NULL; } } memset(&rsp, 0, sizeof(struct ipmi_rs)); rsp.ccode = (unsigned char)rs_buf[1]; rsp.data_len = (int)rs_len - 2; if (!rsp.ccode && rsp.data_len) memcpy(rsp.data, rs_buf + 2, rsp.data_len); return &rsp; }