diff --git a/ipmitool/include/ipmitool/ipmi.h b/ipmitool/include/ipmitool/ipmi.h index d071f02..54180f0 100644 --- a/ipmitool/include/ipmitool/ipmi.h +++ b/ipmitool/include/ipmitool/ipmi.h @@ -63,7 +63,8 @@ extern int csv_output; struct ipmi_rq { struct { - uint8_t netfn; + uint8_t netfn :6; + uint8_t lun :2; uint8_t cmd; uint8_t target_cmd; uint16_t data_len; diff --git a/ipmitool/include/ipmitool/ipmi_intf.h b/ipmitool/include/ipmitool/ipmi_intf.h index 8bbe49d..b2aa95d 100644 --- a/ipmitool/include/ipmitool/ipmi_intf.h +++ b/ipmitool/include/ipmitool/ipmi_intf.h @@ -173,6 +173,8 @@ struct ipmi_intf { struct ipmi_cmd * cmdlist; uint32_t my_addr; uint32_t target_addr; + uint8_t target_lun; + uint8_t target_channel; int (*setup)(struct ipmi_intf * intf); int (*open)(struct ipmi_intf * intf); diff --git a/ipmitool/lib/ipmi_main.c b/ipmitool/lib/ipmi_main.c index 4e431e7..e328c30 100644 --- a/ipmitool/lib/ipmi_main.c +++ b/ipmitool/lib/ipmi_main.c @@ -74,7 +74,7 @@ #endif #ifdef ENABLE_ALL_OPTIONS -# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:C:L:A:t:m:S:" +# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:C:L:A:t:m:S:l:b:" #else # define OPTION_STRING "I:hVvcH:f:U:p:S:" #endif @@ -233,6 +233,9 @@ ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_ lprintf(LOG_NOTICE, " -P password Remote session password"); lprintf(LOG_NOTICE, " -E Read password from IPMI_PASSWORD environment variable"); lprintf(LOG_NOTICE, " -m address Set local IPMB address"); + lprintf(LOG_NOTICE, " -b channel Set destination channel for bridged request"); + lprintf(LOG_NOTICE, " -l lun Set destination lun for raw commands"); + lprintf(LOG_NOTICE, " -t address Bridge request to remote target address"); lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)"); #endif @@ -264,6 +267,8 @@ ipmi_main(int argc, char ** argv, struct ipmi_intf_support * sup; int privlvl = 0; uint8_t target_addr = 0; + uint8_t target_channel = 0; + uint8_t target_lun = 0; uint8_t my_addr = 0; int authtype = -1; char * tmp = NULL; @@ -443,6 +448,12 @@ ipmi_main(int argc, char ** argv, case 't': target_addr = (uint8_t)strtol(optarg, NULL, 0); break; + case 'b': + target_channel = (uint8_t)strtol(optarg, NULL, 0); + break; + case 'l': + target_lun = (uint8_t)strtol(optarg, NULL, 0); + break; case 'm': my_addr = (uint8_t)strtol(optarg, NULL, 0); break; @@ -534,6 +545,12 @@ ipmi_main(int argc, char ** argv, ipmi_intf_session_set_cipher_suite_id(intf, cipher_suite_id); + /* setup destination lun if given */ + intf->target_lun = target_lun ; + + /* setup destination channel if given */ + intf->target_channel = target_channel ; + /* setup IPMB local and target address if given */ intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR; if (target_addr > 0) { diff --git a/ipmitool/lib/ipmi_raw.c b/ipmitool/lib/ipmi_raw.c index c5c7c94..1077b8f 100644 --- a/ipmitool/lib/ipmi_raw.c +++ b/ipmitool/lib/ipmi_raw.c @@ -217,7 +217,7 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv) { struct ipmi_rs * rsp; struct ipmi_rq req; - uint8_t netfn, cmd; + uint8_t netfn, cmd, lun; int i; unsigned long ufn; @@ -235,6 +235,7 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv) return -1; } + lun = intf->target_lun; netfn = str2val(argv[0], ipmi_netfn_vals); if (netfn == 0xff) { netfn = (uint8_t)strtol(argv[0], NULL, 0); @@ -245,6 +246,7 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv) memset(data, 0, sizeof(data)); memset(&req, 0, sizeof(req)); req.msg.netfn = netfn; + req.msg.lun = lun; req.msg.cmd = cmd; req.msg.data = data; @@ -254,8 +256,10 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv) req.msg.data_len++; } - lprintf(LOG_INFO, "RAW REQ (netfn=0x%x cmd=0x%x data_len=%d)", - req.msg.netfn, req.msg.cmd, req.msg.data_len); + lprintf(LOG_INFO, + "RAW REQ (channel=0x%x netfn=0x%x lun=0x%x cmd=0x%x data_len=%d)", + intf->target_channel & 0x0f, req.msg.netfn,req.msg.lun , + req.msg.cmd, req.msg.data_len); printbuf(req.msg.data, req.msg.data_len, "RAW REQUEST"); @@ -263,14 +267,14 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv) if (rsp == NULL) { lprintf(LOG_ERR, "Unable to send RAW command " - "(netfn=0x%x cmd=0x%x)", - req.msg.netfn, req.msg.cmd); + "(channel=0x%x netfn=0x%x lun=0x%x cmd=0x%x)", + intf->target_channel & 0x0f, req.msg.netfn,req.msg.lun, req.msg.cmd); return -1; } if (rsp->ccode > 0) { lprintf(LOG_ERR, "Unable to send RAW command " - "(netfn=0x%x cmd=0x%x rsp=0x%x): %s", - req.msg.netfn, req.msg.cmd, rsp->ccode, + "(channel=0x%x netfn=0x%x lun=0x%x cmd=0x%x rsp=0x%x): %s", + intf->target_channel & 0x0f, req.msg.netfn,req.msg.lun, rsp->ccode, val2str(rsp->ccode, completion_code_vals)); return -1; } diff --git a/ipmitool/src/plugins/open/open.c b/ipmitool/src/plugins/open/open.c index 36b5b92..6b67c82 100644 --- a/ipmitool/src/plugins/open/open.c +++ b/ipmitool/src/plugins/open/open.c @@ -119,6 +119,7 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) }; struct ipmi_ipmb_addr ipmb_addr = { addr_type: IPMI_IPMB_ADDR_TYPE, + channel: intf->target_channel & 0x0f, }; struct ipmi_req _req; static struct ipmi_rs rsp; @@ -153,6 +154,7 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) /* otherwise use system interface */ lprintf(LOG_DEBUG+2, "Sending request to " "System Interface"); + bmc_addr.lun = req->msg.lun; _req.addr = (char *) &bmc_addr; _req.addr_len = sizeof(bmc_addr); }