diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ipmievd.c | 5 | ||||
-rw-r--r-- | src/ipmitool.c | 2 | ||||
-rw-r--r-- | src/plugins/imb/imbapi.c | 2895 | ||||
-rw-r--r-- | src/plugins/ipmi_intf.c | 10 | ||||
-rw-r--r-- | src/plugins/lanplus/lanplus.c | 126 | ||||
-rw-r--r-- | src/plugins/lanplus/lanplus.h | 18 | ||||
-rw-r--r-- | src/plugins/lanplus/lanplus_crypt.c | 196 | ||||
-rw-r--r-- | src/plugins/lanplus/lanplus_crypt_impl.c | 11 | ||||
-rw-r--r-- | src/plugins/lanplus/lanplus_dump.c | 39 | ||||
-rw-r--r-- | src/plugins/open/open.c | 2 | ||||
-rw-r--r-- | src/plugins/serial/serial_basic.c | 8 | ||||
-rw-r--r-- | src/plugins/serial/serial_terminal.c | 11 |
12 files changed, 1467 insertions, 1856 deletions
diff --git a/src/ipmievd.c b/src/ipmievd.c index caefd95..67788e5 100644 --- a/src/ipmievd.c +++ b/src/ipmievd.c @@ -239,8 +239,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt) return; } - type = ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, - evt->sel_type.standard_type.event_data[0]); + type = ipmi_get_sensor_type(intf, evt->sel_type.standard_type.sensor_type); ipmi_get_event_desc(intf, evt, &desc); @@ -333,7 +332,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt) break; default: - lprintf(LOG_NOTICE, "%s%s sensor - %s", + lprintf(LOG_NOTICE, "%s%s sensor (0x%02x) - %s", eintf->prefix, type, evt->sel_type.standard_type.sensor_num, desc ? desc : ""); break; diff --git a/src/ipmitool.c b/src/ipmitool.c index 164fd44..5e19c6e 100644 --- a/src/ipmitool.c +++ b/src/ipmitool.c @@ -77,6 +77,7 @@ extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv); extern int ipmi_echo_main(struct ipmi_intf * intf, int argc, char ** argv); extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv); extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv); +extern int ipmi_lan6_main(struct ipmi_intf *intf, int argc, char **argv); int csv_output = 0; @@ -122,6 +123,7 @@ struct ipmi_cmd ipmitool_cmd_list[] = { { ipmi_ekanalyzer_main,"ekanalyzer", "run FRU-Ekeying analyzer using FRU files"}, { ipmi_ime_main, "ime", "Update Intel Manageability Engine Firmware"}, { ipmi_vita_main, "vita", "Run a VITA 46.11 extended cmd"}, + { ipmi_lan6_main, "lan6", "Configure IPv6 LAN Channels"}, { NULL }, }; diff --git a/src/plugins/imb/imbapi.c b/src/plugins/imb/imbapi.c index 84eec2e..34c9c82 100644 --- a/src/plugins/imb/imbapi.c +++ b/src/plugins/imb/imbapi.c @@ -1,1889 +1,1307 @@ -/*M* -// PVCS: -// $Workfile: imbapi.c $ -// $Revision: 1.5 $ -// $Modtime: 06 Aug 2001 13:16:56 $ -// $Author: stybla $ -// -// Purpose: This file contains the entry point that opens the IMB device in -// order to issue the IMB driver API related IOCTLs. -// This file implements the IMB driver API for the Server -// Management Agents -// -// -*M*/ -/*----------------------------------------------------------------------* -The BSD License -Copyright (c) 2002, Intel Corporation -All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - a.. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - b.. Redistributions 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. - c.. Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *----------------------------------------------------------------------*/ /* - * $Log: imbapi.c,v $ - * Revision 1.5 2013/07/22 08:35:23 stybla - * ID: 65 - Fixes for configure.in for cross compilation + * Copyright (c) 2002, Intel Corporation * - * 'src/plugins/imb/imbapi.c' - don't cast NULL to int, ever!!! + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * Revision 1.4 2013/07/21 11:33:57 stybla - * ID: 65 - Fixes for configure.in for cross compilation + * Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * NULL should never be cast to an int. + * 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. * - * Commit for Dan Gora + * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Revision 1.3 2013/01/18 12:46:52 ledva - * 3600962 descriptor leaks - * - * Revision 1.2 2004/08/31 23:52:58 iceblink - * fix lots of little errors that show up with -Werror -Wall - * - * Revision 1.1 2004/08/27 16:33:25 iceblink - * add support for Intel IMB kernel driver (for legacy kernel support) - * imbapi.[ch] code is BSD licensed and taken from panicsel.sf.net - * - * - * Rev 1.12ac 04 Apr 2002 13:17:58 arcress - * Mods for open-source & various compile cleanup mods - * - * Rev 1.12 06 Aug 2001 13:17:58 spoola - * Fixed tracker items #15667, #15666, #15664 - * - * Rev 1.0 05 Sep 1999 17:20:30 mramacha - * Linux checkin - * - * Note: This file is derived from the NTWORK version of the imbapi.c - * It was decided to create OS specific ones for Linux and Solaris. - * It has all the fixes that went into the imbapi.c up to Rev 1.12 - * in the 2.2 NTWORK branch. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* Purpose: This file contains the entry point that opens the IMB device in + * order to issue the IMB driver API related IOCTLs. This file implements the + * IMB driver API for the Server Management Agents + */ + + +/* Use -DLINUX_DEBUG_MAX in the Makefile, resp. CFLAGS if you want a dump of the + * memory to debug mmap system call in MapPhysicalMemory() below. */ #define IMB_API #ifdef WIN32 -#define NO_MACRO_ARGS 1 -#include <windows.h> -#include <stdio.h> - -#else /* LINUX, SCO_UW, UNIX */ -#include <unistd.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> +# define NO_MACRO_ARGS 1 +# include <stdio.h> +# include <windows.h> +#else /* LINUX, SCO_UW, UNIX */ +# include <fcntl.h> +# include <stdio.h> +# include <stdlib.h> +# include <string.h> +# include <sys/ioctl.h> +# include <sys/mman.h> +# include <sys/param.h> +# include <sys/stat.h> +# include <sys/types.h> +# include <unistd.h> #endif + #include "imbapi.h" #include <sys/socket.h> +#include <ipmitool/log.h> #ifdef SCO_UW -#define NO_MACRO_ARGS 1 -#define __FUNCTION__ "func" -#define IMB_DEVICE "/dev/instru/mismic" +# define NO_MACRO_ARGS 1 +# define __FUNCTION__ "func" +# define IMB_DEVICE "/dev/instru/mismic" #else -#define IMB_DEVICE "/dev/imb" +# define IMB_DEVICE "/dev/imb" #endif #if !defined(PAGESIZE) && defined(PAGE_SIZE) -# define PAGESIZE PAGE_SIZE +# define PAGESIZE PAGE_SIZE #endif #if !defined(_SC_PAGESIZE) && defined(_SC_PAGE_SIZE) -# define _SC_PAGESIZE _SC_PAGE_SIZE -#endif - -/*Just to make the DEBUG code cleaner.*/ -#ifndef NO_MACRO_ARGS -#ifdef LINUX_DEBUG -#define DEBUG(format, args...) printf(format, ##args) -#else -#define DEBUG(format, args...) +# define _SC_PAGESIZE _SC_PAGE_SIZE #endif -#endif - -/* uncomment out the #define below or use -DLINUX_DEBUG_MAX in the makefile -// if you want a dump of the memory to debug mmap system call in -// MapPhysicalMemory() below. -// -//#define LINUX_DEBUG_MAX */ - -/*keep it simple. use global varibles for event objects and handles -//pai 10/8 */ - -/* UnixWare should eventually have its own source code file. Right now -// new code has been added based on the exsisting policy of using -// pre-processor directives to separate os-specific code (pai 11/21) */ - -HANDLE AsyncEventHandle = 0; -//static void * AsyncEventObject = 0; +HANDLE AsyncEventHandle = 0; static int IpmiVersion; -/*//////////////////////////////////////////////////////////////////////////// -// GLOBAL VARIABLES -///////////////////////////////////////////////////////////////////////////// */ - -IO_STATUS_BLOCK NTstatus; /*dummy place holder. See deviceiocontrol. */ +/* GLOBAL VARIABLES */ +/* dummy place holder. See deviceiocontrol. */ +IO_STATUS_BLOCK NTstatus; static HANDLE hDevice1; static HANDLE hDevice; -/*mutex_t deviceMutex; */ -static int fDriverTyp; /*from ipmicmd.c*/ +static int fDriverTyp; /* from ipmicmd.c */ -/*//////////////////////////////////////////////////////////////////// -// open_imb -////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: open_imb -// Purpose: To open imb device -// Context: Called from each routine to make sure that open is done. -// Returns: returns 0 for Fail and 1 for Success, sets hDevice to open -// handle. -// Parameters: none -// Notes: none -*F*/ +/* open_imb - Open IMB device. Called from each routine to make sure that open + * is done. + * + * Returns: returns 0 for Fail and 1 for Success, sets hDevice to open handle. + */ #ifdef WIN32 -int open_imb(void) +int +open_imb(void) { -/* This routine will be called from all other routines before doing any - interfacing with imb driver. It will open only once. */ - IMBPREQUESTDATA requestData; - BYTE respBuffer[16]; - DWORD respLength; - BYTE completionCode; - - if (hDevice1 == 0) /*INVALID_HANDLE_VALUE*/ - { - // - // Open IMB driver device - // - hDevice = CreateFile( "\\\\.\\Imb", - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL - ); - if (hDevice == NULL || hDevice == INVALID_HANDLE_VALUE) - return (0); /*FALSE*/ - - // Detect the IPMI version for processing requests later. - // This is a crude but most reliable method to differentiate - // between old IPMI versions and the 1.0 version. If we had used the - // version field instead then we would have had to revalidate all the - // older platforms (pai 4/27/99) - requestData.cmdType = GET_DEVICE_ID; - requestData.rsSa = BMC_SA; - requestData.rsLun = BMC_LUN; - requestData.netFn = APP_NETFN ; - requestData.busType = PUBLIC_BUS; - requestData.data = NULL; - requestData.dataLength = 0; - respLength = 16; - if ( (SendTimedImbpRequest ( &requestData, (DWORD)400, - respBuffer, &respLength, &completionCode - ) != ACCESN_OK ) || ( completionCode != 0) ) - { - CloseHandle(hDevice); - return (0); /*FALSE*/ - } - hDevice1 = hDevice; + /* This routine will be called from all other routines before doing any + * interfacing with imb driver. It will open only once. + */ + IMBPREQUESTDATA requestData; + BYTE respBuffer[16]; + DWORD respLength; + BYTE completionCode; - if (respLength < (IPMI10_GET_DEVICE_ID_RESP_LENGTH-1)) - IpmiVersion = IPMI_09_VERSION; - else { - if ( respBuffer[4] == 0x51 ) - IpmiVersion = IPMI_15_VERSION; - else - IpmiVersion = IPMI_10_VERSION; - } - } - return (1); /*TRUE*/ + if (hDevice1 != 0) { + return 1; + } -} /*end open_imb for Win32 */ + /* Open IMB driver device */ + hDevice = CreateFile("\\\\.\\Imb", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hDevice == NULL || hDevice == INVALID_HANDLE_VALUE) { + return 0; + } + /* Detect the IPMI version for processing requests later. This + * is a crude but most reliable method to differentiate between + * old IPMI versions and the 1.0 version. If we had used the + * version field instead then we would have had to revalidate + * all the older platforms (pai 4/27/99) + */ + requestData.cmdType = GET_DEVICE_ID; + requestData.rsSa = BMC_SA; + requestData.rsLun = BMC_LUN; + requestData.netFn = APP_NETFN ; + requestData.busType = PUBLIC_BUS; + requestData.data = NULL; + requestData.dataLength = 0; + respLength = 16; + if ((SendTimedImbpRequest(&requestData, (DWORD)400, respBuffer, + &respLength, &completionCode) != ACCESN_OK) + || (completionCode != 0)) { + CloseHandle(hDevice); + return 0; + } + hDevice1 = hDevice; + if (respLength < (IPMI10_GET_DEVICE_ID_RESP_LENGTH - 1)) { + IpmiVersion = IPMI_09_VERSION; + } else { + if (respBuffer[4] == 0x51) { + IpmiVersion = IPMI_15_VERSION; + } else { + IpmiVersion = IPMI_10_VERSION; + } + } + return 1; +} /* end open_imb for Win32 */ #else /* LINUX, SCO_UW, etc. */ -int open_imb(void) +int +open_imb(void) { -/* This routine will be called from all other routines before doing any - interfacing with imb driver. It will open only once. */ - IMBPREQUESTDATA requestData; - BYTE respBuffer[16]; - DWORD respLength; - BYTE completionCode; - + /* This routine will be called from all other routines before doing any + * interfacing with imb driver. It will open only once. + */ + IMBPREQUESTDATA requestData; + BYTE respBuffer[16]; + DWORD respLength; + BYTE completionCode; int my_ret_code; - if (hDevice1 == 0) - { -#ifndef NO_MACRO_ARGS - DEBUG("%s: opening the driver\n", __FUNCTION__); -#endif - /* - printf("open_imb: " + if (hDevice1 != 0) { + return 1; + } + lprintf(LOG_DEBUG, "%s: opening the driver", __FUNCTION__); + /* printf("open_imb: " "IOCTL_IMB_SEND_MESSAGE =%x \n" "IOCTL_IMB_GET_ASYNC_MSG=%x \n" "IOCTL_IMB_MAP_MEMORY = %x \n" "IOCTL_IMB_UNMAP_MEMORY= %x \n" "IOCTL_IMB_SHUTDOWN_CODE=%x \n" "IOCTL_IMB_REGISTER_ASYNC_OBJ =%x \n" "IOCTL_IMB_DEREGISTER_ASYNC_OBJ=%x \n" "IOCTL_IMB_CHECK_EVENT =%x \n" "IOCTL_IMB_POLL_ASYNC =%x \n", - IOCTL_IMB_SEND_MESSAGE, IOCTL_IMB_GET_ASYNC_MSG, + IOCTL_IMB_SEND_MESSAGE, IOCTL_IMB_GET_ASYNC_MSG, IOCTL_IMB_MAP_MEMORY, IOCTL_IMB_UNMAP_MEMORY, IOCTL_IMB_SHUTDOWN_CODE, IOCTL_IMB_REGISTER_ASYNC_OBJ, IOCTL_IMB_DEREGISTER_ASYNC_OBJ, - IOCTL_IMB_CHECK_EVENT , IOCTL_IMB_POLL_ASYNC); *%%%%*/ - - /*O_NDELAY flag will cause problems later when driver makes - //you wait. Hence removing it. */ - /*if ((hDevice1 = open(IMB_DEVICE,O_RDWR|O_NDELAY)) <0) */ - if ((hDevice1 = open(IMB_DEVICE,O_RDWR)) <0) - { - char buf[128]; - - hDevice1 = 0; - if (fDriverTyp != 0) { /*not 1st time*/ - sprintf(buf,"%s %s: open(%s) failed", - __FILE__,__FUNCTION__,IMB_DEVICE); - perror(buf); - } - return (0); - } - - /* Detect the IPMI version for processing requests later. - // This is a crude but most reliable method to differentiate - // between old IPMI versions and the 1.0 version. If we had used the - // version field instead then we would have had to revalidate all - // the older platforms (pai 4/27/99) */ - requestData.cmdType = GET_DEVICE_ID; - requestData.rsSa = BMC_SA; - requestData.rsLun = BMC_LUN; - requestData.netFn = APP_NETFN ; - requestData.busType = PUBLIC_BUS; - requestData.data = NULL; - requestData.dataLength = 0; - respLength = 16; -#ifndef NO_MACRO_ARGS - DEBUG("%s: opened driver, getting IPMI version\n", __FUNCTION__); -#endif - if ( ((my_ret_code = SendTimedImbpRequest(&requestData, (DWORD)400, - respBuffer, (int *)&respLength, &completionCode) - ) != ACCESN_OK ) || ( completionCode != 0) ) - { - printf("%s: SendTimedImbpRequest error. Ret = %d CC = 0x%X\n", - __FUNCTION__, my_ret_code, completionCode); - close(hDevice1); - hDevice1 = 0; - return (0); - } + IOCTL_IMB_CHECK_EVENT , IOCTL_IMB_POLL_ASYNC); + */ - if (respLength < (IPMI10_GET_DEVICE_ID_RESP_LENGTH-1)) - IpmiVersion = IPMI_09_VERSION; - else { - if ( respBuffer[4] == 0x51 ) - IpmiVersion = IPMI_15_VERSION; - else - IpmiVersion = IPMI_10_VERSION; - } -#ifndef NO_MACRO_ARGS - DEBUG("%s: IPMI version 0x%x\n", __FUNCTION__, IpmiVersion); -#endif - -/* -//initialise a mutex - if(mutex_init(&deviceMutex , USYNC_THREAD, NULL) != 0) - { - return(0); + /* O_NDELAY flag will cause problems later when driver makes + * you wait. Hence removing it. + */ + if ((hDevice1 = open(IMB_DEVICE, O_RDWR)) < 0) { + char buf[128]; + hDevice1 = 0; + if (fDriverTyp != 0) { + /* not 1st time */ + sprintf(buf,"%s %s: open(%s) failed", + __FILE__, __FUNCTION__, IMB_DEVICE); + perror(buf); } -*/ + return 0; + } + /* Detect the IPMI version for processing requests later. + * This is a crude but most reliable method to differentiate + * between old IPMI versions and the 1.0 version. If we had used the + * version field instead then we would have had to revalidate all + * the older platforms (pai 4/27/99) + */ + requestData.cmdType = GET_DEVICE_ID; + requestData.rsSa = BMC_SA; + requestData.rsLun = BMC_LUN; + requestData.netFn = APP_NETFN ; + requestData.busType = PUBLIC_BUS; + requestData.data = NULL; + requestData.dataLength = 0; + respLength = 16; + lprintf(LOG_DEBUG, "%s: opened driver, getting IPMI version", __FUNCTION__); + if (((my_ret_code = SendTimedImbpRequest(&requestData, (DWORD)400, + respBuffer, + (int *)&respLength, + &completionCode)) != ACCESN_OK) + || (completionCode != 0)) { + printf("%s: SendTimedImbpRequest error. Ret = %d CC = 0x%X\n", + __FUNCTION__, my_ret_code, completionCode); + close(hDevice1); + hDevice1 = 0; + return 0; + } + if (respLength < (IPMI10_GET_DEVICE_ID_RESP_LENGTH - 1)) { + IpmiVersion = IPMI_09_VERSION; + } else { + if (respBuffer[4] == 0x51) { + IpmiVersion = IPMI_15_VERSION; + } else { + IpmiVersion = IPMI_10_VERSION; + } } - - return (1); -} /*end open_imb()*/ + lprintf(LOG_DEBUG, "%s: IPMI version 0x%x", __FUNCTION__, + IpmiVersion); + return 1; +} /* end open_imb() */ #endif -/*---------------------------------------------------------------------* - * ipmi_open_ia & ipmi_close_ia - *---------------------------------------------------------------------*/ -int ipmi_open_ia(void) +/* ipmi_open_ia */ +int +ipmi_open_ia(void) { - int rc = 0; - rc = open_imb(); /*sets hDevice1*/ - if (rc == 1) rc = 0; - else rc = -1; - return(rc); + int rc = 0; + /* sets hDevice1 */ + rc = open_imb(); + if (rc == 1) { + rc = 0; + } else { + rc = -1; + } + return rc; } -int ipmi_close_ia(void) +/* ipmi_close_ia */ +int +ipmi_close_ia(void) { - int rc = 0; - if (hDevice1 != 0) { + int rc = 0; + if (hDevice1 != 0) { #ifdef WIN32 - CloseHandle(hDevice1); + CloseHandle(hDevice1); #else - rc = close(hDevice1); + rc = close(hDevice1); #endif - } - return(rc); + } + return rc; } #ifndef WIN32 -/*/////////////////////////////////////////////////////////////////////////// -// DeviceIoControl -///////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: DeviceIoControl -// Purpose: Simulate NT DeviceIoControl using unix calls and structures. -// Context: called for every NT DeviceIoControl -// Returns: FALSE for fail and TRUE for success. Same as standarad NTOS call -// as it also sets Ntstatus.status. -// Parameters: Standard NT call parameters, see below. -// Notes: none -*F*/ +/* DeviceIoControl - Simulate NT DeviceIoControl using unix calls and structures. + * + * @dummy_hDevice - handle of device + * @dwIoControlCode - control code of operation to perform + * @lpvInBuffer, address of buffer for input data + * @cbInBuffer, size of input buffer + * @lpvOutBuffer, address of output buffer + * @cbOutBuffer, size of output buffer + * @lpcbBytesReturned, address of actual bytes of output + * @lpoOverlapped address of overlapped struct + * + * returns - FALSE for fail and TRUE for success. Same as standarad NTOS call as + * it also sets Ntstatus.status. + */ static BOOL -DeviceIoControl( - HANDLE dummey_hDevice, /* handle of device */ - DWORD dwIoControlCode, /* control code of operation to perform*/ - LPVOID lpvInBuffer, /* address of buffer for input data */ - DWORD cbInBuffer, /* size of input buffer */ - LPVOID lpvOutBuffer, /* address of output buffer */ - DWORD cbOutBuffer, /* size of output buffer */ - LPDWORD lpcbBytesReturned, /* address of actual bytes of output */ - LPOVERLAPPED lpoOverlapped /* address of overlapped struct */ - ) +DeviceIoControl(HANDLE dummey_hDevice, DWORD dwIoControlCode, LPVOID + lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, + DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, + LPOVERLAPPED lpoOverlapped) { struct smi s; int rc; int ioctl_status; - rc = open_imb(); - if (rc == 0) { - return FALSE; - } + rc = open_imb(); + if (rc == 0) { + return FALSE; + } + lprintf(LOG_DEBUG, "%s: ioctl cmd = 0x%lx", __FUNCTION__, + dwIoControlCode); + lprintf(LOG_DEBUG, "cbInBuffer %d cbOutBuffer %d", cbInBuffer, + cbOutBuffer); + if (cbInBuffer > 41) { + cbInBuffer = 41; /* Intel driver max buf */ + } - /* - //lock the mutex, before making the request.... - if(mutex_lock(&deviceMutex) != 0) - { - return(FALSE); - } - */ -#ifndef NO_MACRO_ARGS - DEBUG("%s: ioctl cmd = 0x%lx ", __FUNCTION__,dwIoControlCode); - DEBUG("cbInBuffer %d cbOutBuffer %d\n", cbInBuffer, cbOutBuffer); -#endif - if (cbInBuffer > 41) cbInBuffer = 41; /* Intel driver max buf */ - - s.lpvInBuffer = lpvInBuffer; - s.cbInBuffer = cbInBuffer; - s.lpvOutBuffer = lpvOutBuffer; - s.cbOutBuffer = cbOutBuffer; - s.lpcbBytesReturned = lpcbBytesReturned; - s.lpoOverlapped = lpoOverlapped; - s.ntstatus = (LPVOID)&NTstatus; /*dummy place holder. Linux IMB driver - //doesnt return status or info via it.*/ - - if ( (ioctl_status = ioctl(hDevice1, dwIoControlCode,&s) ) <0) { -#ifndef NO_MACRO_ARGS - DEBUG("%s %s: ioctl cmd = 0x%x failed", - __FILE__,__FUNCTION__,dwIoControlCode); -#endif - /* mutex_unlock(&deviceMutex); */ - return FALSE; - } - /* mutex_unlock(&deviceMutex); */ - -#ifndef NO_MACRO_ARGS - DEBUG("%s: ioctl_status %d bytes returned = %d \n", - __FUNCTION__, ioctl_status, *lpcbBytesReturned); -#endif + s.lpvInBuffer = lpvInBuffer; + s.cbInBuffer = cbInBuffer; + s.lpvOutBuffer = lpvOutBuffer; + s.cbOutBuffer = cbOutBuffer; + s.lpcbBytesReturned = lpcbBytesReturned; + s.lpoOverlapped = lpoOverlapped; + /* dummy place holder. Linux IMB driver doesnt return status or info + * via it + */ + s.ntstatus = (LPVOID)&NTstatus; -/*MR commented this just as in Sol1.10. lpcbBytesReturned has the right data -// *lpcbBytesReturned = NTstatus.Information; */ - + if ((ioctl_status = ioctl(hDevice1, dwIoControlCode,&s)) < 0) { + lprintf(LOG_DEBUG, "%s %s: ioctl cmd = 0x%x failed", + __FILE__, __FUNCTION__, dwIoControlCode); + return FALSE; + } + lprintf(LOG_DEBUG, "%s: ioctl_status %d bytes returned = %d", + __FUNCTION__, ioctl_status, *lpcbBytesReturned); if (ioctl_status == STATUS_SUCCESS) { -#ifndef NO_MACRO_ARGS - DEBUG("%s returning true\n", __FUNCTION__); -#endif - return (TRUE); + lprintf(LOG_DEBUG, "%s returning true", __FUNCTION__); + return (TRUE); + } else { + lprintf(LOG_DEBUG, "%s returning false", __FUNCTION__); + return (FALSE); } - else { -#ifndef NO_MACRO_ARGS - DEBUG("%s returning false\n", __FUNCTION__); -#endif - return (FALSE); - } } #endif -/*Used only by UW. Left here for now. IMB driver will not accept this -//ioctl. */ +/* Used only by UW. Left here for now. IMB driver will not accept this ioctl. */ ACCESN_STATUS StartAsyncMesgPoll() { + DWORD retLength; + BOOL status; + lprintf(LOG_DEBUG, "%s: DeviceIoControl cmd = %x", + __FUNCTION__, IOCTL_IMB_POLL_ASYNC); - DWORD retLength; - BOOL status; - -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl cmd = %x\n",__FUNCTION__,IOCTL_IMB_POLL_ASYNC); -#endif - status = DeviceIoControl ( hDevice, - IOCTL_IMB_POLL_ASYNC, - NULL, - 0, - NULL, - 0, - & retLength, - 0 - ); - -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif + status = DeviceIoControl(hDevice, IOCTL_IMB_POLL_ASYNC, NULL, 0, NULL, + 0, &retLength, 0); - if( status == TRUE ) { + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if (status == TRUE) { return ACCESN_OK; } else { return ACCESN_ERROR; } - } -/*///////////////////////////////////////////////////////////////////////////// -// SendTimedI2cRequest -///////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: SendTimedI2cRequest -// Purpose: This function sends a request to a I2C device -// Context: Used by Upper level agents (sis modules) to access dumb I2c devices -// Returns: ACCESN_OK else error status code -// Parameters: -// reqPtr -// timeOut -// respDataPtr -// respLen -// Notes: none -*F*/ - +/* SendTimedI2cRequest - This function sends a request to a I2C device. Used by + * Upper level agents (sis modules) to access dumb I2c devices. + * + * @reqPtr - pointer to I2C request + * timeOut - how long to wait, mSec units + * @respDataPtr - where to put response data + * @respDataLen - size of response buffer and size of returned data + * @completionCode - request status from BMC + * + * returns - ACCESN_OK else error status code + */ ACCESN_STATUS -SendTimedI2cRequest ( - I2CREQUESTDATA *reqPtr, /* I2C request */ - int timeOut, /* how long to wait, mSec units */ - BYTE *respDataPtr, /* where to put response data */ - int *respDataLen, /* size of response buffer and */ - /* size of returned data */ - BYTE *completionCode /* request status from BMC */ - ) +SendTimedI2cRequest(I2CREQUESTDATA *reqPtr, int timeOut, BYTE *respDataPtr, + int *respDataLen, BYTE *completionCode) { - BOOL status; - BYTE responseData[MAX_IMB_RESP_SIZE]; - ImbResponseBuffer * resp = (ImbResponseBuffer *) responseData; - DWORD respLength = sizeof( responseData ); - BYTE requestData[MAX_IMB_RESP_SIZE]; - ImbRequestBuffer * req = (ImbRequestBuffer *) requestData; - - struct WriteReadI2C { /* format of a write/read I2C request */ +/* size of write/read request minus any data */ +# define MIN_WRI2C_SIZE 3 + BOOL status; + BYTE responseData[MAX_IMB_RESP_SIZE]; + ImbResponseBuffer *resp = (ImbResponseBuffer *)responseData; + DWORD respLength = sizeof(responseData); + BYTE requestData[MAX_IMB_RESP_SIZE]; + ImbRequestBuffer *req = (ImbRequestBuffer *)requestData; + + /* format of a write/read I2C request */ + struct WriteReadI2C { BYTE busType; BYTE rsSa; BYTE count; BYTE data[1]; - } * wrReq = (struct WriteReadI2C *) req->req.data; - -#define MIN_WRI2C_SIZE 3 /* size of write/read request minus any data */ - - - /* - // If the Imb driver is not present return AccessFailed - */ - - req->req.rsSa = BMC_SA; - req->req.cmd = WRITE_READ_I2C; - req->req.netFn = APP_NETFN; - req->req.rsLun = BMC_LUN; - req->req.dataLength = reqPtr->dataLength + MIN_WRI2C_SIZE; - - wrReq->busType = reqPtr->busType; - wrReq->rsSa = reqPtr->rsSa; - wrReq->count = reqPtr->numberOfBytesToRead; - - memcpy( wrReq->data, reqPtr->data, reqPtr->dataLength ); - - req->flags = 0; - req->timeOut = timeOut * 1000; /* convert to uSec units */ - - status = DeviceIoControl( hDevice, - IOCTL_IMB_SEND_MESSAGE, - requestData, - sizeof( requestData ), - & responseData, - sizeof( responseData ), - & respLength, - NULL - ); -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif - - if( status != TRUE ) { + } *wrReq = (struct WriteReadI2C *)req->req.data; + + /* If the IMB driver is not present return AccessFailed */ + req->req.rsSa = BMC_SA; + req->req.cmd = WRITE_READ_I2C; + req->req.netFn = APP_NETFN; + req->req.rsLun = BMC_LUN; + req->req.dataLength = reqPtr->dataLength + MIN_WRI2C_SIZE; + + wrReq->busType = reqPtr->busType; + wrReq->rsSa = reqPtr->rsSa; + wrReq->count = reqPtr->numberOfBytesToRead; + + memcpy(wrReq->data, reqPtr->data, reqPtr->dataLength); + + req->flags = 0; + /* convert to uSec units */ + req->timeOut = timeOut * 1000; + + status = DeviceIoControl(hDevice, IOCTL_IMB_SEND_MESSAGE, requestData, + sizeof(requestData), &responseData, + sizeof(responseData), &respLength, NULL); + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if (status != TRUE) { DWORD error; error = GetLastError(); return error; } - if( respLength == 0 ) { + if (respLength == 0) { return ACCESN_ERROR; } - - /* - // give the caller his response - */ + /* give the caller his response */ *completionCode = resp->cCode; - *respDataLen = respLength - 1; - - if(( *respDataLen ) && (respDataPtr)) - memcpy( respDataPtr, resp->data, *respDataLen); - + *respDataLen = respLength - 1; + if ((*respDataLen) && (respDataPtr)) { + memcpy(respDataPtr, resp->data, *respDataLen); + } return ACCESN_OK; - } -/*This is not a API exported by the driver in stricter sense. It is -//added to support EMP functionality. Upper level software could have -//implemented this function.(pai 5/4/99) */ -/*///////////////////////////////////////////////////////////////////////////// -// SendTimedEmpMessageResponse -///////////////////////////////////////////////////////////////////////////// */ - -/*F* -// Name: SendTimedEmpMessageResponse -// Purpose: This function sends a response message to the EMP port -// Context: -// Returns: OK else error status code -// Parameters: -// -// Notes: none -*F*/ - +/* SendTimedEmpMessageResponse - This function sends a response message to the + * EMP port. + * + * @ptr - pointer to the original request from EMP + * @responseDataBuf + * @responseDataLen + * @timeOut - how long to wait, in mSec units + * + * retruns - OK else error status code + */ ACCESN_STATUS -SendTimedEmpMessageResponse ( - ImbPacket *ptr, /* pointer to the original request from EMP */ - char *responseDataBuf, - int responseDataLen, - int timeOut /* how long to wait, in mSec units */ - ) +SendTimedEmpMessageResponse (ImbPacket *ptr, char *responseDataBuf, + int responseDataLen, int timeOut) { - BOOL status; - BYTE responseData[MAX_IMB_RESP_SIZE]; - /*ImbResponseBuffer * resp = (ImbResponseBuffer *) responseData; */ - DWORD respLength = sizeof( responseData ); - BYTE requestData[MAX_IMB_RESP_SIZE]; - ImbRequestBuffer * req = (ImbRequestBuffer *) requestData; - int i,j; - - /*form the response packet first */ - req->req.rsSa = BMC_SA; - if (IpmiVersion == IPMI_09_VERSION) - req->req.cmd = WRITE_EMP_BUFFER; - else - req->req.cmd = SEND_MESSAGE; - req->req.netFn = APP_NETFN; - req->req.rsLun = 0; + BOOL status; + BYTE responseData[MAX_IMB_RESP_SIZE]; + DWORD respLength = sizeof(responseData); + BYTE requestData[MAX_IMB_RESP_SIZE]; + ImbRequestBuffer *req = (ImbRequestBuffer *)requestData; + int i; + int j; + /* form the response packet first */ + req->req.rsSa = BMC_SA; + if (IpmiVersion == IPMI_09_VERSION) { + req->req.cmd = WRITE_EMP_BUFFER; + } else { + req->req.cmd = SEND_MESSAGE; + } + req->req.netFn = APP_NETFN; + req->req.rsLun = 0; i = 0; - if (IpmiVersion != IPMI_09_VERSION) - req->req.data[i++] = EMP_CHANNEL; - - req->req.data[i++] = ptr->rqSa; - req->req.data[i++] = (((ptr->nfLn & 0xfc) | 0x4) | ((ptr->seqLn) & 0x3)); - if (IpmiVersion == IPMI_09_VERSION) - req->req.data[i++] = ((~(req->req.data[0] + req->req.data[1])) +1); - else - req->req.data[i++] = ((~(req->req.data[1] + req->req.data[2])) +1); - - req->req.data[i++] = BMC_SA; /*though software is responding, we have to - //provide BMCs slave address as responder - //address. */ - - req->req.data[i++] = ( (ptr->seqLn & 0xfc) | (ptr->nfLn & 0x3) ); - - req->req.data[i++] = ptr->cmd; - for ( j = 0 ; j < responseDataLen ; ++j,++i) - req->req.data[i] = responseDataBuf[j]; - - req->req.data[i] = 0; - if (IpmiVersion == IPMI_09_VERSION) - j = 0; - else - j = 1; - for ( ; j < ( i -3); ++j) - req->req.data[i] += req->req.data[j+3]; - req->req.data[i] = ~(req->req.data[i]) +1; - ++i; - req->req.dataLength = i; - - req->flags = 0; - req->timeOut = timeOut * 1000; /* convert to uSec units */ - - - status = DeviceIoControl( hDevice, - IOCTL_IMB_SEND_MESSAGE, - requestData, - sizeof(requestData), - responseData, - sizeof( responseData ), - & respLength, - NULL - ); - -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif + if (IpmiVersion != IPMI_09_VERSION) { + req->req.data[i++] = EMP_CHANNEL; + } + req->req.data[i++] = ptr->rqSa; + req->req.data[i++] = (((ptr->nfLn & 0xfc) | 0x4) | ((ptr->seqLn) & 0x3)); + if (IpmiVersion == IPMI_09_VERSION) { + req->req.data[i++] = ((~(req->req.data[0] + req->req.data[1])) + 1); + } else { + req->req.data[i++] = ((~(req->req.data[1] + req->req.data[2])) + 1); + } + /* though software is responding, we have to provide BMCs slave address + * as responder address. + */ + req->req.data[i++] = BMC_SA; + req->req.data[i++] = ((ptr->seqLn & 0xfc) | (ptr->nfLn & 0x3)); + req->req.data[i++] = ptr->cmd; + for (j = 0; j < responseDataLen; ++j, ++i) { + req->req.data[i] = responseDataBuf[j]; + } - if ( (status != TRUE) || (respLength != 1) || (responseData[0] != 0) ) - { + req->req.data[i] = 0; + if (IpmiVersion == IPMI_09_VERSION) { + j = 0; + } else { + j = 1; + } + for (; j < (i - 3); ++j) { + req->req.data[i] += req->req.data[j + 3]; + } + req->req.data[i] = ~(req->req.data[i]) + 1; + ++i; + req->req.dataLength = i; + + req->flags = 0; + /* convert to uSec units */ + req->timeOut = timeOut * 1000; + status = DeviceIoControl(hDevice, IOCTL_IMB_SEND_MESSAGE, requestData, + sizeof(requestData), responseData, sizeof(responseData), + &respLength, NULL); + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if ((status != TRUE) || (respLength != 1) || (responseData[0] != 0)) { return ACCESN_ERROR; } return ACCESN_OK; } - -/*This is not a API exported by the driver in stricter sense. It is added to support -// EMP functionality. Upper level software could have implemented this function.(pai 5/4/99) */ -/*/////////////////////////////////////////////////////////////////////////// -// SendTimedEmpMessageResponse_Ex -//////////////////////////////////////////////////////////////////////////// */ - -/*F* -// Name: SendTimedEmpMessageResponse_Ex -// Purpose: This function sends a response message to the EMP port -// Context: -// Returns: OK else error status code -// Parameters: -// -// Notes: none -*F*/ - - - +/* SendTimedEmpMessageResponse_Ex - sends response message to the EMP port. + * + * @ptr - pointer to the original request from EMP + * @responseDataBuf + * @responseDataLen + * @timeOut - how long to wait, in mSec units + * @sessionHandle - This is introduced in IPMI1.5,this is required to be sent in + * sendd message command as a parameter, which is then used by BMC + * to identify the correct DPC session to send the mesage to. + * @channelNumber - There are 3 different channels on which DPC communication + * goes on: + * * Emp - 1 + * * Lan channel one - 6, + * * Lan channel two(primary channel) - 7 + * + * returns - OK else error status code + */ ACCESN_STATUS -SendTimedEmpMessageResponse_Ex ( - - ImbPacket * ptr, /* pointer to the original request from EMP */ - char *responseDataBuf, - int responseDataLen, - int timeOut, /* how long to wait, in mSec units*/ - BYTE sessionHandle, /*This is introduced in IPMI1.5,this is required to be sent in - //send message command as a parameter,which is then used by BMC - //to identify the correct DPC session to send the mesage to. */ - BYTE channelNumber /*There are 3 different channels on which DPC communication goes on - //Emp - 1,Lan channel one - 6,Lan channel two(primary channel) - 7. */ - ) +SendTimedEmpMessageResponse_Ex (ImbPacket *ptr, char *responseDataBuf, int + responseDataLen, int timeOut, BYTE sessionHandle, BYTE + channelNumber) { - BOOL status; - BYTE responseData[MAX_IMB_RESP_SIZE]; - /* ImbResponseBuffer * resp = (ImbResponseBuffer *) responseData; */ - DWORD respLength = sizeof( responseData ); - BYTE requestData[MAX_IMB_RESP_SIZE]; - ImbRequestBuffer * req = (ImbRequestBuffer *) requestData; - int i,j; - + BOOL status; + BYTE responseData[MAX_IMB_RESP_SIZE]; + DWORD respLength = sizeof(responseData); + BYTE requestData[MAX_IMB_RESP_SIZE]; + ImbRequestBuffer *req = (ImbRequestBuffer *)requestData; + int i; + int j; /*form the response packet first */ - req->req.rsSa = BMC_SA; - if (IpmiVersion == IPMI_09_VERSION) - req->req.cmd = WRITE_EMP_BUFFER; - else - req->req.cmd = SEND_MESSAGE; - req->req.netFn = APP_NETFN; - req->req.rsLun = 0; + req->req.rsSa = BMC_SA; + if (IpmiVersion == IPMI_09_VERSION) { + req->req.cmd = WRITE_EMP_BUFFER; + } else { + req->req.cmd = SEND_MESSAGE; + } + req->req.netFn = APP_NETFN; + req->req.rsLun = 0; i = 0; + /* checking for the IPMI version & then assigning the channel number for + * EMP. Actually the channel number is same in both the versions.This is + * just to maintain the consistancy with the same method for LAN. This + * is the 1st byte of the SEND MESSAGE command. + */ + if (IpmiVersion == IPMI_10_VERSION) { + req->req.data[i++] = EMP_CHANNEL; + } else if (IpmiVersion == IPMI_15_VERSION) { + req->req.data[i++] = channelNumber; + } - /*checking for the IPMI version & then assigning the channel number for EMP - //Actually the channel number is same in both the versions.This is just to - //maintain the consistancy with the same method for LAN. - //This is the 1st byte of the SEND MESSAGE command. */ - if (IpmiVersion == IPMI_10_VERSION) - req->req.data[i++] = EMP_CHANNEL; - else if (IpmiVersion == IPMI_15_VERSION) - req->req.data[i++] = channelNumber; - - /*The second byte of data for SEND MESSAGE starts with session handle */ + /* The second byte of data for SEND MESSAGE starts with session + * handle + */ req->req.data[i++] = sessionHandle; - - /*Then it is the response slave address for SEND MESSAGE. */ - req->req.data[i++] = ptr->rqSa; - - /*Then the net function + lun for SEND MESSAGE command. */ - req->req.data[i++] = (((ptr->nfLn & 0xfc) | 0x4) | ((ptr->seqLn) & 0x3)); - - /*Here the checksum is calculated.The checksum calculation starts after the channel number. - //so for the IPMI 1.5 version its a checksum of 3 bytes that is session handle,response slave - //address & netfun+lun. */ - if (IpmiVersion == IPMI_09_VERSION) - req->req.data[i++] = ((~(req->req.data[0] + req->req.data[1])) +1); - else - { - if (IpmiVersion == IPMI_10_VERSION) - req->req.data[i++] = ((~(req->req.data[1] + req->req.data[2])) +1); - else - req->req.data[i++] = ((~(req->req.data[2]+ req->req.data[3])) +1); - } - - /*This is the next byte of the message data for SEND MESSAGE command.It is the request - //slave address. */ - req->req.data[i++] = BMC_SA; /*though software is responding, we have to - //provide BMCs slave address as responder - //address. */ - - /*This is just the sequence number,which is the next byte of data for SEND MESSAGE */ - req->req.data[i++] = ( (ptr->seqLn & 0xfc) | (ptr->nfLn & 0x3) ); - - /*The next byte is the command like get software ID(00).*/ - req->req.data[i++] = ptr->cmd; - - /*after the cmd the data ,which is sent by DPC & is retrived using the get message earlier - // is sent back to DPC. */ - for ( j = 0 ; j < responseDataLen ; ++j,++i) - req->req.data[i] = responseDataBuf[j]; - - req->req.data[i] = 0; - - /*The last byte of data for SEND MESSAGE command is the check sum ,which is calculated - //from the next byte of the previous checksum that is the request slave address. */ - if (IpmiVersion == IPMI_09_VERSION) - j = 0; - else - { - if (IpmiVersion == IPMI_10_VERSION) + /* Then it is the response slave address for SEND MESSAGE. */ + req->req.data[i++] = ptr->rqSa; + /* Then the net function + lun for SEND MESSAGE command. */ + req->req.data[i++] = (((ptr->nfLn & 0xfc) | 0x4) | ((ptr->seqLn) & 0x3)); + /* Here the checksum is calculated.The checksum calculation starts after + * the channel number. So for the IPMI 1.5 version its a checksum of 3 + * bytes that is session handle,response slave address & netfun+lun. + */ + if (IpmiVersion == IPMI_09_VERSION) { + req->req.data[i++] = ((~(req->req.data[0] + req->req.data[1])) +1); + } else { + if (IpmiVersion == IPMI_10_VERSION) { + req->req.data[i++] = ((~(req->req.data[1] + req->req.data[2])) + 1); + } else { + req->req.data[i++] = ((~(req->req.data[2] + req->req.data[3])) + 1); + } + } + /* This is the next byte of the message data for SEND MESSAGE command.It + * is the request slave address. + */ + /* though software is responding, we have to provide BMCs slave address + * as responder address. + */ + req->req.data[i++] = BMC_SA; + /* This is just the sequence number,which is the next byte of data for + * SEND MESSAGE + */ + req->req.data[i++] = ((ptr->seqLn & 0xfc) | (ptr->nfLn & 0x3)); + /* The next byte is the command like get software ID(00). */ + req->req.data[i++] = ptr->cmd; + /* after the cmd the data, which is sent by DPC & is retrived using the + * get message earlier is sent back to DPC. + */ + for (j = 0; j < responseDataLen; ++j, ++i) { + req->req.data[i] = responseDataBuf[j]; + } + + req->req.data[i] = 0; + /* The last byte of data for SEND MESSAGE command is the check sum, which + * is calculated from the next byte of the previous checksum that is the + * request slave address. + */ + if (IpmiVersion == IPMI_09_VERSION) { + j = 0; + } else { + if (IpmiVersion == IPMI_10_VERSION) { j = 1; - else + } else { j = 2; - } - for ( ; j < ( i -3); ++j) - req->req.data[i] += req->req.data[j+3]; - req->req.data[i] = ~(req->req.data[i]) +1; + } + } + for (; j < (i - 3); ++j) { + req->req.data[i] += req->req.data[j + 3]; + } + req->req.data[i] = ~(req->req.data[i]) + 1; ++i; - req->req.dataLength = i; - - /*The flags & timeouts are used by the driver internally. */ - req->flags = 0; - req->timeOut = timeOut * 1000; /* convert to uSec units */ - - status = DeviceIoControl( hDevice, - IOCTL_IMB_SEND_MESSAGE, - requestData, - sizeof(requestData), - responseData, - sizeof( responseData ), - & respLength, - NULL - ); - - -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif - - - if ( (status != TRUE) || (respLength != 1) || (responseData[0] != 0) ) - { + req->req.dataLength = i; + /* The flags & timeouts are used by the driver internally. */ + req->flags = 0; + /* convert to uSec units */ + req->timeOut = timeOut * 1000; + status = DeviceIoControl(hDevice, IOCTL_IMB_SEND_MESSAGE, requestData, + sizeof(requestData), responseData, sizeof(responseData), + &respLength, NULL); + + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if ((status != TRUE) || (respLength != 1) || (responseData[0] != 0)) { return ACCESN_ERROR; } return ACCESN_OK; - - - } -/*This is not a API exported by the driver in stricter sense. It is -//added to support EMP functionality. Upper level software could have -//implemented this function.(pai 5/4/99) */ -/*/////////////////////////////////////////////////////////////////////////// -// SendTimedLanMessageResponse -///////////////////////////////////////////////////////////////////////////// */ - -/*F* -// Name: SendTimedLanMessageResponse -// Purpose: This function sends a response message to the DPC Over Lan -// Context: -// Returns: OK else error status code -// Parameters: -// -// Notes: none -*F*/ - +/* SendTimedLanMessageResponse - sends a response message to the DPC Over Lan + * + * @ptr - pointer to the original request from EMP + * @responseDataBuf + * @responseDataLen, + * @timeOut - how long to wait, in mSec units + * + * returns: OK else error status code + */ ACCESN_STATUS -SendTimedLanMessageResponse( - ImbPacket *ptr, /* pointer to the original request from EMP */ - char *responseDataBuf, - int responseDataLen, - int timeOut /* how long to wait, in mSec units */ - ) +SendTimedLanMessageResponse(ImbPacket *ptr, char *responseDataBuf, + int responseDataLen, int timeOut) { - BOOL status; - BYTE responseData[MAX_IMB_RESP_SIZE]; - /* ImbResponseBuffer * resp = (ImbResponseBuffer *) responseData; */ - DWORD respLength = sizeof( responseData ); - BYTE requestData[MAX_IMB_RESP_SIZE]; - ImbRequestBuffer * req = (ImbRequestBuffer *) requestData; - int i,j; - - /*form the response packet first */ - req->req.rsSa = BMC_SA; - if (IpmiVersion == IPMI_09_VERSION) - req->req.cmd = WRITE_EMP_BUFFER; - else - req->req.cmd = SEND_MESSAGE; - req->req.netFn = APP_NETFN; - - /* After discussion with firmware team (Shailendra), the lun number needs to stay at 0 - // even though the DPC over Lan firmware EPS states that the lun should be 1 for DPC - // Over Lan. - Simont (5/17/00) */ - req->req.rsLun = 0; + BOOL status; + BYTE responseData[MAX_IMB_RESP_SIZE]; + DWORD respLength = sizeof(responseData); + BYTE requestData[MAX_IMB_RESP_SIZE]; + ImbRequestBuffer *req = (ImbRequestBuffer *)requestData; + int i; + int j; + /* Form the response packet first */ + req->req.rsSa = BMC_SA; + if (IpmiVersion == IPMI_09_VERSION) { + req->req.cmd = WRITE_EMP_BUFFER; + } else { + req->req.cmd = SEND_MESSAGE; + } + req->req.netFn = APP_NETFN; + /* After discussion with firmware team (Shailendra), the lun number + * needs to stay at 0 even though the DPC over Lan firmware EPS states + * that the lun should be 1 for DPC Over Lan. - Simont (5/17/00) + */ + req->req.rsLun = 0; i = 0; - if (IpmiVersion != IPMI_09_VERSION) - req->req.data[i++] = LAN_CHANNEL; - - req->req.data[i++] = ptr->rqSa; - req->req.data[i++] = (((ptr->nfLn & 0xfc) | 0x4) | ((ptr->seqLn) & 0x3)); - if (IpmiVersion == IPMI_09_VERSION) - req->req.data[i++] = ((~(req->req.data[0] + req->req.data[1])) +1); - else - req->req.data[i++] = ((~(req->req.data[1] + req->req.data[2])) +1); - - req->req.data[i++] = BMC_SA; /*though software is responding, we have to - //provide BMCs slave address as responder - //address. */ - - req->req.data[i++] = ( (ptr->seqLn & 0xfc) | (ptr->nfLn & 0x3) ); - - req->req.data[i++] = ptr->cmd; - for ( j = 0 ; j < responseDataLen ; ++j,++i) - req->req.data[i] = responseDataBuf[j]; - - req->req.data[i] = 0; - if (IpmiVersion == IPMI_09_VERSION) - j = 0; - else - j = 1; - for ( ; j < ( i -3); ++j) - req->req.data[i] += req->req.data[j+3]; - req->req.data[i] = ~(req->req.data[i]) +1; - ++i; - req->req.dataLength = i; - - req->flags = 0; - req->timeOut = timeOut * 1000; /* convert to uSec units */ - + if (IpmiVersion != IPMI_09_VERSION) { + req->req.data[i++] = LAN_CHANNEL; + } - status = DeviceIoControl( hDevice, - IOCTL_IMB_SEND_MESSAGE, - requestData, - sizeof(requestData), - responseData, - sizeof( responseData ), - & respLength, - NULL - ); + req->req.data[i++] = ptr->rqSa; + req->req.data[i++] = (((ptr->nfLn & 0xfc) | 0x4) | ((ptr->seqLn) & 0x3)); + if (IpmiVersion == IPMI_09_VERSION) { + req->req.data[i++] = ((~(req->req.data[0] + req->req.data[1])) + 1); + } else { + req->req.data[i++] = ((~(req->req.data[1] + req->req.data[2])) + 1); + } + /* Though software is responding, we have to provide BMCs slave address + * as responder address. + */ + req->req.data[i++] = BMC_SA; + req->req.data[i++] = ((ptr->seqLn & 0xfc) | (ptr->nfLn & 0x3)); + req->req.data[i++] = ptr->cmd; + for (j = 0; j < responseDataLen; ++j, ++i) { + req->req.data[i] = responseDataBuf[j]; + } -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif + req->req.data[i] = 0; + if (IpmiVersion == IPMI_09_VERSION) { + j = 0; + } else { + j = 1; + } - if ( (status != TRUE) || (respLength != 1) || (responseData[0] != 0) ) - { + for (; j < (i - 3); ++j) { + req->req.data[i] += req->req.data[j + 3]; + } + req->req.data[i] = ~(req->req.data[i]) + 1; + ++i; + req->req.dataLength = i; + + req->flags = 0; + /* convert to uSec units */ + req->timeOut = timeOut * 1000; + status = DeviceIoControl(hDevice, IOCTL_IMB_SEND_MESSAGE, requestData, + sizeof(requestData), responseData, sizeof(responseData), + &respLength, NULL); + + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if ((status != TRUE) || (respLength != 1) || (responseData[0] != 0)) { return ACCESN_ERROR; } return ACCESN_OK; } -/*This is not a API exported by the driver in stricter sense. It is -//added to support EMP functionality. Upper level software could have -//implemented this function.(pai 5/4/99) */ -/*/////////////////////////////////////////////////////////////////////////// -// SendTimedLanMessageResponse_Ex -///////////////////////////////////////////////////////////////////////////// */ - -/*F* -// Name: SendTimedLanMessageResponse_Ex -// Purpose: This function sends a response message to the DPC Over Lan -// Context: -// Returns: OK else error status code -// Parameters: -// -// Notes: none -*F*/ - +/* SendTimedLanMessageResponse_Ex - sends a response message to the DPC Over + * LAN. + * + * @ptr - pointer to the original request from EMP + * @responseDataBuf + * @responseDataLen + * @timeOut - how long to wait, in mSec units + * @sessionHandle - This is introduced in IPMI1.5,this is required to be sent in + * send message command as a parameter,which is then used by BMC to identify the + * correct DPC session to send the mesage to. + * @channelNumber - There are 3 different channels on which DPC communication + * goes on: + * * Emp - 1 + * * Lan channel one - 6 + * * Lan channel two(primary channel) - 7 + * + * returns: OK else error status code + */ ACCESN_STATUS -SendTimedLanMessageResponse_Ex( - ImbPacket *ptr, /* pointer to the original request from EMP */ - char *responseDataBuf, - int responseDataLen, - int timeOut , /* how long to wait, in mSec units */ - BYTE sessionHandle, /*This is introduced in IPMI1.5,this is required to be sent in - //send message command as a parameter,which is then used by BMC - //to identify the correct DPC session to send the mesage to. */ - BYTE channelNumber /*There are 3 different channels on which DPC communication goes on - //Emp - 1,Lan channel one - 6,Lan channel two(primary channel) - 7. */ - ) +SendTimedLanMessageResponse_Ex(ImbPacket *ptr, char *responseDataBuf, int + responseDataLen, int timeOut, BYTE sessionHandle, BYTE + channelNumber) { - BOOL status; - BYTE responseData[MAX_IMB_RESP_SIZE]; - /* ImbResponseBuffer * resp = (ImbResponseBuffer *) responseData; */ - DWORD respLength = sizeof( responseData ); - BYTE requestData[MAX_IMB_RESP_SIZE]; - ImbRequestBuffer * req = (ImbRequestBuffer *) requestData; - int i,j; - - /*form the response packet first */ - req->req.rsSa = BMC_SA; - if (IpmiVersion == IPMI_09_VERSION) - req->req.cmd = WRITE_EMP_BUFFER; - else - req->req.cmd = SEND_MESSAGE; - req->req.netFn = APP_NETFN; - - /* After discussion with firmware team (Shailendra), the lun number needs to stay at 0 - // even though the DPC over Lan firmware EPS states that the lun should be 1 for DPC - // Over Lan. - Simont (5/17/00) */ - req->req.rsLun = 0; + BOOL status; + BYTE responseData[MAX_IMB_RESP_SIZE]; + DWORD respLength = sizeof(responseData); + BYTE requestData[MAX_IMB_RESP_SIZE]; + ImbRequestBuffer *req = (ImbRequestBuffer *)requestData; + int i; + int j; + /* form the response packet first */ + req->req.rsSa = BMC_SA; + if (IpmiVersion == IPMI_09_VERSION) { + req->req.cmd = WRITE_EMP_BUFFER; + } else { + req->req.cmd = SEND_MESSAGE; + } + req->req.netFn = APP_NETFN; + /* After discussion with firmware team (Shailendra), the lun number + * needs to stay at 0 even though the DPC over Lan firmware EPS states + * that the lun should be 1 for DPC Over Lan. - Simont (5/17/00) + */ + req->req.rsLun = 0; i = 0; - - /*checking for the IPMI version & then assigning the channel number for Lan accordingly. - //This is the 1st byte of the SEND MESSAGE command. */ - if (IpmiVersion == IPMI_10_VERSION) - req->req.data[i++] = LAN_CHANNEL; - else if (IpmiVersion == IPMI_15_VERSION) - req->req.data[i++] = channelNumber; - - /*The second byte of data for SEND MESSAGE starts with session handle */ + /* checking for the IPMI version & then assigning the channel number for + * LAN accordingly. + * This is the 1st byte of the SEND MESSAGE command. + */ + if (IpmiVersion == IPMI_10_VERSION) { + req->req.data[i++] = LAN_CHANNEL; + } else if (IpmiVersion == IPMI_15_VERSION) { + req->req.data[i++] = channelNumber; + } + /* The second byte of data for SEND MESSAGE starts with session handle + */ req->req.data[i++] = sessionHandle; - - /*Then it is the response slave address for SEND MESSAGE. */ - req->req.data[i++] = ptr->rqSa; - - /*Then the net function + lun for SEND MESSAGE command. */ - req->req.data[i++] = (((ptr->nfLn & 0xfc) | 0x4) | ((ptr->seqLn) & 0x3)); - - /*Here the checksum is calculated.The checksum calculation starts after the channel number. - //so for the IPMI 1.5 version its a checksum of 3 bytes that is session handle,response slave - //address & netfun+lun. */ - if (IpmiVersion == IPMI_09_VERSION) - req->req.data[i++] = ((~(req->req.data[0] + req->req.data[1])) +1); - else - { - if (IpmiVersion == IPMI_10_VERSION) - req->req.data[i++] = ((~(req->req.data[1] + req->req.data[2])) +1); - else - req->req.data[i++] = ((~(req->req.data[2]+ req->req.data[3])) +1); - } - - /*This is the next byte of the message data for SEND MESSAGE command.It is the request - //slave address. */ - req->req.data[i++] = BMC_SA; /*though software is responding, we have to - //provide BMC's slave address as responder - //address. */ - - /*This is just the sequence number,which is the next byte of data for SEND MESSAGE */ - req->req.data[i++] = ( (ptr->seqLn & 0xfc) | (ptr->nfLn & 0x3) ); - - /*The next byte is the command like get software ID(00). */ - req->req.data[i++] = ptr->cmd; - - /*after the cmd the data ,which is sent by DPC & is retrived using the get message earlier - // is sent back to DPC. */ - for ( j = 0 ; j < responseDataLen ; ++j,++i) - req->req.data[i] = responseDataBuf[j]; - - req->req.data[i] = 0; - - /*The last byte of data for SEND MESSAGE command is the check sum ,which is calculated - //from the next byte of the previous checksum that is the request slave address. */ - if (IpmiVersion == IPMI_09_VERSION) - j = 0; - else - { - if (IpmiVersion == IPMI_10_VERSION) + /* Then it is the response slave address for SEND MESSAGE. */ + req->req.data[i++] = ptr->rqSa; + /* Then the net function + lun for SEND MESSAGE command. */ + req->req.data[i++] = (((ptr->nfLn & 0xfc) | 0x4) | ((ptr->seqLn) & 0x3)); + /* Here the checksum is calculated.The checksum calculation starts after + * the channel number. So for the IPMI 1.5 version its a checksum of 3 + * bytes that is session handle,response slave address & netfun+lun. + */ + if (IpmiVersion == IPMI_09_VERSION) { + req->req.data[i++] = ((~(req->req.data[0] + req->req.data[1])) + 1); + } else { + if (IpmiVersion == IPMI_10_VERSION) { + req->req.data[i++] = ((~(req->req.data[1] + req->req.data[2])) + 1); + } else { + req->req.data[i++] = ((~(req->req.data[2] + req->req.data[3])) + 1); + } + } + /* This is the next byte of the message data for SEND MESSAGE command.It + * is the request slave address. + */ + /* Though software is responding, we have to provide BMC's slave address + * as responder address. + */ + req->req.data[i++] = BMC_SA; + /* This is just the sequence number,which is the next byte of data for + * SEND MESSAGE + */ + req->req.data[i++] = ((ptr->seqLn & 0xfc) | (ptr->nfLn & 0x3)); + /* The next byte is the command like get software ID(00). */ + req->req.data[i++] = ptr->cmd; + /* After the cmd the data ,which is sent by DPC & is retrived using the + * get message earlier is sent back to DPC. + */ + for (j = 0; j < responseDataLen; ++j, ++i) { + req->req.data[i] = responseDataBuf[j]; + } + req->req.data[i] = 0; + /* The last byte of data for SEND MESSAGE command is the check sum which + * is calculated from the next byte of the previous checksum that is the + * request slave address. + */ + if (IpmiVersion == IPMI_09_VERSION) { + j = 0; + } else { + if (IpmiVersion == IPMI_10_VERSION) { j = 1; - else + } else { j = 2; - } - for ( ; j < ( i -3); ++j) - req->req.data[i] += req->req.data[j+3]; - req->req.data[i] = ~(req->req.data[i]) +1; + } + } + for (; j < (i - 3); ++j) { + req->req.data[i] += req->req.data[j + 3]; + } + req->req.data[i] = ~(req->req.data[i]) + 1; ++i; - req->req.dataLength = i; - - /*The flags & timeouts are used by the driver internally */ - req->flags = 0; - req->timeOut = timeOut * 1000; /* convert to uSec units */ - - - status = DeviceIoControl( hDevice, - IOCTL_IMB_SEND_MESSAGE, - requestData, - sizeof(requestData), - responseData, - sizeof( responseData ), - & respLength, - NULL - ); - -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif - - if ( (status != TRUE) || (respLength != 1) || (responseData[0] != 0) ) - { + req->req.dataLength = i; + /* The flags & timeouts are used by the driver internally */ + req->flags = 0; + /* convert to uSec units */ + req->timeOut = timeOut * 1000; + status = DeviceIoControl(hDevice, IOCTL_IMB_SEND_MESSAGE, requestData, + sizeof(requestData), responseData, sizeof(responseData), + &respLength, NULL); + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if ((status != TRUE) || (respLength != 1) || (responseData[0] != 0)) { return ACCESN_ERROR; } return ACCESN_OK; } -/*/////////////////////////////////////////////////////////////////////////// -// SendTimedImbpRequest -///////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: SendTimedImbpRequest -// Purpose: This function sends a request for BMC implemented function -// Context: Used by Upper level agents (sis modules) to access BMC implemented functionality. -// Returns: OK else error status code -// Parameters: -// reqPtr -// timeOut -// respDataPtr -// respLen -// Notes: none -*F*/ +/* SendTimedImbpRequest - This function sends a request for BMC implemented function + * + * @reqPtr - request info and data + * @timeOut - how long to wait, in mSec units + * @respDataPtr - where to put response data + * @respDataLen - how much response data there is + * @completionCode - request status from dest controller + * + * returns: OK else error status code + */ ACCESN_STATUS -SendTimedImbpRequest ( - IMBPREQUESTDATA *reqPtr, /* request info and data */ - int timeOut, /* how long to wait, in mSec units */ - BYTE *respDataPtr, /* where to put response data */ - int *respDataLen, /* how much response data there is */ - BYTE *completionCode /* request status from dest controller */ - ) +SendTimedImbpRequest(IMBPREQUESTDATA *reqPtr, int timeOut, BYTE *respDataPtr, + int *respDataLen, BYTE *completionCode) { - BYTE responseData[MAX_BUFFER_SIZE]; - ImbResponseBuffer * resp = (ImbResponseBuffer *) responseData; - DWORD respLength = sizeof( responseData ); - BYTE requestData[MAX_BUFFER_SIZE]; - ImbRequestBuffer * req = (ImbRequestBuffer *) requestData; - BOOL status; - - - req->req.rsSa = reqPtr->rsSa; - req->req.cmd = reqPtr->cmdType; - req->req.netFn = reqPtr->netFn; - req->req.rsLun = reqPtr->rsLun; - req->req.dataLength = reqPtr->dataLength; - -#ifndef NO_MACRO_ARGS - DEBUG("cmd=%02x, pdata=%p, datalen=%x\n", req->req.cmd, - reqPtr->data, reqPtr->dataLength ); -#endif - memcpy( req->req.data, reqPtr->data, reqPtr->dataLength ); - - req->flags = 0; - req->timeOut = timeOut * 1000; /* convert to uSec units */ - -#ifndef NO_MACRO_ARGS - DEBUG("%s: rsSa 0x%x cmd 0x%x netFn 0x%x rsLun 0x%x\n", __FUNCTION__, - req->req.rsSa, req->req.cmd, req->req.netFn, req->req.rsLun); -#endif - - - status = DeviceIoControl( hDevice, - IOCTL_IMB_SEND_MESSAGE, - requestData, - sizeof( requestData ), - & responseData, - sizeof( responseData ), - & respLength, - NULL - ); -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl returned status = %d\n",__FUNCTION__, status); -#endif + BYTE responseData[MAX_BUFFER_SIZE]; + ImbResponseBuffer *resp = (ImbResponseBuffer *)responseData; + DWORD respLength = sizeof(responseData); + BYTE requestData[MAX_BUFFER_SIZE]; + ImbRequestBuffer *req = (ImbRequestBuffer *)requestData; + BOOL status; + + req->req.rsSa = reqPtr->rsSa; + req->req.cmd = reqPtr->cmdType; + req->req.netFn = reqPtr->netFn; + req->req.rsLun = reqPtr->rsLun; + req->req.dataLength = reqPtr->dataLength; + + lprintf(LOG_DEBUG, "cmd=%02x, pdata=%p, datalen=%x", req->req.cmd, + reqPtr->data, reqPtr->dataLength); + memcpy(req->req.data, reqPtr->data, reqPtr->dataLength); + + req->flags = 0; + /* convert to uSec units */ + req->timeOut = timeOut * 1000; + lprintf(LOG_DEBUG, "%s: rsSa 0x%x cmd 0x%x netFn 0x%x rsLun 0x%x", + __FUNCTION__, req->req.rsSa, req->req.cmd, + req->req.netFn, req->req.rsLun); + + status = DeviceIoControl(hDevice, IOCTL_IMB_SEND_MESSAGE, requestData, + sizeof(requestData), &responseData, + sizeof(responseData), &respLength, NULL); + + lprintf(LOG_DEBUG, "%s: DeviceIoControl returned status = %d", + __FUNCTION__, status); #ifdef DBG_IPMI - printf("%s: rsSa %x cmd %x netFn %x lun %x, status=%d, cc=%x, rlen=%d\n", - __FUNCTION__, req->req.rsSa, req->req.cmd, req->req.netFn, - req->req.rsLun, status, resp->cCode, respLength ); + /* TODO */ + printf("%s: rsSa %x cmd %x netFn %x lun %x, status=%d, cc=%x, rlen=%d\n", + __FUNCTION__, req->req.rsSa, req->req.cmd, + req->req.netFn, req->req.rsLun, status, resp->cCode, + respLength); #endif - if( status != TRUE ) { + if (status != TRUE) { DWORD error; error = GetLastError(); return error; - } - if( respLength == 0 ) { + } else if (respLength == 0) { return ACCESN_ERROR; } - - /* - * give the caller his response - */ + /* give the caller his response */ *completionCode = resp->cCode; - *respDataLen = 0; + *respDataLen = 0; - if(( respLength > 1 ) && ( respDataPtr)) - { - *respDataLen = respLength - 1; - memcpy( respDataPtr, resp->data, *respDataLen); + if ((respLength > 1) && (respDataPtr)) { + *respDataLen = respLength - 1; + memcpy(respDataPtr,resp->data, *respDataLen); } - - return ACCESN_OK; } - -/*///////////////////////////////////////////////////////////////////////// -//SendAsyncImbpRequest -/////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: SendAsyncImbpRequest -// Purpose: This function sends a request for Asynchronous IMB implemented function -// Context: Used by Upper level agents (sis modules) to access Asynchronous IMB implemented functionality. -// Returns: OK else error status code -// Parameters: -// reqPtr Pointer to Async IMB request -// seqNo Sequence Munber -// Notes: none -*F*/ +/* SendAsyncImbpRequest - sends a request for Asynchronous IMB implemented function. + * + * @reqPtr - Pointer to Async IMB request + * @seqNo -Sequence Munber + * + * returns: OK else error status code + */ ACCESN_STATUS -SendAsyncImbpRequest ( - IMBPREQUESTDATA *reqPtr, /* request info and data */ - BYTE * seqNo /* sequence number used in creating IMB msg */ - ) +SendAsyncImbpRequest(IMBPREQUESTDATA *reqPtr, BYTE *seqNo) { - - BOOL status; - BYTE responseData[MAX_IMB_RESP_SIZE]; - ImbResponseBuffer * resp = (ImbResponseBuffer *) responseData; - DWORD respLength = sizeof( responseData ); - BYTE requestData[MAX_IMB_RESP_SIZE]; - ImbRequestBuffer * req = (ImbRequestBuffer *) requestData; - - req->req.rsSa = reqPtr->rsSa; - req->req.cmd = reqPtr->cmdType; - req->req.netFn = reqPtr->netFn; - req->req.rsLun = reqPtr->rsLun; - req->req.dataLength = reqPtr->dataLength; - - memcpy( req->req.data, reqPtr->data, reqPtr->dataLength ); - - req->flags = NO_RESPONSE_EXPECTED; - req->timeOut = 0; /* no timeouts for async sends */ - - status = DeviceIoControl( hDevice, - IOCTL_IMB_SEND_MESSAGE, - requestData, - sizeof( requestData ), - & responseData, - sizeof( responseData ), - & respLength, - NULL - ); -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif - - if( status != TRUE ) { + BOOL status; + BYTE responseData[MAX_IMB_RESP_SIZE]; + ImbResponseBuffer *resp = (ImbResponseBuffer *)responseData; + DWORD respLength = sizeof(responseData); + BYTE requestData[MAX_IMB_RESP_SIZE]; + ImbRequestBuffer *req = (ImbRequestBuffer *)requestData; + + req->req.rsSa = reqPtr->rsSa; + req->req.cmd = reqPtr->cmdType; + req->req.netFn = reqPtr->netFn; + req->req.rsLun = reqPtr->rsLun; + req->req.dataLength = reqPtr->dataLength; + memcpy(req->req.data, reqPtr->data, reqPtr->dataLength); + + req->flags = NO_RESPONSE_EXPECTED; + /* no timeouts for async sends */ + req->timeOut = 0; + + status = DeviceIoControl(hDevice, IOCTL_IMB_SEND_MESSAGE, requestData, + sizeof(requestData), &responseData, + sizeof(responseData), &respLength, NULL); + + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if (status != TRUE) { DWORD error; error = GetLastError(); return error; - } - if( respLength != 2 ) { + } else if (respLength != 2) { return ACCESN_ERROR; } - /* - // give the caller his sequence number - */ + /* give the caller his sequence number */ *seqNo = resp->data[0]; - return ACCESN_OK; - } -/*/////////////////////////////////////////////////////////////////////////// -//GetAsyncImbpMessage -///////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: GetAsyncImbpMessage -// Purpose: This function gets the next available async message with a message id -// greater than SeqNo. The message looks like an IMB packet -// and the length and Sequence number is returned -// Context: Used by Upper level agents (sis modules) to access Asynchronous IMB implemented functionality. -// Returns: OK else error status code -// Parameters: -// msgPtr Pointer to Async IMB request -// msgLen Length -// timeOut Time to wait -// seqNo Sequence Munber -// Notes: none -*F*/ - +/* GetAsyncImbpMessage - This function gets the next available async message + * with a message ID greater than SeqNo. The message looks like an IMB packet + * and the length and Sequence number is returned. + * + * @msgPtr - request info and data + * @msgLen - IN - length of buffer, OUT - msg len + * @timeOut - how long to wait for the message + * @seqNo - previously returned seq number(or ASYNC_SEQ_START) + * @channelNumber + * + * returns: OK else error status code + */ ACCESN_STATUS -GetAsyncImbpMessage ( - ImbPacket * msgPtr, /* request info and data */ - DWORD *msgLen, /* IN - length of buffer, OUT - msg len */ - DWORD timeOut, /* how long to wait for the message */ - ImbAsyncSeq *seqNo, /* previously returned seq number */ - /* (or ASYNC_SEQ_START) */ - DWORD channelNumber - ) +GetAsyncImbpMessage (ImbPacket *msgPtr, DWORD *msgLen, DWORD timeOut, + ImbAsyncSeq *seqNo, DWORD channelNumber) { - - BOOL status; - BYTE responseData[MAX_ASYNC_RESP_SIZE], lun; - ImbAsyncResponse * resp = (ImbAsyncResponse *) responseData; - DWORD respLength = sizeof( responseData ); - ImbAsyncRequest req; - - while(1) - { - - - if( (msgPtr == NULL) || (msgLen == NULL) || ( seqNo == NULL) ) + BOOL status; + BYTE responseData[MAX_ASYNC_RESP_SIZE]; + BYTE lun; + ImbAsyncResponse *resp = (ImbAsyncResponse *)responseData; + DWORD respLength = sizeof(responseData); + ImbAsyncRequest req; + + while (1) { + if ((msgPtr == NULL) || (msgLen == NULL) || ( seqNo == NULL)) { + return ACCESN_ERROR; + } + /* convert to uSec units */ + req.timeOut = timeOut * 1000; + req.lastSeq = *seqNo; + + status = DeviceIoControl(hDevice, IOCTL_IMB_GET_ASYNC_MSG, &req, + sizeof(req), &responseData, + sizeof(responseData), &respLength, NULL); + + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", + __FUNCTION__, status); + if (status != TRUE) { + DWORD error = GetLastError(); + /* handle "msg not available" specially. it is different + * from a random old error. + */ + switch (error) { + case IMB_MSG_NOT_AVAILABLE: + return ACCESN_END_OF_DATA; + break; + default: return ACCESN_ERROR; + break; + } + } else if (respLength < MIN_ASYNC_RESP_SIZE) { + return ACCESN_ERROR; + } + respLength -= MIN_ASYNC_RESP_SIZE; - req.timeOut = timeOut * 1000; /* convert to uSec units */ - req.lastSeq = *seqNo; - - - status = DeviceIoControl( hDevice, - IOCTL_IMB_GET_ASYNC_MSG, - & req, - sizeof( req ), - & responseData, - sizeof( responseData ), - & respLength, - NULL - ); - -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif + if (*msgLen < respLength) { + return ACCESN_ERROR; + } - if( status != TRUE ) { - DWORD error = GetLastError(); - /* - // handle "msg not available" specially. it is - // different from a random old error. - */ - switch( error ) { - case IMB_MSG_NOT_AVAILABLE: - return ACCESN_END_OF_DATA; - default: - return ACCESN_ERROR; - } - return ACCESN_ERROR; + /* same code as in NT section */ + if (IpmiVersion == IPMI_09_VERSION) { + switch (channelNumber) { + case IPMB_CHANNEL: + lun = IPMB_LUN; + break; + case EMP_CHANNEL: + lun = EMP_LUN; + break; + default: + lun = RESERVED_LUN; + break; } - if( respLength < MIN_ASYNC_RESP_SIZE ) { - return ACCESN_ERROR; + if ((lun == RESERVED_LUN) + || (lun != ((((ImbPacket *)(resp->data))->nfLn) & 0x3 ))) { + *seqNo = resp->thisSeq; + continue; } - respLength -= MIN_ASYNC_RESP_SIZE; - - if( *msgLen < respLength ) { - return ACCESN_ERROR; - } - - - /*same code as in NT section */ - if ( IpmiVersion == IPMI_09_VERSION) - { - - switch( channelNumber) { - case IPMB_CHANNEL: - lun = IPMB_LUN; - break; - - case EMP_CHANNEL: - lun = EMP_LUN; - break; - - default: - lun = RESERVED_LUN; - break; - } - - if ( (lun == RESERVED_LUN) || - (lun != ((((ImbPacket *)(resp->data))->nfLn) & 0x3 )) - ) - { - *seqNo = resp->thisSeq; - continue; - } - - - memcpy( msgPtr, resp->data, respLength ); - *msgLen = respLength; - - } - else - { - /* it is a 1.0 or above version */ - - if (resp->data[0] != (BYTE)channelNumber) - { - *seqNo = resp->thisSeq; - continue; - } - - memcpy( msgPtr, &(resp->data[1]), respLength-1 ); - *msgLen = respLength-1; - - + memcpy(msgPtr, resp->data, respLength); + *msgLen = respLength; + } else { + /* it is version 1.0 or better */ + if (resp->data[0] != (BYTE)channelNumber) { + *seqNo = resp->thisSeq; + continue; } - - /* - // give the caller his sequence number - */ + memcpy(msgPtr, &(resp->data[1]), (respLength - 1)); + *msgLen = respLength - 1; + } + /* give the caller his sequence number */ *seqNo = resp->thisSeq; - return ACCESN_OK; - - } /*while (1) */ + } } - -/*/////////////////////////////////////////////////////////////////////////// -//GetAsyncImbpMessage_Ex -///////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: GetAsyncImbpMessage_Ex -// Purpose: This function gets the next available async message with a message id -// greater than SeqNo. The message looks like an IMB packet -// and the length and Sequence number is returned -// Context: Used by Upper level agents (sis modules) to access Asynchronous IMB implemented functionality. -// Returns: OK else error status code -// Parameters: -// msgPtr Pointer to Async IMB request -// msgLen Length -// timeOut Time to wait -// seqNo Sequence Munber -// Notes: none -*F*/ - +/* GetAsyncImbpMessage_Ex - gets the next available async message with a message + * ID greater than SeqNo. The message looks like an IMB packet and the length + * and Sequence number is returned. + * + * @msgPtr - request info and data + * @msgLen - IN - length of buffer, OUT - msg len + * @timeOut - how long to wait for the message + * @seqNo - previously returned seq number(or ASYNC_SEQ_START) + * @channelNumber + * @sessionHandle + * @privilege + * + * returns: OK else error status code + */ ACCESN_STATUS -GetAsyncImbpMessage_Ex ( - ImbPacket * msgPtr, /* request info and data */ - DWORD *msgLen, /* IN - length of buffer, OUT - msg len */ - DWORD timeOut, /* how long to wait for the message */ - ImbAsyncSeq *seqNo, /* previously returned seq number */ - /* (or ASYNC_SEQ_START) */ - DWORD channelNumber, - BYTE * sessionHandle, - BYTE * privilege - ) +GetAsyncImbpMessage_Ex(ImbPacket *msgPtr, DWORD *msgLen, DWORD timeOut, + ImbAsyncSeq *seqNo, DWORD channelNumber, BYTE *sessionHandle, + BYTE *privilege) { + BOOL status; + BYTE responseData[MAX_ASYNC_RESP_SIZE]; + BYTE lun; + ImbAsyncResponse *resp = (ImbAsyncResponse *)responseData; + DWORD respLength = sizeof(responseData); + ImbAsyncRequest req; + + while (1) { + if ((msgPtr == NULL) || (msgLen == NULL) || ( seqNo == NULL)) { + return ACCESN_ERROR; + } - BOOL status; - BYTE responseData[MAX_ASYNC_RESP_SIZE], lun; - ImbAsyncResponse * resp = (ImbAsyncResponse *) responseData; - DWORD respLength = sizeof( responseData ); - ImbAsyncRequest req; - - while(1) - { - - - if( (msgPtr == NULL) || (msgLen == NULL) || ( seqNo == NULL) ) + /* convert to uSec units */ + req.timeOut = timeOut * 1000; + req.lastSeq = *seqNo; + status = DeviceIoControl(hDevice, IOCTL_IMB_GET_ASYNC_MSG, &req, + sizeof(req), &responseData, + sizeof(responseData), &respLength, NULL); + + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", + __FUNCTION__, status); + if (status != TRUE) { + DWORD error = GetLastError(); + /* handle "msg not available" specially. it is + * different from a random old error. + */ + switch (error) { + case IMB_MSG_NOT_AVAILABLE: + return ACCESN_END_OF_DATA; + break; + default: return ACCESN_ERROR; + break; + } + } + if (respLength < MIN_ASYNC_RESP_SIZE) { + return ACCESN_ERROR; + } - req.timeOut = timeOut * 1000; /* convert to uSec units */ - req.lastSeq = *seqNo; - - - status = DeviceIoControl( hDevice, - IOCTL_IMB_GET_ASYNC_MSG, - & req, - sizeof( req ), - & responseData, - sizeof( responseData ), - & respLength, - NULL - ); - -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif + respLength -= MIN_ASYNC_RESP_SIZE; + if (*msgLen < respLength) { + return ACCESN_ERROR; + } - if( status != TRUE ) { - DWORD error = GetLastError(); - /* - // handle "msg not available" specially. it is - // different from a random old error. - */ - switch( error ) { - case IMB_MSG_NOT_AVAILABLE: - return ACCESN_END_OF_DATA; - default: - return ACCESN_ERROR; - } - return ACCESN_ERROR; - } - if( respLength < MIN_ASYNC_RESP_SIZE ) { - return ACCESN_ERROR; + /* same code as in NT section */ + if (IpmiVersion == IPMI_09_VERSION) { + switch (channelNumber) { + case IPMB_CHANNEL: + lun = IPMB_LUN; + break; + case EMP_CHANNEL: + lun = EMP_LUN; + break; + default: + lun = RESERVED_LUN; + break; } - respLength -= MIN_ASYNC_RESP_SIZE; - if( *msgLen < respLength ) { - return ACCESN_ERROR; + if ((lun == RESERVED_LUN) + || (lun != ((((ImbPacket *)(resp->data))->nfLn) & 0x3))) { + *seqNo = resp->thisSeq; + continue; } - - /*same code as in NT section */ - if ( IpmiVersion == IPMI_09_VERSION) - { - - switch( channelNumber) { - case IPMB_CHANNEL: - lun = IPMB_LUN; - break; - - case EMP_CHANNEL: - lun = EMP_LUN; - break; - - default: - lun = RESERVED_LUN; - break; - } - - if ( (lun == RESERVED_LUN) || - (lun != ((((ImbPacket *)(resp->data))->nfLn) & 0x3 )) - ) - { - *seqNo = resp->thisSeq; - continue; - } - - - memcpy( msgPtr, resp->data, respLength ); - *msgLen = respLength; - - } - else - { - if((sessionHandle ==NULL) || (privilege ==NULL)) - return ACCESN_ERROR; - - /*With the new IPMI version the get message command returns the - //channel number along with the privileges.The 1st 4 bits of the - //second byte of the response data for get message command represent - //the channel number & the last 4 bits are the privileges. */ - *privilege = (resp->data[0] & 0xf0)>> 4; - - if ((resp->data[0] & 0x0f) != (BYTE)channelNumber) - { - *seqNo = resp->thisSeq; - continue; - } - - - /*The get message command according to IPMI 1.5 spec now even - //returns the session handle.This is required to be captured - //as it is required as request data for send message command. */ - *sessionHandle = resp->data[1]; - memcpy( msgPtr, &(resp->data[2]), respLength-1 ); - *msgLen = respLength-1; - - + memcpy(msgPtr, resp->data, respLength); + *msgLen = respLength; + } else { + if ((sessionHandle ==NULL) || (privilege ==NULL)) { + return ACCESN_ERROR; + } + /* With the new IPMI version the get message command + * returns the channel number along with the + * privileges.The 1st 4 bits of the second byte of the + * response data for get message command represent the + * channel number & the last 4 bits are the privileges. + */ + *privilege = (resp->data[0] & 0xf0)>> 4; + if ((resp->data[0] & 0x0f) != (BYTE)channelNumber) { + *seqNo = resp->thisSeq; + continue; } - - /* - // give the caller his sequence number - */ + /* The get message command according to IPMI 1.5 spec + * now even returns the session handle.This is required + * to be captured as it is required as request data for + * send message command. + */ + *sessionHandle = resp->data[1]; + memcpy(msgPtr, &(resp->data[2]), (respLength - 1)); + *msgLen = respLength - 1; + } + /* give the caller his sequence number */ *seqNo = resp->thisSeq; - return ACCESN_OK; - - } /*while (1) */ -} - - - -/*////////////////////////////////////////////////////////////////////////////// -//IsAsyncMessageAvailable -///////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: IsMessageAvailable -// Purpose: This function waits for an Async Message -// -// Context: Used by Upper level agents access Asynchronous IMB based -// messages -// Returns: OK else error status code -// Parameters: -// eventId -// -// Notes: This call will block the calling thread if no Async events are -// are available in the queue. -// -*F*/ -ACCESN_STATUS -IsAsyncMessageAvailable (unsigned int eventId ) -{ - int dummy; - int respLength = 0; - BOOL status; - - /* confirm that app is not using a bad Id */ - - - if ( AsyncEventHandle != (HANDLE) eventId) - return ACCESN_ERROR; - - status = DeviceIoControl(hDevice, - IOCTL_IMB_CHECK_EVENT, - &AsyncEventHandle, - sizeof(HANDLE ), - &dummy, - sizeof(int), - (LPDWORD) & respLength, - NULL - ); -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif - - if( status != TRUE ) - return ACCESN_ERROR; - - - return ACCESN_OK; + } } - -/*I have retained this commented code because later we may want to use -//DPC message specific Processing (pai 11/21) */ - -#ifdef NOT_COMPILED_BUT_LEFT_HERE_FOR_NOW - -/*////////////////////////////////////////////////////////////////////////////// -//GetAsyncDpcMessage -///////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: GetAsyncDpcMessage -// Purpose: This function gets the next available async message from -// the DPC client. -// -// Context: Used by Upper level agents access Asynchronous IMB based -// messages sent by the DPC client. -// Returns: OK else error status code -// Parameters: -// msgPtr Pointer to Async IMB request -// msgLen Length -// timeOut Time to wait -// seqNo Sequence Munber -// Notes: This call will block the calling thread if no Async events are -// are available in the queue. -// -*F*/ - +/* IsAsyncMessageAvailable - Waits for an Async Message. This call will block + * the calling thread if no Async events are are available in the queue. + * + * @dummy + * @respLength + * @status + * + * returns: OK else error status code + */ ACCESN_STATUS -GetAsyncDpcMessage ( - ImbPacket * msgPtr, /* request info and data */ - DWORD * msgLen, /* IN - length of buffer, OUT - msg len */ - DWORD timeOut, /* how long to wait for the message */ - ImbAsyncSeq * seqNo, /* previously returned seq number (or ASYNC_SEQ_START) */ - ) +IsAsyncMessageAvailable(unsigned int eventId) { - BOOL status; - BYTE responseData[MAX_ASYNC_RESP_SIZE]; - ImbAsyncResponse * resp = (ImbAsyncResponse *) responseData; - DWORD respLength = sizeof( responseData ); - ImbAsyncRequest req; - - if( msgPtr == NULL || msgLen == NULL || seqNo == NULL ) - return ACCESN_ERROR; - - req.lastSeq = *seqNo; - - - hEvt = CreateEvent (NULL, TRUE, FALSE, NULL) ; - if (!hEvt) { + int dummy; + int respLength = 0; + BOOL status; + /* confirm that app is not using a bad Id */ + if (AsyncEventHandle != (HANDLE)eventId) { return ACCESN_ERROR; } - - status = DeviceIoControl( hDevice, - IOCTL_IMB_GET_DPC_MSG, - & req, - sizeof( req ), - & responseData, - sizeof( responseData ), - & respLength, - &ovl - ); - - if( status != TRUE ) { - DWORD error = GetLastError(); - /* - // handle "msg not available" specially. it is different from - // a random old error. - // - */ - if (!status) - { - switch (error ) - { - case ERROR_IO_PENDING: - - WaitForSingleObject (hEvt, INFINITE) ; - ResetEvent (hEvt) ; - break; - - case IMB_MSG_NOT_AVAILABLE: - - CloseHandle(hEvt); - return ACCESN_END_OF_DATA; - - default: - CloseHandle(hEvt); - return ACCESN_ERROR; - - } - } - - - - if ( - ( GetOverlappedResult(hDevice, - &ovl, - (LPDWORD)&respLength, - TRUE - ) == 0 ) || (respLength <= 0) - ) - - { - - CloseHandle(hEvt); - return ACCESN_ERROR; - - } - - - } - - if( respLength < MIN_ASYNC_RESP_SIZE ) { - CloseHandle(hEvt); - return ACCESN_ERROR; - } - - respLength -= MIN_ASYNC_RESP_SIZE; - - if( *msgLen < respLength ) { - - /* The following code should have been just return ACCESN_out_of_range */ - CloseHandle(hEvt); + status = DeviceIoControl(hDevice, IOCTL_IMB_CHECK_EVENT, + &AsyncEventHandle, sizeof(HANDLE), &dummy, sizeof(int), + (LPDWORD)&respLength, NULL); + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if (status != TRUE) { return ACCESN_ERROR; } - - memcpy( msgPtr, resp->data, respLength ); - - *msgLen = respLength; - /* - // give the caller his sequence number - */ - *seqNo = resp->thisSeq; - - CloseHandle(hEvt); - - return ACCESN_OK; - } -#endif /*NOT_COMPILED_BUT_LEFT_HERE_FOR_NOW*/ - - -/*///////////////////////////////////////////////////////////////////////////// -//RegisterForImbAsyncMessageNotification -///////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: RegisterForImbAsyncMessageNotification -// Purpose: This function Registers the calling application -// for Asynchronous notification when a sms message -// is available with the IMB driver. -// -// Context: Used by Upper level agents to know that an async -// SMS message is available with the driver. -// Returns: OK else error status code -// Parameters: -// handleId pointer to the registration handle -// -// Notes: The calling application should use the returned handle to -// get the Async messages.. -*F*/ +/* RegisterForImbAsyncMessageNotification - This function Registers the calling + * application for Asynchronous notification when a sms message is available + * with the IMB driver. + * + * Notes: The calling application should use the returned handle to + * get the Async messages.. + * + * @handleId - pointer to the registration handle + * + * returns: OK else error status code + */ ACCESN_STATUS -RegisterForImbAsyncMessageNotification (unsigned int *handleId) - +RegisterForImbAsyncMessageNotification(unsigned int *handleId) { - BOOL status; - DWORD respLength ; - int dummy; - + BOOL status; + DWORD respLength ; + int dummy; /*allow only one app to register */ - - if( (handleId == NULL ) || (AsyncEventHandle) ) + if ((handleId == NULL ) || (AsyncEventHandle)) { return ACCESN_ERROR; - - - status = DeviceIoControl(hDevice, - IOCTL_IMB_REGISTER_ASYNC_OBJ, - &dummy, - sizeof( int ), - &AsyncEventHandle, - (DWORD)sizeof(HANDLE ), - (LPDWORD) & respLength, - NULL - ); -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif - - if( (respLength != sizeof(int)) || (status != TRUE )) - return ACCESN_ERROR; - + } + status = DeviceIoControl(hDevice, IOCTL_IMB_REGISTER_ASYNC_OBJ, &dummy, + sizeof(int), &AsyncEventHandle, (DWORD)sizeof(HANDLE), + (LPDWORD)&respLength, NULL); + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if ((respLength != sizeof(int)) || (status != TRUE)) { + return ACCESN_ERROR; + } /* printf("imbapi: Register handle = %x\n",AsyncEventHandle); *//*++++*/ - *handleId = (unsigned int) AsyncEventHandle; - -#ifndef NO_MACRO_ARGS - DEBUG("handleId = %x AsyncEventHandle %x\n", *handleId, AsyncEventHandle); -#endif + *handleId = (unsigned int)AsyncEventHandle; + lprintf(LOG_DEBUG, "handleId = %x AsyncEventHandle %x", *handleId, + AsyncEventHandle); return ACCESN_OK; } - - - - -/*///////////////////////////////////////////////////////////////////////////// -//UnRegisterForImbAsyncMessageNotification -///////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: UnRegisterForImbAsyncMessageNotification -// Purpose: This function un-registers the calling application -// for Asynchronous notification when a sms message -// is available with the IMB driver. -// -// Context: Used by Upper level agents to un-register -// for async. notification of sms messages -// Returns: OK else error status code -// Parameters: -// handleId pointer to the registration handle -// iFlag value used to determine where this function was called from -// _it is used currently on in NetWare environment_ -// -// Notes: -*F*/ +/* UnRegisterForImbAsyncMessageNotification - This function un-registers the + * calling application for Asynchronous notification when a sms message is + * available with the IMB driver. It is used by Upper level agents to + * un-register for async. notification of sms messages. + * + * @handleId - pointer to the registration handle + * @iFlag - value used to determine where this function was called from. It is + * used currently on in NetWare environment. + * + * returns - status + */ ACCESN_STATUS -UnRegisterForImbAsyncMessageNotification (unsigned int handleId, int iFlag) - +UnRegisterForImbAsyncMessageNotification(unsigned int handleId, int iFlag) { - BOOL status; - DWORD respLength ; - int dummy; - - iFlag = iFlag; /* to keep compiler happy We are not using this flag*/ - - if ( AsyncEventHandle != (HANDLE) handleId) - return ACCESN_ERROR; - - status = DeviceIoControl(hDevice, - IOCTL_IMB_DEREGISTER_ASYNC_OBJ, - &AsyncEventHandle, - (DWORD)sizeof(HANDLE ), - &dummy, - (DWORD)sizeof(int ), - (LPDWORD) & respLength, - NULL - ); -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif + BOOL status; + DWORD respLength ; + int dummy; + /* to keep compiler happy. We are not using this flag*/ + iFlag = iFlag; - if( status != TRUE ) - return ACCESN_ERROR; + if (AsyncEventHandle != (HANDLE)handleId) { + return ACCESN_ERROR; + } + status = DeviceIoControl(hDevice, IOCTL_IMB_DEREGISTER_ASYNC_OBJ, + &AsyncEventHandle, (DWORD)sizeof(HANDLE ), &dummy, + (DWORD)sizeof(int), (LPDWORD)&respLength, NULL ); + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if (status != TRUE) { + return ACCESN_ERROR; + } return ACCESN_OK; } - -/*/////////////////////////////////////////////////////////////////////////// -// SetShutDownCode -///////////////////////////////////////////////////////////////////////////// */ -/*F* -// Name: SetShutDownCode -// Purpose: To set the shutdown action code -// Context: Called by the System Control Subsystem -// Returns: none -// Parameters: -// code shutdown action code which can be either -// SD_NO_ACTION, SD_RESET, SD_POWER_OFF as defined in imb_if.h -*F*/ - -ACCESN_STATUS -SetShutDownCode ( - int delayTime, /* time to delay in 100ms units */ - int code /* what to do when time expires */ - ) -{ - DWORD retLength; - BOOL status; - ShutdownCmdBuffer cmd; - - /* - // If Imb driver is not present return AccessFailed - */ - if(hDevice == INVALID_HANDLE_VALUE) +/* SetShutDownCode - To set the shutdown action code. + * + * @code - shutdown action code which can be either SD_NO_ACTION, SD_RESET, + * SD_POWER_OFF as defined in imb_if.h + * @delayTime - time to delay in 100ms units + * + * returns - status + */ +ACCESN_STATUS +SetShutDownCode(int delayTime, int code) +{ + DWORD retLength; + BOOL status; + ShutdownCmdBuffer cmd; + /* If IMB interface isn't open, return AccessFailed */ + if (hDevice == INVALID_HANDLE_VALUE) { return ACCESN_ERROR; - - cmd.code = code; - cmd.delayTime = delayTime; - - status = DeviceIoControl( hDevice, - IOCTL_IMB_SHUTDOWN_CODE, - & cmd, - sizeof( cmd ), - NULL, - 0, - & retLength, - NULL - ); -#ifndef NO_MACRO_ARGS - DEBUG("%s: DeviceIoControl status = %d\n",__FUNCTION__, status); -#endif - - if(status == TRUE) + } + cmd.code = code; + cmd.delayTime = delayTime; + status = DeviceIoControl(hDevice, IOCTL_IMB_SHUTDOWN_CODE, &cmd, + sizeof(cmd), NULL, 0, &retLength, NULL); + lprintf(LOG_DEBUG, "%s: DeviceIoControl status = %d", __FUNCTION__, + status); + if (status == TRUE) { return ACCESN_OK; - else + } else { return ACCESN_ERROR; + } } /*///////////////////////////////////////////////////////////////////////// @@ -1919,36 +1337,27 @@ SetShutDownCode ( *F*/ #ifdef WIN32 ACCESN_STATUS -MapPhysicalMemory ( - int startAddress, // physical address to map in - int addressLength, // how much to map - int *virtualAddress // where it got mapped to - ) +MapPhysicalMemory(int startAddress, int addressLength, int *virtualAddress) { - DWORD retLength; - BOOL status; + DWORD retLength; + BOOL status; PHYSICAL_MEMORY_INFO pmi; - if (startAddress == 0 || addressLength <= 0) + if (startAddress == 0 || addressLength <= 0) { return ACCESN_OUT_OF_RANGE; + } - pmi.InterfaceType = Internal; - pmi.BusNumber = 0; + pmi.InterfaceType = Internal; + pmi.BusNumber = 0; pmi.BusAddress.HighPart = (LONG)0x0; - pmi.BusAddress.LowPart = (LONG)startAddress; - pmi.AddressSpace = (LONG) 0; - pmi.Length = addressLength; - - status = DeviceIoControl ( hDevice, - IOCTL_IMB_MAP_MEMORY, - & pmi, - sizeof(PHYSICAL_MEMORY_INFO), - virtualAddress, - sizeof(PVOID), - & retLength, - 0 - ); - if( status == TRUE ) { + pmi.BusAddress.LowPart = (LONG)startAddress; + pmi.AddressSpace = (LONG)0; + pmi.Length = addressLength; + + status = DeviceIoControl(hDevice, IOCTL_IMB_MAP_MEMORY, &pmi, + sizeof(PHYSICAL_MEMORY_INFO), virtualAddress, + sizeof(PVOID), &retLength, 0); + if (status == TRUE) { return ACCESN_OK; } else { return ACCESN_ERROR; @@ -1956,40 +1365,27 @@ MapPhysicalMemory ( } ACCESN_STATUS -UnmapPhysicalMemory ( - int virtualAddress, // what memory to unmap - int Length ) +UnmapPhysicalMemory(int virtualAddress, int Length) { - DWORD retLength; - BOOL status; - - status = DeviceIoControl ( hDevice, - IOCTL_IMB_UNMAP_MEMORY, - & virtualAddress, - sizeof(PVOID), - NULL, - 0, - & retLength, - 0 - ); - - if( status == TRUE ) { + DWORD retLength; + BOOL status; + status = DeviceIoControl(hDevice, IOCTL_IMB_UNMAP_MEMORY, + &virtualAddress, sizeof(PVOID), NULL, 0, &retLength, 0); + if (status == TRUE) { return ACCESN_OK; } else { return ACCESN_ERROR; } } - -#else /*Linux, SCO, UNIX, etc.*/ - +#else /* Linux, SCO, UNIX, etc. */ ACCESN_STATUS -MapPhysicalMemory(int startAddress,int addressLength, int *virtualAddress ) +MapPhysicalMemory(int startAddress, int addressLength, int *virtualAddress) { - int fd; - unsigned int length = addressLength; - off_t startpAddress = (off_t)startAddress; - unsigned int diff; - char *startvAddress; + int fd; + unsigned int length = addressLength; + off_t startpAddress = (off_t)startAddress; + unsigned int diff; + char *startvAddress; #if defined(PAGESIZE) long int pagesize = PAGESIZE; #elif defined(_SC_PAGESIZE) @@ -1998,64 +1394,47 @@ MapPhysicalMemory(int startAddress,int addressLength, int *virtualAddress ) perror("Invalid pagesize"); } #else -# error PAGESIZE unsupported +# error PAGESIZE unsupported #endif - - if ((startAddress == 0) || (addressLength <= 0)) + if ((startAddress == 0) || (addressLength <= 0)) { return ACCESN_ERROR; - - if ( (fd = open("/dev/mem", O_RDONLY)) < 0) { + } + if ((fd = open("/dev/mem", O_RDONLY)) < 0) { char buf[128]; - sprintf(buf,"%s %s: open(%s) failed", - __FILE__,__FUNCTION__,IMB_DEVICE); + __FILE__, __FUNCTION__, IMB_DEVICE); perror(buf); - return ACCESN_ERROR ; + return ACCESN_ERROR; } - /* aliging the offset to a page boundary and adjusting the length */ diff = (int)startpAddress % pagesize; startpAddress -= diff; length += diff; - - if ( (startvAddress = mmap(0, - length, - PROT_READ, - MAP_SHARED, - fd, - startpAddress - ) ) == MAP_FAILED) - { + if ((startvAddress = mmap(0, length, PROT_READ, MAP_SHARED, fd, + startpAddress)) == MAP_FAILED) { char buf[128]; - - sprintf(buf,"%s %s: mmap failed", __FILE__,__FUNCTION__); + sprintf(buf, "%s %s: mmap failed", __FILE__, __FUNCTION__); perror(buf); close(fd); return ACCESN_ERROR; } -#ifndef NO_MACRO_ARGS - DEBUG("%s: mmap of 0x%x success\n",__FUNCTION__,startpAddress); -#endif + lprintf(LOG_DEBUG, "%s: mmap of 0x%x success", __FUNCTION__, + startpAddress); #ifdef LINUX_DEBUG_MAX -/* dont want this memory dump for normal level of debugging. -// So, I have put it under a stronger debug symbol. mahendra */ - - for(i=0; i < length; i++) - { + for (int i = 0; i < length; i++) { printf("0x%x ", (startvAddress[i])); if(isascii(startvAddress[i])) { printf("%c ", (startvAddress[i])); } - } -#endif /*LINUX_DEBUG_MAX */ - + } +#endif /* LINUX_DEBUG_MAX */ *virtualAddress = (long)(startvAddress + diff); close(fd); return ACCESN_OK; } ACCESN_STATUS -UnmapPhysicalMemory( int virtualAddress, int Length ) +UnmapPhysicalMemory(int virtualAddress, int Length) { unsigned int diff = 0; #if defined(PAGESIZE) @@ -2066,53 +1445,29 @@ UnmapPhysicalMemory( int virtualAddress, int Length ) perror("Invalid pagesize"); } #else -# error PAGESIZE unsupported +# error PAGESIZE unsupported #endif - /* page align the virtual address and adjust length accordingly */ - diff = ((unsigned int) virtualAddress) % pagesize; + diff = ((unsigned int)virtualAddress) % pagesize; virtualAddress -= diff; Length += diff; -#ifndef NO_MACRO_ARGS - DEBUG("%s: calling munmap(0x%x,%d)\n",__FUNCTION__,virtualAddress,Length); -#endif - - if(munmap(&virtualAddress, Length) != 0) - { + lprintf(LOG_DEBUG, "%s: calling munmap(0x%x,%d)", __FUNCTION__, + virtualAddress,Length); + if (munmap(&virtualAddress, Length) != 0) { char buf[128]; - - sprintf(buf,"%s %s: munmap failed", __FILE__,__FUNCTION__); + sprintf(buf, "%s %s: munmap failed", __FILE__, __FUNCTION__); perror(buf); return ACCESN_ERROR; - } -#ifndef NO_MACRO_ARGS - DEBUG("%s: munmap(0x%x,%d) success\n",__FUNCTION__,virtualAddress,Length); -#endif - + lprintf(LOG_DEBUG, "%s: munmap(0x%x,%d) success", __FUNCTION__, + virtualAddress, Length); return ACCESN_OK; } -#endif /*unix*/ +#endif /* unix */ - -/*///////////////////////////////////////////////////////////////////////////// -// GetIpmiVersion -//////////////////////////////////////////////////////////////////////////// */ - -/*F* -// Name: GetIpmiVersion -// Purpose: This function returns current IPMI version -// Context: -// Returns: IPMI version -// Parameters: -// reqPtr -// timeOut -// respDataPtr -// respLen -// Notes: svuppula -*F*/ -BYTE GetIpmiVersion() +/* GetIpmiVersion - returns current IPMI version. */ +BYTE +GetIpmiVersion() { - return IpmiVersion; + return IpmiVersion; } - diff --git a/src/plugins/ipmi_intf.c b/src/plugins/ipmi_intf.c index 6cf0553..9225a34 100644 --- a/src/plugins/ipmi_intf.c +++ b/src/plugins/ipmi_intf.c @@ -264,15 +264,9 @@ ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_c } void -ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey) +ipmi_intf_session_set_kgkey(struct ipmi_intf *intf, const uint8_t *kgkey) { - memset(intf->ssn_params.kg, 0, IPMI_KG_BUFFER_SIZE); - - if (kgkey == NULL) - return; - - memcpy(intf->ssn_params.kg, kgkey, - __min(strlen(kgkey), IPMI_KG_BUFFER_SIZE)); + memcpy(intf->ssn_params.kg, kgkey, IPMI_KG_BUFFER_SIZE); } void diff --git a/src/plugins/lanplus/lanplus.c b/src/plugins/lanplus/lanplus.c index 2a89a14..a0e388c 100644 --- a/src/plugins/lanplus/lanplus.c +++ b/src/plugins/lanplus/lanplus.c @@ -169,9 +169,14 @@ int lanplus_get_requested_ciphers(int cipher_suite_id, uint8_t * integrity_alg, uint8_t * crypt_alg) { +#ifdef HAVE_CRYPTO_SHA256 + if ((cipher_suite_id < 0) || (cipher_suite_id > 17)) { + return 1; + } +#else if ((cipher_suite_id < 0) || (cipher_suite_id > 14)) return 1; - +#endif /* HAVE_CRYPTO_SHA256 */ /* See table 22-19 for the source of the statement */ switch (cipher_suite_id) { @@ -250,6 +255,23 @@ int lanplus_get_requested_ciphers(int cipher_suite_id, *integrity_alg = IPMI_INTEGRITY_MD5_128; *crypt_alg = IPMI_CRYPT_XRC4_40; break; +#ifdef HAVE_CRYPTO_SHA256 + case 15: + *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA256; + *integrity_alg = IPMI_INTEGRITY_NONE; + *crypt_alg = IPMI_CRYPT_NONE; + break; + case 16: + *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA256; + *integrity_alg = IPMI_INTEGRITY_HMAC_SHA256_128; + *crypt_alg = IPMI_CRYPT_NONE; + break; + case 17: + *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA256; + *integrity_alg = IPMI_INTEGRITY_HMAC_SHA256_128; + *crypt_alg = IPMI_CRYPT_AES_CBC_128; + break; +#endif /* HAVE_CRYPTO_SHA256 */ } return 0; @@ -1022,15 +1044,34 @@ read_rakp2_message( break; case IPMI_AUTH_RAKP_HMAC_SHA1: - /* We need to copy 20 bytes */ - for (i = 0; i < 20; ++i) - rsp->payload.rakp2_message.key_exchange_auth_code[i] = - rsp->data[offset + 40 + i]; - break; + /* We need to copy 20 bytes */ + for (i = 0; i < IPMI_SHA_DIGEST_LENGTH; ++i) { + rsp->payload.rakp2_message.key_exchange_auth_code[i] = + rsp->data[offset + 40 + i]; + } + break; case IPMI_AUTH_RAKP_HMAC_MD5: - lprintf(LOG_ERR, "read_rakp2_message: no support for " - "IPMI_AUTH_RAKP_HMAC_MD5"); + /* We need to copy 16 bytes */ + for (i = 0; i < IPMI_MD5_DIGEST_LENGTH; ++i) { + rsp->payload.rakp2_message.key_exchange_auth_code[i] = + rsp->data[offset + 40 + i]; + } + break; + +#ifdef HAVE_CRYPTO_SHA256 + case IPMI_AUTH_RAKP_HMAC_SHA256: + /* We need to copy 32 bytes */ + for (i = 0; i < IPMI_SHA256_DIGEST_LENGTH; ++i) { + rsp->payload.rakp2_message.key_exchange_auth_code[i] = + rsp->data[offset + 40 + i]; + } + break; +#endif /* HAVE_CRYPTO_SHA256 */ + + default: + lprintf(LOG_ERR, "read_rakp2_message: no support " + "for authentication algorithm 0x%x", auth_alg); assert(0); break; } @@ -1088,13 +1129,32 @@ read_rakp4_message( break; case IPMI_AUTH_RAKP_HMAC_SHA1: - /* We need to copy 12 bytes */ - for (i = 0; i < 12; ++i) - rsp->payload.rakp4_message.integrity_check_value[i] = - rsp->data[offset + 8 + i]; - break; + /* We need to copy 12 bytes */ + for (i = 0; i < IPMI_SHA1_AUTHCODE_SIZE; ++i) { + rsp->payload.rakp4_message.integrity_check_value[i] = + rsp->data[offset + 8 + i]; + } + break; case IPMI_AUTH_RAKP_HMAC_MD5: + /* We need to copy 16 bytes */ + for (i = 0; i < IPMI_HMAC_MD5_AUTHCODE_SIZE; ++i) { + rsp->payload.rakp4_message.integrity_check_value[i] = + rsp->data[offset + 8 + i]; + } + break; + +#ifdef HAVE_CRYPTO_SHA256 + case IPMI_AUTH_RAKP_HMAC_SHA256: + /* We need to copy 16 bytes */ + for (i = 0; i < IPMI_HMAC_SHA256_AUTHCODE_SIZE; ++i) { + rsp->payload.rakp4_message.integrity_check_value[i] = + rsp->data[offset + 8 + i]; + } + break; +#endif /* HAVE_CRYPTO_SHA256 */ + + default: lprintf(LOG_ERR, "read_rakp4_message: no support " "for authentication algorithm 0x%x", auth_alg); assert(0); @@ -1760,7 +1820,11 @@ ipmi_lanplus_build_v2x_msg( if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE) && (session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE)) { - uint32_t i, hmac_length, integrity_pad_size = 0, hmac_input_size; + uint32_t i; + uint32_t hmac_length; + uint32_t auth_length = 0; + uint32_t integrity_pad_size = 0; + uint32_t hmac_input_size; uint8_t * hmac_output; uint32_t start_of_session_trailer = IPMI_LANPLUS_OFFSET_PAYLOAD + @@ -1818,22 +1882,43 @@ ipmi_lanplus_build_v2x_msg( /* Auth Code */ lanplus_HMAC(session->v2_data.integrity_alg, session->v2_data.k1, /* key */ - 20, /* key length */ + session->v2_data.k1_len, /* key length */ msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */ hmac_input_size, hmac_output, &hmac_length); - assert(hmac_length == 20); + switch(session->v2_data.integrity_alg) { + case IPMI_INTEGRITY_HMAC_SHA1_96: + assert(hmac_length == IPMI_SHA_DIGEST_LENGTH); + auth_length = IPMI_SHA1_AUTHCODE_SIZE; + break; + case IPMI_INTEGRITY_HMAC_MD5_128 : + assert(hmac_length == IPMI_MD5_DIGEST_LENGTH); + auth_length = IPMI_HMAC_MD5_AUTHCODE_SIZE; + break; +#ifdef HAVE_CRYPTO_SHA256 + case IPMI_INTEGRITY_HMAC_SHA256_128: + assert(hmac_length == IPMI_SHA256_DIGEST_LENGTH); + auth_length = IPMI_HMAC_SHA256_AUTHCODE_SIZE; + break; +#endif /* HAVE_CRYPTO_SHA256 */ + default: + assert(0); + break; + } if (verbose > 2) - printbuf(hmac_output, 12, "authcode output"); + printbuf(hmac_output, auth_length, "authcode output"); /* Set session_trailer_length appropriately */ session_trailer_length = integrity_pad_size + 2 + /* pad length + next header */ - 12; /* Size of the authcode (we only use the first 12 bytes) */ + auth_length; /* Size of the authcode. We only + * use the first 12(SHA1) or + * 16(MD5/SHA256) bytes. + */ } @@ -2284,6 +2369,10 @@ ipmi_lanplus_send_payload( rsp = ipmi_lanplus_recv_sol(intf); /* Grab the next packet */ + if (!is_sol_packet(rsp)) { + break; + } + if (sol_response_acks_packet(rsp, payload)) break; @@ -2296,6 +2385,7 @@ ipmi_lanplus_send_payload( intf->session->sol_data.sol_input_handler(rsp); /* In order to avoid duplicate output, just set data_len to 0 */ rsp->data_len = 0; + break; } } diff --git a/src/plugins/lanplus/lanplus.h b/src/plugins/lanplus/lanplus.h index 4b6ae1e..d967462 100644 --- a/src/plugins/lanplus/lanplus.h +++ b/src/plugins/lanplus/lanplus.h @@ -96,12 +96,20 @@ #define IPMI_MAX_CONF_HEADER_SIZE 0x20 #define IPMI_MAX_PAYLOAD_SIZE 0xFFFF /* Includes confidentiality header/trailer */ #define IPMI_MAX_CONF_TRAILER_SIZE 0x20 -#define IPMI_MAX_INTEGRITY_PAD_SIZE 0x20 -#define IPMI_MAX_AUTH_CODE_SIZE 0x20 +#define IPMI_MAX_INTEGRITY_PAD_SIZE IPMI_MAX_MD_SIZE +#define IPMI_MAX_AUTH_CODE_SIZE IPMI_MAX_MD_SIZE #define IPMI_REQUEST_MESSAGE_SIZE 0x07 -#define IPMI_MAX_MAC_SIZE 0x14 /* The largest mac we ever expect to generate */ -#define IPMI_SHA1_AUTHCODE_SIZE 0x0C +#define IPMI_MAX_MAC_SIZE IPMI_MAX_MD_SIZE /* The largest mac we ever expect to generate */ + +#define IPMI_SHA1_AUTHCODE_SIZE 12 +#define IPMI_HMAC_MD5_AUTHCODE_SIZE 16 +#define IPMI_MD5_AUTHCODE_SIZE 16 +#define IPMI_HMAC_SHA256_AUTHCODE_SIZE 16 + +#define IPMI_SHA_DIGEST_LENGTH 20 +#define IPMI_MD5_DIGEST_LENGTH 16 +#define IPMI_SHA256_DIGEST_LENGTH 32 /* *This is accurate, as long as we're only passing 1 auth algorithm, @@ -109,7 +117,7 @@ */ #define IPMI_OPEN_SESSION_REQUEST_SIZE 32 #define IPMI_RAKP1_MESSAGE_SIZE 44 -#define IPMI_RAKP3_MESSAGE_MAX_SIZE 28 +#define IPMI_RAKP3_MESSAGE_MAX_SIZE (8 + IPMI_MAX_MD_SIZE) #define IPMI_MAX_USER_NAME_LENGTH 16 diff --git a/src/plugins/lanplus/lanplus_crypt.c b/src/plugins/lanplus/lanplus_crypt.c index 1cdd050..cb963f4 100644 --- a/src/plugins/lanplus/lanplus_crypt.c +++ b/src/plugins/lanplus/lanplus_crypt.c @@ -74,7 +74,7 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session, { uint8_t * buffer; int bufferLength, i; - uint8_t mac[20]; + uint8_t mac[IPMI_MAX_MD_SIZE]; uint32_t macLength; uint32_t SIDm_lsbf, SIDc_lsbf; @@ -84,7 +84,12 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session, return 1; /* We don't yet support other algorithms */ - assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1); + assert((session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1) + || (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_MD5) +#ifdef HAVE_CRYPTO_SHA256 + || (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA256) +#endif /* HAVE_CRYPTO_SHA256 */ + ); bufferLength = @@ -228,8 +233,9 @@ lanplus_rakp4_hmac_matches(const struct ipmi_session * session, { uint8_t * buffer; int bufferLength, i; - uint8_t mac[20]; + uint8_t mac[IPMI_MAX_MD_SIZE]; uint32_t macLength; + uint32_t cmpLength; uint32_t SIDc_lsbf; if (ipmi_oem_active(intf, "intelplus")){ @@ -238,13 +244,19 @@ lanplus_rakp4_hmac_matches(const struct ipmi_session * session, return 1; /* We don't yet support other algorithms */ - assert(session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_SHA1_96); + assert((session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_SHA1_96) + || (session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_MD5_128)); } else { if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE) return 1; /* We don't yet support other algorithms */ - assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1); + assert((session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1) + || (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_MD5) +#ifdef HAVE_CRYPTO_SHA256 + || (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA256) +#endif /* HAVE_CRYPTO_SHA256 */ + ); } bufferLength = @@ -294,7 +306,8 @@ lanplus_rakp4_hmac_matches(const struct ipmi_session * session, if (verbose > 2) { printbuf((const uint8_t *)buffer, bufferLength, ">> rakp4 mac input buffer"); - printbuf(session->v2_data.sik, 20l, ">> rakp4 mac key (sik)"); + printbuf(session->v2_data.sik, session->v2_data.sik_len, + ">> rakp4 mac key (sik)"); } @@ -305,7 +318,7 @@ lanplus_rakp4_hmac_matches(const struct ipmi_session * session, ? session->v2_data.integrity_alg : session->v2_data.auth_alg , session->v2_data.sik, - IPMI_SIK_BUFFER_SIZE, + session->v2_data.sik_len, buffer, bufferLength, mac, @@ -317,12 +330,48 @@ lanplus_rakp4_hmac_matches(const struct ipmi_session * session, printbuf(mac, macLength, ">> rakp4 mac as computed by the remote console"); } - + if (ipmi_oem_active(intf, "intelplus")) { + /* Intel BMC responds with the integrity Algorithm in RAKP4 */ + switch(session->v2_data.integrity_alg) { + case IPMI_INTEGRITY_HMAC_SHA1_96: + assert(macLength == IPMI_SHA_DIGEST_LENGTH); + cmpLength = IPMI_SHA1_AUTHCODE_SIZE; + break; + case IPMI_INTEGRITY_HMAC_MD5_128: + assert(macLength == IPMI_MD5_DIGEST_LENGTH); + cmpLength = IPMI_HMAC_MD5_AUTHCODE_SIZE; + break; + default: + assert(0); + break; + } + } else { + /* We don't yet support other algorithms */ + switch(session->v2_data.auth_alg) { + case IPMI_AUTH_RAKP_HMAC_SHA1: + assert(macLength == IPMI_SHA_DIGEST_LENGTH); + cmpLength = IPMI_SHA1_AUTHCODE_SIZE; + break; + case IPMI_AUTH_RAKP_HMAC_MD5: + assert(macLength == IPMI_MD5_DIGEST_LENGTH); + cmpLength = IPMI_HMAC_MD5_AUTHCODE_SIZE; + break; +#ifdef HAVE_CRYPTO_SHA256 + case IPMI_AUTH_RAKP_HMAC_SHA256: + assert(macLength == IPMI_SHA256_DIGEST_LENGTH); + cmpLength = IPMI_HMAC_SHA256_AUTHCODE_SIZE; + break; +#endif /* HAVE_CRYPTO_SHA256 */ + default: + assert(0); + break; + } + } free(buffer); buffer = NULL; - assert(macLength == 20); - return (memcmp(bmc_mac, mac, 12) == 0); + assert(macLength >= cmpLength); + return (memcmp(bmc_mac, mac, cmpLength) == 0); } @@ -368,7 +417,12 @@ lanplus_generate_rakp3_authcode(uint8_t * output_buffer, } /* We don't yet support other algorithms */ - assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1); + assert((session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1) + || (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_MD5) +#ifdef HAVE_CRYPTO_SHA256 + || (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA256) +#endif /* HAVE_CRYPTO_SHA256 */ + ); input_buffer_length = 16 + /* Rc */ @@ -478,13 +532,19 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf) uint32_t mac_length; - memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE); + memset(session->v2_data.sik, 0, sizeof(session->v2_data.sik)); + session->v2_data.sik_len = 0; if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE) return 0; /* We don't yet support other algorithms */ - assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1); + assert((session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1) + || (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_MD5) +#ifdef HAVE_CRYPTO_SHA256 + || (session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA256) +#endif /* HAVE_CRYPTO_SHA256 */ + ); input_buffer_length = 16 + /* Rm */ @@ -572,15 +632,33 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf) free(input_buffer); input_buffer = NULL; - assert(mac_length == 20); + switch (session->v2_data.auth_alg) { + case IPMI_AUTH_RAKP_HMAC_SHA1: + assert(mac_length == IPMI_SHA_DIGEST_LENGTH); + break; + case IPMI_AUTH_RAKP_HMAC_MD5: + assert(mac_length == IPMI_MD5_DIGEST_LENGTH); + break; +#ifdef HAVE_CRYPTO_SHA256 + case IPMI_AUTH_RAKP_HMAC_SHA256: + assert(mac_length == IPMI_SHA256_DIGEST_LENGTH); + break; +#endif /* HAVE_CRYPTO_SHA256 */ + default: + assert(0); + break; + } + + session->v2_data.sik_len = mac_length; /* * The key MAC generated is 20 bytes, but we will only be using the first * 12 for SHA1 96 */ - if (verbose >= 2) - printbuf(session->v2_data.sik, 20, "Generated session integrity key"); - + if (verbose >= 2) { + printbuf(session->v2_data.sik, session->v2_data.sik_len, + "Generated session integrity key"); + } return 0; } @@ -614,16 +692,32 @@ lanplus_generate_k1(struct ipmi_session * session) { lanplus_HMAC(session->v2_data.auth_alg, session->v2_data.sik, - IPMI_SIK_BUFFER_SIZE, /* SIK length */ + session->v2_data.sik_len, /* SIK length */ CONST_1, 20, session->v2_data.k1, &mac_length); - assert(mac_length == 20); + switch (session->v2_data.auth_alg) { + case IPMI_AUTH_RAKP_HMAC_SHA1: + assert(mac_length == IPMI_SHA_DIGEST_LENGTH); + break; + case IPMI_AUTH_RAKP_HMAC_MD5: + assert(mac_length == IPMI_MD5_DIGEST_LENGTH); + break; +#ifdef HAVE_CRYPTO_SHA256 + case IPMI_AUTH_RAKP_HMAC_SHA256: + assert(mac_length == IPMI_SHA256_DIGEST_LENGTH); + break; +#endif /* HAVE_CRYPTO_SHA256 */ + default: + assert(0); + break; + } + session->v2_data.k1_len = mac_length; } if (verbose >= 2) - printbuf(session->v2_data.k1, 20, "Generated K1"); + printbuf(session->v2_data.k1, session->v2_data.k1_len, "Generated K1"); return 0; } @@ -658,16 +752,32 @@ lanplus_generate_k2(struct ipmi_session * session) { lanplus_HMAC(session->v2_data.auth_alg, session->v2_data.sik, - IPMI_SIK_BUFFER_SIZE, /* SIK length */ + session->v2_data.sik_len, /* SIK length */ CONST_2, 20, session->v2_data.k2, &mac_length); - assert(mac_length == 20); + switch (session->v2_data.auth_alg) { + case IPMI_AUTH_RAKP_HMAC_SHA1: + assert(mac_length == IPMI_SHA_DIGEST_LENGTH); + break; + case IPMI_AUTH_RAKP_HMAC_MD5: + assert(mac_length == IPMI_MD5_DIGEST_LENGTH); + break; +#ifdef HAVE_CRYPTO_SHA256 + case IPMI_AUTH_RAKP_HMAC_SHA256: + assert(mac_length == IPMI_SHA256_DIGEST_LENGTH); + break; +#endif /* HAVE_CRYPTO_SHA256 */ + default: + assert(0); + break; + } + session->v2_data.k2_len = mac_length; } if (verbose >= 2) - printbuf(session->v2_data.k2, 20, "Generated K2"); + printbuf(session->v2_data.k2, session->v2_data.k2_len, "Generated K2"); return 0; } @@ -803,6 +913,7 @@ lanplus_has_valid_auth_code(struct ipmi_rs * rs, struct ipmi_session * session) uint8_t * bmc_authcode; uint8_t generated_authcode[IPMI_MAX_MAC_SIZE]; uint32_t generated_authcode_length; + uint32_t authcode_length; if ((rs->session.authtype != IPMI_SESSION_AUTHTYPE_RMCP_PLUS) || @@ -811,36 +922,51 @@ lanplus_has_valid_auth_code(struct ipmi_rs * rs, struct ipmi_session * session) (session->v2_data.integrity_alg == IPMI_INTEGRITY_NONE)) return 1; - /* We only support SHA1-96 now */ - assert(session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_SHA1_96); + switch (session->v2_data.integrity_alg) { + case IPMI_INTEGRITY_HMAC_SHA1_96: + authcode_length = IPMI_SHA1_AUTHCODE_SIZE; + break; + case IPMI_INTEGRITY_HMAC_MD5_128: + authcode_length = IPMI_HMAC_MD5_AUTHCODE_SIZE; + break; +#ifdef HAVE_CRYPTO_SHA256 + case IPMI_INTEGRITY_HMAC_SHA256_128: + authcode_length = IPMI_HMAC_SHA256_AUTHCODE_SIZE; + break; +#endif /* HAVE_CRYPTO_SHA256 */ + /* Unsupported */ + default: + assert(0); + break; + } /* * For SHA1-96, the authcode will be the last 12 bytes in the packet + * For SHA256-128 or MD5-128, the authcode will be the last 16 bytes in the packet */ - bmc_authcode = rs->data + (rs->data_len - IPMI_SHA1_AUTHCODE_SIZE); + bmc_authcode = rs->data + (rs->data_len - authcode_length); lanplus_HMAC(session->v2_data.integrity_alg, session->v2_data.k1, - IPMI_AUTHCODE_BUFFER_SIZE, + session->v2_data.k1_len, rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE, - rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, + rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - authcode_length, generated_authcode, &generated_authcode_length); if (verbose > 3) { lprintf(LOG_DEBUG+2, "Validating authcode"); - printbuf(session->v2_data.k1, 20, "K1"); + printbuf(session->v2_data.k1, session->v2_data.k1_len, "K1"); printbuf(rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE, - rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, + rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - authcode_length, "Authcode Input Data"); - printbuf(generated_authcode, 12, "Generated authcode"); - printbuf(bmc_authcode, 12, "Expected authcode"); + printbuf(generated_authcode, generated_authcode_length, "Generated authcode"); + printbuf(bmc_authcode, authcode_length, "Expected authcode"); } - - assert(generated_authcode_length == 20); - return (memcmp(bmc_authcode, generated_authcode, 12) == 0); + assert(generated_authcode_length >= authcode_length); + return (memcmp(bmc_authcode, generated_authcode, authcode_length) == 0); } diff --git a/src/plugins/lanplus/lanplus_crypt_impl.c b/src/plugins/lanplus/lanplus_crypt_impl.c index cde6c54..d5fac37 100644 --- a/src/plugins/lanplus/lanplus_crypt_impl.c +++ b/src/plugins/lanplus/lanplus_crypt_impl.c @@ -99,7 +99,8 @@ lanplus_rand(uint8_t * buffer, uint32_t num_bytes) /* * lanplus_HMAC * - * param mac specifies the algorithm to be used, currently only SHA1 is supported + * param mac specifies the algorithm to be used, currently SHA1, SHA256 and MD5 + * are supported * param key is the key used for HMAC generation * param key_len is the lenght of key * param d is the data to be MAC'd @@ -123,6 +124,14 @@ lanplus_HMAC(uint8_t mac, if ((mac == IPMI_AUTH_RAKP_HMAC_SHA1) || (mac == IPMI_INTEGRITY_HMAC_SHA1_96)) evp_md = EVP_sha1(); + else if ((mac == IPMI_AUTH_RAKP_HMAC_MD5) || + (mac == IPMI_INTEGRITY_HMAC_MD5_128)) + evp_md = EVP_md5(); +#ifdef HAVE_CRYPTO_SHA256 + else if ((mac == IPMI_AUTH_RAKP_HMAC_SHA256) || + (mac == IPMI_INTEGRITY_HMAC_SHA256_128)) + evp_md = EVP_sha256(); +#endif /* HAVE_CRYPTO_SHA256 */ else { lprintf(LOG_DEBUG, "Invalid mac type 0x%x in lanplus_HMAC\n", mac); diff --git a/src/plugins/lanplus/lanplus_dump.c b/src/plugins/lanplus/lanplus_dump.c index 8d52fab..bbfc1b0 100644 --- a/src/plugins/lanplus/lanplus_dump.c +++ b/src/plugins/lanplus/lanplus_dump.c @@ -31,6 +31,7 @@ */ #include "lanplus.h" +#include "lanplus_crypt.h" #include "lanplus_dump.h" extern const struct valstr ipmi_rakp_return_codes[]; @@ -127,16 +128,27 @@ void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, uint8_t auth_alg) break; case IPMI_AUTH_RAKP_HMAC_SHA1: printf("%s Key exchange auth code [sha1] : 0x", DUMP_PREFIX_INCOMING); - for (i = 0; i < 20; ++i) + for (i = 0; i < IPMI_SHA_DIGEST_LENGTH; ++i) { printf("%02x", rsp->payload.rakp2_message.key_exchange_auth_code[i]); - printf("\n"); + } + printf("\n"); break; case IPMI_AUTH_RAKP_HMAC_MD5: printf("%s Key exchange auth code [md5] : 0x", DUMP_PREFIX_INCOMING); - for (i = 0; i < 16; ++i) + for (i = 0; i < IPMI_MD5_DIGEST_LENGTH; ++i) { printf("%02x", rsp->payload.rakp2_message.key_exchange_auth_code[i]); - printf("\n"); + } + printf("\n"); break; +#ifdef HAVE_CRYPTO_SHA256 + case IPMI_AUTH_RAKP_HMAC_SHA256: + printf("%s Key exchange auth code [sha256]: 0x", DUMP_PREFIX_INCOMING); + for (i = 0; i < IPMI_SHA256_DIGEST_LENGTH; ++i) { + printf("%02x", rsp->payload.rakp2_message.key_exchange_auth_code[i]); + } + printf("\n"); + break; +#endif /* HAVE_CRYPTO_SHA256 */ default: printf("%s Key exchange auth code : invalid", DUMP_PREFIX_INCOMING); } @@ -174,16 +186,27 @@ void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, uint8_t auth_alg) break; case IPMI_AUTH_RAKP_HMAC_SHA1: printf("%s Key exchange auth code [sha1] : 0x", DUMP_PREFIX_INCOMING); - for (i = 0; i < 12; ++i) + for (i = 0; i < IPMI_SHA1_AUTHCODE_SIZE; ++i) { printf("%02x", rsp->payload.rakp4_message.integrity_check_value[i]); - printf("\n"); + } + printf("\n"); break; case IPMI_AUTH_RAKP_HMAC_MD5: printf("%s Key exchange auth code [md5] : 0x", DUMP_PREFIX_INCOMING); - for (i = 0; i < 12; ++i) + for (i = 0; i < IPMI_HMAC_MD5_AUTHCODE_SIZE; ++i) { + printf("%02x", rsp->payload.rakp4_message.integrity_check_value[i]); + } + printf("\n"); + break; +#ifdef HAVE_CRYPTO_SHA256 + case IPMI_AUTH_RAKP_HMAC_SHA256: + printf("%s Key exchange auth code [sha256]: 0x", DUMP_PREFIX_INCOMING); + for (i = 0; i < IPMI_HMAC_SHA256_AUTHCODE_SIZE; ++i) { printf("%02x", rsp->payload.rakp4_message.integrity_check_value[i]); - printf("\n"); + } + printf("\n"); break; +#endif /* HAVE_CRYPTO_SHA256 */ default: printf("%s Key exchange auth code : invalid", DUMP_PREFIX_INCOMING); } diff --git a/src/plugins/open/open.c b/src/plugins/open/open.c index df56172..5beeac7 100644 --- a/src/plugins/open/open.c +++ b/src/plugins/open/open.c @@ -29,7 +29,7 @@ * 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. */ -#define _POSIX_SOURCE +#define _POSIX_C_SOURCE 1 #include <stdio.h> #include <fcntl.h> diff --git a/src/plugins/serial/serial_basic.c b/src/plugins/serial/serial_basic.c index e3322c1..21a239a 100644 --- a/src/plugins/serial/serial_basic.c +++ b/src/plugins/serial/serial_basic.c @@ -33,7 +33,9 @@ /* Serial Interface, Basic Mode plugin. */ +#if defined HAVE_ALLOCA_H #include <alloca.h> +#endif #include <stdio.h> #include <fcntl.h> #include <time.h> @@ -79,7 +81,7 @@ struct ipmb_msg_hdr { unsigned char rqSA; unsigned char rqSeq; /* RQ SEQ | RQ LUN */ unsigned char cmd; - unsigned char data[0]; + unsigned char data[]; }; /* @@ -101,7 +103,7 @@ struct ipmi_get_message_rp { unsigned char rsSA; unsigned char rqSeq; unsigned char cmd; - unsigned char data[0]; + unsigned char data[]; }; /* @@ -128,7 +130,7 @@ struct serial_bm_parse_ctx{ * Receiving context */ struct serial_bm_recv_ctx { - char buffer[SERIAL_BM_MAX_BUFFER_SIZE]; + uint8_t buffer[SERIAL_BM_MAX_BUFFER_SIZE]; size_t buffer_size; size_t max_buffer_size; }; diff --git a/src/plugins/serial/serial_terminal.c b/src/plugins/serial/serial_terminal.c index cd33422..4459f64 100644 --- a/src/plugins/serial/serial_terminal.c +++ b/src/plugins/serial/serial_terminal.c @@ -33,7 +33,9 @@ /* Serial Interface, Terminal Mode plugin. */ +#if defined HAVE_ALLOCA_H #include <alloca.h> +#endif #include <stdio.h> #include <fcntl.h> #include <unistd.h> @@ -77,7 +79,7 @@ struct ipmb_msg_hdr { unsigned char rqSA; unsigned char rqSeq; /* RQ SEQ | RQ LUN */ unsigned char cmd; - unsigned char data[0]; + unsigned char data[]; }; /* @@ -99,7 +101,7 @@ struct ipmi_get_message_rp { unsigned char rsSA; unsigned char rqSeq; unsigned char cmd; - unsigned char data[0]; + unsigned char data[]; }; /* @@ -371,8 +373,9 @@ recv_response(struct ipmi_intf * intf, unsigned char *data, int len) } p += rv; resp_len += rv; - if (*(p - 2) == ']' && (*(p - 1) == '\n' || *(p - 1) == '\r')) { - *p = 0; + if (resp_len >= 2 && *(p - 2) == ']' + && (*(p - 1) == '\n' || *(p - 1) == '\r')) { + *(p - 1) = 0; /* overwrite EOL */ break; } } |