Hello, all,The attached patch adds a OEM handle and workaround code for Intel i82751 MAC working in the super pass-though mode which has known deviations in its RMCP+ implementation. With the OEM handle active, IPMITool can successfully interact with this Intel 82751-based boards.
Please, review. Regards, Dmitry
diff -Nurp ipmitool.sav/lib/ipmi_oem.c ipmitool.cvs/lib/ipmi_oem.c --- ipmitool.sav/lib/ipmi_oem.c 2013-04-15 15:12:11 +0600 +++ ipmitool.cvs/lib/ipmi_oem.c 2013-04-17 22:47:19 +0600 @@ -63,6 +63,10 @@ static struct ipmi_oem_handle ipmi_oem_l desc: "IBM OEM support", setup: ipmi_oem_ibm, }, + { + name: "i82571spt", + desc: "Intel 82571 MAC with integrated RMCP+ support in super pass-through mode", + }, { 0 } }; diff -Nurp ipmitool.sav/lib/ipmi_sol.c ipmitool.cvs/lib/ipmi_sol.c --- ipmitool.sav/lib/ipmi_sol.c 2013-04-15 15:12:11 +0600 +++ ipmitool.cvs/lib/ipmi_sol.c 2013-04-17 22:45:59 +0600 @@ -1568,6 +1568,8 @@ ipmi_sol_red_pill(struct ipmi_intf * int FD_SET(0, &read_fds); FD_SET(intf->fd, &read_fds); + if (!ipmi_oem_active(intf,"i82571spt")) + { /* Send periodic keepalive packet */ if(_use_sol_for_keepalive == 0) { @@ -1604,7 +1606,7 @@ ipmi_sol_red_pill(struct ipmi_intf * int /* if the keep Alive is successful reset retries to zero */ retrySol = 0; } - + } /* !oem="i82571spt" */ /* Wait up to half a second */ tv.tv_sec = 0; tv.tv_usec = 500000; @@ -1757,6 +1759,20 @@ ipmi_sol_activate(struct ipmi_intf * int if (ipmi_oem_active(intf, "intelplus")) { data[2] |= IPMI_SOL_BMC_ASSERTS_CTS_MASK_TRUE; + } else if (ipmi_oem_active(intf, "i82571spt")) { + /* + * A quote from Intel: "Engineering believes the problem + * lies within the Auxiliary data being sent with the + * 'Activate Payload' command from IPMITool. IPMITool + * sends a C6h which sets some bits having to do with + * encryption and some behavior dealing with CTS DCD/DSR. + * I recommend that the customer modify this request + * to send 08h instead. This is what our internal utility + * sends and it works without issue. I will work with + * engineering to ensure the settings that IPMITool uses + * (C6h) are supported in the future. + */ + data[2] = 0x08; } else { data[2] |= IPMI_SOL_BMC_ASSERTS_CTS_MASK_FALSE; } diff -Nurp ipmitool.sav/src/plugins/lanplus/lanplus.c ipmitool.cvs/src/plugins/lanplus/lanplus.c --- ipmitool.sav/src/plugins/lanplus/lanplus.c 2013-04-15 15:12:11 +0600 +++ ipmitool.cvs/src/plugins/lanplus/lanplus.c 2013-04-17 22:45:59 +0600 @@ -3157,7 +3157,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * in } /* Generate our Session Integrity Key, K1, and K2 */ - if (lanplus_generate_sik(session)) + if (lanplus_generate_sik(session, intf)) { /* Error */ lprintf(LOG_INFO, "> Error generating session integrity key"); @@ -3408,7 +3408,8 @@ ipmi_lanplus_open(struct ipmi_intf * int * * I'm not sure why we accept a failure for the first call */ - if (ipmi_get_auth_capabilities_cmd(intf, &auth_cap)) { + if (!ipmi_oem_active(intf, "i82571spt") && + ipmi_get_auth_capabilities_cmd(intf, &auth_cap)) { sleep(1); if (ipmi_get_auth_capabilities_cmd(intf, &auth_cap)); { @@ -3418,7 +3419,7 @@ ipmi_lanplus_open(struct ipmi_intf * int } } - if (! auth_cap.v20_data_available) + if (!ipmi_oem_active(intf, "i82571spt") && ! auth_cap.v20_data_available) { lprintf(LOG_INFO, "This BMC does not support IPMI v2 / RMCP+"); goto fail; @@ -3455,9 +3456,11 @@ ipmi_lanplus_open(struct ipmi_intf * int bridgePossible = 1; - rc = ipmi_set_session_privlvl_cmd(intf); - if (rc < 0) - goto fail; + if (!ipmi_oem_active(intf, "i82571spt")) { + rc = ipmi_set_session_privlvl_cmd(intf); + if (rc < 0) + goto fail; + } intf->manufacturer_id = ipmi_get_oem(intf); return intf->fd; diff -Nurp ipmitool.sav/src/plugins/lanplus/lanplus_crypt.c ipmitool.cvs/src/plugins/lanplus/lanplus_crypt.c --- ipmitool.sav/src/plugins/lanplus/lanplus_crypt.c 2013-04-15 15:12:12 +0600 +++ ipmitool.cvs/src/plugins/lanplus/lanplus_crypt.c 2013-04-17 22:45:59 +0600 @@ -153,6 +153,15 @@ int lanplus_rakp2_hmac_matches(const str /* ROLEm */ buffer[56] = session->v2_data.requested_role; + if (ipmi_oem_active(intf, "i82571spt")) { + /* + * The HMAC calculation code in the Intel 82571 GbE + * skips this bit! Looks like a GbE bug, but we need + * to work around it here anyway... + */ + buffer[56] &= ~0x10; + } + /* ULENGTHm */ buffer[57] = strlen((const char *)session->username); @@ -396,7 +405,7 @@ int lanplus_generate_rakp3_authcode(uint memcpy(input_buffer + 16, &SIDm_lsbf, 4); /* ROLEm */ - if (ipmi_oem_active(intf, "intelplus")) + if (ipmi_oem_active(intf, "intelplus") || ipmi_oem_active(intf, "i82571spt")) input_buffer[20] = session->privlvl; else input_buffer[20] = session->v2_data.requested_role; @@ -460,7 +469,7 @@ int lanplus_generate_rakp3_authcode(uint * returns 0 on success * 1 on failure */ -int lanplus_generate_sik(struct ipmi_session * session) +int lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf) { uint8_t * input_buffer; int input_buffer_length, i; @@ -516,6 +525,15 @@ int lanplus_generate_sik(struct ipmi_ses /* ROLEm */ input_buffer[32] = session->v2_data.requested_role; + if (ipmi_oem_active(intf, "i82571spt")) { + /* + * The HMAC calculation code in the Intel 82571 GbE + * skips this bit! Looks like a GbE bug, but we need + * to work around it here anyway... + */ + input_buffer[32] &= ~0x10; + } + /* ULENGTHm */ input_buffer[33] = strlen((const char *)session->username); @@ -897,7 +915,7 @@ int lanplus_decrypt_payload(uint8_t */ for (i = 0; i < conf_pad_length; ++i) { - if (decrypted_payload[*payload_size + i] == i) + if (decrypted_payload[*payload_size + i] != (i + 1)) { lprintf(LOG_ERR, "Malformed payload padding"); assert(0); diff -Nurp ipmitool.sav/src/plugins/lanplus/lanplus_crypt.h ipmitool.cvs/src/plugins/lanplus/lanplus_crypt.h --- ipmitool.sav/src/plugins/lanplus/lanplus_crypt.h 2006-03-20 02:54:44 +0600 +++ ipmitool.cvs/src/plugins/lanplus/lanplus_crypt.h 2013-04-17 22:45:59 +0600 @@ -51,7 +51,7 @@ int lanplus_generate_rakp3_authcode(uint const struct ipmi_session * session, uint32_t * auth_length, struct ipmi_intf * intf); -int lanplus_generate_sik(struct ipmi_session * session); +int lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf); int lanplus_generate_k1(struct ipmi_session * session); int lanplus_generate_k2(struct ipmi_session * session); int lanplus_encrypt_payload(uint8_t crypt_alg,
------------------------------------------------------------------------------ Precog is a next-generation analytics platform capable of advanced analytics on semi-structured data. The platform includes APIs for building apps and a phenomenal toolset for data science. Developers can use our toolset for easy data analysis & visualization. Get a free account! http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________ Ipmitool-devel mailing list Ipmitool-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ipmitool-devel