From c046fdc3b05cb15bc8e599dd9c8604a847c84707 Mon Sep 17 00:00:00 2001 From: Matthew Johnson Date: Sun, 22 Mar 2009 16:45:03 +0000 Subject: switch to quilt --- debian/changelog | 8 + debian/control | 3 +- debian/patches/00list | 5 - debian/patches/10_ipmi_lanp | 67 ++ debian/patches/10_ipmi_lanp.dpatch | 72 -- debian/patches/20_ipmi_impi | 335 ++++++ debian/patches/20_ipmi_impi.dpatch | 340 ------- debian/patches/20_ipmi_isol | 1852 +++++++++++++++++++++++++++++++++ debian/patches/20_ipmi_isol.dpatch | 1857 ---------------------------------- debian/patches/20_ipmi_sdr | 19 + debian/patches/20_ipmi_sdr.dpatch | 24 - debian/patches/99_readme_typo | 27 + debian/patches/99_readme_typo.dpatch | 32 - debian/patches/series | 5 + debian/rules | 9 +- 15 files changed, 2320 insertions(+), 2335 deletions(-) delete mode 100644 debian/patches/00list create mode 100644 debian/patches/10_ipmi_lanp delete mode 100644 debian/patches/10_ipmi_lanp.dpatch create mode 100644 debian/patches/20_ipmi_impi delete mode 100644 debian/patches/20_ipmi_impi.dpatch create mode 100644 debian/patches/20_ipmi_isol delete mode 100644 debian/patches/20_ipmi_isol.dpatch create mode 100644 debian/patches/20_ipmi_sdr delete mode 100644 debian/patches/20_ipmi_sdr.dpatch create mode 100644 debian/patches/99_readme_typo delete mode 100644 debian/patches/99_readme_typo.dpatch create mode 100644 debian/patches/series diff --git a/debian/changelog b/debian/changelog index 1ebd148..39a28cd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +ipmitool (1.8.11-1) unstable; urgency=low + + * New upstream release + * Change to quilt rather than dpatch + * Refresh config.sub/config.guess in configure + + -- Matthew Johnson Sun, 22 Mar 2009 16:44:06 +0000 + ipmitool (1.8.9-2) unstable; urgency=medium * Change pidfile name to the one it actually is. (Closes: #508434) diff --git a/debian/control b/debian/control index 623af56..1ce659c 100644 --- a/debian/control +++ b/debian/control @@ -2,8 +2,7 @@ Source: ipmitool Section: utils Priority: optional Maintainer: Matthew Johnson -Uploaders: -Build-Depends: debhelper (>> 5.0.0), libreadline5-dev | libreadline-dev, libssl-dev, dpatch +Build-Depends: debhelper (>> 5.0.0), libreadline5-dev | libreadline-dev, libssl-dev, quilt, autotools-dev Standards-Version: 3.7.3 Package: ipmitool diff --git a/debian/patches/00list b/debian/patches/00list deleted file mode 100644 index 6c4ed35..0000000 --- a/debian/patches/00list +++ /dev/null @@ -1,5 +0,0 @@ -10_ipmi_lanp.dpatch -20_ipmi_isol.dpatch -20_ipmi_impi.dpatch -20_ipmi_sdr.dpatch -99_readme_typo.dpatch diff --git a/debian/patches/10_ipmi_lanp b/debian/patches/10_ipmi_lanp new file mode 100644 index 0000000..7bd5f97 --- /dev/null +++ b/debian/patches/10_ipmi_lanp @@ -0,0 +1,67 @@ +## 10_ipmi_lanp.dpatch by +## +## 10_ipmi_lanp closes #389741 +--- ipmitool-1.8.9.orig/lib/ipmi_lanp.c 2007-03-06 22:15:36.000000000 +0000 ++++ ipmitool-1.8.9/lib/ipmi_lanp.c 2007-12-13 10:06:18.045813387 +0000 +@@ -1489,28 +1489,43 @@ + } + } + /* ip address */ +- else if ((strncmp(argv[1], "ipaddr", 6) == 0) && +- (get_cmdline_ipaddr(argv[2], data) == 0)) { +- printf("Setting LAN %s to %d.%d.%d.%d\n", +- ipmi_lan_params[IPMI_LANP_IP_ADDR].desc, +- data[0], data[1], data[2], data[3]); +- rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4); ++ else if (strncmp(argv[1], "ipaddr", 6) == 0) { ++ if ( argc < 3 || strncmp(argv[2], "help", 4) == 0 || ++ get_cmdline_ipaddr(argv[2], data) != 0 ) { ++ lprintf(LOG_NOTICE, "lan set ipaddr "); ++ } ++ else { ++ printf("Setting LAN %s to %d.%d.%d.%d\n", ++ ipmi_lan_params[IPMI_LANP_IP_ADDR].desc, ++ data[0], data[1], data[2], data[3]); ++ rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4); ++ } + } + /* network mask */ +- else if ((strncmp(argv[1], "netmask", 7) == 0) && +- (get_cmdline_ipaddr(argv[2], data) == 0)) { +- printf("Setting LAN %s to %d.%d.%d.%d\n", +- ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc, +- data[0], data[1], data[2], data[3]); +- rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4); ++ else if (strncmp(argv[1], "netmask", 7) == 0) { ++ if ( argc < 3 || strncmp(argv[2], "help", 4) == 0 || ++ get_cmdline_ipaddr(argv[2], data) != 0 ) { ++ lprintf(LOG_NOTICE, "lan set netmask "); ++ } ++ else { ++ printf("Setting LAN %s to %d.%d.%d.%d\n", ++ ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc, ++ data[0], data[1], data[2], data[3]); ++ rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4); ++ } + } + /* mac address */ +- else if ((strncmp(argv[1], "macaddr", 7) == 0) && +- (get_cmdline_macaddr(argv[2], data) == 0)) { +- printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", +- ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc, +- data[0], data[1], data[2], data[3], data[4], data[5]); +- rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6); ++ else if (strncmp(argv[1], "macaddr", 7) == 0) { ++ if ( argc < 3 || strncmp(argv[2], "help", 4) == 0 || ++ get_cmdline_macaddr(argv[2], data) != 0 ) { ++ lprintf(LOG_NOTICE, "lan set macaddr "); ++ } ++ else { ++ printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", ++ ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc, ++ data[0], data[1], data[2], data[3], data[4], data[5]); ++ rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6); ++ } + } + /* default gateway settings */ + else if (strncmp(argv[1], "defgw", 5) == 0) { diff --git a/debian/patches/10_ipmi_lanp.dpatch b/debian/patches/10_ipmi_lanp.dpatch deleted file mode 100644 index 4e7edfd..0000000 --- a/debian/patches/10_ipmi_lanp.dpatch +++ /dev/null @@ -1,72 +0,0 @@ -#! /bin/sh /usr/share/dpatch/dpatch-run -## 10_ipmi_lanp.dpatch by -## -## All lines beginning with `## DP:' are a description of the patch. -## DP: 10_ipmi_lanp closes #389741 - -@DPATCH@ - ---- ipmitool-1.8.9.orig/lib/ipmi_lanp.c 2007-03-06 22:15:36.000000000 +0000 -+++ ipmitool-1.8.9/lib/ipmi_lanp.c 2007-12-13 10:06:18.045813387 +0000 -@@ -1489,28 +1489,43 @@ - } - } - /* ip address */ -- else if ((strncmp(argv[1], "ipaddr", 6) == 0) && -- (get_cmdline_ipaddr(argv[2], data) == 0)) { -- printf("Setting LAN %s to %d.%d.%d.%d\n", -- ipmi_lan_params[IPMI_LANP_IP_ADDR].desc, -- data[0], data[1], data[2], data[3]); -- rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4); -+ else if (strncmp(argv[1], "ipaddr", 6) == 0) { -+ if ( argc < 3 || strncmp(argv[2], "help", 4) == 0 || -+ get_cmdline_ipaddr(argv[2], data) != 0 ) { -+ lprintf(LOG_NOTICE, "lan set ipaddr "); -+ } -+ else { -+ printf("Setting LAN %s to %d.%d.%d.%d\n", -+ ipmi_lan_params[IPMI_LANP_IP_ADDR].desc, -+ data[0], data[1], data[2], data[3]); -+ rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4); -+ } - } - /* network mask */ -- else if ((strncmp(argv[1], "netmask", 7) == 0) && -- (get_cmdline_ipaddr(argv[2], data) == 0)) { -- printf("Setting LAN %s to %d.%d.%d.%d\n", -- ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc, -- data[0], data[1], data[2], data[3]); -- rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4); -+ else if (strncmp(argv[1], "netmask", 7) == 0) { -+ if ( argc < 3 || strncmp(argv[2], "help", 4) == 0 || -+ get_cmdline_ipaddr(argv[2], data) != 0 ) { -+ lprintf(LOG_NOTICE, "lan set netmask "); -+ } -+ else { -+ printf("Setting LAN %s to %d.%d.%d.%d\n", -+ ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc, -+ data[0], data[1], data[2], data[3]); -+ rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4); -+ } - } - /* mac address */ -- else if ((strncmp(argv[1], "macaddr", 7) == 0) && -- (get_cmdline_macaddr(argv[2], data) == 0)) { -- printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", -- ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc, -- data[0], data[1], data[2], data[3], data[4], data[5]); -- rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6); -+ else if (strncmp(argv[1], "macaddr", 7) == 0) { -+ if ( argc < 3 || strncmp(argv[2], "help", 4) == 0 || -+ get_cmdline_macaddr(argv[2], data) != 0 ) { -+ lprintf(LOG_NOTICE, "lan set macaddr "); -+ } -+ else { -+ printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", -+ ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc, -+ data[0], data[1], data[2], data[3], data[4], data[5]); -+ rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6); -+ } - } - /* default gateway settings */ - else if (strncmp(argv[1], "defgw", 5) == 0) { diff --git a/debian/patches/20_ipmi_impi b/debian/patches/20_ipmi_impi new file mode 100644 index 0000000..dd5a770 --- /dev/null +++ b/debian/patches/20_ipmi_impi @@ -0,0 +1,335 @@ +## 20ipmi_impi.dpatch by +## +## 20ipmi_impi, closes #412816 +--- ipmitool-1.8.9-rc1/lib/ipmi_strings.c.orig 2005-05-15 06:26:33.000000000 +0200 ++++ ipmitool-1.8.9-rc1/lib/ipmi_strings.c 2005-10-23 15:22:57.000000000 +0200 +@@ -43,7 +43,7 @@ + /* + * From table 26-4 of the IPMI v2 specification + */ +-const struct valstr impi_bit_rate_vals[] = { ++const struct valstr ipmi_bit_rate_vals[] = { + { 0x00, "IPMI-Over-Serial-Setting"}, /* Using the value in the IPMI Over Serial Config */ + { 0x06, "9.6" }, + { 0x07, "19.2" }, +--- ipmitool-1.8.9-rc1/lib/ipmi_sol.c.orig 2006-08-02 19:17:10.000000000 +0200 ++++ ipmitool-1.8.9-rc1/lib/ipmi_sol.c 2006-08-25 16:01:54.000000000 +0200 +@@ -108,7 +108,7 @@ + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_TRANSPORT; +- req.msg.cmd = IMPI_GET_SOL_CONFIG_PARAMETERS; ++ req.msg.cmd = IPMI_GET_SOL_CONFIG_PARAMETERS; + req.msg.data_len = 4; + req.msg.data = data; + +@@ -485,10 +485,10 @@ + printf("%d,", params.retry_interval * 10); + + printf("%s,", +- val2str(params.volatile_bit_rate, impi_bit_rate_vals)); ++ val2str(params.volatile_bit_rate, ipmi_bit_rate_vals)); + + printf("%s,", +- val2str(params.non_volatile_bit_rate, impi_bit_rate_vals)); ++ val2str(params.non_volatile_bit_rate, ipmi_bit_rate_vals)); + + printf("%d,", params.payload_channel); + printf("%d\n", params.payload_port); +@@ -516,10 +516,10 @@ + params.retry_interval * 10); + + printf("Volatile Bit Rate (kbps) : %s\n", +- val2str(params.volatile_bit_rate, impi_bit_rate_vals)); ++ val2str(params.volatile_bit_rate, ipmi_bit_rate_vals)); + + printf("Non-Volatile Bit Rate (kbps) : %s\n", +- val2str(params.non_volatile_bit_rate, impi_bit_rate_vals)); ++ val2str(params.non_volatile_bit_rate, ipmi_bit_rate_vals)); + + printf("Payload Channel : %d (0x%02x)\n", + params.payload_channel, params.payload_channel); +@@ -554,7 +554,7 @@ + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_TRANSPORT; /* 0x0c */ +- req.msg.cmd = IMPI_SET_SOL_CONFIG_PARAMETERS; /* 0x21 */ ++ req.msg.cmd = IPMI_SET_SOL_CONFIG_PARAMETERS; /* 0x21 */ + req.msg.data = data; + + data[0] = channel; +@@ -1105,7 +1105,7 @@ + + + /* +- * impi_sol_deactivate ++ * ipmi_sol_deactivate + */ + static int + ipmi_sol_deactivate(struct ipmi_intf * intf) +@@ -1451,7 +1451,7 @@ + + + /* +- * impi_sol_activate ++ * ipmi_sol_activate + */ + static int + ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval) +--- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_intf.h.orig 2005-04-21 01:03:57.000000000 +0200 ++++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_intf.h 2005-10-23 16:07:56.000000000 +0200 +@@ -96,7 +96,7 @@ + socklen_t addrlen; + + /* +- * This struct holds state data specific to IMPI v2 / RMCP+ sessions ++ * This struct holds state data specific to IPMI v2 / RMCP+ sessions + */ + struct { + enum LANPLUS_SESSION_STATE session_state; +--- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_user.h.orig 2005-01-07 03:05:45.000000000 +0100 ++++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_user.h 2005-10-23 16:08:25.000000000 +0200 +@@ -44,7 +44,7 @@ + + + /* +- * The GET USER ACCESS response from table 22-32 of the IMPI v2.0 spec ++ * The GET USER ACCESS response from table 22-32 of the IPMI v2.0 spec + */ + struct user_access_rsp { + #if WORDS_BIGENDIAN +--- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_strings.h.orig 2005-05-11 07:46:40.000000000 +0200 ++++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_strings.h 2005-10-23 15:22:19.000000000 +0200 +@@ -45,7 +45,7 @@ + + extern const struct valstr ipmi_channel_activity_type_vals[]; + extern const struct valstr ipmi_privlvl_vals[]; +-extern const struct valstr impi_bit_rate_vals[]; ++extern const struct valstr ipmi_bit_rate_vals[]; + extern const struct valstr ipmi_set_in_progress_vals[]; + extern const struct valstr ipmi_authtype_session_vals[]; + extern const struct valstr ipmi_authtype_vals[]; +--- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_constants.h.orig 2005-05-11 07:46:40.000000000 +0200 ++++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_constants.h 2005-10-23 16:08:13.000000000 +0200 +@@ -42,9 +42,9 @@ + * COMMANDS + */ + #define IPMI_GET_SDR_REPOSITORY_INFO 0x20 +-#define IMPI_SOL_ACTIVATING 0x20 +-#define IMPI_SET_SOL_CONFIG_PARAMETERS 0x21 +-#define IMPI_GET_SOL_CONFIG_PARAMETERS 0x22 ++#define IPMI_SOL_ACTIVATING 0x20 ++#define IPMI_SET_SOL_CONFIG_PARAMETERS 0x21 ++#define IPMI_GET_SOL_CONFIG_PARAMETERS 0x22 + #define IPMI_SET_USER_ACCESS 0x43 + #define IPMI_GET_USER_ACCESS 0x44 + #define IPMI_SET_USER_NAME 0x45 +--- ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.c.orig 2006-08-03 18:26:06.000000000 +0200 ++++ ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.c 2006-08-25 16:06:37.000000000 +0200 +@@ -862,7 +862,7 @@ + /* + * read_open_session_reponse + * +- * Initialize the ipmi_rs from the IMPI 2.x open session response data. ++ * Initialize the ipmi_rs from the IPMI 2.x open session response data. + * + * The offset should point to the first byte of the the Open Session Response + * payload when this function is called. +@@ -924,7 +924,7 @@ + /* + * read_rakp2_message + * +- * Initialize the ipmi_rs from the IMPI 2.x RAKP 2 message ++ * Initialize the ipmi_rs from the IPMI 2.x RAKP 2 message + * + * The offset should point the first byte of the the RAKP 2 payload when this + * function is called. +@@ -1004,7 +1004,7 @@ + /* + * read_rakp4_message + * +- * Initialize the ipmi_rs from the IMPI 2.x RAKP 4 message ++ * Initialize the ipmi_rs from the IPMI 2.x RAKP 4 message + * + * The offset should point the first byte of the the RAKP 4 payload when this + * function is called. +@@ -1212,7 +1212,7 @@ + /* + * read_ipmi_response + * +- * Initialize the impi_rs from with the IPMI response specific data ++ * Initialize the ipmi_rs from with the IPMI response specific data + * + * The offset should point the first byte of the the IPMI payload when this + * function is called. +@@ -1244,7 +1244,7 @@ + /* + * read_sol_packet + * +- * Initialize the impi_rs with the SOL response data ++ * Initialize the ipmi_rs with the SOL response data + * + * The offset should point the first byte of the the SOL payload when this + * function is called. +@@ -1562,32 +1562,32 @@ + *------------------------------------------ + */ + /* ipmi session Auth Type / Format is always 0x06 for IPMI v2 */ +- msg[IMPI_LANPLUS_OFFSET_AUTHTYPE] = 0x06; ++ msg[IPMI_LANPLUS_OFFSET_AUTHTYPE] = 0x06; + + /* Payload Type -- also specifies whether were authenticated/encyrpted */ +- msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] = payload->payload_type; ++ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] = payload->payload_type; + + if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE) + { +- msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= ++ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= + ((session->v2_data.crypt_alg != IPMI_CRYPT_NONE )? 0x80 : 0x00); +- msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= ++ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= + ((session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE)? 0x40 : 0x00); + } + + if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE) + { + /* Session ID -- making it LSB */ +- msg[IMPI_LANPLUS_OFFSET_SESSION_ID ] = session->v2_data.bmc_id & 0xff; +- msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8) & 0xff; +- msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 2] = (session->v2_data.bmc_id >> 16) & 0xff; +- msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 3] = (session->v2_data.bmc_id >> 24) & 0xff; ++ msg[IPMI_LANPLUS_OFFSET_SESSION_ID ] = session->v2_data.bmc_id & 0xff; ++ msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8) & 0xff; ++ msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 2] = (session->v2_data.bmc_id >> 16) & 0xff; ++ msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 3] = (session->v2_data.bmc_id >> 24) & 0xff; + + /* Sequence Number -- making it LSB */ +- msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM ] = session->out_seq & 0xff; +- msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 1] = (session->out_seq >> 8) & 0xff; +- msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff; +- msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff; ++ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM ] = session->out_seq & 0xff; ++ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 1] = (session->out_seq >> 8) & 0xff; ++ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff; ++ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff; + } + + /* +@@ -1679,9 +1679,9 @@ + } + + /* Now we know the payload length */ +- msg[IMPI_LANPLUS_OFFSET_PAYLOAD_SIZE ] = ++ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE ] = + payload->payload_length & 0xff; +- msg[IMPI_LANPLUS_OFFSET_PAYLOAD_SIZE + 1] = ++ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE + 1] = + (payload->payload_length >> 8) & 0xff; + + +@@ -1745,14 +1745,14 @@ + 2; + + if (verbose > 2) +- printbuf(msg + IMPI_LANPLUS_OFFSET_AUTHTYPE, hmac_input_size, "authcode input"); ++ printbuf(msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, hmac_input_size, "authcode input"); + + + /* Auth Code */ + lanplus_HMAC(session->v2_data.integrity_alg, + session->v2_data.k1, /* key */ + 20, /* key length */ +- msg + IMPI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */ ++ msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */ + hmac_input_size, + hmac_output, + &hmac_length); +@@ -2529,7 +2529,7 @@ + * ipmi_get_auth_capabilities_cmd + * + * This command may have to be sent twice. We first ask for the +- * authentication capabilities with the "request IMPI v2 data bit" ++ * authentication capabilities with the "request IPMI v2 data bit" + * set. If this fails, we send the same command without that bit + * set. + * +@@ -2602,7 +2602,7 @@ + + + static int +-impi_close_session_cmd(struct ipmi_intf * intf) ++ipmi_close_session_cmd(struct ipmi_intf * intf) + { + struct ipmi_rs * rsp; + struct ipmi_rq req; +@@ -2836,7 +2836,7 @@ + /* + * ipmi_lanplus_rakp1 + * +- * Build and send the RAKP 1 message as part of the IMPI v2 / RMCP+ session ++ * Build and send the RAKP 1 message as part of the IPMI v2 / RMCP+ session + * negotiation protocol. We also read and validate the RAKP 2 message received + * from the BMC, here. See section 13.20 of the IPMI v2 specification for + * details. +@@ -2990,7 +2990,7 @@ + /* + * ipmi_lanplus_rakp3 + * +- * Build and send the RAKP 3 message as part of the IMPI v2 / RMCP+ session ++ * Build and send the RAKP 3 message as part of the IPMI v2 / RMCP+ session + * negotiation protocol. We also read and validate the RAKP 4 message received + * from the BMC, here. See section 13.20 of the IPMI v2 specification for + * details. +@@ -3154,7 +3154,7 @@ + ipmi_lanplus_close(struct ipmi_intf * intf) + { + if (!intf->abort) +- impi_close_session_cmd(intf); ++ ipmi_close_session_cmd(intf); + + if (intf->fd >= 0) + close(intf->fd); +--- ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.h.orig 2005-03-17 00:17:37.000000000 +0100 ++++ ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.h 2005-10-23 16:09:48.000000000 +0200 +@@ -84,11 +84,11 @@ + + + /* Session message offsets, from table 13-8 of the v2 specification */ +-#define IMPI_LANPLUS_OFFSET_AUTHTYPE 0x04 +-#define IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE 0x05 +-#define IMPI_LANPLUS_OFFSET_SESSION_ID 0x06 +-#define IMPI_LANPLUS_OFFSET_SEQUENCE_NUM 0x0A +-#define IMPI_LANPLUS_OFFSET_PAYLOAD_SIZE 0x0E ++#define IPMI_LANPLUS_OFFSET_AUTHTYPE 0x04 ++#define IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE 0x05 ++#define IPMI_LANPLUS_OFFSET_SESSION_ID 0x06 ++#define IPMI_LANPLUS_OFFSET_SEQUENCE_NUM 0x0A ++#define IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE 0x0E + #define IPMI_LANPLUS_OFFSET_PAYLOAD 0x10 + + +--- ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus_crypt.c.orig 2005-03-24 02:46:03.000000000 +0100 ++++ ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus_crypt.c 2005-10-23 16:10:06.000000000 +0200 +@@ -800,8 +800,8 @@ + lanplus_HMAC(session->v2_data.integrity_alg, + session->v2_data.k1, + IPMI_AUTHCODE_BUFFER_SIZE, +- rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE, +- rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, ++ rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE, ++ rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, + generated_authcode, + &generated_authcode_length); + +@@ -809,8 +809,8 @@ + { + lprintf(LOG_DEBUG+2, "Validating authcode"); + printbuf(session->v2_data.k1, 20, "K1"); +- printbuf(rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE, +- rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, ++ printbuf(rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE, ++ rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, + "Authcode Input Data"); + printbuf(generated_authcode, 12, "Generated authcode"); + printbuf(bmc_authcode, 12, "Expected authcode"); diff --git a/debian/patches/20_ipmi_impi.dpatch b/debian/patches/20_ipmi_impi.dpatch deleted file mode 100644 index d966a1d..0000000 --- a/debian/patches/20_ipmi_impi.dpatch +++ /dev/null @@ -1,340 +0,0 @@ -#! /bin/sh /usr/share/dpatch/dpatch-run -## 20ipmi_impi.dpatch by -## -## All lines beginning with `## DP:' are a description of the patch. -## DP: 20ipmi_impi, closes #412816 - -@DPATCH@ - ---- ipmitool-1.8.9-rc1/lib/ipmi_strings.c.orig 2005-05-15 06:26:33.000000000 +0200 -+++ ipmitool-1.8.9-rc1/lib/ipmi_strings.c 2005-10-23 15:22:57.000000000 +0200 -@@ -43,7 +43,7 @@ - /* - * From table 26-4 of the IPMI v2 specification - */ --const struct valstr impi_bit_rate_vals[] = { -+const struct valstr ipmi_bit_rate_vals[] = { - { 0x00, "IPMI-Over-Serial-Setting"}, /* Using the value in the IPMI Over Serial Config */ - { 0x06, "9.6" }, - { 0x07, "19.2" }, ---- ipmitool-1.8.9-rc1/lib/ipmi_sol.c.orig 2006-08-02 19:17:10.000000000 +0200 -+++ ipmitool-1.8.9-rc1/lib/ipmi_sol.c 2006-08-25 16:01:54.000000000 +0200 -@@ -108,7 +108,7 @@ - - memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_TRANSPORT; -- req.msg.cmd = IMPI_GET_SOL_CONFIG_PARAMETERS; -+ req.msg.cmd = IPMI_GET_SOL_CONFIG_PARAMETERS; - req.msg.data_len = 4; - req.msg.data = data; - -@@ -485,10 +485,10 @@ - printf("%d,", params.retry_interval * 10); - - printf("%s,", -- val2str(params.volatile_bit_rate, impi_bit_rate_vals)); -+ val2str(params.volatile_bit_rate, ipmi_bit_rate_vals)); - - printf("%s,", -- val2str(params.non_volatile_bit_rate, impi_bit_rate_vals)); -+ val2str(params.non_volatile_bit_rate, ipmi_bit_rate_vals)); - - printf("%d,", params.payload_channel); - printf("%d\n", params.payload_port); -@@ -516,10 +516,10 @@ - params.retry_interval * 10); - - printf("Volatile Bit Rate (kbps) : %s\n", -- val2str(params.volatile_bit_rate, impi_bit_rate_vals)); -+ val2str(params.volatile_bit_rate, ipmi_bit_rate_vals)); - - printf("Non-Volatile Bit Rate (kbps) : %s\n", -- val2str(params.non_volatile_bit_rate, impi_bit_rate_vals)); -+ val2str(params.non_volatile_bit_rate, ipmi_bit_rate_vals)); - - printf("Payload Channel : %d (0x%02x)\n", - params.payload_channel, params.payload_channel); -@@ -554,7 +554,7 @@ - - memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_TRANSPORT; /* 0x0c */ -- req.msg.cmd = IMPI_SET_SOL_CONFIG_PARAMETERS; /* 0x21 */ -+ req.msg.cmd = IPMI_SET_SOL_CONFIG_PARAMETERS; /* 0x21 */ - req.msg.data = data; - - data[0] = channel; -@@ -1105,7 +1105,7 @@ - - - /* -- * impi_sol_deactivate -+ * ipmi_sol_deactivate - */ - static int - ipmi_sol_deactivate(struct ipmi_intf * intf) -@@ -1451,7 +1451,7 @@ - - - /* -- * impi_sol_activate -+ * ipmi_sol_activate - */ - static int - ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval) ---- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_intf.h.orig 2005-04-21 01:03:57.000000000 +0200 -+++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_intf.h 2005-10-23 16:07:56.000000000 +0200 -@@ -96,7 +96,7 @@ - socklen_t addrlen; - - /* -- * This struct holds state data specific to IMPI v2 / RMCP+ sessions -+ * This struct holds state data specific to IPMI v2 / RMCP+ sessions - */ - struct { - enum LANPLUS_SESSION_STATE session_state; ---- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_user.h.orig 2005-01-07 03:05:45.000000000 +0100 -+++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_user.h 2005-10-23 16:08:25.000000000 +0200 -@@ -44,7 +44,7 @@ - - - /* -- * The GET USER ACCESS response from table 22-32 of the IMPI v2.0 spec -+ * The GET USER ACCESS response from table 22-32 of the IPMI v2.0 spec - */ - struct user_access_rsp { - #if WORDS_BIGENDIAN ---- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_strings.h.orig 2005-05-11 07:46:40.000000000 +0200 -+++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_strings.h 2005-10-23 15:22:19.000000000 +0200 -@@ -45,7 +45,7 @@ - - extern const struct valstr ipmi_channel_activity_type_vals[]; - extern const struct valstr ipmi_privlvl_vals[]; --extern const struct valstr impi_bit_rate_vals[]; -+extern const struct valstr ipmi_bit_rate_vals[]; - extern const struct valstr ipmi_set_in_progress_vals[]; - extern const struct valstr ipmi_authtype_session_vals[]; - extern const struct valstr ipmi_authtype_vals[]; ---- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_constants.h.orig 2005-05-11 07:46:40.000000000 +0200 -+++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_constants.h 2005-10-23 16:08:13.000000000 +0200 -@@ -42,9 +42,9 @@ - * COMMANDS - */ - #define IPMI_GET_SDR_REPOSITORY_INFO 0x20 --#define IMPI_SOL_ACTIVATING 0x20 --#define IMPI_SET_SOL_CONFIG_PARAMETERS 0x21 --#define IMPI_GET_SOL_CONFIG_PARAMETERS 0x22 -+#define IPMI_SOL_ACTIVATING 0x20 -+#define IPMI_SET_SOL_CONFIG_PARAMETERS 0x21 -+#define IPMI_GET_SOL_CONFIG_PARAMETERS 0x22 - #define IPMI_SET_USER_ACCESS 0x43 - #define IPMI_GET_USER_ACCESS 0x44 - #define IPMI_SET_USER_NAME 0x45 ---- ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.c.orig 2006-08-03 18:26:06.000000000 +0200 -+++ ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.c 2006-08-25 16:06:37.000000000 +0200 -@@ -862,7 +862,7 @@ - /* - * read_open_session_reponse - * -- * Initialize the ipmi_rs from the IMPI 2.x open session response data. -+ * Initialize the ipmi_rs from the IPMI 2.x open session response data. - * - * The offset should point to the first byte of the the Open Session Response - * payload when this function is called. -@@ -924,7 +924,7 @@ - /* - * read_rakp2_message - * -- * Initialize the ipmi_rs from the IMPI 2.x RAKP 2 message -+ * Initialize the ipmi_rs from the IPMI 2.x RAKP 2 message - * - * The offset should point the first byte of the the RAKP 2 payload when this - * function is called. -@@ -1004,7 +1004,7 @@ - /* - * read_rakp4_message - * -- * Initialize the ipmi_rs from the IMPI 2.x RAKP 4 message -+ * Initialize the ipmi_rs from the IPMI 2.x RAKP 4 message - * - * The offset should point the first byte of the the RAKP 4 payload when this - * function is called. -@@ -1212,7 +1212,7 @@ - /* - * read_ipmi_response - * -- * Initialize the impi_rs from with the IPMI response specific data -+ * Initialize the ipmi_rs from with the IPMI response specific data - * - * The offset should point the first byte of the the IPMI payload when this - * function is called. -@@ -1244,7 +1244,7 @@ - /* - * read_sol_packet - * -- * Initialize the impi_rs with the SOL response data -+ * Initialize the ipmi_rs with the SOL response data - * - * The offset should point the first byte of the the SOL payload when this - * function is called. -@@ -1562,32 +1562,32 @@ - *------------------------------------------ - */ - /* ipmi session Auth Type / Format is always 0x06 for IPMI v2 */ -- msg[IMPI_LANPLUS_OFFSET_AUTHTYPE] = 0x06; -+ msg[IPMI_LANPLUS_OFFSET_AUTHTYPE] = 0x06; - - /* Payload Type -- also specifies whether were authenticated/encyrpted */ -- msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] = payload->payload_type; -+ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] = payload->payload_type; - - if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE) - { -- msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= -+ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= - ((session->v2_data.crypt_alg != IPMI_CRYPT_NONE )? 0x80 : 0x00); -- msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= -+ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= - ((session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE)? 0x40 : 0x00); - } - - if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE) - { - /* Session ID -- making it LSB */ -- msg[IMPI_LANPLUS_OFFSET_SESSION_ID ] = session->v2_data.bmc_id & 0xff; -- msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8) & 0xff; -- msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 2] = (session->v2_data.bmc_id >> 16) & 0xff; -- msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 3] = (session->v2_data.bmc_id >> 24) & 0xff; -+ msg[IPMI_LANPLUS_OFFSET_SESSION_ID ] = session->v2_data.bmc_id & 0xff; -+ msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8) & 0xff; -+ msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 2] = (session->v2_data.bmc_id >> 16) & 0xff; -+ msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 3] = (session->v2_data.bmc_id >> 24) & 0xff; - - /* Sequence Number -- making it LSB */ -- msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM ] = session->out_seq & 0xff; -- msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 1] = (session->out_seq >> 8) & 0xff; -- msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff; -- msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff; -+ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM ] = session->out_seq & 0xff; -+ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 1] = (session->out_seq >> 8) & 0xff; -+ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff; -+ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff; - } - - /* -@@ -1679,9 +1679,9 @@ - } - - /* Now we know the payload length */ -- msg[IMPI_LANPLUS_OFFSET_PAYLOAD_SIZE ] = -+ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE ] = - payload->payload_length & 0xff; -- msg[IMPI_LANPLUS_OFFSET_PAYLOAD_SIZE + 1] = -+ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE + 1] = - (payload->payload_length >> 8) & 0xff; - - -@@ -1745,14 +1745,14 @@ - 2; - - if (verbose > 2) -- printbuf(msg + IMPI_LANPLUS_OFFSET_AUTHTYPE, hmac_input_size, "authcode input"); -+ printbuf(msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, hmac_input_size, "authcode input"); - - - /* Auth Code */ - lanplus_HMAC(session->v2_data.integrity_alg, - session->v2_data.k1, /* key */ - 20, /* key length */ -- msg + IMPI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */ -+ msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */ - hmac_input_size, - hmac_output, - &hmac_length); -@@ -2529,7 +2529,7 @@ - * ipmi_get_auth_capabilities_cmd - * - * This command may have to be sent twice. We first ask for the -- * authentication capabilities with the "request IMPI v2 data bit" -+ * authentication capabilities with the "request IPMI v2 data bit" - * set. If this fails, we send the same command without that bit - * set. - * -@@ -2602,7 +2602,7 @@ - - - static int --impi_close_session_cmd(struct ipmi_intf * intf) -+ipmi_close_session_cmd(struct ipmi_intf * intf) - { - struct ipmi_rs * rsp; - struct ipmi_rq req; -@@ -2836,7 +2836,7 @@ - /* - * ipmi_lanplus_rakp1 - * -- * Build and send the RAKP 1 message as part of the IMPI v2 / RMCP+ session -+ * Build and send the RAKP 1 message as part of the IPMI v2 / RMCP+ session - * negotiation protocol. We also read and validate the RAKP 2 message received - * from the BMC, here. See section 13.20 of the IPMI v2 specification for - * details. -@@ -2990,7 +2990,7 @@ - /* - * ipmi_lanplus_rakp3 - * -- * Build and send the RAKP 3 message as part of the IMPI v2 / RMCP+ session -+ * Build and send the RAKP 3 message as part of the IPMI v2 / RMCP+ session - * negotiation protocol. We also read and validate the RAKP 4 message received - * from the BMC, here. See section 13.20 of the IPMI v2 specification for - * details. -@@ -3154,7 +3154,7 @@ - ipmi_lanplus_close(struct ipmi_intf * intf) - { - if (!intf->abort) -- impi_close_session_cmd(intf); -+ ipmi_close_session_cmd(intf); - - if (intf->fd >= 0) - close(intf->fd); ---- ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.h.orig 2005-03-17 00:17:37.000000000 +0100 -+++ ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.h 2005-10-23 16:09:48.000000000 +0200 -@@ -84,11 +84,11 @@ - - - /* Session message offsets, from table 13-8 of the v2 specification */ --#define IMPI_LANPLUS_OFFSET_AUTHTYPE 0x04 --#define IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE 0x05 --#define IMPI_LANPLUS_OFFSET_SESSION_ID 0x06 --#define IMPI_LANPLUS_OFFSET_SEQUENCE_NUM 0x0A --#define IMPI_LANPLUS_OFFSET_PAYLOAD_SIZE 0x0E -+#define IPMI_LANPLUS_OFFSET_AUTHTYPE 0x04 -+#define IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE 0x05 -+#define IPMI_LANPLUS_OFFSET_SESSION_ID 0x06 -+#define IPMI_LANPLUS_OFFSET_SEQUENCE_NUM 0x0A -+#define IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE 0x0E - #define IPMI_LANPLUS_OFFSET_PAYLOAD 0x10 - - ---- ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus_crypt.c.orig 2005-03-24 02:46:03.000000000 +0100 -+++ ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus_crypt.c 2005-10-23 16:10:06.000000000 +0200 -@@ -800,8 +800,8 @@ - lanplus_HMAC(session->v2_data.integrity_alg, - session->v2_data.k1, - IPMI_AUTHCODE_BUFFER_SIZE, -- rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE, -- rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, -+ rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE, -+ rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, - generated_authcode, - &generated_authcode_length); - -@@ -809,8 +809,8 @@ - { - lprintf(LOG_DEBUG+2, "Validating authcode"); - printbuf(session->v2_data.k1, 20, "K1"); -- printbuf(rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE, -- rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, -+ printbuf(rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE, -+ rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, - "Authcode Input Data"); - printbuf(generated_authcode, 12, "Generated authcode"); - printbuf(bmc_authcode, 12, "Expected authcode"); diff --git a/debian/patches/20_ipmi_isol b/debian/patches/20_ipmi_isol new file mode 100644 index 0000000..ac70722 --- /dev/null +++ b/debian/patches/20_ipmi_isol @@ -0,0 +1,1852 @@ +## 20_ipmi_isol.dpatch by +## +## 20_ipmi_isol, closes #412816 +diff -urN ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h ipmitool-1.8.9/include/ipmitool/ipmi_isol.h +--- ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h 2007-02-22 08:38:55.000000000 +0000 ++++ ipmitool-1.8.9/include/ipmitool/ipmi_isol.h 2007-12-13 10:16:57.063986495 +0000 +@@ -41,15 +41,16 @@ + + #define ISOL_ENABLE_PARAM 0x01 + #define ISOL_AUTHENTICATION_PARAM 0x02 +-#define ISOL_ENABLE_FLAG 0x01 +-#define ISOL_PRIVILEGE_LEVEL_USER 0x02 ++ + #define ISOL_BAUD_RATE_PARAM 0x05 +-#define ISOL_BAUD_RATE_9600 0x06 +-#define ISOL_BAUD_RATE_19200 0x07 +-#define ISOL_BAUD_RATE_38400 0x08 +-#define ISOL_BAUD_RATE_57600 0x09 +-#define ISOL_BAUD_RATE_115200 0x0A +-#define ISOL_PREFERRED_BAUD_RATE 0x07 ++ ++#define ISOL_PREFERRED_BAUD_RATE 0x07 ++ ++struct isol_config_parameters { ++ uint8_t enabled; ++ uint8_t privilege_level; ++ uint8_t bit_rate; ++}; + + int ipmi_isol_main(struct ipmi_intf *, int, char **); + +diff -urN ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h.orig ipmitool-1.8.9/include/ipmitool/ipmi_isol.h.orig +--- ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ ipmitool-1.8.9/include/ipmitool/ipmi_isol.h.orig 2007-02-22 08:38:55.000000000 +0000 +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * Redistribution of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * Redistribution in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * Neither the name of Sun Microsystems, Inc. or the names of ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * This software is provided "AS IS," without a warranty of any kind. ++ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, ++ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A ++ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ++ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE ++ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING ++ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL ++ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, ++ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR ++ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF ++ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, ++ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ++ */ ++ ++#ifndef IPMI_ISOL_H ++#define IPMI_ISOL_H ++ ++#include ++ ++#define ACTIVATE_ISOL 0x01 ++#define SET_ISOL_CONFIG 0x03 ++#define GET_ISOL_CONFIG 0x04 ++ ++#define ISOL_ENABLE_PARAM 0x01 ++#define ISOL_AUTHENTICATION_PARAM 0x02 ++#define ISOL_ENABLE_FLAG 0x01 ++#define ISOL_PRIVILEGE_LEVEL_USER 0x02 ++#define ISOL_BAUD_RATE_PARAM 0x05 ++#define ISOL_BAUD_RATE_9600 0x06 ++#define ISOL_BAUD_RATE_19200 0x07 ++#define ISOL_BAUD_RATE_38400 0x08 ++#define ISOL_BAUD_RATE_57600 0x09 ++#define ISOL_BAUD_RATE_115200 0x0A ++#define ISOL_PREFERRED_BAUD_RATE 0x07 ++ ++int ipmi_isol_main(struct ipmi_intf *, int, char **); ++ ++#endif /* IPMI_SOL_H */ +diff -urN ipmitool-1.8.9.orig/lib/ipmi_isol.c ipmitool-1.8.9/lib/ipmi_isol.c +--- ipmitool-1.8.9.orig/lib/ipmi_isol.c 2007-02-22 08:38:56.000000000 +0000 ++++ ipmitool-1.8.9/lib/ipmi_isol.c 2007-12-13 10:16:57.063986495 +0000 +@@ -32,7 +32,17 @@ + + #include + #include ++#include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#include + + #include + #include +@@ -41,39 +51,40 @@ + #include + #include + +-const struct valstr ipmi_isol_baud_vals[] = { +- { ISOL_BAUD_RATE_9600, "9600" }, +- { ISOL_BAUD_RATE_19200, "19200" }, +- { ISOL_BAUD_RATE_38400, "38400" }, +- { ISOL_BAUD_RATE_57600, "57600" }, +- { ISOL_BAUD_RATE_115200, "115200" }, +- { 0x00, NULL } +-}; ++static struct termios _saved_tio; ++static int _in_raw_mode = 0; + + extern int verbose; + +-static int ipmi_isol_setup(struct ipmi_intf * intf, char baudsetting) ++#define ISOL_ESCAPE_CHARACTER '~' ++ ++/* ++ * ipmi_get_isol_info ++ */ ++static int ipmi_get_isol_info(struct ipmi_intf * intf, ++ struct isol_config_parameters * params) + { + struct ipmi_rs * rsp; + struct ipmi_rq req; +- unsigned char data[6]; ++ unsigned char data[6]; + +- /* TEST FOR AVAILABILITY */ ++ memset(&req, 0, sizeof(req)); ++ req.msg.netfn = IPMI_NETFN_ISOL; ++ req.msg.cmd = GET_ISOL_CONFIG; ++ req.msg.data = data; ++ req.msg.data_len = 4; + ++ /* GET ISOL ENABLED CONFIG */ ++ + memset(data, 0, 6); + data[0] = 0x00; + data[1] = ISOL_ENABLE_PARAM; +- data[2] = ISOL_ENABLE_FLAG; +- +- memset(&req, 0, sizeof(req)); +- req.msg.netfn = IPMI_NETFN_ISOL; +- req.msg.cmd = SET_ISOL_CONFIG; +- req.msg.data = data; +- req.msg.data_len = 3; ++ data[2] = 0x00; /* block */ ++ data[3] = 0x00; /* selector */ + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { +- lprintf(LOG_ERR, "Error in Set ISOL Config Command"); ++ lprintf(LOG_ERR, "Error in Get ISOL Config Command"); + return -1; + } + if (rsp->ccode == 0xc1) { +@@ -81,20 +92,19 @@ + return -1; + } + if (rsp->ccode > 0) { +- lprintf(LOG_ERR, "Error in Set ISOL Config Command: %s", ++ lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } ++ params->enabled = rsp->data[1]; + +- /* GET ISOL CONFIG */ +- ++ /* GET ISOL AUTHENTICATON CONFIG */ ++ + memset(data, 0, 6); + data[0] = 0x00; + data[1] = ISOL_AUTHENTICATION_PARAM; + data[2] = 0x00; /* block */ + data[3] = 0x00; /* selector */ +- req.msg.cmd = GET_ISOL_CONFIG; +- req.msg.data_len = 4; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { +@@ -106,86 +116,713 @@ + val2str(rsp->ccode, completion_code_vals)); + return -1; + } +- +- if (verbose > 1) +- printbuf(rsp->data, rsp->data_len, "ISOL Config"); +- +- /* SET ISOL CONFIG - AUTHENTICATION */ +- ++ params->privilege_level = rsp->data[1]; ++ ++ /* GET ISOL BAUD RATE CONFIG */ ++ + memset(data, 0, 6); + data[0] = 0x00; +- data[1] = ISOL_AUTHENTICATION_PARAM; +- data[2] = ISOL_PRIVILEGE_LEVEL_USER | (rsp->data[1] & 0x80); +- req.msg.cmd = SET_ISOL_CONFIG; +- req.msg.data_len = 3; ++ data[1] = ISOL_BAUD_RATE_PARAM; ++ data[2] = 0x00; /* block */ ++ data[3] = 0x00; /* selector */ + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { +- lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command"); ++ lprintf(LOG_ERR, "Error in Get ISOL Config Command"); + return -1; + } + if (rsp->ccode > 0) { +- lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command: %s", ++ lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } ++ params->bit_rate = rsp->data[1]; + +- /* SET ISOL CONFIG - BAUD RATE */ ++ return 0; ++} + +- memset(data, 0, 6); +- data[0] = 0x00; +- data[1] = ISOL_BAUD_RATE_PARAM; +- data[2] = baudsetting; ++static int ipmi_print_isol_info(struct ipmi_intf * intf) ++{ ++ struct isol_config_parameters params = {0}; ++ if (ipmi_get_isol_info(intf, ¶ms)) ++ return -1; ++ ++ if (csv_output) ++ { ++ printf("%s,", (params.enabled & 0x1)?"true": "false"); ++ printf("%s,", ++ val2str((params.privilege_level & 0xf), ipmi_privlvl_vals)); ++ printf("%s,", ++ val2str((params.bit_rate & 0xf), ipmi_bit_rate_vals)); ++ } ++ else ++ { ++ printf("Enabled : %s\n", ++ (params.enabled & 0x1)?"true": "false"); ++ printf("Privilege Level : %s\n", ++ val2str((params.privilege_level & 0xf), ipmi_privlvl_vals)); ++ printf("Bit Rate (kbps) : %s\n", ++ val2str((params.bit_rate & 0xf), ipmi_bit_rate_vals)); ++ } ++ ++ return 0; ++} ++ ++static int ipmi_isol_set_param(struct ipmi_intf * intf, ++ const char *param, ++ const char *value) ++{ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ unsigned char data[6]; ++ struct isol_config_parameters params = {0}; ++ ++ /* We need other values to complete the request */ ++ if (ipmi_get_isol_info(intf, ¶ms)) ++ return -1; ++ ++ memset(&req, 0, sizeof(req)); ++ req.msg.netfn = IPMI_NETFN_ISOL; + req.msg.cmd = SET_ISOL_CONFIG; ++ req.msg.data = data; + req.msg.data_len = 3; + ++ memset(data, 0, 6); ++ ++ /* ++ * enabled ++ */ ++ if (strcmp(param, "enabled") == 0) ++ { ++ data[1] = ISOL_ENABLE_PARAM; ++ if (strcmp(value, "true") == 0) ++ data[2] = 0x01; ++ else if (strcmp(value, "false") == 0) ++ data[2] = 0x00; ++ else { ++ lprintf(LOG_ERR, "Invalid value %s for parameter %s", ++ value, param); ++ lprintf(LOG_ERR, "Valid values are true and false"); ++ return -1; ++ } ++ } ++ ++ /* ++ * privilege-level ++ */ ++ else if (strcmp(param, "privilege-level") == 0) ++ { ++ data[1] = ISOL_AUTHENTICATION_PARAM; ++ if (! strcmp(value, "user")) ++ data[2] = 0x02; ++ else if (! strcmp(value, "operator")) ++ data[2] = 0x03; ++ else if (! strcmp(value, "admin")) ++ data[2] = 0x04; ++ else if (! strcmp(value, "oem")) ++ data[2] = 0x05; ++ else ++ { ++ lprintf(LOG_ERR, "Invalid value %s for parameter %s", ++ value, param); ++ lprintf(LOG_ERR, "Valid values are user, operator, admin, and oem"); ++ return -1; ++ } ++ /* We need to mask bit7 from the fetched value */ ++ data[2] |= (params.privilege_level & 0x80) ? 0x80 : 0x00; ++ } ++ ++ /* ++ * bit-rate ++ */ ++ else if (strcmp(param, "bit-rate") == 0) ++ { ++ data[1] = ISOL_BAUD_RATE_PARAM; ++ if (strncmp(value, "9.6", 3) == 0) { ++ data[2] = 0x06; ++ } ++ else if (strncmp(value, "19.2", 4) == 0) { ++ data[2] = 0x07; ++ } ++ else if (strncmp(value, "38.4", 4) == 0) { ++ data[2] = 0x08; ++ } ++ else if (strncmp(value, "57.6", 4) == 0) { ++ data[2] = 0x09; ++ } ++ else if (strncmp(value, "115.2", 5) == 0) { ++ data[2] = 0x0A; ++ } ++ else { ++ lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", value); ++ lprintf(LOG_ERR, "Valid values are 9.6, 19.2, 38.4, 57.6 and 115.2"); ++ return -1; ++ } ++ } ++ else ++ { ++ lprintf(LOG_ERR, "Error: invalid ISOL parameter %s", param); ++ return -1; ++ } ++ ++ ++ /* ++ * Execute the request ++ */ ++ + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { +- lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command"); ++ lprintf(LOG_ERR, "Error setting ISOL parameter '%s'", param); + return -1; + } + if (rsp->ccode > 0) { +- lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command: %s", +- val2str(rsp->ccode, completion_code_vals)); ++ lprintf(LOG_ERR, "Error setting ISOL parameter '%s': %s", ++ param, val2str(rsp->ccode, completion_code_vals)); + return -1; + } + +- printf("Set ISOL Baud Rate to %s\n", +- val2str(baudsetting, ipmi_isol_baud_vals)); ++ return 0; ++} ++ ++static void ++leave_raw_mode(void) ++{ ++ if (!_in_raw_mode) ++ return; ++ if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) ++ perror("tcsetattr"); ++ else ++ _in_raw_mode = 0; ++} ++ ++ ++ ++static void ++enter_raw_mode(void) ++{ ++ struct termios tio; ++ if (tcgetattr(fileno(stdin), &tio) == -1) { ++ perror("tcgetattr"); ++ return; ++ } ++ _saved_tio = tio; ++ tio.c_iflag |= IGNPAR; ++ tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF)\ ++ ; ++ tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); ++ // #ifdef IEXTEN ++ tio.c_lflag &= ~IEXTEN; ++ // #endif ++ tio.c_oflag &= ~OPOST; ++ tio.c_cc[VMIN] = 1; ++ tio.c_cc[VTIME] = 0; ++ if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1) ++ perror("tcsetattr"); ++ else ++ _in_raw_mode = 1; ++} ++ ++ ++static void ++sendBreak(struct ipmi_intf * intf) ++{ ++ struct ipmi_v2_payload v2_payload; ++ ++ memset(&v2_payload, 0, sizeof(v2_payload)); ++ ++ v2_payload.payload.sol_packet.character_count = 0; ++ v2_payload.payload.sol_packet.generate_break = 1; ++ ++ intf->send_sol(intf, &v2_payload); ++} ++ ++/* ++ * suspendSelf ++ * ++ * Put ourself in the background ++ * ++ * param bRestoreTty specifies whether we will put our self back ++ * in raw mode when we resume ++ */ ++static void ++suspendSelf(int bRestoreTty) ++{ ++ leave_raw_mode(); ++ kill(getpid(), SIGTSTP); ++ ++ if (bRestoreTty) ++ enter_raw_mode(); ++} ++ ++ ++ ++/* ++ * printiSolEscapeSequences ++ * ++ * Send some useful documentation to the user ++ */ ++static void ++printiSolEscapeSequences(void) ++{ ++ printf( ++ "%c?\r\n\ ++ Supported escape sequences:\r\n\ ++ %c. - terminate connection\r\n\ ++ %c^Z - suspend ipmitool\r\n\ ++ %c^X - suspend ipmitool, but don't restore tty on restart\r\n\ ++ %cB - send break\r\n\ ++ %c? - this message\r\n\ ++ %c%c - send the escape character by typing it twice\r\n\ ++ (Note that escapes are only recognized immediately after newline.)\r\n", ++ ISOL_ESCAPE_CHARACTER, ++ ISOL_ESCAPE_CHARACTER, ++ ISOL_ESCAPE_CHARACTER, ++ ISOL_ESCAPE_CHARACTER, ++ ISOL_ESCAPE_CHARACTER, ++ ISOL_ESCAPE_CHARACTER, ++ ISOL_ESCAPE_CHARACTER, ++ ISOL_ESCAPE_CHARACTER); ++} ++ ++ ++ ++/* ++ * output ++ * ++ * Send the specified data to stdout ++ */ ++static void ++output(struct ipmi_rs * rsp) ++{ ++ if (rsp) ++ { ++ int i; ++ for (i = 0; i < rsp->data_len; ++i) ++ putc(rsp->data[i], stdout); ++ ++ fflush(stdout); ++ } ++} ++ ++/* ++ * ipmi_isol_deactivate ++ */ ++static int ++ipmi_isol_deactivate(struct ipmi_intf * intf) ++{ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ uint8_t data[6]; ++ struct isol_config_parameters params; ++ ++ memset(&req, 0, sizeof(req)); ++ req.msg.netfn = IPMI_NETFN_ISOL; ++ req.msg.cmd = ACTIVATE_ISOL; ++ req.msg.data = data; ++ req.msg.data_len = 5; + ++ memset(data, 0, 6); ++ data[0] = 0x00; /* Deactivate */ ++ data[1] = 0x00; ++ data[2] = 0x00; ++ data[3] = 0x00; ++ data[5] = 0x00; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, "Error deactivating ISOL"); ++ return -1; ++ } ++ if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, "Error deactivating ISOL: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ /* response contain 4 additional bytes : 80 00 32 ff ++ Don't know what to use them for yet... */ + return 0; + } + +-int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv) ++/* ++ * processiSolUserInput ++ * ++ * Act on user input into the ISOL session. The only reason this ++ * is complicated is that we have to process escape sequences. ++ * ++ * return 0 on success ++ * 1 if we should exit ++ * < 0 on error (BMC probably closed the session) ++ */ ++static int ++processiSolUserInput(struct ipmi_intf * intf, ++ uint8_t * input, ++ uint16_t buffer_length) + { +- int ret = 0; ++ static int escape_pending = 0; ++ static int last_was_cr = 1; ++ struct ipmi_v2_payload v2_payload; ++ int length = 0; ++ int retval = 0; ++ char ch; ++ int i; ++ ++ memset(&v2_payload, 0, sizeof(v2_payload)); ++ ++ /* ++ * Our first order of business is to check the input for escape ++ * sequences to act on. ++ */ ++ for (i = 0; i < buffer_length; ++i) ++ { ++ ch = input[i]; ++ ++ if (escape_pending){ ++ escape_pending = 0; ++ ++ /* ++ * Process a possible escape sequence. ++ */ ++ switch (ch) { ++ case '.': ++ printf("%c. [terminated ipmitool]\r\n", ISOL_ESCAPE_CHARACTER); ++ retval = 1; ++ break; ++ case 'Z' - 64: ++ printf("%c^Z [suspend ipmitool]\r\n", ISOL_ESCAPE_CHARACTER); ++ suspendSelf(1); /* Restore tty back to raw */ ++ continue; ++ ++ case 'X' - 64: ++ printf("%c^X [suspend ipmitool]\r\n", ISOL_ESCAPE_CHARACTER); ++ suspendSelf(0); /* Don't restore to raw mode */ ++ continue; ++ ++ case 'B': ++ printf("%cb [send break]\r\n", ISOL_ESCAPE_CHARACTER); ++ sendBreak(intf); ++ continue; ++ ++ case '?': ++ printiSolEscapeSequences(); ++ continue; ++ default: ++ if (ch != ISOL_ESCAPE_CHARACTER) ++ v2_payload.payload.sol_packet.data[length++] = ++ ISOL_ESCAPE_CHARACTER; ++ v2_payload.payload.sol_packet.data[length++] = ch; ++ } ++ } + +- if (argc < 2 || strncmp(argv[0], "help", 4) == 0) { +- lprintf(LOG_NOTICE, "ISOL Commands: setup "); +- lprintf(LOG_NOTICE, "ISOL Baud Rates: 9600, 19200, 38400, 57600, 115200"); +- return 0; +- } +- +- if (strncmp(argv[0], "setup", 5) == 0) { +- if (strncmp(argv[1], "9600", 4) == 0) { +- ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_9600); +- } +- else if (strncmp(argv[1], "19200", 5) == 0) { +- ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_19200); ++ else ++ { ++ if (last_was_cr && (ch == ISOL_ESCAPE_CHARACTER)) { ++ escape_pending = 1; ++ continue; ++ } ++ ++ v2_payload.payload.sol_packet.data[length++] = ch; + } +- else if (strncmp(argv[1], "38400", 5) == 0) { +- ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_38400); ++ ++ ++ /* ++ * Normal character. Record whether it was a newline. ++ */ ++ last_was_cr = (ch == '\r' || ch == '\n'); ++ } ++ ++ /* ++ * If there is anything left to process we dispatch it to the BMC, ++ * send intf->session->sol_data.max_outbound_payload_size bytes ++ * at a time. ++ */ ++ if (length) ++ { ++ struct ipmi_rs * rsp; ++ ++ v2_payload.payload.sol_packet.flush_outbound = 1; /* Not sure if necessary ? */ ++ v2_payload.payload.sol_packet.character_count = length; ++ rsp = intf->send_sol(intf, &v2_payload); ++ ++ if (! rsp) { ++ lprintf(LOG_ERR, "Error sending SOL data"); ++ retval = -1; + } +- else if (strncmp(argv[1], "57600", 5) == 0) { +- ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_57600); ++ ++ /* If the sequence number is set we know we have new data */ ++ else if ((rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) && ++ (rsp->payload.sol_packet.packet_sequence_number)) ++ output(rsp); ++ } ++ return retval; ++} ++ ++/* ++ * ipmi_isol_red_pill ++ */ ++static int ++ipmi_isol_red_pill(struct ipmi_intf * intf) ++{ ++ char * buffer; ++ int numRead; ++ int bShouldExit = 0; ++ int bBmcClosedSession = 0; ++ fd_set read_fds; ++ struct timeval tv; ++ int retval; ++ int buffer_size = 255; ++ int timedout = 0; ++ ++ buffer = (char*)malloc(buffer_size); ++ if (buffer == NULL) { ++ lprintf(LOG_ERR, "ipmitool: malloc failure"); ++ return -1; ++ } ++ ++ enter_raw_mode(); ++ ++ while (! bShouldExit) ++ { ++ FD_ZERO(&read_fds); ++ FD_SET(0, &read_fds); ++ FD_SET(intf->fd, &read_fds); ++ ++ /* Wait up to half a second */ ++ tv.tv_sec = 0; ++ tv.tv_usec = 500000; ++ ++ retval = select(intf->fd + 1, &read_fds, NULL, NULL, &tv); ++ ++ if (retval) ++ { ++ if (retval == -1) ++ { ++ /* ERROR */ ++ perror("select"); ++ return -1; ++ } ++ ++ timedout = 0; ++ ++ /* ++ * Process input from the user ++ */ ++ if (FD_ISSET(0, &read_fds)) ++ { ++ bzero(buffer, sizeof(buffer)); ++ numRead = read(fileno(stdin), ++ buffer, ++ buffer_size); ++ ++ if (numRead > 0) ++ { ++ int rc = processiSolUserInput(intf, buffer, numRead); ++ ++ if (rc) ++ { ++ if (rc < 0) ++ bShouldExit = bBmcClosedSession = 1; ++ else ++ bShouldExit = 1; ++ } ++ } ++ else ++ { ++ bShouldExit = 1; ++ } ++ } ++ ++ ++ /* ++ * Process input from the BMC ++ */ ++ else if (FD_ISSET(intf->fd, &read_fds)) ++ { ++ struct ipmi_rs * rs = intf->recv_sol(intf); ++ if (! rs) ++ { ++ bShouldExit = bBmcClosedSession = 1; ++ } ++ else ++ output(rs); ++ } ++ ++ ++ /* ++ * ERROR in select ++ */ ++ else ++ { ++ lprintf(LOG_ERR, "Error: Select returned with nothing to read"); ++ bShouldExit = 1; ++ } + } +- else if (strncmp(argv[1], "115200", 6) == 0) { +- ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_115200); ++ else ++ { ++ if ((++timedout) == 20) /* Every 10 seconds we send a keepalive */ ++ { ++ intf->keepalive(intf); ++ timedout = 0; ++ } + } +- else { +- lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", argv[1]); +- ret = -1; ++ } ++ ++ leave_raw_mode(); ++ ++ if (bBmcClosedSession) ++ { ++ lprintf(LOG_ERR, "SOL session closed by BMC"); ++ } ++ else ++ ipmi_isol_deactivate(intf); ++ ++ return 0; ++} ++ ++/* ++ * ipmi_isol_activate ++ */ ++static int ++ipmi_isol_activate(struct ipmi_intf * intf) ++{ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ uint8_t data[6]; ++ struct isol_config_parameters params; ++ ++ if (ipmi_get_isol_info(intf, ¶ms)) ++ return -1; ++ ++ if (!(params.enabled & 0x1)) { ++ lprintf(LOG_ERR, "ISOL is not enabled!"); ++ return -1; ++ } ++ ++ /* ++ * Setup a callback so that the lanplus processing knows what ++ * to do with packets that come unexpectedly (while waiting for ++ * an ACK, perhaps. ++ */ ++ intf->session->sol_data.sol_input_handler = output; ++ ++ memset(&req, 0, sizeof(req)); ++ req.msg.netfn = IPMI_NETFN_ISOL; ++ req.msg.cmd = ACTIVATE_ISOL; ++ req.msg.data = data; ++ req.msg.data_len = 5; ++ ++ memset(data, 0, 6); ++ data[0] = 0x01; ++ data[1] = 0x00; ++ data[2] = 0x00; ++ data[3] = 0x00; ++ data[5] = 0x00; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (NULL != rsp) { ++ switch (rsp->ccode) { ++ case 0x00: ++ if (rsp->data_len == 4) { ++ break; ++ } else { ++ lprintf(LOG_ERR, "Error: Unexpected data length (%d) received " ++ "in ISOL activation response", ++ rsp->data_len); ++ return -1; ++ } ++ break; ++ case 0x80: ++ lprintf(LOG_ERR, "Info: ISOL already active on another session"); ++ return -1; ++ case 0x81: ++ lprintf(LOG_ERR, "Info: ISOL disabled"); ++ return -1; ++ case 0x82: ++ lprintf(LOG_ERR, "Info: ISOL activation limit reached"); ++ return -1; ++ default: ++ lprintf(LOG_ERR, "Error activating ISOL: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ } else { ++ lprintf(LOG_ERR, "Error: No response activating ISOL"); ++ return -1; ++ } ++ ++ /* response contain 4 additional bytes : 80 01 32 ff ++ Don't know what to use them for yet... */ ++ ++ printf("[SOL Session operational. Use %c? for help]\r\n", ++ ISOL_ESCAPE_CHARACTER); ++ ++ /* ++ * At this point we are good to go with our SOL session. We ++ * need to listen to ++ * 1) STDIN for user input ++ * 2) The FD for incoming SOL packets ++ */ ++ if (ipmi_isol_red_pill(intf)) { ++ lprintf(LOG_ERR, "Error in SOL session"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static void print_isol_set_usage(void) { ++ lprintf(LOG_NOTICE, "\nISOL set parameters and values: \n"); ++ lprintf(LOG_NOTICE, " enabled true | false"); ++ lprintf(LOG_NOTICE, " privilege-level user | operator | admin | oem"); ++ lprintf(LOG_NOTICE, " bit-rate " ++ "9.6 | 19.2 | 38.4 | 57.6 | 115.2"); ++ lprintf(LOG_NOTICE, ""); ++} ++ ++static void print_isol_usage(void) { ++ lprintf(LOG_NOTICE, "ISOL Commands: info"); ++ lprintf(LOG_NOTICE, " set "); ++ lprintf(LOG_NOTICE, " activate"); ++} ++ ++int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv) ++{ ++ int ret = 0; ++ ++ /* ++ * Help ++ */ ++ if (!argc || !strncmp(argv[0], "help", 4)) ++ print_isol_usage(); ++ ++ /* ++ * Info ++ */ ++ else if (!strncmp(argv[0], "info", 4)) { ++ ret = ipmi_print_isol_info(intf); ++ } ++ ++ /* ++ * Set a parameter value ++ */ ++ else if (!strncmp(argv[0], "set", 3)) { ++ if (argc < 3) { ++ print_isol_set_usage(); ++ return -1; + } ++ ret = ipmi_isol_set_param(intf, argv[1], argv[2]); ++ } ++ ++ /* ++ * Activate ++ */ ++ else if (!strncmp(argv[0], "activate", 8)) { ++ ret = ipmi_isol_activate(intf); ++ } ++ ++ else { ++ print_isol_usage(); ++ ret = -1; + } ++ + return ret; + } +diff -urN ipmitool-1.8.9.orig/lib/ipmi_isol.c.orig ipmitool-1.8.9/lib/ipmi_isol.c.orig +--- ipmitool-1.8.9.orig/lib/ipmi_isol.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ ipmitool-1.8.9/lib/ipmi_isol.c.orig 2007-02-22 08:38:56.000000000 +0000 +@@ -0,0 +1,191 @@ ++/* ++ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * Redistribution of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * Redistribution in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * Neither the name of Sun Microsystems, Inc. or the names of ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * This software is provided "AS IS," without a warranty of any kind. ++ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, ++ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A ++ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ++ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE ++ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING ++ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL ++ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, ++ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR ++ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF ++ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, ++ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++const struct valstr ipmi_isol_baud_vals[] = { ++ { ISOL_BAUD_RATE_9600, "9600" }, ++ { ISOL_BAUD_RATE_19200, "19200" }, ++ { ISOL_BAUD_RATE_38400, "38400" }, ++ { ISOL_BAUD_RATE_57600, "57600" }, ++ { ISOL_BAUD_RATE_115200, "115200" }, ++ { 0x00, NULL } ++}; ++ ++extern int verbose; ++ ++static int ipmi_isol_setup(struct ipmi_intf * intf, char baudsetting) ++{ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ unsigned char data[6]; ++ ++ /* TEST FOR AVAILABILITY */ ++ ++ memset(data, 0, 6); ++ data[0] = 0x00; ++ data[1] = ISOL_ENABLE_PARAM; ++ data[2] = ISOL_ENABLE_FLAG; ++ ++ memset(&req, 0, sizeof(req)); ++ req.msg.netfn = IPMI_NETFN_ISOL; ++ req.msg.cmd = SET_ISOL_CONFIG; ++ req.msg.data = data; ++ req.msg.data_len = 3; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, "Error in Set ISOL Config Command"); ++ return -1; ++ } ++ if (rsp->ccode == 0xc1) { ++ lprintf(LOG_ERR, "IPMI v1.5 Serial Over Lan (ISOL) not supported!"); ++ return -1; ++ } ++ if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, "Error in Set ISOL Config Command: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ /* GET ISOL CONFIG */ ++ ++ memset(data, 0, 6); ++ data[0] = 0x00; ++ data[1] = ISOL_AUTHENTICATION_PARAM; ++ data[2] = 0x00; /* block */ ++ data[3] = 0x00; /* selector */ ++ req.msg.cmd = GET_ISOL_CONFIG; ++ req.msg.data_len = 4; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, "Error in Get ISOL Config Command"); ++ return -1; ++ } ++ if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ if (verbose > 1) ++ printbuf(rsp->data, rsp->data_len, "ISOL Config"); ++ ++ /* SET ISOL CONFIG - AUTHENTICATION */ ++ ++ memset(data, 0, 6); ++ data[0] = 0x00; ++ data[1] = ISOL_AUTHENTICATION_PARAM; ++ data[2] = ISOL_PRIVILEGE_LEVEL_USER | (rsp->data[1] & 0x80); ++ req.msg.cmd = SET_ISOL_CONFIG; ++ req.msg.data_len = 3; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command"); ++ return -1; ++ } ++ if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ /* SET ISOL CONFIG - BAUD RATE */ ++ ++ memset(data, 0, 6); ++ data[0] = 0x00; ++ data[1] = ISOL_BAUD_RATE_PARAM; ++ data[2] = baudsetting; ++ req.msg.cmd = SET_ISOL_CONFIG; ++ req.msg.data_len = 3; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command"); ++ return -1; ++ } ++ if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ printf("Set ISOL Baud Rate to %s\n", ++ val2str(baudsetting, ipmi_isol_baud_vals)); ++ ++ return 0; ++} ++ ++int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv) ++{ ++ int ret = 0; ++ ++ if (argc < 2 || strncmp(argv[0], "help", 4) == 0) { ++ lprintf(LOG_NOTICE, "ISOL Commands: setup "); ++ lprintf(LOG_NOTICE, "ISOL Baud Rates: 9600, 19200, 38400, 57600, 115200"); ++ return 0; ++ } ++ ++ if (strncmp(argv[0], "setup", 5) == 0) { ++ if (strncmp(argv[1], "9600", 4) == 0) { ++ ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_9600); ++ } ++ else if (strncmp(argv[1], "19200", 5) == 0) { ++ ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_19200); ++ } ++ else if (strncmp(argv[1], "38400", 5) == 0) { ++ ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_38400); ++ } ++ else if (strncmp(argv[1], "57600", 5) == 0) { ++ ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_57600); ++ } ++ else if (strncmp(argv[1], "115200", 6) == 0) { ++ ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_115200); ++ } ++ else { ++ lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", argv[1]); ++ ret = -1; ++ } ++ } ++ return ret; ++} +diff -urN ipmitool-1.8.9.orig/src/plugins/lan/lan.c ipmitool-1.8.9/src/plugins/lan/lan.c +--- ipmitool-1.8.9.orig/src/plugins/lan/lan.c 2007-02-22 08:38:57.000000000 +0000 ++++ ipmitool-1.8.9/src/plugins/lan/lan.c 2007-12-13 10:16:57.063986495 +0000 +@@ -79,6 +79,11 @@ + static struct ipmi_rs * ipmi_lan_poll_recv(struct ipmi_intf * intf); + static int ipmi_lan_setup(struct ipmi_intf * intf); + static int ipmi_lan_keepalive(struct ipmi_intf * intf); ++static struct ipmi_rs * ipmi_lan_send_payload(struct ipmi_intf * intf, ++ struct ipmi_v2_payload * payload); ++static struct ipmi_rs * ipmi_lan_recv_sol(struct ipmi_intf * intf); ++static struct ipmi_rs * ipmi_lan_send_sol(struct ipmi_intf * intf, ++ struct ipmi_v2_payload * payload); + static struct ipmi_rs * ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req); + static int ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp); + static int ipmi_lan_open(struct ipmi_intf * intf); +@@ -93,6 +98,8 @@ + close: ipmi_lan_close, + sendrecv: ipmi_lan_send_cmd, + sendrsp: ipmi_lan_send_rsp, ++ recv_sol: ipmi_lan_recv_sol, ++ send_sol: ipmi_lan_send_sol, + keepalive: ipmi_lan_keepalive, + target_addr: IPMI_BMC_SLAVE_ADDR, + }; +@@ -456,80 +463,141 @@ + memcpy(&rsp->session.id, rsp->data+x, 4); + x += 4; + +- if (intf->session->active && (rsp->session.authtype || intf->session->authtype)) +- x += 16; +- +- rsp->session.msglen = rsp->data[x++]; +- rsp->payload.ipmi_response.rq_addr = rsp->data[x++]; +- rsp->payload.ipmi_response.netfn = rsp->data[x] >> 2; +- rsp->payload.ipmi_response.rq_lun = rsp->data[x++] & 0x3; +- x++; /* checksum */ +- rsp->payload.ipmi_response.rs_addr = rsp->data[x++]; +- rsp->payload.ipmi_response.rq_seq = rsp->data[x] >> 2; +- rsp->payload.ipmi_response.rs_lun = rsp->data[x++] & 0x3; +- rsp->payload.ipmi_response.cmd = rsp->data[x++]; +- rsp->ccode = rsp->data[x++]; +- +- if (verbose > 2) +- printbuf(rsp->data, rsp->data_len, "ipmi message header"); +- +- lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header"); +- lprintf(LOG_DEBUG+1, "<< Authtype : %s", +- val2str(rsp->session.authtype, ipmi_authtype_session_vals)); +- lprintf(LOG_DEBUG+1, "<< Sequence : 0x%08lx", +- (long)rsp->session.seq); +- lprintf(LOG_DEBUG+1, "<< Session ID : 0x%08lx", +- (long)rsp->session.id); +- lprintf(LOG_DEBUG+1, "<< IPMI Response Message Header"); +- lprintf(LOG_DEBUG+1, "<< Rq Addr : %02x", +- rsp->payload.ipmi_response.rq_addr); +- lprintf(LOG_DEBUG+1, "<< NetFn : %02x", +- rsp->payload.ipmi_response.netfn); +- lprintf(LOG_DEBUG+1, "<< Rq LUN : %01x", +- rsp->payload.ipmi_response.rq_lun); +- lprintf(LOG_DEBUG+1, "<< Rs Addr : %02x", +- rsp->payload.ipmi_response.rs_addr); +- lprintf(LOG_DEBUG+1, "<< Rq Seq : %02x", +- rsp->payload.ipmi_response.rq_seq); +- lprintf(LOG_DEBUG+1, "<< Rs Lun : %01x", +- rsp->payload.ipmi_response.rs_lun); +- lprintf(LOG_DEBUG+1, "<< Command : %02x", +- rsp->payload.ipmi_response.cmd); +- lprintf(LOG_DEBUG+1, "<< Compl Code : 0x%02x", +- rsp->ccode); +- +- /* now see if we have outstanding entry in request list */ +- entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq, +- rsp->payload.ipmi_response.cmd); +- if (entry) { +- lprintf(LOG_DEBUG+2, "IPMI Request Match found"); +- if ((intf->target_addr != our_address) && bridge_possible) { +- if ((rsp->data_len) && +- (rsp->payload.ipmi_response.cmd != 0x34)) { +- printbuf(&rsp->data[x], rsp->data_len-x, +- "bridge command response"); +- } +- /* bridged command: lose extra header */ +- if (rsp->payload.ipmi_response.cmd == 0x34) { +- if (rsp->data_len == 38) { +- entry->req.msg.cmd = entry->req.msg.target_cmd; +- rsp = ipmi_lan_recv_packet(intf); +- continue; ++ if (rsp->session.id == (intf->session->session_id + 0x10000000)) { ++ /* With SOL, authtype is always NONE, so we have no authcode */ ++ rsp->session.payloadtype = IPMI_PAYLOAD_TYPE_SOL; ++ ++ rsp->session.msglen = rsp->data[x++]; ++ ++ rsp->payload.sol_packet.packet_sequence_number = ++ rsp->data[x++] & 0x0F; ++ ++ rsp->payload.sol_packet.acked_packet_number = ++ rsp->data[x++] & 0x0F; ++ ++ rsp->payload.sol_packet.accepted_character_count = ++ rsp->data[x++]; ++ ++ rsp->payload.sol_packet.is_nack = ++ rsp->data[x] & 0x40; ++ ++ rsp->payload.sol_packet.transfer_unavailable = ++ rsp->data[x] & 0x20; ++ ++ rsp->payload.sol_packet.sol_inactive = ++ rsp->data[x] & 0x10; ++ ++ rsp->payload.sol_packet.transmit_overrun = ++ rsp->data[x] & 0x08; ++ ++ rsp->payload.sol_packet.break_detected = ++ rsp->data[x++] & 0x04; ++ ++ x++; /* On ISOL there's and additional fifth byte before the data starts */ ++ ++ lprintf(LOG_DEBUG, "SOL sequence number : 0x%02x", ++ rsp->payload.sol_packet.packet_sequence_number); ++ ++ lprintf(LOG_DEBUG, "SOL acked packet : 0x%02x", ++ rsp->payload.sol_packet.acked_packet_number); ++ ++ lprintf(LOG_DEBUG, "SOL accepted char count : 0x%02x", ++ rsp->payload.sol_packet.accepted_character_count); ++ ++ lprintf(LOG_DEBUG, "SOL is nack : %s", ++ rsp->payload.sol_packet.is_nack? "true" : "false"); ++ ++ lprintf(LOG_DEBUG, "SOL xfer unavailable : %s", ++ rsp->payload.sol_packet.transfer_unavailable? "true" : "false"); ++ ++ lprintf(LOG_DEBUG, "SOL inactive : %s", ++ rsp->payload.sol_packet.sol_inactive? "true" : "false"); ++ ++ lprintf(LOG_DEBUG, "SOL transmit overrun : %s", ++ rsp->payload.sol_packet.transmit_overrun? "true" : "false"); ++ ++ lprintf(LOG_DEBUG, "SOL break detected : %s", ++ rsp->payload.sol_packet.break_detected? "true" : "false"); ++ } ++ else ++ { ++ /* Standard IPMI 1.5 packet */ ++ rsp->session.payloadtype = IPMI_PAYLOAD_TYPE_IPMI; ++ if (intf->session->active && (rsp->session.authtype || intf->session->authtype)) ++ x += 16; ++ ++ rsp->session.msglen = rsp->data[x++]; ++ rsp->payload.ipmi_response.rq_addr = rsp->data[x++]; ++ rsp->payload.ipmi_response.netfn = rsp->data[x] >> 2; ++ rsp->payload.ipmi_response.rq_lun = rsp->data[x++] & 0x3; ++ x++; /* checksum */ ++ rsp->payload.ipmi_response.rs_addr = rsp->data[x++]; ++ rsp->payload.ipmi_response.rq_seq = rsp->data[x] >> 2; ++ rsp->payload.ipmi_response.rs_lun = rsp->data[x++] & 0x3; ++ rsp->payload.ipmi_response.cmd = rsp->data[x++]; ++ rsp->ccode = rsp->data[x++]; ++ ++ if (verbose > 2) ++ printbuf(rsp->data, rsp->data_len, "ipmi message header"); ++ ++ lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header"); ++ lprintf(LOG_DEBUG+1, "<< Authtype : %s", ++ val2str(rsp->session.authtype, ipmi_authtype_session_vals)); ++ lprintf(LOG_DEBUG+1, "<< Sequence : 0x%08lx", ++ (long)rsp->session.seq); ++ lprintf(LOG_DEBUG+1, "<< Session ID : 0x%08lx", ++ (long)rsp->session.id); ++ lprintf(LOG_DEBUG+1, "<< IPMI Response Message Header"); ++ lprintf(LOG_DEBUG+1, "<< Rq Addr : %02x", ++ rsp->payload.ipmi_response.rq_addr); ++ lprintf(LOG_DEBUG+1, "<< NetFn : %02x", ++ rsp->payload.ipmi_response.netfn); ++ lprintf(LOG_DEBUG+1, "<< Rq LUN : %01x", ++ rsp->payload.ipmi_response.rq_lun); ++ lprintf(LOG_DEBUG+1, "<< Rs Addr : %02x", ++ rsp->payload.ipmi_response.rs_addr); ++ lprintf(LOG_DEBUG+1, "<< Rq Seq : %02x", ++ rsp->payload.ipmi_response.rq_seq); ++ lprintf(LOG_DEBUG+1, "<< Rs Lun : %01x", ++ rsp->payload.ipmi_response.rs_lun); ++ lprintf(LOG_DEBUG+1, "<< Command : %02x", ++ rsp->payload.ipmi_response.cmd); ++ lprintf(LOG_DEBUG+1, "<< Compl Code : 0x%02x", ++ rsp->ccode); ++ ++ /* now see if we have outstanding entry in request list */ ++ entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq, ++ rsp->payload.ipmi_response.cmd); ++ if (entry) { ++ lprintf(LOG_DEBUG+2, "IPMI Request Match found"); ++ if ((intf->target_addr != our_address) && bridge_possible) { ++ if ((rsp->data_len) && ++ (rsp->payload.ipmi_response.cmd != 0x34)) { ++ printbuf(&rsp->data[x], rsp->data_len-x, ++ "bridge command response"); ++ } ++ /* bridged command: lose extra header */ ++ if (rsp->payload.ipmi_response.cmd == 0x34) { ++ if (rsp->data_len == 38) { ++ entry->req.msg.cmd = entry->req.msg.target_cmd; ++ rsp = ipmi_lan_recv_packet(intf); ++ continue; ++ } ++ } else { ++ //x += sizeof(rsp->payload.ipmi_response); ++ if (rsp->data[x-1] != 0) ++ lprintf(LOG_DEBUG, "WARNING: Bridged " ++ "cmd ccode = 0x%02x", ++ rsp->data[x-1]); + } +- } else { +- //x += sizeof(rsp->payload.ipmi_response); +- if (rsp->data[x-1] != 0) +- lprintf(LOG_DEBUG, "WARNING: Bridged " +- "cmd ccode = 0x%02x", +- rsp->data[x-1]); + } ++ ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq, ++ rsp->payload.ipmi_response.cmd); ++ } else { ++ lprintf(LOG_INFO, "IPMI Request Match NOT FOUND"); ++ rsp = ipmi_lan_recv_packet(intf); ++ continue; + } +- ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq, +- rsp->payload.ipmi_response.cmd); +- } else { +- lprintf(LOG_INFO, "IPMI Request Match NOT FOUND"); +- rsp = ipmi_lan_recv_packet(intf); +- continue; + } + + break; +@@ -537,7 +605,9 @@ + + /* shift response data to start of array */ + if (rsp && rsp->data_len > x) { +- rsp->data_len -= x + 1; ++ rsp->data_len -= x; ++ if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_IPMI) ++ rsp->data_len -= 1; /* We don't want the checksum */ + memmove(rsp->data, rsp->data + x, rsp->data_len); + memset(rsp->data + rsp->data_len, 0, IPMI_BUF_SIZE - rsp->data_len); + } +@@ -553,9 +623,9 @@ + * | rmcp.seq | + * | rmcp.class | + * +--------------------+ +- * | session.authtype | 9 bytes +- * | session.seq | +- * | session.id | ++ * | session.authtype | 9 bytes ++ * | session.seq | ++ * | session.id | + * +--------------------+ + * | [session.authcode] | 16 bytes (AUTHTYPE != none) + * +--------------------+ +@@ -910,6 +980,430 @@ + return 0; + } + ++/* ++ * IPMI SOL Payload Format ++ * +--------------------+ ++ * | rmcp.ver | 4 bytes ++ * | rmcp.__reserved | ++ * | rmcp.seq | ++ * | rmcp.class | ++ * +--------------------+ ++ * | session.authtype | 9 bytes ++ * | session.seq | ++ * | session.id | ++ * +--------------------+ ++ * | message length | 1 byte ++ * +--------------------+ ++ * | sol.seq | 5 bytes ++ * | sol.ack_seq | ++ * | sol.acc_count | ++ * | sol.control | ++ * | sol.__reserved | ++ * +--------------------+ ++ * | [request data] | data_len bytes ++ * +--------------------+ ++ */ ++uint8_t * ipmi_lan_build_sol_msg(struct ipmi_intf * intf, ++ struct ipmi_v2_payload * payload, ++ int * llen) ++{ ++ struct rmcp_hdr rmcp = { ++ .ver = RMCP_VERSION_1, ++ .class = RMCP_CLASS_IPMI, ++ .seq = 0xff, ++ }; ++ struct ipmi_session * session = intf->session; ++ ++ /* msg will hold the entire message to be sent */ ++ uint8_t * msg; ++ ++ int len = 0; ++ ++ len = sizeof(rmcp) + // RMCP Header (4) ++ 10 + // IPMI Session Header ++ 5 + // SOL header ++ payload->payload.sol_packet.character_count; // The actual payload ++ ++ msg = malloc(len); ++ if (msg == NULL) { ++ lprintf(LOG_ERR, "ipmitool: malloc failure"); ++ return; ++ } ++ memset(msg, 0, len); ++ ++ /* rmcp header */ ++ memcpy(msg, &rmcp, sizeof(rmcp)); ++ len = sizeof(rmcp); ++ ++ /* ipmi session header */ ++ msg[len++] = 0; /* SOL is always authtype = NONE */ ++ msg[len++] = session->in_seq & 0xff; ++ msg[len++] = (session->in_seq >> 8) & 0xff; ++ msg[len++] = (session->in_seq >> 16) & 0xff; ++ msg[len++] = (session->in_seq >> 24) & 0xff; ++ ++ msg[len++] = session->session_id & 0xff; ++ msg[len++] = (session->session_id >> 8) & 0xff; ++ msg[len++] = (session->session_id >> 16) & 0xff; ++ msg[len++] = ((session->session_id >> 24) + 0x10) & 0xff; /* Add 0x10 to MSB for SOL */ ++ ++ msg[len++] = payload->payload.sol_packet.character_count + 5; ++ ++ /* sol header */ ++ msg[len++] = payload->payload.sol_packet.packet_sequence_number; ++ msg[len++] = payload->payload.sol_packet.acked_packet_number; ++ msg[len++] = payload->payload.sol_packet.accepted_character_count; ++ msg[len] = payload->payload.sol_packet.is_nack ? 0x40 : 0; ++ msg[len] |= payload->payload.sol_packet.assert_ring_wor ? 0x20 : 0; ++ msg[len] |= payload->payload.sol_packet.generate_break ? 0x10 : 0; ++ msg[len] |= payload->payload.sol_packet.deassert_cts ? 0x08 : 0; ++ msg[len] |= payload->payload.sol_packet.deassert_dcd_dsr ? 0x04 : 0; ++ msg[len] |= payload->payload.sol_packet.flush_inbound ? 0x02 : 0; ++ msg[len++] |= payload->payload.sol_packet.flush_outbound ? 0x01 : 0; ++ ++ len++; /* On SOL there's and additional fifth byte before the data starts */ ++ ++ if (payload->payload.sol_packet.character_count) { ++ /* We may have data to add */ ++ memcpy(msg + len, ++ payload->payload.sol_packet.data, ++ payload->payload.sol_packet.character_count); ++ len += payload->payload.sol_packet.character_count; ++ } ++ ++ session->in_seq++; ++ if (session->in_seq == 0) ++ session->in_seq++; ++ ++ *llen = len; ++ return msg; ++} ++ ++/* ++ * is_sol_packet ++ */ ++static int ++is_sol_packet(struct ipmi_rs * rsp) ++{ ++ return (rsp && ++ (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)); ++} ++ ++ ++ ++/* ++ * sol_response_acks_packet ++ */ ++static int ++sol_response_acks_packet(struct ipmi_rs * rsp, ++ struct ipmi_v2_payload * payload) ++{ ++ return (is_sol_packet(rsp) && ++ payload && ++ (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL) && ++ (rsp->payload.sol_packet.acked_packet_number == ++ payload->payload.sol_packet.packet_sequence_number)); ++} ++ ++/* ++ * ipmi_lan_send_sol_payload ++ * ++ */ ++static struct ipmi_rs * ++ipmi_lan_send_sol_payload(struct ipmi_intf * intf, ++ struct ipmi_v2_payload * payload) ++{ ++ struct ipmi_rs * rsp = NULL; ++ uint8_t * msg; ++ int len; ++ int try = 0; ++ ++ if (intf->opened == 0 && intf->open != NULL) { ++ if (intf->open(intf) < 0) ++ return NULL; ++ } ++ ++ msg = ipmi_lan_build_sol_msg(intf, payload, &len); ++ if (len <= 0 || msg == NULL) { ++ lprintf(LOG_ERR, "Invalid SOL payload packet"); ++ if (msg != NULL) ++ free(msg); ++ return NULL; ++ } ++ ++ lprintf(LOG_DEBUG, ">> SENDING A SOL MESSAGE\n"); ++ ++ for (;;) { ++ if (ipmi_lan_send_packet(intf, msg, len) < 0) { ++ try++; ++ usleep(5000); ++ continue; ++ } ++ ++ /* if we are set to noanswer we do not expect response */ ++ if (intf->noanswer) ++ break; ++ ++ if (payload->payload.sol_packet.packet_sequence_number == 0) { ++ /* We're just sending an ACK. No need to retry. */ ++ break; ++ } ++ ++ usleep(100); ++ ++ rsp = ipmi_lan_recv_sol(intf); /* Grab the next packet */ ++ ++ if (sol_response_acks_packet(rsp, payload)) ++ break; ++ ++ else if (is_sol_packet(rsp) && rsp->data_len) ++ { ++ /* ++ * We're still waiting for our ACK, but we more data from ++ * the BMC ++ */ ++ intf->session->sol_data.sol_input_handler(rsp); ++ } ++ ++ usleep(5000); ++ if (++try >= intf->session->retry) { ++ lprintf(LOG_DEBUG, " No response from remote controller"); ++ break; ++ } ++ } ++ ++ return rsp; ++} ++ ++/* ++ * is_sol_partial_ack ++ * ++ * Determine if the response is a partial ACK/NACK that indicates ++ * we need to resend part of our packet. ++ * ++ * returns the number of characters we need to resend, or ++ * 0 if this isn't an ACK or we don't need to resend anything ++ */ ++static int is_sol_partial_ack(struct ipmi_v2_payload * v2_payload, ++ struct ipmi_rs * rsp) ++{ ++ int chars_to_resend = 0; ++ ++ if (v2_payload && ++ rsp && ++ is_sol_packet(rsp) && ++ sol_response_acks_packet(rsp, v2_payload) && ++ (rsp->payload.sol_packet.accepted_character_count < ++ v2_payload->payload.sol_packet.character_count)) ++ { ++ if (rsp->payload.sol_packet.accepted_character_count == 0) { ++ /* We should not resend data */ ++ chars_to_resend = 0; ++ } ++ else ++ { ++ chars_to_resend = ++ v2_payload->payload.sol_packet.character_count - ++ rsp->payload.sol_packet.accepted_character_count; ++ } ++ } ++ ++ return chars_to_resend; ++} ++ ++/* ++ * set_sol_packet_sequence_number ++ */ ++static void set_sol_packet_sequence_number(struct ipmi_intf * intf, ++ struct ipmi_v2_payload * v2_payload) ++{ ++ /* Keep our sequence number sane */ ++ if (intf->session->sol_data.sequence_number > 0x0F) ++ intf->session->sol_data.sequence_number = 1; ++ ++ v2_payload->payload.sol_packet.packet_sequence_number = ++ intf->session->sol_data.sequence_number++; ++} ++ ++/* ++ * ipmi_lan_send_sol ++ * ++ * Sends a SOL packet.. We handle partial ACK/NACKs from the BMC here. ++ * ++ * Returns a pointer to the SOL ACK we received, or ++ * 0 on failure ++ * ++ */ ++struct ipmi_rs * ++ipmi_lan_send_sol(struct ipmi_intf * intf, ++ struct ipmi_v2_payload * v2_payload) ++{ ++ struct ipmi_rs * rsp; ++ int chars_to_resend = 0; ++ ++ v2_payload->payload_type = IPMI_PAYLOAD_TYPE_SOL; ++ ++ /* ++ * Payload length is just the length of the character ++ * data here. ++ */ ++ v2_payload->payload.sol_packet.acked_packet_number = 0; /* NA */ ++ ++ set_sol_packet_sequence_number(intf, v2_payload); ++ ++ v2_payload->payload.sol_packet.accepted_character_count = 0; /* NA */ ++ ++ rsp = ipmi_lan_send_sol_payload(intf, v2_payload); ++ ++ /* Determine if we need to resend some of our data */ ++ chars_to_resend = is_sol_partial_ack(v2_payload, rsp); ++ ++ while (chars_to_resend) ++ { ++ /* ++ * We first need to handle any new data we might have ++ * received in our NACK ++ */ ++ if (rsp->data_len) ++ intf->session->sol_data.sol_input_handler(rsp); ++ ++ set_sol_packet_sequence_number(intf, v2_payload); ++ ++ /* Just send the required data */ ++ memmove(v2_payload->payload.sol_packet.data, ++ v2_payload->payload.sol_packet.data + ++ rsp->payload.sol_packet.accepted_character_count, ++ chars_to_resend); ++ ++ v2_payload->payload.sol_packet.character_count = chars_to_resend; ++ ++ rsp = ipmi_lan_send_sol_payload(intf, v2_payload); ++ ++ chars_to_resend = is_sol_partial_ack(v2_payload, rsp); ++ } ++ ++ return rsp; ++} ++ ++/* ++ * check_sol_packet_for_new_data ++ * ++ * Determine whether the SOL packet has already been seen ++ * and whether the packet has new data for us. ++ * ++ * This function has the side effect of removing an previously ++ * seen data, and moving new data to the front. ++ * ++ * It also "Remembers" the data so we don't get repeats. ++ * ++ */ ++static int ++check_sol_packet_for_new_data(struct ipmi_intf * intf, ++ struct ipmi_rs *rsp) ++{ ++ static uint8_t last_received_sequence_number = 0; ++ static uint8_t last_received_byte_count = 0; ++ int new_data_size = 0; ++ ++ if (rsp && ++ (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)) ++ ++ { ++ uint8_t unaltered_data_len = rsp->data_len; ++ if (rsp->payload.sol_packet.packet_sequence_number == ++ last_received_sequence_number) ++ { ++ /* ++ * This is the same as the last packet, but may include ++ * extra data ++ */ ++ new_data_size = rsp->data_len - last_received_byte_count; ++ ++ if (new_data_size > 0) ++ { ++ /* We have more data to process */ ++ memmove(rsp->data, ++ rsp->data + ++ rsp->data_len - new_data_size, ++ new_data_size); ++ } ++ ++ rsp->data_len = new_data_size; ++ } ++ ++ /* ++ *Rember the data for next round ++ */ ++ if (rsp && rsp->payload.sol_packet.packet_sequence_number) ++ { ++ last_received_sequence_number = ++ rsp->payload.sol_packet.packet_sequence_number; ++ last_received_byte_count = unaltered_data_len; ++ } ++ } ++ ++ return new_data_size; ++} ++ ++/* ++ * ack_sol_packet ++ * ++ * Provided the specified packet looks reasonable, ACK it. ++ */ ++static void ++ack_sol_packet(struct ipmi_intf * intf, ++ struct ipmi_rs * rsp) ++{ ++ if (rsp && ++ (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) && ++ (rsp->payload.sol_packet.packet_sequence_number)) ++ { ++ struct ipmi_v2_payload ack; ++ ++ memset(&ack, 0, sizeof(struct ipmi_v2_payload)); ++ ++ ack.payload_type = IPMI_PAYLOAD_TYPE_SOL; ++ ++ /* ++ * Payload length is just the length of the character ++ * data here. ++ */ ++ ack.payload_length = 0; ++ ++ /* ACK packets have sequence numbers of 0 */ ++ ack.payload.sol_packet.packet_sequence_number = 0; ++ ++ ack.payload.sol_packet.acked_packet_number = ++ rsp->payload.sol_packet.packet_sequence_number; ++ ++ ack.payload.sol_packet.accepted_character_count = rsp->data_len; ++ ++ ipmi_lan_send_sol_payload(intf, &ack); ++ } ++} ++ ++/* ++ * ipmi_recv_sol ++ * ++ * Receive a SOL packet and send an ACK in response. ++ * ++ */ ++struct ipmi_rs * ++ipmi_lan_recv_sol(struct ipmi_intf * intf) ++{ ++ struct ipmi_rs * rsp = ipmi_lan_poll_recv(intf); ++ ++ ack_sol_packet(intf, rsp); ++ ++ /* ++ * Remembers the data sent, and alters the data to just ++ * include the new stuff. ++ */ ++ check_sol_packet_for_new_data(intf, rsp); ++ ++ return rsp; ++} ++ + /* send a get device id command to keep session active */ + static int + ipmi_lan_keepalive(struct ipmi_intf * intf) +@@ -1411,6 +1905,8 @@ + + intf->abort = 1; + ++ intf->session->sol_data.sequence_number = 1; ++ + /* open port to BMC */ + memset(&s->addr, 0, sizeof(struct sockaddr_in)); + s->addr.sin_family = AF_INET; diff --git a/debian/patches/20_ipmi_isol.dpatch b/debian/patches/20_ipmi_isol.dpatch deleted file mode 100644 index 382e62a..0000000 --- a/debian/patches/20_ipmi_isol.dpatch +++ /dev/null @@ -1,1857 +0,0 @@ -#! /bin/sh /usr/share/dpatch/dpatch-run -## 20_ipmi_isol.dpatch by -## -## All lines beginning with `## DP:' are a description of the patch. -## DP: 20_ipmi_isol, closes #412816 - -@DPATCH@ - -diff -urN ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h ipmitool-1.8.9/include/ipmitool/ipmi_isol.h ---- ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h 2007-02-22 08:38:55.000000000 +0000 -+++ ipmitool-1.8.9/include/ipmitool/ipmi_isol.h 2007-12-13 10:16:57.063986495 +0000 -@@ -41,15 +41,16 @@ - - #define ISOL_ENABLE_PARAM 0x01 - #define ISOL_AUTHENTICATION_PARAM 0x02 --#define ISOL_ENABLE_FLAG 0x01 --#define ISOL_PRIVILEGE_LEVEL_USER 0x02 -+ - #define ISOL_BAUD_RATE_PARAM 0x05 --#define ISOL_BAUD_RATE_9600 0x06 --#define ISOL_BAUD_RATE_19200 0x07 --#define ISOL_BAUD_RATE_38400 0x08 --#define ISOL_BAUD_RATE_57600 0x09 --#define ISOL_BAUD_RATE_115200 0x0A --#define ISOL_PREFERRED_BAUD_RATE 0x07 -+ -+#define ISOL_PREFERRED_BAUD_RATE 0x07 -+ -+struct isol_config_parameters { -+ uint8_t enabled; -+ uint8_t privilege_level; -+ uint8_t bit_rate; -+}; - - int ipmi_isol_main(struct ipmi_intf *, int, char **); - -diff -urN ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h.orig ipmitool-1.8.9/include/ipmitool/ipmi_isol.h.orig ---- ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h.orig 1970-01-01 01:00:00.000000000 +0100 -+++ ipmitool-1.8.9/include/ipmitool/ipmi_isol.h.orig 2007-02-22 08:38:55.000000000 +0000 -@@ -0,0 +1,56 @@ -+/* -+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * Redistribution of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * Redistribution in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * Neither the name of Sun Microsystems, Inc. or the names of -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * This software is provided "AS IS," without a warranty of any kind. -+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, -+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A -+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. -+ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE -+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING -+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL -+ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, -+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR -+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF -+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, -+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -+ */ -+ -+#ifndef IPMI_ISOL_H -+#define IPMI_ISOL_H -+ -+#include -+ -+#define ACTIVATE_ISOL 0x01 -+#define SET_ISOL_CONFIG 0x03 -+#define GET_ISOL_CONFIG 0x04 -+ -+#define ISOL_ENABLE_PARAM 0x01 -+#define ISOL_AUTHENTICATION_PARAM 0x02 -+#define ISOL_ENABLE_FLAG 0x01 -+#define ISOL_PRIVILEGE_LEVEL_USER 0x02 -+#define ISOL_BAUD_RATE_PARAM 0x05 -+#define ISOL_BAUD_RATE_9600 0x06 -+#define ISOL_BAUD_RATE_19200 0x07 -+#define ISOL_BAUD_RATE_38400 0x08 -+#define ISOL_BAUD_RATE_57600 0x09 -+#define ISOL_BAUD_RATE_115200 0x0A -+#define ISOL_PREFERRED_BAUD_RATE 0x07 -+ -+int ipmi_isol_main(struct ipmi_intf *, int, char **); -+ -+#endif /* IPMI_SOL_H */ -diff -urN ipmitool-1.8.9.orig/lib/ipmi_isol.c ipmitool-1.8.9/lib/ipmi_isol.c ---- ipmitool-1.8.9.orig/lib/ipmi_isol.c 2007-02-22 08:38:56.000000000 +0000 -+++ ipmitool-1.8.9/lib/ipmi_isol.c 2007-12-13 10:16:57.063986495 +0000 -@@ -32,7 +32,17 @@ - - #include - #include -+#include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#include - - #include - #include -@@ -41,39 +51,40 @@ - #include - #include - --const struct valstr ipmi_isol_baud_vals[] = { -- { ISOL_BAUD_RATE_9600, "9600" }, -- { ISOL_BAUD_RATE_19200, "19200" }, -- { ISOL_BAUD_RATE_38400, "38400" }, -- { ISOL_BAUD_RATE_57600, "57600" }, -- { ISOL_BAUD_RATE_115200, "115200" }, -- { 0x00, NULL } --}; -+static struct termios _saved_tio; -+static int _in_raw_mode = 0; - - extern int verbose; - --static int ipmi_isol_setup(struct ipmi_intf * intf, char baudsetting) -+#define ISOL_ESCAPE_CHARACTER '~' -+ -+/* -+ * ipmi_get_isol_info -+ */ -+static int ipmi_get_isol_info(struct ipmi_intf * intf, -+ struct isol_config_parameters * params) - { - struct ipmi_rs * rsp; - struct ipmi_rq req; -- unsigned char data[6]; -+ unsigned char data[6]; - -- /* TEST FOR AVAILABILITY */ -+ memset(&req, 0, sizeof(req)); -+ req.msg.netfn = IPMI_NETFN_ISOL; -+ req.msg.cmd = GET_ISOL_CONFIG; -+ req.msg.data = data; -+ req.msg.data_len = 4; - -+ /* GET ISOL ENABLED CONFIG */ -+ - memset(data, 0, 6); - data[0] = 0x00; - data[1] = ISOL_ENABLE_PARAM; -- data[2] = ISOL_ENABLE_FLAG; -- -- memset(&req, 0, sizeof(req)); -- req.msg.netfn = IPMI_NETFN_ISOL; -- req.msg.cmd = SET_ISOL_CONFIG; -- req.msg.data = data; -- req.msg.data_len = 3; -+ data[2] = 0x00; /* block */ -+ data[3] = 0x00; /* selector */ - - rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { -- lprintf(LOG_ERR, "Error in Set ISOL Config Command"); -+ lprintf(LOG_ERR, "Error in Get ISOL Config Command"); - return -1; - } - if (rsp->ccode == 0xc1) { -@@ -81,20 +92,19 @@ - return -1; - } - if (rsp->ccode > 0) { -- lprintf(LOG_ERR, "Error in Set ISOL Config Command: %s", -+ lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s", - val2str(rsp->ccode, completion_code_vals)); - return -1; - } -+ params->enabled = rsp->data[1]; - -- /* GET ISOL CONFIG */ -- -+ /* GET ISOL AUTHENTICATON CONFIG */ -+ - memset(data, 0, 6); - data[0] = 0x00; - data[1] = ISOL_AUTHENTICATION_PARAM; - data[2] = 0x00; /* block */ - data[3] = 0x00; /* selector */ -- req.msg.cmd = GET_ISOL_CONFIG; -- req.msg.data_len = 4; - - rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { -@@ -106,86 +116,713 @@ - val2str(rsp->ccode, completion_code_vals)); - return -1; - } -- -- if (verbose > 1) -- printbuf(rsp->data, rsp->data_len, "ISOL Config"); -- -- /* SET ISOL CONFIG - AUTHENTICATION */ -- -+ params->privilege_level = rsp->data[1]; -+ -+ /* GET ISOL BAUD RATE CONFIG */ -+ - memset(data, 0, 6); - data[0] = 0x00; -- data[1] = ISOL_AUTHENTICATION_PARAM; -- data[2] = ISOL_PRIVILEGE_LEVEL_USER | (rsp->data[1] & 0x80); -- req.msg.cmd = SET_ISOL_CONFIG; -- req.msg.data_len = 3; -+ data[1] = ISOL_BAUD_RATE_PARAM; -+ data[2] = 0x00; /* block */ -+ data[3] = 0x00; /* selector */ - - rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { -- lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command"); -+ lprintf(LOG_ERR, "Error in Get ISOL Config Command"); - return -1; - } - if (rsp->ccode > 0) { -- lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command: %s", -+ lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s", - val2str(rsp->ccode, completion_code_vals)); - return -1; - } -+ params->bit_rate = rsp->data[1]; - -- /* SET ISOL CONFIG - BAUD RATE */ -+ return 0; -+} - -- memset(data, 0, 6); -- data[0] = 0x00; -- data[1] = ISOL_BAUD_RATE_PARAM; -- data[2] = baudsetting; -+static int ipmi_print_isol_info(struct ipmi_intf * intf) -+{ -+ struct isol_config_parameters params = {0}; -+ if (ipmi_get_isol_info(intf, ¶ms)) -+ return -1; -+ -+ if (csv_output) -+ { -+ printf("%s,", (params.enabled & 0x1)?"true": "false"); -+ printf("%s,", -+ val2str((params.privilege_level & 0xf), ipmi_privlvl_vals)); -+ printf("%s,", -+ val2str((params.bit_rate & 0xf), ipmi_bit_rate_vals)); -+ } -+ else -+ { -+ printf("Enabled : %s\n", -+ (params.enabled & 0x1)?"true": "false"); -+ printf("Privilege Level : %s\n", -+ val2str((params.privilege_level & 0xf), ipmi_privlvl_vals)); -+ printf("Bit Rate (kbps) : %s\n", -+ val2str((params.bit_rate & 0xf), ipmi_bit_rate_vals)); -+ } -+ -+ return 0; -+} -+ -+static int ipmi_isol_set_param(struct ipmi_intf * intf, -+ const char *param, -+ const char *value) -+{ -+ struct ipmi_rs * rsp; -+ struct ipmi_rq req; -+ unsigned char data[6]; -+ struct isol_config_parameters params = {0}; -+ -+ /* We need other values to complete the request */ -+ if (ipmi_get_isol_info(intf, ¶ms)) -+ return -1; -+ -+ memset(&req, 0, sizeof(req)); -+ req.msg.netfn = IPMI_NETFN_ISOL; - req.msg.cmd = SET_ISOL_CONFIG; -+ req.msg.data = data; - req.msg.data_len = 3; - -+ memset(data, 0, 6); -+ -+ /* -+ * enabled -+ */ -+ if (strcmp(param, "enabled") == 0) -+ { -+ data[1] = ISOL_ENABLE_PARAM; -+ if (strcmp(value, "true") == 0) -+ data[2] = 0x01; -+ else if (strcmp(value, "false") == 0) -+ data[2] = 0x00; -+ else { -+ lprintf(LOG_ERR, "Invalid value %s for parameter %s", -+ value, param); -+ lprintf(LOG_ERR, "Valid values are true and false"); -+ return -1; -+ } -+ } -+ -+ /* -+ * privilege-level -+ */ -+ else if (strcmp(param, "privilege-level") == 0) -+ { -+ data[1] = ISOL_AUTHENTICATION_PARAM; -+ if (! strcmp(value, "user")) -+ data[2] = 0x02; -+ else if (! strcmp(value, "operator")) -+ data[2] = 0x03; -+ else if (! strcmp(value, "admin")) -+ data[2] = 0x04; -+ else if (! strcmp(value, "oem")) -+ data[2] = 0x05; -+ else -+ { -+ lprintf(LOG_ERR, "Invalid value %s for parameter %s", -+ value, param); -+ lprintf(LOG_ERR, "Valid values are user, operator, admin, and oem"); -+ return -1; -+ } -+ /* We need to mask bit7 from the fetched value */ -+ data[2] |= (params.privilege_level & 0x80) ? 0x80 : 0x00; -+ } -+ -+ /* -+ * bit-rate -+ */ -+ else if (strcmp(param, "bit-rate") == 0) -+ { -+ data[1] = ISOL_BAUD_RATE_PARAM; -+ if (strncmp(value, "9.6", 3) == 0) { -+ data[2] = 0x06; -+ } -+ else if (strncmp(value, "19.2", 4) == 0) { -+ data[2] = 0x07; -+ } -+ else if (strncmp(value, "38.4", 4) == 0) { -+ data[2] = 0x08; -+ } -+ else if (strncmp(value, "57.6", 4) == 0) { -+ data[2] = 0x09; -+ } -+ else if (strncmp(value, "115.2", 5) == 0) { -+ data[2] = 0x0A; -+ } -+ else { -+ lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", value); -+ lprintf(LOG_ERR, "Valid values are 9.6, 19.2, 38.4, 57.6 and 115.2"); -+ return -1; -+ } -+ } -+ else -+ { -+ lprintf(LOG_ERR, "Error: invalid ISOL parameter %s", param); -+ return -1; -+ } -+ -+ -+ /* -+ * Execute the request -+ */ -+ - rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { -- lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command"); -+ lprintf(LOG_ERR, "Error setting ISOL parameter '%s'", param); - return -1; - } - if (rsp->ccode > 0) { -- lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command: %s", -- val2str(rsp->ccode, completion_code_vals)); -+ lprintf(LOG_ERR, "Error setting ISOL parameter '%s': %s", -+ param, val2str(rsp->ccode, completion_code_vals)); - return -1; - } - -- printf("Set ISOL Baud Rate to %s\n", -- val2str(baudsetting, ipmi_isol_baud_vals)); -+ return 0; -+} -+ -+static void -+leave_raw_mode(void) -+{ -+ if (!_in_raw_mode) -+ return; -+ if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) -+ perror("tcsetattr"); -+ else -+ _in_raw_mode = 0; -+} -+ -+ -+ -+static void -+enter_raw_mode(void) -+{ -+ struct termios tio; -+ if (tcgetattr(fileno(stdin), &tio) == -1) { -+ perror("tcgetattr"); -+ return; -+ } -+ _saved_tio = tio; -+ tio.c_iflag |= IGNPAR; -+ tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF)\ -+ ; -+ tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); -+ // #ifdef IEXTEN -+ tio.c_lflag &= ~IEXTEN; -+ // #endif -+ tio.c_oflag &= ~OPOST; -+ tio.c_cc[VMIN] = 1; -+ tio.c_cc[VTIME] = 0; -+ if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1) -+ perror("tcsetattr"); -+ else -+ _in_raw_mode = 1; -+} -+ -+ -+static void -+sendBreak(struct ipmi_intf * intf) -+{ -+ struct ipmi_v2_payload v2_payload; -+ -+ memset(&v2_payload, 0, sizeof(v2_payload)); -+ -+ v2_payload.payload.sol_packet.character_count = 0; -+ v2_payload.payload.sol_packet.generate_break = 1; -+ -+ intf->send_sol(intf, &v2_payload); -+} -+ -+/* -+ * suspendSelf -+ * -+ * Put ourself in the background -+ * -+ * param bRestoreTty specifies whether we will put our self back -+ * in raw mode when we resume -+ */ -+static void -+suspendSelf(int bRestoreTty) -+{ -+ leave_raw_mode(); -+ kill(getpid(), SIGTSTP); -+ -+ if (bRestoreTty) -+ enter_raw_mode(); -+} -+ -+ -+ -+/* -+ * printiSolEscapeSequences -+ * -+ * Send some useful documentation to the user -+ */ -+static void -+printiSolEscapeSequences(void) -+{ -+ printf( -+ "%c?\r\n\ -+ Supported escape sequences:\r\n\ -+ %c. - terminate connection\r\n\ -+ %c^Z - suspend ipmitool\r\n\ -+ %c^X - suspend ipmitool, but don't restore tty on restart\r\n\ -+ %cB - send break\r\n\ -+ %c? - this message\r\n\ -+ %c%c - send the escape character by typing it twice\r\n\ -+ (Note that escapes are only recognized immediately after newline.)\r\n", -+ ISOL_ESCAPE_CHARACTER, -+ ISOL_ESCAPE_CHARACTER, -+ ISOL_ESCAPE_CHARACTER, -+ ISOL_ESCAPE_CHARACTER, -+ ISOL_ESCAPE_CHARACTER, -+ ISOL_ESCAPE_CHARACTER, -+ ISOL_ESCAPE_CHARACTER, -+ ISOL_ESCAPE_CHARACTER); -+} -+ -+ -+ -+/* -+ * output -+ * -+ * Send the specified data to stdout -+ */ -+static void -+output(struct ipmi_rs * rsp) -+{ -+ if (rsp) -+ { -+ int i; -+ for (i = 0; i < rsp->data_len; ++i) -+ putc(rsp->data[i], stdout); -+ -+ fflush(stdout); -+ } -+} -+ -+/* -+ * ipmi_isol_deactivate -+ */ -+static int -+ipmi_isol_deactivate(struct ipmi_intf * intf) -+{ -+ struct ipmi_rs * rsp; -+ struct ipmi_rq req; -+ uint8_t data[6]; -+ struct isol_config_parameters params; -+ -+ memset(&req, 0, sizeof(req)); -+ req.msg.netfn = IPMI_NETFN_ISOL; -+ req.msg.cmd = ACTIVATE_ISOL; -+ req.msg.data = data; -+ req.msg.data_len = 5; - -+ memset(data, 0, 6); -+ data[0] = 0x00; /* Deactivate */ -+ data[1] = 0x00; -+ data[2] = 0x00; -+ data[3] = 0x00; -+ data[5] = 0x00; -+ -+ rsp = intf->sendrecv(intf, &req); -+ if (rsp == NULL) { -+ lprintf(LOG_ERR, "Error deactivating ISOL"); -+ return -1; -+ } -+ if (rsp->ccode > 0) { -+ lprintf(LOG_ERR, "Error deactivating ISOL: %s", -+ val2str(rsp->ccode, completion_code_vals)); -+ return -1; -+ } -+ /* response contain 4 additional bytes : 80 00 32 ff -+ Don't know what to use them for yet... */ - return 0; - } - --int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv) -+/* -+ * processiSolUserInput -+ * -+ * Act on user input into the ISOL session. The only reason this -+ * is complicated is that we have to process escape sequences. -+ * -+ * return 0 on success -+ * 1 if we should exit -+ * < 0 on error (BMC probably closed the session) -+ */ -+static int -+processiSolUserInput(struct ipmi_intf * intf, -+ uint8_t * input, -+ uint16_t buffer_length) - { -- int ret = 0; -+ static int escape_pending = 0; -+ static int last_was_cr = 1; -+ struct ipmi_v2_payload v2_payload; -+ int length = 0; -+ int retval = 0; -+ char ch; -+ int i; -+ -+ memset(&v2_payload, 0, sizeof(v2_payload)); -+ -+ /* -+ * Our first order of business is to check the input for escape -+ * sequences to act on. -+ */ -+ for (i = 0; i < buffer_length; ++i) -+ { -+ ch = input[i]; -+ -+ if (escape_pending){ -+ escape_pending = 0; -+ -+ /* -+ * Process a possible escape sequence. -+ */ -+ switch (ch) { -+ case '.': -+ printf("%c. [terminated ipmitool]\r\n", ISOL_ESCAPE_CHARACTER); -+ retval = 1; -+ break; -+ case 'Z' - 64: -+ printf("%c^Z [suspend ipmitool]\r\n", ISOL_ESCAPE_CHARACTER); -+ suspendSelf(1); /* Restore tty back to raw */ -+ continue; -+ -+ case 'X' - 64: -+ printf("%c^X [suspend ipmitool]\r\n", ISOL_ESCAPE_CHARACTER); -+ suspendSelf(0); /* Don't restore to raw mode */ -+ continue; -+ -+ case 'B': -+ printf("%cb [send break]\r\n", ISOL_ESCAPE_CHARACTER); -+ sendBreak(intf); -+ continue; -+ -+ case '?': -+ printiSolEscapeSequences(); -+ continue; -+ default: -+ if (ch != ISOL_ESCAPE_CHARACTER) -+ v2_payload.payload.sol_packet.data[length++] = -+ ISOL_ESCAPE_CHARACTER; -+ v2_payload.payload.sol_packet.data[length++] = ch; -+ } -+ } - -- if (argc < 2 || strncmp(argv[0], "help", 4) == 0) { -- lprintf(LOG_NOTICE, "ISOL Commands: setup "); -- lprintf(LOG_NOTICE, "ISOL Baud Rates: 9600, 19200, 38400, 57600, 115200"); -- return 0; -- } -- -- if (strncmp(argv[0], "setup", 5) == 0) { -- if (strncmp(argv[1], "9600", 4) == 0) { -- ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_9600); -- } -- else if (strncmp(argv[1], "19200", 5) == 0) { -- ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_19200); -+ else -+ { -+ if (last_was_cr && (ch == ISOL_ESCAPE_CHARACTER)) { -+ escape_pending = 1; -+ continue; -+ } -+ -+ v2_payload.payload.sol_packet.data[length++] = ch; - } -- else if (strncmp(argv[1], "38400", 5) == 0) { -- ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_38400); -+ -+ -+ /* -+ * Normal character. Record whether it was a newline. -+ */ -+ last_was_cr = (ch == '\r' || ch == '\n'); -+ } -+ -+ /* -+ * If there is anything left to process we dispatch it to the BMC, -+ * send intf->session->sol_data.max_outbound_payload_size bytes -+ * at a time. -+ */ -+ if (length) -+ { -+ struct ipmi_rs * rsp; -+ -+ v2_payload.payload.sol_packet.flush_outbound = 1; /* Not sure if necessary ? */ -+ v2_payload.payload.sol_packet.character_count = length; -+ rsp = intf->send_sol(intf, &v2_payload); -+ -+ if (! rsp) { -+ lprintf(LOG_ERR, "Error sending SOL data"); -+ retval = -1; - } -- else if (strncmp(argv[1], "57600", 5) == 0) { -- ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_57600); -+ -+ /* If the sequence number is set we know we have new data */ -+ else if ((rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) && -+ (rsp->payload.sol_packet.packet_sequence_number)) -+ output(rsp); -+ } -+ return retval; -+} -+ -+/* -+ * ipmi_isol_red_pill -+ */ -+static int -+ipmi_isol_red_pill(struct ipmi_intf * intf) -+{ -+ char * buffer; -+ int numRead; -+ int bShouldExit = 0; -+ int bBmcClosedSession = 0; -+ fd_set read_fds; -+ struct timeval tv; -+ int retval; -+ int buffer_size = 255; -+ int timedout = 0; -+ -+ buffer = (char*)malloc(buffer_size); -+ if (buffer == NULL) { -+ lprintf(LOG_ERR, "ipmitool: malloc failure"); -+ return -1; -+ } -+ -+ enter_raw_mode(); -+ -+ while (! bShouldExit) -+ { -+ FD_ZERO(&read_fds); -+ FD_SET(0, &read_fds); -+ FD_SET(intf->fd, &read_fds); -+ -+ /* Wait up to half a second */ -+ tv.tv_sec = 0; -+ tv.tv_usec = 500000; -+ -+ retval = select(intf->fd + 1, &read_fds, NULL, NULL, &tv); -+ -+ if (retval) -+ { -+ if (retval == -1) -+ { -+ /* ERROR */ -+ perror("select"); -+ return -1; -+ } -+ -+ timedout = 0; -+ -+ /* -+ * Process input from the user -+ */ -+ if (FD_ISSET(0, &read_fds)) -+ { -+ bzero(buffer, sizeof(buffer)); -+ numRead = read(fileno(stdin), -+ buffer, -+ buffer_size); -+ -+ if (numRead > 0) -+ { -+ int rc = processiSolUserInput(intf, buffer, numRead); -+ -+ if (rc) -+ { -+ if (rc < 0) -+ bShouldExit = bBmcClosedSession = 1; -+ else -+ bShouldExit = 1; -+ } -+ } -+ else -+ { -+ bShouldExit = 1; -+ } -+ } -+ -+ -+ /* -+ * Process input from the BMC -+ */ -+ else if (FD_ISSET(intf->fd, &read_fds)) -+ { -+ struct ipmi_rs * rs = intf->recv_sol(intf); -+ if (! rs) -+ { -+ bShouldExit = bBmcClosedSession = 1; -+ } -+ else -+ output(rs); -+ } -+ -+ -+ /* -+ * ERROR in select -+ */ -+ else -+ { -+ lprintf(LOG_ERR, "Error: Select returned with nothing to read"); -+ bShouldExit = 1; -+ } - } -- else if (strncmp(argv[1], "115200", 6) == 0) { -- ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_115200); -+ else -+ { -+ if ((++timedout) == 20) /* Every 10 seconds we send a keepalive */ -+ { -+ intf->keepalive(intf); -+ timedout = 0; -+ } - } -- else { -- lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", argv[1]); -- ret = -1; -+ } -+ -+ leave_raw_mode(); -+ -+ if (bBmcClosedSession) -+ { -+ lprintf(LOG_ERR, "SOL session closed by BMC"); -+ } -+ else -+ ipmi_isol_deactivate(intf); -+ -+ return 0; -+} -+ -+/* -+ * ipmi_isol_activate -+ */ -+static int -+ipmi_isol_activate(struct ipmi_intf * intf) -+{ -+ struct ipmi_rs * rsp; -+ struct ipmi_rq req; -+ uint8_t data[6]; -+ struct isol_config_parameters params; -+ -+ if (ipmi_get_isol_info(intf, ¶ms)) -+ return -1; -+ -+ if (!(params.enabled & 0x1)) { -+ lprintf(LOG_ERR, "ISOL is not enabled!"); -+ return -1; -+ } -+ -+ /* -+ * Setup a callback so that the lanplus processing knows what -+ * to do with packets that come unexpectedly (while waiting for -+ * an ACK, perhaps. -+ */ -+ intf->session->sol_data.sol_input_handler = output; -+ -+ memset(&req, 0, sizeof(req)); -+ req.msg.netfn = IPMI_NETFN_ISOL; -+ req.msg.cmd = ACTIVATE_ISOL; -+ req.msg.data = data; -+ req.msg.data_len = 5; -+ -+ memset(data, 0, 6); -+ data[0] = 0x01; -+ data[1] = 0x00; -+ data[2] = 0x00; -+ data[3] = 0x00; -+ data[5] = 0x00; -+ -+ rsp = intf->sendrecv(intf, &req); -+ if (NULL != rsp) { -+ switch (rsp->ccode) { -+ case 0x00: -+ if (rsp->data_len == 4) { -+ break; -+ } else { -+ lprintf(LOG_ERR, "Error: Unexpected data length (%d) received " -+ "in ISOL activation response", -+ rsp->data_len); -+ return -1; -+ } -+ break; -+ case 0x80: -+ lprintf(LOG_ERR, "Info: ISOL already active on another session"); -+ return -1; -+ case 0x81: -+ lprintf(LOG_ERR, "Info: ISOL disabled"); -+ return -1; -+ case 0x82: -+ lprintf(LOG_ERR, "Info: ISOL activation limit reached"); -+ return -1; -+ default: -+ lprintf(LOG_ERR, "Error activating ISOL: %s", -+ val2str(rsp->ccode, completion_code_vals)); -+ return -1; -+ } -+ } else { -+ lprintf(LOG_ERR, "Error: No response activating ISOL"); -+ return -1; -+ } -+ -+ /* response contain 4 additional bytes : 80 01 32 ff -+ Don't know what to use them for yet... */ -+ -+ printf("[SOL Session operational. Use %c? for help]\r\n", -+ ISOL_ESCAPE_CHARACTER); -+ -+ /* -+ * At this point we are good to go with our SOL session. We -+ * need to listen to -+ * 1) STDIN for user input -+ * 2) The FD for incoming SOL packets -+ */ -+ if (ipmi_isol_red_pill(intf)) { -+ lprintf(LOG_ERR, "Error in SOL session"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static void print_isol_set_usage(void) { -+ lprintf(LOG_NOTICE, "\nISOL set parameters and values: \n"); -+ lprintf(LOG_NOTICE, " enabled true | false"); -+ lprintf(LOG_NOTICE, " privilege-level user | operator | admin | oem"); -+ lprintf(LOG_NOTICE, " bit-rate " -+ "9.6 | 19.2 | 38.4 | 57.6 | 115.2"); -+ lprintf(LOG_NOTICE, ""); -+} -+ -+static void print_isol_usage(void) { -+ lprintf(LOG_NOTICE, "ISOL Commands: info"); -+ lprintf(LOG_NOTICE, " set "); -+ lprintf(LOG_NOTICE, " activate"); -+} -+ -+int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv) -+{ -+ int ret = 0; -+ -+ /* -+ * Help -+ */ -+ if (!argc || !strncmp(argv[0], "help", 4)) -+ print_isol_usage(); -+ -+ /* -+ * Info -+ */ -+ else if (!strncmp(argv[0], "info", 4)) { -+ ret = ipmi_print_isol_info(intf); -+ } -+ -+ /* -+ * Set a parameter value -+ */ -+ else if (!strncmp(argv[0], "set", 3)) { -+ if (argc < 3) { -+ print_isol_set_usage(); -+ return -1; - } -+ ret = ipmi_isol_set_param(intf, argv[1], argv[2]); -+ } -+ -+ /* -+ * Activate -+ */ -+ else if (!strncmp(argv[0], "activate", 8)) { -+ ret = ipmi_isol_activate(intf); -+ } -+ -+ else { -+ print_isol_usage(); -+ ret = -1; - } -+ - return ret; - } -diff -urN ipmitool-1.8.9.orig/lib/ipmi_isol.c.orig ipmitool-1.8.9/lib/ipmi_isol.c.orig ---- ipmitool-1.8.9.orig/lib/ipmi_isol.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ ipmitool-1.8.9/lib/ipmi_isol.c.orig 2007-02-22 08:38:56.000000000 +0000 -@@ -0,0 +1,191 @@ -+/* -+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * Redistribution of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * Redistribution in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * Neither the name of Sun Microsystems, Inc. or the names of -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * This software is provided "AS IS," without a warranty of any kind. -+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, -+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A -+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. -+ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE -+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING -+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL -+ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, -+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR -+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF -+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, -+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+const struct valstr ipmi_isol_baud_vals[] = { -+ { ISOL_BAUD_RATE_9600, "9600" }, -+ { ISOL_BAUD_RATE_19200, "19200" }, -+ { ISOL_BAUD_RATE_38400, "38400" }, -+ { ISOL_BAUD_RATE_57600, "57600" }, -+ { ISOL_BAUD_RATE_115200, "115200" }, -+ { 0x00, NULL } -+}; -+ -+extern int verbose; -+ -+static int ipmi_isol_setup(struct ipmi_intf * intf, char baudsetting) -+{ -+ struct ipmi_rs * rsp; -+ struct ipmi_rq req; -+ unsigned char data[6]; -+ -+ /* TEST FOR AVAILABILITY */ -+ -+ memset(data, 0, 6); -+ data[0] = 0x00; -+ data[1] = ISOL_ENABLE_PARAM; -+ data[2] = ISOL_ENABLE_FLAG; -+ -+ memset(&req, 0, sizeof(req)); -+ req.msg.netfn = IPMI_NETFN_ISOL; -+ req.msg.cmd = SET_ISOL_CONFIG; -+ req.msg.data = data; -+ req.msg.data_len = 3; -+ -+ rsp = intf->sendrecv(intf, &req); -+ if (rsp == NULL) { -+ lprintf(LOG_ERR, "Error in Set ISOL Config Command"); -+ return -1; -+ } -+ if (rsp->ccode == 0xc1) { -+ lprintf(LOG_ERR, "IPMI v1.5 Serial Over Lan (ISOL) not supported!"); -+ return -1; -+ } -+ if (rsp->ccode > 0) { -+ lprintf(LOG_ERR, "Error in Set ISOL Config Command: %s", -+ val2str(rsp->ccode, completion_code_vals)); -+ return -1; -+ } -+ -+ /* GET ISOL CONFIG */ -+ -+ memset(data, 0, 6); -+ data[0] = 0x00; -+ data[1] = ISOL_AUTHENTICATION_PARAM; -+ data[2] = 0x00; /* block */ -+ data[3] = 0x00; /* selector */ -+ req.msg.cmd = GET_ISOL_CONFIG; -+ req.msg.data_len = 4; -+ -+ rsp = intf->sendrecv(intf, &req); -+ if (rsp == NULL) { -+ lprintf(LOG_ERR, "Error in Get ISOL Config Command"); -+ return -1; -+ } -+ if (rsp->ccode > 0) { -+ lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s", -+ val2str(rsp->ccode, completion_code_vals)); -+ return -1; -+ } -+ -+ if (verbose > 1) -+ printbuf(rsp->data, rsp->data_len, "ISOL Config"); -+ -+ /* SET ISOL CONFIG - AUTHENTICATION */ -+ -+ memset(data, 0, 6); -+ data[0] = 0x00; -+ data[1] = ISOL_AUTHENTICATION_PARAM; -+ data[2] = ISOL_PRIVILEGE_LEVEL_USER | (rsp->data[1] & 0x80); -+ req.msg.cmd = SET_ISOL_CONFIG; -+ req.msg.data_len = 3; -+ -+ rsp = intf->sendrecv(intf, &req); -+ if (rsp == NULL) { -+ lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command"); -+ return -1; -+ } -+ if (rsp->ccode > 0) { -+ lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command: %s", -+ val2str(rsp->ccode, completion_code_vals)); -+ return -1; -+ } -+ -+ /* SET ISOL CONFIG - BAUD RATE */ -+ -+ memset(data, 0, 6); -+ data[0] = 0x00; -+ data[1] = ISOL_BAUD_RATE_PARAM; -+ data[2] = baudsetting; -+ req.msg.cmd = SET_ISOL_CONFIG; -+ req.msg.data_len = 3; -+ -+ rsp = intf->sendrecv(intf, &req); -+ if (rsp == NULL) { -+ lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command"); -+ return -1; -+ } -+ if (rsp->ccode > 0) { -+ lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command: %s", -+ val2str(rsp->ccode, completion_code_vals)); -+ return -1; -+ } -+ -+ printf("Set ISOL Baud Rate to %s\n", -+ val2str(baudsetting, ipmi_isol_baud_vals)); -+ -+ return 0; -+} -+ -+int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv) -+{ -+ int ret = 0; -+ -+ if (argc < 2 || strncmp(argv[0], "help", 4) == 0) { -+ lprintf(LOG_NOTICE, "ISOL Commands: setup "); -+ lprintf(LOG_NOTICE, "ISOL Baud Rates: 9600, 19200, 38400, 57600, 115200"); -+ return 0; -+ } -+ -+ if (strncmp(argv[0], "setup", 5) == 0) { -+ if (strncmp(argv[1], "9600", 4) == 0) { -+ ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_9600); -+ } -+ else if (strncmp(argv[1], "19200", 5) == 0) { -+ ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_19200); -+ } -+ else if (strncmp(argv[1], "38400", 5) == 0) { -+ ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_38400); -+ } -+ else if (strncmp(argv[1], "57600", 5) == 0) { -+ ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_57600); -+ } -+ else if (strncmp(argv[1], "115200", 6) == 0) { -+ ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_115200); -+ } -+ else { -+ lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", argv[1]); -+ ret = -1; -+ } -+ } -+ return ret; -+} -diff -urN ipmitool-1.8.9.orig/src/plugins/lan/lan.c ipmitool-1.8.9/src/plugins/lan/lan.c ---- ipmitool-1.8.9.orig/src/plugins/lan/lan.c 2007-02-22 08:38:57.000000000 +0000 -+++ ipmitool-1.8.9/src/plugins/lan/lan.c 2007-12-13 10:16:57.063986495 +0000 -@@ -79,6 +79,11 @@ - static struct ipmi_rs * ipmi_lan_poll_recv(struct ipmi_intf * intf); - static int ipmi_lan_setup(struct ipmi_intf * intf); - static int ipmi_lan_keepalive(struct ipmi_intf * intf); -+static struct ipmi_rs * ipmi_lan_send_payload(struct ipmi_intf * intf, -+ struct ipmi_v2_payload * payload); -+static struct ipmi_rs * ipmi_lan_recv_sol(struct ipmi_intf * intf); -+static struct ipmi_rs * ipmi_lan_send_sol(struct ipmi_intf * intf, -+ struct ipmi_v2_payload * payload); - static struct ipmi_rs * ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req); - static int ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp); - static int ipmi_lan_open(struct ipmi_intf * intf); -@@ -93,6 +98,8 @@ - close: ipmi_lan_close, - sendrecv: ipmi_lan_send_cmd, - sendrsp: ipmi_lan_send_rsp, -+ recv_sol: ipmi_lan_recv_sol, -+ send_sol: ipmi_lan_send_sol, - keepalive: ipmi_lan_keepalive, - target_addr: IPMI_BMC_SLAVE_ADDR, - }; -@@ -456,80 +463,141 @@ - memcpy(&rsp->session.id, rsp->data+x, 4); - x += 4; - -- if (intf->session->active && (rsp->session.authtype || intf->session->authtype)) -- x += 16; -- -- rsp->session.msglen = rsp->data[x++]; -- rsp->payload.ipmi_response.rq_addr = rsp->data[x++]; -- rsp->payload.ipmi_response.netfn = rsp->data[x] >> 2; -- rsp->payload.ipmi_response.rq_lun = rsp->data[x++] & 0x3; -- x++; /* checksum */ -- rsp->payload.ipmi_response.rs_addr = rsp->data[x++]; -- rsp->payload.ipmi_response.rq_seq = rsp->data[x] >> 2; -- rsp->payload.ipmi_response.rs_lun = rsp->data[x++] & 0x3; -- rsp->payload.ipmi_response.cmd = rsp->data[x++]; -- rsp->ccode = rsp->data[x++]; -- -- if (verbose > 2) -- printbuf(rsp->data, rsp->data_len, "ipmi message header"); -- -- lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header"); -- lprintf(LOG_DEBUG+1, "<< Authtype : %s", -- val2str(rsp->session.authtype, ipmi_authtype_session_vals)); -- lprintf(LOG_DEBUG+1, "<< Sequence : 0x%08lx", -- (long)rsp->session.seq); -- lprintf(LOG_DEBUG+1, "<< Session ID : 0x%08lx", -- (long)rsp->session.id); -- lprintf(LOG_DEBUG+1, "<< IPMI Response Message Header"); -- lprintf(LOG_DEBUG+1, "<< Rq Addr : %02x", -- rsp->payload.ipmi_response.rq_addr); -- lprintf(LOG_DEBUG+1, "<< NetFn : %02x", -- rsp->payload.ipmi_response.netfn); -- lprintf(LOG_DEBUG+1, "<< Rq LUN : %01x", -- rsp->payload.ipmi_response.rq_lun); -- lprintf(LOG_DEBUG+1, "<< Rs Addr : %02x", -- rsp->payload.ipmi_response.rs_addr); -- lprintf(LOG_DEBUG+1, "<< Rq Seq : %02x", -- rsp->payload.ipmi_response.rq_seq); -- lprintf(LOG_DEBUG+1, "<< Rs Lun : %01x", -- rsp->payload.ipmi_response.rs_lun); -- lprintf(LOG_DEBUG+1, "<< Command : %02x", -- rsp->payload.ipmi_response.cmd); -- lprintf(LOG_DEBUG+1, "<< Compl Code : 0x%02x", -- rsp->ccode); -- -- /* now see if we have outstanding entry in request list */ -- entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq, -- rsp->payload.ipmi_response.cmd); -- if (entry) { -- lprintf(LOG_DEBUG+2, "IPMI Request Match found"); -- if ((intf->target_addr != our_address) && bridge_possible) { -- if ((rsp->data_len) && -- (rsp->payload.ipmi_response.cmd != 0x34)) { -- printbuf(&rsp->data[x], rsp->data_len-x, -- "bridge command response"); -- } -- /* bridged command: lose extra header */ -- if (rsp->payload.ipmi_response.cmd == 0x34) { -- if (rsp->data_len == 38) { -- entry->req.msg.cmd = entry->req.msg.target_cmd; -- rsp = ipmi_lan_recv_packet(intf); -- continue; -+ if (rsp->session.id == (intf->session->session_id + 0x10000000)) { -+ /* With SOL, authtype is always NONE, so we have no authcode */ -+ rsp->session.payloadtype = IPMI_PAYLOAD_TYPE_SOL; -+ -+ rsp->session.msglen = rsp->data[x++]; -+ -+ rsp->payload.sol_packet.packet_sequence_number = -+ rsp->data[x++] & 0x0F; -+ -+ rsp->payload.sol_packet.acked_packet_number = -+ rsp->data[x++] & 0x0F; -+ -+ rsp->payload.sol_packet.accepted_character_count = -+ rsp->data[x++]; -+ -+ rsp->payload.sol_packet.is_nack = -+ rsp->data[x] & 0x40; -+ -+ rsp->payload.sol_packet.transfer_unavailable = -+ rsp->data[x] & 0x20; -+ -+ rsp->payload.sol_packet.sol_inactive = -+ rsp->data[x] & 0x10; -+ -+ rsp->payload.sol_packet.transmit_overrun = -+ rsp->data[x] & 0x08; -+ -+ rsp->payload.sol_packet.break_detected = -+ rsp->data[x++] & 0x04; -+ -+ x++; /* On ISOL there's and additional fifth byte before the data starts */ -+ -+ lprintf(LOG_DEBUG, "SOL sequence number : 0x%02x", -+ rsp->payload.sol_packet.packet_sequence_number); -+ -+ lprintf(LOG_DEBUG, "SOL acked packet : 0x%02x", -+ rsp->payload.sol_packet.acked_packet_number); -+ -+ lprintf(LOG_DEBUG, "SOL accepted char count : 0x%02x", -+ rsp->payload.sol_packet.accepted_character_count); -+ -+ lprintf(LOG_DEBUG, "SOL is nack : %s", -+ rsp->payload.sol_packet.is_nack? "true" : "false"); -+ -+ lprintf(LOG_DEBUG, "SOL xfer unavailable : %s", -+ rsp->payload.sol_packet.transfer_unavailable? "true" : "false"); -+ -+ lprintf(LOG_DEBUG, "SOL inactive : %s", -+ rsp->payload.sol_packet.sol_inactive? "true" : "false"); -+ -+ lprintf(LOG_DEBUG, "SOL transmit overrun : %s", -+ rsp->payload.sol_packet.transmit_overrun? "true" : "false"); -+ -+ lprintf(LOG_DEBUG, "SOL break detected : %s", -+ rsp->payload.sol_packet.break_detected? "true" : "false"); -+ } -+ else -+ { -+ /* Standard IPMI 1.5 packet */ -+ rsp->session.payloadtype = IPMI_PAYLOAD_TYPE_IPMI; -+ if (intf->session->active && (rsp->session.authtype || intf->session->authtype)) -+ x += 16; -+ -+ rsp->session.msglen = rsp->data[x++]; -+ rsp->payload.ipmi_response.rq_addr = rsp->data[x++]; -+ rsp->payload.ipmi_response.netfn = rsp->data[x] >> 2; -+ rsp->payload.ipmi_response.rq_lun = rsp->data[x++] & 0x3; -+ x++; /* checksum */ -+ rsp->payload.ipmi_response.rs_addr = rsp->data[x++]; -+ rsp->payload.ipmi_response.rq_seq = rsp->data[x] >> 2; -+ rsp->payload.ipmi_response.rs_lun = rsp->data[x++] & 0x3; -+ rsp->payload.ipmi_response.cmd = rsp->data[x++]; -+ rsp->ccode = rsp->data[x++]; -+ -+ if (verbose > 2) -+ printbuf(rsp->data, rsp->data_len, "ipmi message header"); -+ -+ lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header"); -+ lprintf(LOG_DEBUG+1, "<< Authtype : %s", -+ val2str(rsp->session.authtype, ipmi_authtype_session_vals)); -+ lprintf(LOG_DEBUG+1, "<< Sequence : 0x%08lx", -+ (long)rsp->session.seq); -+ lprintf(LOG_DEBUG+1, "<< Session ID : 0x%08lx", -+ (long)rsp->session.id); -+ lprintf(LOG_DEBUG+1, "<< IPMI Response Message Header"); -+ lprintf(LOG_DEBUG+1, "<< Rq Addr : %02x", -+ rsp->payload.ipmi_response.rq_addr); -+ lprintf(LOG_DEBUG+1, "<< NetFn : %02x", -+ rsp->payload.ipmi_response.netfn); -+ lprintf(LOG_DEBUG+1, "<< Rq LUN : %01x", -+ rsp->payload.ipmi_response.rq_lun); -+ lprintf(LOG_DEBUG+1, "<< Rs Addr : %02x", -+ rsp->payload.ipmi_response.rs_addr); -+ lprintf(LOG_DEBUG+1, "<< Rq Seq : %02x", -+ rsp->payload.ipmi_response.rq_seq); -+ lprintf(LOG_DEBUG+1, "<< Rs Lun : %01x", -+ rsp->payload.ipmi_response.rs_lun); -+ lprintf(LOG_DEBUG+1, "<< Command : %02x", -+ rsp->payload.ipmi_response.cmd); -+ lprintf(LOG_DEBUG+1, "<< Compl Code : 0x%02x", -+ rsp->ccode); -+ -+ /* now see if we have outstanding entry in request list */ -+ entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq, -+ rsp->payload.ipmi_response.cmd); -+ if (entry) { -+ lprintf(LOG_DEBUG+2, "IPMI Request Match found"); -+ if ((intf->target_addr != our_address) && bridge_possible) { -+ if ((rsp->data_len) && -+ (rsp->payload.ipmi_response.cmd != 0x34)) { -+ printbuf(&rsp->data[x], rsp->data_len-x, -+ "bridge command response"); -+ } -+ /* bridged command: lose extra header */ -+ if (rsp->payload.ipmi_response.cmd == 0x34) { -+ if (rsp->data_len == 38) { -+ entry->req.msg.cmd = entry->req.msg.target_cmd; -+ rsp = ipmi_lan_recv_packet(intf); -+ continue; -+ } -+ } else { -+ //x += sizeof(rsp->payload.ipmi_response); -+ if (rsp->data[x-1] != 0) -+ lprintf(LOG_DEBUG, "WARNING: Bridged " -+ "cmd ccode = 0x%02x", -+ rsp->data[x-1]); - } -- } else { -- //x += sizeof(rsp->payload.ipmi_response); -- if (rsp->data[x-1] != 0) -- lprintf(LOG_DEBUG, "WARNING: Bridged " -- "cmd ccode = 0x%02x", -- rsp->data[x-1]); - } -+ ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq, -+ rsp->payload.ipmi_response.cmd); -+ } else { -+ lprintf(LOG_INFO, "IPMI Request Match NOT FOUND"); -+ rsp = ipmi_lan_recv_packet(intf); -+ continue; - } -- ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq, -- rsp->payload.ipmi_response.cmd); -- } else { -- lprintf(LOG_INFO, "IPMI Request Match NOT FOUND"); -- rsp = ipmi_lan_recv_packet(intf); -- continue; - } - - break; -@@ -537,7 +605,9 @@ - - /* shift response data to start of array */ - if (rsp && rsp->data_len > x) { -- rsp->data_len -= x + 1; -+ rsp->data_len -= x; -+ if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_IPMI) -+ rsp->data_len -= 1; /* We don't want the checksum */ - memmove(rsp->data, rsp->data + x, rsp->data_len); - memset(rsp->data + rsp->data_len, 0, IPMI_BUF_SIZE - rsp->data_len); - } -@@ -553,9 +623,9 @@ - * | rmcp.seq | - * | rmcp.class | - * +--------------------+ -- * | session.authtype | 9 bytes -- * | session.seq | -- * | session.id | -+ * | session.authtype | 9 bytes -+ * | session.seq | -+ * | session.id | - * +--------------------+ - * | [session.authcode] | 16 bytes (AUTHTYPE != none) - * +--------------------+ -@@ -910,6 +980,430 @@ - return 0; - } - -+/* -+ * IPMI SOL Payload Format -+ * +--------------------+ -+ * | rmcp.ver | 4 bytes -+ * | rmcp.__reserved | -+ * | rmcp.seq | -+ * | rmcp.class | -+ * +--------------------+ -+ * | session.authtype | 9 bytes -+ * | session.seq | -+ * | session.id | -+ * +--------------------+ -+ * | message length | 1 byte -+ * +--------------------+ -+ * | sol.seq | 5 bytes -+ * | sol.ack_seq | -+ * | sol.acc_count | -+ * | sol.control | -+ * | sol.__reserved | -+ * +--------------------+ -+ * | [request data] | data_len bytes -+ * +--------------------+ -+ */ -+uint8_t * ipmi_lan_build_sol_msg(struct ipmi_intf * intf, -+ struct ipmi_v2_payload * payload, -+ int * llen) -+{ -+ struct rmcp_hdr rmcp = { -+ .ver = RMCP_VERSION_1, -+ .class = RMCP_CLASS_IPMI, -+ .seq = 0xff, -+ }; -+ struct ipmi_session * session = intf->session; -+ -+ /* msg will hold the entire message to be sent */ -+ uint8_t * msg; -+ -+ int len = 0; -+ -+ len = sizeof(rmcp) + // RMCP Header (4) -+ 10 + // IPMI Session Header -+ 5 + // SOL header -+ payload->payload.sol_packet.character_count; // The actual payload -+ -+ msg = malloc(len); -+ if (msg == NULL) { -+ lprintf(LOG_ERR, "ipmitool: malloc failure"); -+ return; -+ } -+ memset(msg, 0, len); -+ -+ /* rmcp header */ -+ memcpy(msg, &rmcp, sizeof(rmcp)); -+ len = sizeof(rmcp); -+ -+ /* ipmi session header */ -+ msg[len++] = 0; /* SOL is always authtype = NONE */ -+ msg[len++] = session->in_seq & 0xff; -+ msg[len++] = (session->in_seq >> 8) & 0xff; -+ msg[len++] = (session->in_seq >> 16) & 0xff; -+ msg[len++] = (session->in_seq >> 24) & 0xff; -+ -+ msg[len++] = session->session_id & 0xff; -+ msg[len++] = (session->session_id >> 8) & 0xff; -+ msg[len++] = (session->session_id >> 16) & 0xff; -+ msg[len++] = ((session->session_id >> 24) + 0x10) & 0xff; /* Add 0x10 to MSB for SOL */ -+ -+ msg[len++] = payload->payload.sol_packet.character_count + 5; -+ -+ /* sol header */ -+ msg[len++] = payload->payload.sol_packet.packet_sequence_number; -+ msg[len++] = payload->payload.sol_packet.acked_packet_number; -+ msg[len++] = payload->payload.sol_packet.accepted_character_count; -+ msg[len] = payload->payload.sol_packet.is_nack ? 0x40 : 0; -+ msg[len] |= payload->payload.sol_packet.assert_ring_wor ? 0x20 : 0; -+ msg[len] |= payload->payload.sol_packet.generate_break ? 0x10 : 0; -+ msg[len] |= payload->payload.sol_packet.deassert_cts ? 0x08 : 0; -+ msg[len] |= payload->payload.sol_packet.deassert_dcd_dsr ? 0x04 : 0; -+ msg[len] |= payload->payload.sol_packet.flush_inbound ? 0x02 : 0; -+ msg[len++] |= payload->payload.sol_packet.flush_outbound ? 0x01 : 0; -+ -+ len++; /* On SOL there's and additional fifth byte before the data starts */ -+ -+ if (payload->payload.sol_packet.character_count) { -+ /* We may have data to add */ -+ memcpy(msg + len, -+ payload->payload.sol_packet.data, -+ payload->payload.sol_packet.character_count); -+ len += payload->payload.sol_packet.character_count; -+ } -+ -+ session->in_seq++; -+ if (session->in_seq == 0) -+ session->in_seq++; -+ -+ *llen = len; -+ return msg; -+} -+ -+/* -+ * is_sol_packet -+ */ -+static int -+is_sol_packet(struct ipmi_rs * rsp) -+{ -+ return (rsp && -+ (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)); -+} -+ -+ -+ -+/* -+ * sol_response_acks_packet -+ */ -+static int -+sol_response_acks_packet(struct ipmi_rs * rsp, -+ struct ipmi_v2_payload * payload) -+{ -+ return (is_sol_packet(rsp) && -+ payload && -+ (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL) && -+ (rsp->payload.sol_packet.acked_packet_number == -+ payload->payload.sol_packet.packet_sequence_number)); -+} -+ -+/* -+ * ipmi_lan_send_sol_payload -+ * -+ */ -+static struct ipmi_rs * -+ipmi_lan_send_sol_payload(struct ipmi_intf * intf, -+ struct ipmi_v2_payload * payload) -+{ -+ struct ipmi_rs * rsp = NULL; -+ uint8_t * msg; -+ int len; -+ int try = 0; -+ -+ if (intf->opened == 0 && intf->open != NULL) { -+ if (intf->open(intf) < 0) -+ return NULL; -+ } -+ -+ msg = ipmi_lan_build_sol_msg(intf, payload, &len); -+ if (len <= 0 || msg == NULL) { -+ lprintf(LOG_ERR, "Invalid SOL payload packet"); -+ if (msg != NULL) -+ free(msg); -+ return NULL; -+ } -+ -+ lprintf(LOG_DEBUG, ">> SENDING A SOL MESSAGE\n"); -+ -+ for (;;) { -+ if (ipmi_lan_send_packet(intf, msg, len) < 0) { -+ try++; -+ usleep(5000); -+ continue; -+ } -+ -+ /* if we are set to noanswer we do not expect response */ -+ if (intf->noanswer) -+ break; -+ -+ if (payload->payload.sol_packet.packet_sequence_number == 0) { -+ /* We're just sending an ACK. No need to retry. */ -+ break; -+ } -+ -+ usleep(100); -+ -+ rsp = ipmi_lan_recv_sol(intf); /* Grab the next packet */ -+ -+ if (sol_response_acks_packet(rsp, payload)) -+ break; -+ -+ else if (is_sol_packet(rsp) && rsp->data_len) -+ { -+ /* -+ * We're still waiting for our ACK, but we more data from -+ * the BMC -+ */ -+ intf->session->sol_data.sol_input_handler(rsp); -+ } -+ -+ usleep(5000); -+ if (++try >= intf->session->retry) { -+ lprintf(LOG_DEBUG, " No response from remote controller"); -+ break; -+ } -+ } -+ -+ return rsp; -+} -+ -+/* -+ * is_sol_partial_ack -+ * -+ * Determine if the response is a partial ACK/NACK that indicates -+ * we need to resend part of our packet. -+ * -+ * returns the number of characters we need to resend, or -+ * 0 if this isn't an ACK or we don't need to resend anything -+ */ -+static int is_sol_partial_ack(struct ipmi_v2_payload * v2_payload, -+ struct ipmi_rs * rsp) -+{ -+ int chars_to_resend = 0; -+ -+ if (v2_payload && -+ rsp && -+ is_sol_packet(rsp) && -+ sol_response_acks_packet(rsp, v2_payload) && -+ (rsp->payload.sol_packet.accepted_character_count < -+ v2_payload->payload.sol_packet.character_count)) -+ { -+ if (rsp->payload.sol_packet.accepted_character_count == 0) { -+ /* We should not resend data */ -+ chars_to_resend = 0; -+ } -+ else -+ { -+ chars_to_resend = -+ v2_payload->payload.sol_packet.character_count - -+ rsp->payload.sol_packet.accepted_character_count; -+ } -+ } -+ -+ return chars_to_resend; -+} -+ -+/* -+ * set_sol_packet_sequence_number -+ */ -+static void set_sol_packet_sequence_number(struct ipmi_intf * intf, -+ struct ipmi_v2_payload * v2_payload) -+{ -+ /* Keep our sequence number sane */ -+ if (intf->session->sol_data.sequence_number > 0x0F) -+ intf->session->sol_data.sequence_number = 1; -+ -+ v2_payload->payload.sol_packet.packet_sequence_number = -+ intf->session->sol_data.sequence_number++; -+} -+ -+/* -+ * ipmi_lan_send_sol -+ * -+ * Sends a SOL packet.. We handle partial ACK/NACKs from the BMC here. -+ * -+ * Returns a pointer to the SOL ACK we received, or -+ * 0 on failure -+ * -+ */ -+struct ipmi_rs * -+ipmi_lan_send_sol(struct ipmi_intf * intf, -+ struct ipmi_v2_payload * v2_payload) -+{ -+ struct ipmi_rs * rsp; -+ int chars_to_resend = 0; -+ -+ v2_payload->payload_type = IPMI_PAYLOAD_TYPE_SOL; -+ -+ /* -+ * Payload length is just the length of the character -+ * data here. -+ */ -+ v2_payload->payload.sol_packet.acked_packet_number = 0; /* NA */ -+ -+ set_sol_packet_sequence_number(intf, v2_payload); -+ -+ v2_payload->payload.sol_packet.accepted_character_count = 0; /* NA */ -+ -+ rsp = ipmi_lan_send_sol_payload(intf, v2_payload); -+ -+ /* Determine if we need to resend some of our data */ -+ chars_to_resend = is_sol_partial_ack(v2_payload, rsp); -+ -+ while (chars_to_resend) -+ { -+ /* -+ * We first need to handle any new data we might have -+ * received in our NACK -+ */ -+ if (rsp->data_len) -+ intf->session->sol_data.sol_input_handler(rsp); -+ -+ set_sol_packet_sequence_number(intf, v2_payload); -+ -+ /* Just send the required data */ -+ memmove(v2_payload->payload.sol_packet.data, -+ v2_payload->payload.sol_packet.data + -+ rsp->payload.sol_packet.accepted_character_count, -+ chars_to_resend); -+ -+ v2_payload->payload.sol_packet.character_count = chars_to_resend; -+ -+ rsp = ipmi_lan_send_sol_payload(intf, v2_payload); -+ -+ chars_to_resend = is_sol_partial_ack(v2_payload, rsp); -+ } -+ -+ return rsp; -+} -+ -+/* -+ * check_sol_packet_for_new_data -+ * -+ * Determine whether the SOL packet has already been seen -+ * and whether the packet has new data for us. -+ * -+ * This function has the side effect of removing an previously -+ * seen data, and moving new data to the front. -+ * -+ * It also "Remembers" the data so we don't get repeats. -+ * -+ */ -+static int -+check_sol_packet_for_new_data(struct ipmi_intf * intf, -+ struct ipmi_rs *rsp) -+{ -+ static uint8_t last_received_sequence_number = 0; -+ static uint8_t last_received_byte_count = 0; -+ int new_data_size = 0; -+ -+ if (rsp && -+ (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)) -+ -+ { -+ uint8_t unaltered_data_len = rsp->data_len; -+ if (rsp->payload.sol_packet.packet_sequence_number == -+ last_received_sequence_number) -+ { -+ /* -+ * This is the same as the last packet, but may include -+ * extra data -+ */ -+ new_data_size = rsp->data_len - last_received_byte_count; -+ -+ if (new_data_size > 0) -+ { -+ /* We have more data to process */ -+ memmove(rsp->data, -+ rsp->data + -+ rsp->data_len - new_data_size, -+ new_data_size); -+ } -+ -+ rsp->data_len = new_data_size; -+ } -+ -+ /* -+ *Rember the data for next round -+ */ -+ if (rsp && rsp->payload.sol_packet.packet_sequence_number) -+ { -+ last_received_sequence_number = -+ rsp->payload.sol_packet.packet_sequence_number; -+ last_received_byte_count = unaltered_data_len; -+ } -+ } -+ -+ return new_data_size; -+} -+ -+/* -+ * ack_sol_packet -+ * -+ * Provided the specified packet looks reasonable, ACK it. -+ */ -+static void -+ack_sol_packet(struct ipmi_intf * intf, -+ struct ipmi_rs * rsp) -+{ -+ if (rsp && -+ (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) && -+ (rsp->payload.sol_packet.packet_sequence_number)) -+ { -+ struct ipmi_v2_payload ack; -+ -+ memset(&ack, 0, sizeof(struct ipmi_v2_payload)); -+ -+ ack.payload_type = IPMI_PAYLOAD_TYPE_SOL; -+ -+ /* -+ * Payload length is just the length of the character -+ * data here. -+ */ -+ ack.payload_length = 0; -+ -+ /* ACK packets have sequence numbers of 0 */ -+ ack.payload.sol_packet.packet_sequence_number = 0; -+ -+ ack.payload.sol_packet.acked_packet_number = -+ rsp->payload.sol_packet.packet_sequence_number; -+ -+ ack.payload.sol_packet.accepted_character_count = rsp->data_len; -+ -+ ipmi_lan_send_sol_payload(intf, &ack); -+ } -+} -+ -+/* -+ * ipmi_recv_sol -+ * -+ * Receive a SOL packet and send an ACK in response. -+ * -+ */ -+struct ipmi_rs * -+ipmi_lan_recv_sol(struct ipmi_intf * intf) -+{ -+ struct ipmi_rs * rsp = ipmi_lan_poll_recv(intf); -+ -+ ack_sol_packet(intf, rsp); -+ -+ /* -+ * Remembers the data sent, and alters the data to just -+ * include the new stuff. -+ */ -+ check_sol_packet_for_new_data(intf, rsp); -+ -+ return rsp; -+} -+ - /* send a get device id command to keep session active */ - static int - ipmi_lan_keepalive(struct ipmi_intf * intf) -@@ -1411,6 +1905,8 @@ - - intf->abort = 1; - -+ intf->session->sol_data.sequence_number = 1; -+ - /* open port to BMC */ - memset(&s->addr, 0, sizeof(struct sockaddr_in)); - s->addr.sin_family = AF_INET; diff --git a/debian/patches/20_ipmi_sdr b/debian/patches/20_ipmi_sdr new file mode 100644 index 0000000..dcb8c23 --- /dev/null +++ b/debian/patches/20_ipmi_sdr @@ -0,0 +1,19 @@ +## 20_ipmi_sdr.dpatch by Cyril Brulebois +## +## Enable reading temperatures again (Closes: #507760). +--- a/lib/ipmi_sdr.c ++++ b/lib/ipmi_sdr.c +@@ -1122,6 +1122,13 @@ + } else if (IS_SCANNING_DISABLED(rsp->data[1])) { + /* Sensor Scanning Disabled */ + validread = 0; ++ if (rsp->data[0] != 0) { ++ /* we might still get a valid reading */ ++ val = sdr_convert_sensor_reading(sensor, ++ rsp->data[0]); ++ if (val != 0.0) ++ validread = 1; ++ } + } else if (rsp->data[0] != 0) { + /* convert RAW reading into units */ + val = sdr_convert_sensor_reading(sensor, rsp->data[0]); diff --git a/debian/patches/20_ipmi_sdr.dpatch b/debian/patches/20_ipmi_sdr.dpatch deleted file mode 100644 index 4e6ff4f..0000000 --- a/debian/patches/20_ipmi_sdr.dpatch +++ /dev/null @@ -1,24 +0,0 @@ -#! /bin/sh /usr/share/dpatch/dpatch-run -## 20_ipmi_sdr.dpatch by Cyril Brulebois -## -## All lines beginning with `## DP:' are a description of the patch. -## DP: Enable reading temperatures again (Closes: #507760). - -@DPATCH@ - ---- a/lib/ipmi_sdr.c -+++ b/lib/ipmi_sdr.c -@@ -1122,6 +1122,13 @@ - } else if (IS_SCANNING_DISABLED(rsp->data[1])) { - /* Sensor Scanning Disabled */ - validread = 0; -+ if (rsp->data[0] != 0) { -+ /* we might still get a valid reading */ -+ val = sdr_convert_sensor_reading(sensor, -+ rsp->data[0]); -+ if (val != 0.0) -+ validread = 1; -+ } - } else if (rsp->data[0] != 0) { - /* convert RAW reading into units */ - val = sdr_convert_sensor_reading(sensor, rsp->data[0]); diff --git a/debian/patches/99_readme_typo b/debian/patches/99_readme_typo new file mode 100644 index 0000000..3338aa8 --- /dev/null +++ b/debian/patches/99_readme_typo @@ -0,0 +1,27 @@ +## 99_readme_typo.dpatch by dann frazier +## +## Typo in README. Closes: #508231 +diff -urpN ipmitool-1.8.9.orig/README ipmitool-1.8.9/README +--- ipmitool-1.8.9.orig/README 2005-01-06 12:13:51.000000000 -0700 ++++ ipmitool-1.8.9/README 2008-12-08 18:12:15.000000000 -0700 +@@ -24,7 +24,7 @@ Background + ========== + I originally wrote ipmitool while between projects and employeed at Sun + Microsystems. Sun had just embarked on a new line of general-purpose x86 +-servers that inclued an OEM Intel board with an IPMIv1.5 BMC on board. ++servers that included an OEM Intel board with an IPMIv1.5 BMC on board. + It started with an idea that remote chassis power control would be a handy + feature for my systems in the lab and from there it grew into a multi- + purpose tool that lots of people found useful. I decided to release it +diff -urpN ipmitool-1.8.9.orig/doc/ipmitool.1 ipmitool-1.8.9/doc/ipmitool.1 +--- ipmitool-1.8.9.orig/doc/ipmitool.1 2007-03-06 15:15:36.000000000 -0700 ++++ ipmitool-1.8.9/doc/ipmitool.1 2008-12-08 18:11:56.000000000 -0700 +@@ -39,7 +39,7 @@ chassis power control. + IPMI management of a local system interface requires a compatible IPMI + kernel driver to be installed and configured. On Linux this driver is + called \fIOpenIPMI\fP and it is included in standard distributions. +-On Solaris this driver is called \fIBMC\fP and is inclued in Solaris 10. ++On Solaris this driver is called \fIBMC\fP and is included in Solaris 10. + Management of a remote station requires the IPMI\-over\-LAN interface to be + enabled and configured. Depending on the particular requirements of each + system it may be possible to enable the LAN interface using ipmitool over diff --git a/debian/patches/99_readme_typo.dpatch b/debian/patches/99_readme_typo.dpatch deleted file mode 100644 index f70f54c..0000000 --- a/debian/patches/99_readme_typo.dpatch +++ /dev/null @@ -1,32 +0,0 @@ -#! /bin/sh /usr/share/dpatch/dpatch-run -## 99_readme_typo.dpatch by dann frazier -## -## All lines beginning with `## DP:' are a description of the patch. -## DP: Typo in README. Closes: #508231 - -@DPATCH@ - -diff -urpN ipmitool-1.8.9.orig/README ipmitool-1.8.9/README ---- ipmitool-1.8.9.orig/README 2005-01-06 12:13:51.000000000 -0700 -+++ ipmitool-1.8.9/README 2008-12-08 18:12:15.000000000 -0700 -@@ -24,7 +24,7 @@ Background - ========== - I originally wrote ipmitool while between projects and employeed at Sun - Microsystems. Sun had just embarked on a new line of general-purpose x86 --servers that inclued an OEM Intel board with an IPMIv1.5 BMC on board. -+servers that included an OEM Intel board with an IPMIv1.5 BMC on board. - It started with an idea that remote chassis power control would be a handy - feature for my systems in the lab and from there it grew into a multi- - purpose tool that lots of people found useful. I decided to release it -diff -urpN ipmitool-1.8.9.orig/doc/ipmitool.1 ipmitool-1.8.9/doc/ipmitool.1 ---- ipmitool-1.8.9.orig/doc/ipmitool.1 2007-03-06 15:15:36.000000000 -0700 -+++ ipmitool-1.8.9/doc/ipmitool.1 2008-12-08 18:11:56.000000000 -0700 -@@ -39,7 +39,7 @@ chassis power control. - IPMI management of a local system interface requires a compatible IPMI - kernel driver to be installed and configured. On Linux this driver is - called \fIOpenIPMI\fP and it is included in standard distributions. --On Solaris this driver is called \fIBMC\fP and is inclued in Solaris 10. -+On Solaris this driver is called \fIBMC\fP and is included in Solaris 10. - Management of a remote station requires the IPMI\-over\-LAN interface to be - enabled and configured. Depending on the particular requirements of each - system it may be possible to enable the LAN interface using ipmitool over diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..e4df9d3 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,5 @@ +10_ipmi_lanp +20_ipmi_isol +20_ipmi_impi +20_ipmi_sdr +99_readme_typo diff --git a/debian/rules b/debian/rules index adbc323..255653e 100755 --- a/debian/rules +++ b/debian/rules @@ -1,5 +1,7 @@ #!/usr/bin/make -f +include /usr/share/quilt/quilt.make + #export DH_VERBOSE=1 export DH_OPTIONS @@ -15,8 +17,10 @@ ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) endif configure: configure-stamp -configure-stamp: patch-stamp +configure-stamp: patch dh_testdir + cp /usr/share/misc/config.sub config.sub + cp /usr/share/misc/config.guess config.guess ./configure --prefix=/usr \ --with-kerneldir \ --mandir=/usr/share/man @@ -43,6 +47,7 @@ clean: unpatch dh_testdir dh_testroot rm -f build-arch-stamp build-indep-stamp configure-stamp + rm -f config.sub config.guess # Add here commands to clean up after the build process. if [ -f Makefile ]; then $(MAKE) distclean; fi @@ -105,5 +110,3 @@ binary-arch: build-arch install-arch binary: binary-arch #binary-indep .PHONY: build build-arch build-indep clean binary-indep binary-arch binary install install-indep install-arch configure - -include /usr/share/dpatch/dpatch.make -- cgit v1.2.3