mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-07-01 02:03:50 +00:00
Compare commits
98 Commits
IPMITOOL_1
...
IPMITOOL_1
Author | SHA1 | Date | |
---|---|---|---|
d0f52c7a6b | |||
2e7571daf2 | |||
c13966f04b | |||
56b892cea1 | |||
bec24b9019 | |||
45185b23ec | |||
ecca25ed2b | |||
eccd10200f | |||
0bad3feabd | |||
edb0ba9c6d | |||
c4a368edfb | |||
b136863199 | |||
628c3ca854 | |||
0a682dbedd | |||
b3dde472ce | |||
22f0fc7c00 | |||
6eaa2e8305 | |||
992b36bc0f | |||
6a68dc2e65 | |||
66958d8c52 | |||
333dc5bedc | |||
a62287c589 | |||
43a529bff0 | |||
cf96efd47d | |||
9cbe0938f1 | |||
7acd1310ec | |||
77b47d3751 | |||
9a4979ac62 | |||
9e4bbc2e65 | |||
8fc8e1a69a | |||
18b6d4cc08 | |||
a74e7d396a | |||
88af9d3652 | |||
968e97d905 | |||
459770d58c | |||
c28da79cab | |||
b548d3573b | |||
68afc1b001 | |||
c78911c730 | |||
6ac87eed90 | |||
9f66ac2cd3 | |||
3bd95062ba | |||
86a32205be | |||
583a5e7cd0 | |||
381783786a | |||
cea777a51d | |||
e3c97ddd3d | |||
e7f7209c32 | |||
5d21a9d8a8 | |||
74e028690b | |||
fda2c028fe | |||
19f9d13807 | |||
9fcde40c97 | |||
34b21d2d57 | |||
9e14d37835 | |||
981a24365f | |||
729bf0e7c3 | |||
db4a2e5951 | |||
ef20239926 | |||
e672819a9d | |||
f61c3acbaf | |||
eab4dfe679 | |||
89199b49f3 | |||
96dec6ddc7 | |||
153965aca2 | |||
4e79265a7c | |||
1c60cbf500 | |||
b82cfdf945 | |||
09a6e0e917 | |||
760de11c71 | |||
50f36dd841 | |||
0d6fecc737 | |||
ab58809b3b | |||
d572add750 | |||
fa21266ec2 | |||
f63189780f | |||
7849cc978f | |||
6013cec710 | |||
9f6133936d | |||
580f416693 | |||
c99e8595e4 | |||
a92765fbc9 | |||
cc63758d53 | |||
388b9e058d | |||
520aa05c07 | |||
533582e9e3 | |||
c3289bb6f4 | |||
b3d2bb937d | |||
070f36d1ae | |||
882d9ce81c | |||
d0e5434790 | |||
4ab522ab29 | |||
ce3636894d | |||
83a924d7ed | |||
28a7f2c14b | |||
10154ba9ce | |||
12a6554416 | |||
78f8f0793f |
@ -1,3 +1,51 @@
|
||||
version 1.8.9 released 2007-03-06
|
||||
* Added initial AMC ekey query operation support
|
||||
* Improvements to ekeying support (PICMG 3.x only)
|
||||
* Added initial interactive edition support for multirec; added IANA
|
||||
verification before interpreting PICMG records.
|
||||
* Added edit support for AMC activation "Maximum Internal Current"
|
||||
* Fix bug generating garbage on the screen when handling GetDeviceId
|
||||
and sol traffic occurs
|
||||
* Added ability to map OEM sensor types to OEM description string using
|
||||
IANA number; moved IANA number table
|
||||
* Fix lan set access command to use value already saved within
|
||||
parameters for PEF and authentication
|
||||
* Fix bug in cmd ipmitool lan stats get 1
|
||||
* Add support to allow ipmitool/ipmievd to target specific device
|
||||
nodes on multi-BMC systems
|
||||
* Add support for name+privilege lookup for lanplus sessions
|
||||
* Fix time_t conversion bug for 64-bit OS
|
||||
* Added prefix of hostname on sel ipmievd sessions
|
||||
* Fixed FWUM Get Info
|
||||
* Fix ipmievd fd closing bug
|
||||
* Add set-in-progress flag support to chassis bootdev
|
||||
* Added new chassis bootdev options
|
||||
* Add sol payload enable/disable comman
|
||||
* Fix SOL set errors when commit-write not supported
|
||||
* Fix reset of session timeout for lanplus interface
|
||||
* Fixed lan interface accessibility timeout handling
|
||||
* Fix bug with Function Get Channel Cipher Suites command when
|
||||
more than 1 page used.
|
||||
* Fix missing firmware firewall top-level command
|
||||
* Fix bug in SOL keepalive functionality
|
||||
* Fix SOLv2 NACK and retry handling for Intel ESB2 BMC
|
||||
* Added ipmi_sel_get_oem_sensor* APIs
|
||||
* Added HPM.1 support
|
||||
* Fix segfault when incorrect oem option supplied
|
||||
* Fix bus problem with spd command
|
||||
* Fix segfault in SOL when remote BMC does not return packet
|
||||
* Adjust packet length for AMC.0 retricting IPMB packets to 32 bytes
|
||||
* Added lan packet size reduction mechanism
|
||||
* Fix bug with sendMessage of bad length with different target
|
||||
* Fix for big endian (PPC) architecture
|
||||
* NetBSD fixes
|
||||
* Fix segfault and channel problem with user priv command
|
||||
* Add support for bus/chan on i2c raw command
|
||||
* Add freeipmi interface support
|
||||
* Add remote spd printing
|
||||
* Add better detection of linux/compiler.h to config
|
||||
* Makefile changes to fix makedistcheck, etc.
|
||||
|
||||
version 1.8.8
|
||||
* Fix segfaults in sensor data repository list
|
||||
* Fix ipmievd to open interface before daemonizing
|
||||
|
@ -28,8 +28,8 @@
|
||||
# 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.
|
||||
|
||||
DOCDIR = $(DESTDIR)/$(datadir)/doc/$(PACKAGE)
|
||||
DOCLIST = README COPYING AUTHORS ChangeLog
|
||||
DOCDIR = $(datadir)/doc/$(PACKAGE)
|
||||
DOCLIST = $(top_srcdir)/README $(top_srcdir)/COPYING $(top_srcdir)/AUTHORS $(top_srcdir)/ChangeLog
|
||||
|
||||
EXTRA_DIST = $(DOCLIST) \
|
||||
debian/changelog debian/control debian/copyright \
|
||||
@ -48,8 +48,11 @@ dist-hook:
|
||||
cp control/ipmitool.spec $(distdir)
|
||||
|
||||
install-data-local:
|
||||
mkdir -p $(DOCDIR)
|
||||
install -m 644 $(DOCLIST) $(DOCDIR)
|
||||
mkdir -p $(DESTDIR)$(DOCDIR)
|
||||
$(INSTALL_DATA) $(DOCLIST) $(DESTDIR)$(DOCDIR)
|
||||
|
||||
uninstall-local:
|
||||
-rm -rf $(DESTDIR)$(DOCDIR)
|
||||
|
||||
.PHONY: pkg
|
||||
pkg: PKG := ipmitool-@VERSION@-@OS@-@ARCH@
|
||||
@ -76,4 +79,3 @@ rpm: control/ipmitool.spec dist
|
||||
.PHONY: clean-rpm
|
||||
clean-rpm:
|
||||
-rm -rf $(RPMDIR)
|
||||
|
||||
|
@ -3,7 +3,7 @@ dnl autoconf for ipmitool
|
||||
dnl
|
||||
AC_INIT([src/ipmitool.c])
|
||||
AC_CANONICAL_SYSTEM
|
||||
AM_INIT_AUTOMAKE([ipmitool], [1.8.8])
|
||||
AM_INIT_AUTOMAKE([ipmitool], [1.8.9])
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_SRCDIR([src/ipmitool.c])
|
||||
AC_PREREQ(2.50)
|
||||
@ -183,6 +183,8 @@ else
|
||||
enable_intf_lanplus=no
|
||||
fi
|
||||
|
||||
ORIG_CPPFLAGS=$CPPFLAGS
|
||||
|
||||
dnl look for OpenIPMI header files
|
||||
AC_ARG_WITH([kerneldir],
|
||||
[AC_HELP_STRING([--with-kerneldir=DIR],
|
||||
@ -192,6 +194,8 @@ AC_ARG_WITH([kerneldir],
|
||||
fi
|
||||
CFLAGS="$CFLAGS -I ${with_kerneldir}/include"
|
||||
AC_SUBST(CFLAGS)
|
||||
CPPFLAGS="$CPPFLAGS -I ${with_kerneldir}/include"
|
||||
AC_SUBST(CPPFLAGS)
|
||||
if test -s ${with_kerneldir}/include/linux/version.h ; then
|
||||
kernelver=`grep UTS_RELEASE ${with_kerneldir}/include/linux/version.h | \
|
||||
sed 's/^\#define UTS_RELEASE \"\(2\.[0-9]\)\..*/\1/'`
|
||||
@ -200,6 +204,18 @@ AC_ARG_WITH([kerneldir],
|
||||
AC_SUBST(CPPFLAGS)
|
||||
fi
|
||||
fi])
|
||||
|
||||
AH_TEMPLATE([HAVE_LINUX_COMPILER_H], [])
|
||||
AC_MSG_CHECKING([for linux/compiler.h])
|
||||
AC_PREPROC_IFELSE([#include <linux/compiler.h>],
|
||||
[AC_DEFINE(HAVE_LINUX_COMPILER_H, [1],
|
||||
[Define to 1 if you have the <linux/compiler.h> header file.])
|
||||
AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
|
||||
CPPFLAGS=$ORIG_CPPFLAGS
|
||||
AC_SUBST(CPPFLAGS)
|
||||
|
||||
AC_CHECK_HEADER([linux/ipmi.h],
|
||||
[AC_DEFINE(HAVE_OPENIPMI_H, [1],
|
||||
[Define to 1 if you have the <linux/ipmi.h> header file.])],
|
||||
@ -208,6 +224,47 @@ AC_CHECK_HEADER([linux/ipmi.h],
|
||||
[Define to 1 if you have the <sys/ipmi.h> header file.])],
|
||||
[echo "** Unable to find OpenIPMI header files. Using internal version."])])
|
||||
|
||||
dnl look for FreeIPMI files
|
||||
AC_CHECK_LIB(freeipmi, ipmi_open_inband, [have_free=yes], [have_free=no])
|
||||
AC_ARG_ENABLE([intf-free],
|
||||
[AC_HELP_STRING([--enable-intf-free],
|
||||
[enable FreeIPMI IPMI interface [default=auto]])],
|
||||
[if test "x$enable_intf_free" != "xno" && test "x$have_free" != "xyes"; then
|
||||
echo "** Unable to build FreeIPMI interface support!"
|
||||
enable_intf_free=no
|
||||
fi],
|
||||
[enable_intf_free=$have_free])
|
||||
if test "x$enable_intf_free" = "xstatic" || test "x$enable_intf_free" = "xplugin"; then
|
||||
enable_intf_free=yes
|
||||
fi
|
||||
if test "x$enable_intf_free" = "xyes"; then
|
||||
dnl Determine if you got the right FreeIPMI version
|
||||
AC_MSG_CHECKING([for good libfreeipmi version])
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h> /* For size_t */
|
||||
#include <stdio.h> /* For NULL */
|
||||
#include <freeipmi/freeipmi.h>
|
||||
#include <freeipmi/udm/ipmi-udm.h>
|
||||
], [
|
||||
ipmi_device_t dev;
|
||||
dev = ipmi_open_inband(IPMI_DEVICE_KCS,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
], ac_free_version_good=yes,ac_free_version_good=no)
|
||||
AC_MSG_RESULT($ac_free_version_good)
|
||||
if test "x$ac_free_version_good" = "xyes"; then
|
||||
AC_DEFINE(IPMI_INTF_FREE, [1], [Define to 1 to enable FreeIPMI interface.])
|
||||
AC_SUBST(INTF_FREE, [free])
|
||||
AC_SUBST(INTF_FREE_LIB, [libintf_free.la])
|
||||
IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB free/libintf_free.la"
|
||||
else
|
||||
enable_intf_free=no
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl look for termios header file
|
||||
AC_CHECK_HEADER([termios.h],
|
||||
[AC_DEFINE(HAVE_TERMIOS_H, [1], [Define to 1 if you have <termios.h>.])],
|
||||
@ -301,8 +358,8 @@ AC_ARG_ENABLE([ipmishell],
|
||||
[enable IPMI shell interface [default=yes]])],
|
||||
[], [enable_ipmishell=yes])
|
||||
if test "x$enable_ipmishell" = "xyes"; then
|
||||
AC_SEARCH_LIBS([tgetent], [readline ncurses curses termcap])
|
||||
AC_SEARCH_LIBS([initscr], [curses ncurses], [have_curses=yes])
|
||||
AC_SEARCH_LIBS([tgetent], [tinfo ncurses curses readline termcap])
|
||||
AC_SEARCH_LIBS([initscr], [ncurses curses], [have_curses=yes])
|
||||
AC_SEARCH_LIBS([readline], [readline edit], [have_readline=yes])
|
||||
if test "x$have_curses" = "xyes" && test "x$have_readline" = "xyes"; then
|
||||
AC_DEFINE(HAVE_READLINE, [1], [Define to 1 if readline present.])
|
||||
@ -344,6 +401,7 @@ AC_CONFIG_FILES([Makefile
|
||||
src/plugins/lan/Makefile
|
||||
src/plugins/lanplus/Makefile
|
||||
src/plugins/open/Makefile
|
||||
src/plugins/free/Makefile
|
||||
src/plugins/imb/Makefile
|
||||
src/plugins/bmc/Makefile
|
||||
src/plugins/lipmi/Makefile])
|
||||
@ -357,6 +415,7 @@ AC_MSG_RESULT([Interfaces])
|
||||
AC_MSG_RESULT([ lan : $enable_intf_lan])
|
||||
AC_MSG_RESULT([ lanplus : $enable_intf_lanplus])
|
||||
AC_MSG_RESULT([ open : $enable_intf_open])
|
||||
AC_MSG_RESULT([ free : $enable_intf_free])
|
||||
AC_MSG_RESULT([ imb : $enable_intf_imb])
|
||||
AC_MSG_RESULT([ bmc : $enable_intf_bmc])
|
||||
AC_MSG_RESULT([ lipmi : $enable_intf_lipmi])
|
||||
|
@ -30,9 +30,8 @@
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
dist_pkgdata_DATA = README oem_ibm_sel_map
|
||||
|
||||
dist_pkgdata_SCRIPTS = bmclanconf ipmi.init.basic ipmi.init.redhat \
|
||||
EXTRA_DIST = README oem_ibm_sel_map \
|
||||
bmclanconf ipmi.init.basic ipmi.init.redhat \
|
||||
ipmievd.init.redhat ipmievd.init.suse ipmievd.init.debian \
|
||||
collect_data.sh create_rrds.sh create_webpage_compact.sh create_webpage.sh
|
||||
|
||||
|
@ -5,7 +5,7 @@ Release: @RPM_RELEASE@%{?_distro:.%{_distro}}
|
||||
License: BSD
|
||||
Group: Utilities
|
||||
Packager: Duncan Laurie <duncan@iceblink.org>
|
||||
Source: ipmitool-@VERSION@.tar.gz
|
||||
Source: %{name}-%{version}.tar.gz
|
||||
Buildroot: /var/tmp/ipmitool-root
|
||||
|
||||
%description
|
||||
@ -50,18 +50,64 @@ make DESTDIR=$RPM_BUILD_ROOT install-strip
|
||||
if [ "$RPM_BUILD_ROOT" ] && [ "$RPM_BUILD_ROOT" != "/" ]; then
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
fi
|
||||
rm -rf $RPM_BUILD_DIR/ipmitool-@VERSION@
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%{_bindir}/*
|
||||
%{_sbindir}/*
|
||||
%{_datadir}/ipmitool/*
|
||||
%doc %{_mandir}/man1/*
|
||||
%doc %{_mandir}/man8/*
|
||||
%doc %{_datadir}/doc/ipmitool/*
|
||||
%defattr(755,root,root)
|
||||
%attr(755,root,root) %{_bindir}/*
|
||||
%attr(755,root,root) %{_sbindir}/*
|
||||
%{_mandir}/man*/*
|
||||
%doc %{_datadir}/doc/ipmitool
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Mar 6 2007 <pere@hungry.com> 1.8.9-1
|
||||
- Added initial AMC ekey query operation support
|
||||
- Improvements to ekeying support (PICMG 3.x only)
|
||||
- Added initial interactive edition support for multirec; added IANA
|
||||
verification before interpreting PICMG records.
|
||||
- Added edit support for AMC activation "Maximum Internal Current"
|
||||
- Fix bug generating garbage on the screen when handling GetDeviceId
|
||||
and sol traffic occurs
|
||||
- Added ability to map OEM sensor types to OEM description string using
|
||||
IANA number; moved IANA number table
|
||||
- Fix lan set access command to use value already saved within parameters
|
||||
for PEF and authentication
|
||||
- Fix bug in cmd ipmitool lan stats get 1
|
||||
- Add support to allow ipmitool/ipmievd to target specific device nodes
|
||||
on multi-BMC systems
|
||||
- Add support for name+privilege lookup for lanplus sessions
|
||||
- Fix time_t conversion bug for 64-bit OS
|
||||
- Added prefix of hostname on sel ipmievd sessions
|
||||
- Fixed FWUM Get Info
|
||||
- Fix ipmievd fd closing bug
|
||||
- Add set-in-progress flag support to chassis bootdev
|
||||
- Added new chassis bootdev options
|
||||
- Add sol payload enable/disable comman
|
||||
- Fix SOL set errors when commit-write not supported
|
||||
- Fix reset of session timeout for lanplus interface
|
||||
- Fixed lan interface accessibility timeout handling
|
||||
- Fix bug with Function Get Channel Cipher Suites command when more
|
||||
than 1 page used.
|
||||
- Fix missing firmware firewall top-level command
|
||||
- Fix bug in SOL keepalive functionality
|
||||
- Fix SOLv2 NACK and retry handling for Intel ESB2 BMC
|
||||
- Added ipmi_sel_get_oem_sensor* APIs
|
||||
- Added HPM.1 support
|
||||
- Fix segfault when incorrect oem option supplied
|
||||
- Fix bus problem with spd command
|
||||
- Fix segfault in SOL when remote BMC does not return packet
|
||||
- Adjust packet length for AMC.0 retricting IPMB packets to 32 bytes
|
||||
- Added lan packet size reduction mechanism
|
||||
- Fix bug with sendMessage of bad length with different target
|
||||
- Fix for big endian (PPC) architecture
|
||||
- NetBSD fixes
|
||||
- Fix segfault and channel problem with user priv command
|
||||
- Add support for bus/chan on i2c raw command
|
||||
- Add freeipmi interface support
|
||||
- Add remote spd printing
|
||||
- Add better detection of linux/compiler.h to config
|
||||
- Makefile changes to fix makedistcheck, etc.
|
||||
|
||||
* Tue May 02 2006 <duncan@iceblink.org> 1.8.8-1
|
||||
- Fix segfaults in sensor data repository list
|
||||
- Fix ipmievd to open interface before daemonizing
|
||||
|
@ -2,7 +2,7 @@
|
||||
.SH "NAME"
|
||||
ipmievd \- IPMI event daemon for sending events to syslog
|
||||
.SH "SYNOPSIS"
|
||||
ipmievd [\fB\-c\fR|\fB\-h\fR|\fB\-v\fR|\fB\-V\fR]
|
||||
ipmievd [\fB\-c\fR|\fB\-h\fR|\fB\-d \fIN\fP\fR|\fB\-v\fR|\fB\-V\fR]
|
||||
\fB\-I\fR \fIopen\fP <\fIopen\fR | \fIsel\fR> [<\fIoption\fP>]
|
||||
|
||||
ipmievd [\fB\-c\fR|\fB\-h\fR|\fB\-v\fR|\fB\-V\fR]
|
||||
@ -116,6 +116,13 @@ Bridge IPMI requests to the remote target address.
|
||||
\fB\-U\fR <\fIusername\fP>
|
||||
Remote server username, default is NULL user.
|
||||
.TP
|
||||
\fB\-d \fIN\fP\fR
|
||||
Use device number N to specify the /dev/ipmiN (or
|
||||
/dev/ipmi/N or /dev/ipmidev/N) device to use for in-band
|
||||
BMC communication. Used to target a specific BMC on a
|
||||
multi-node, multi-BMC system through the ipmi device
|
||||
driver interface. Default is 0.
|
||||
.TP
|
||||
\fB\-v\fR
|
||||
Increase verbose output level. This option may be specified
|
||||
multiple times to increase the level of debug output. If given
|
||||
@ -167,7 +174,8 @@ Do NOT become a daemon, instead log all messages to stderr.
|
||||
.TP
|
||||
\fIpidfile\fP=<\fBfilename\fR>
|
||||
Save process ID to this file when in daemon mode. Defaults to
|
||||
/var/run/ipmievd.pid.
|
||||
/var/run/ipmievd.pid\fIN\fP (where \fIN\fP is the ipmi device
|
||||
number -- defaults to 0).
|
||||
.RE
|
||||
|
||||
.TP
|
||||
@ -189,7 +197,8 @@ Do NOT become a daemon, instead log all messages to stderr.
|
||||
.TP
|
||||
\fIpidfile\fP=<\fBfilename\fR>
|
||||
Save process ID to this file when in daemon mode. Defaults to
|
||||
/var/run/ipmievd.pid.
|
||||
/var/run/ipmievd.pid\fIN\fP (where \fIN\fP is the ipmi device
|
||||
number -- defaults to 0).
|
||||
.TP
|
||||
\fItimeout\fP=<\fBseconds\fR>
|
||||
Time between checks for SEL polling method. Default is 10 seconds.
|
||||
|
@ -2,7 +2,7 @@
|
||||
.SH "NAME"
|
||||
ipmitool \- utility for controlling IPMI\-enabled devices
|
||||
.SH "SYNOPSIS"
|
||||
ipmitool [\fB\-c\fR|\fB\-h\fR|\fB\-v\fR|\fB\-V\fR]
|
||||
ipmitool [\fB\-c\fR|\fB\-h\fR|\fB\-d \fIN\fP\fR|\fB\-v\fR|\fB\-V\fR]
|
||||
\fB\-I\fR \fIopen\fP <\fIcommand\fP>
|
||||
|
||||
ipmitool [\fB\-c\fR|\fB\-h\fR|\fB\-v\fR|\fB\-V\fR]
|
||||
@ -130,6 +130,13 @@ Bridge IPMI requests to the remote target address.
|
||||
.TP
|
||||
\fB\-U\fR <\fIusername\fP>
|
||||
Remote server username, default is NULL user.
|
||||
.TP
|
||||
\fB\-d \fIN\fP\fR
|
||||
Use device number N to specify the /dev/ipmiN (or
|
||||
/dev/ipmi/N or /dev/ipmidev/N) device to use for in-band
|
||||
BMC communication. Used to target a specific BMC on a
|
||||
multi-node, multi-BMC system through the ipmi device
|
||||
driver interface. Default is 0.
|
||||
.TP
|
||||
\fB\-v\fR
|
||||
Increase verbose output level. This option may be specified
|
||||
@ -1521,6 +1528,16 @@ on the cipher suite ID found in the IPMIv2.0 specification in table
|
||||
22\-19. The default cipher suite is \fI3\fP which specifies
|
||||
RAKP\-HMAC\-SHA1 authentication, HMAC\-SHA1\-96 integrity, and AES\-CBC\-128
|
||||
encryption algorightms.
|
||||
|
||||
.SH "FREE INTERFACE"
|
||||
.LP
|
||||
The ipmitool \fIfree\fP interface utilizes the FreeIPMI libfreeipmi
|
||||
drivers.
|
||||
.LP
|
||||
You can tell ipmitool to use the FreeIPMI interface with the -I option:
|
||||
.PP
|
||||
ipmitool \fB\-I\fR \fIfree\fP <\fIcommand\fP>
|
||||
|
||||
.SH "EXAMPLES"
|
||||
.TP
|
||||
\fIExample 1\fP: Listing remote sensors
|
||||
@ -1583,4 +1600,6 @@ http://www.intel.com/design/servers/ipmi
|
||||
.TP
|
||||
OpenIPMI Homepage
|
||||
http://openipmi.sourceforge.net
|
||||
|
||||
.TP
|
||||
FreeIPMI Homepage
|
||||
http://www.gnu.org/software/freeipmi/
|
||||
|
@ -30,8 +30,8 @@
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
noinst_HEADERS = log.h bswap.h helper.h ipmi.h ipmi_intf.h \
|
||||
ipmi_chassis.h ipmi_entity.h ipmi_fru.h ipmi_lanp.h \
|
||||
noinst_HEADERS = log.h bswap.h helper.h ipmi.h ipmi_cc.h ipmi_intf.h \
|
||||
ipmi_chassis.h ipmi_entity.h ipmi_fru.h ipmi_hpmfwupg.h ipmi_lanp.h \
|
||||
ipmi_sdr.h ipmi_sel.h ipmi_sol.h ipmi_mc.h ipmi_raw.h \
|
||||
ipmi_channel.h ipmi_sensor.h ipmi_event.h ipmi_session.h \
|
||||
ipmi_strings.h ipmi_constants.h ipmi_user.h ipmi_pef.h \
|
||||
|
@ -38,11 +38,29 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
|
||||
struct ipmi_intf;
|
||||
|
||||
struct valstr {
|
||||
uint16_t val;
|
||||
const char * str;
|
||||
};
|
||||
struct oemvalstr {
|
||||
uint16_t oem;
|
||||
uint16_t val;
|
||||
const char * str;
|
||||
};
|
||||
|
||||
const char * val2str(uint16_t val, const struct valstr * vs);
|
||||
const char * oemval2str(uint16_t oem,uint16_t val, const struct oemvalstr * vs);
|
||||
uint16_t str2val(const char * str, const struct valstr * vs);
|
||||
void print_valstr(const struct valstr * vs, const char * title, int loglevel);
|
||||
void print_valstr_2col(const struct valstr * vs, const char * title, int loglevel);
|
||||
@ -54,7 +72,7 @@ const char * buf2str(uint8_t * buf, int len);
|
||||
void printbuf(const uint8_t * buf, int len, const char * desc);
|
||||
uint8_t ipmi_csum(uint8_t * d, int s);
|
||||
FILE * ipmi_open_file(const char * file, int rw);
|
||||
void ipmi_start_daemon(void);
|
||||
void ipmi_start_daemon(struct ipmi_intf *intf);
|
||||
|
||||
#define ipmi_open_file_read(file) ipmi_open_file(file, 0)
|
||||
#define ipmi_open_file_write(file) ipmi_open_file(file, 1)
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/ipmi_cc.h>
|
||||
|
||||
|
||||
#define IPMI_BUF_SIZE 1024
|
||||
|
||||
@ -234,6 +236,21 @@ struct ipmi_rs {
|
||||
#define IPMI_BMC_SLAVE_ADDR 0x20
|
||||
#define IPMI_REMOTE_SWID 0x81
|
||||
|
||||
|
||||
/* These values are IANA numbers */
|
||||
typedef enum IPMI_OEM {
|
||||
IPMI_OEM_UNKNOWN = 0,
|
||||
IPMI_OEM_SUN = 42,
|
||||
IPMI_OEM_NOKIA = 94,
|
||||
IPMI_OEM_INTEL = 343,
|
||||
IPMI_OEM_TYAN = 6653,
|
||||
IPMI_OEM_NEWISYS = 9237,
|
||||
IPMI_OEM_SUPERMICRO = 10876,
|
||||
IPMI_OEM_GOOGLE = 11129,
|
||||
IPMI_OEM_PICMG = 12634,
|
||||
IPMI_OEM_KONTRON = 15000,
|
||||
} IPMI_OEM;
|
||||
|
||||
extern const struct valstr completion_code_vals[];
|
||||
|
||||
#endif /* IPMI_H */
|
||||
|
76
ipmitool/include/ipmitool/ipmi_cc.h
Normal file
76
ipmitool/include/ipmitool/ipmi_cc.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistribution of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistribution in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of Sun Microsystems, Inc. or the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* This software is provided "AS IS," without a warranty of any kind.
|
||||
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
|
||||
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
|
||||
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
|
||||
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
|
||||
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
|
||||
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
|
||||
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
|
||||
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
|
||||
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef IPMI_CC_H
|
||||
#define IPMI_CC_H
|
||||
|
||||
/*
|
||||
Thu Jan 11 09:32:41 2007
|
||||
francois.isabelle@ca.kontron.com
|
||||
|
||||
I just noticed that most modules refer to IPMI completion codes using
|
||||
hard coded values ...
|
||||
*/
|
||||
|
||||
/*
|
||||
* CC
|
||||
* See IPMI specification table 5-2 Generic Completion Codes
|
||||
*/
|
||||
|
||||
#define IPMI_CC_OK 0x00
|
||||
#define IPMI_CC_NODE_BUSY 0xc0
|
||||
#define IPMI_CC_INV_CMD 0xc1
|
||||
#define IPMI_CC_INV_CMD_FOR_LUN 0xc2
|
||||
#define IPMI_CC_TIMEOUT 0xc3
|
||||
#define IPMI_CC_OUT_OF_SPACE 0xc4
|
||||
#define IPMI_CC_RES_CANCELED 0xc5
|
||||
#define IPMI_CC_REQ_DATA_TRUNC 0xc6
|
||||
#define IPMI_CC_REQ_DATA_INV_LENGTH 0xc7
|
||||
#define IPMI_CC_REQ_DATA_FIELD_EXCEED 0xc8
|
||||
#define IPMI_CC_PARAM_OUT_OF_RANGE 0xc9
|
||||
#define IPMI_CC_CANT_RET_NUM_REQ_BYTES 0xca
|
||||
#define IPMI_CC_REQ_DATA_NOT_PRESENT 0xcb
|
||||
#define IPMI_CC_INV_DATA_FIELD_IN_REQ 0xcc
|
||||
#define IPMI_CC_ILL_SENSOR_OR_RECORD 0xcd
|
||||
#define IPMI_CC_RESP_COULD_NOT_BE_PRV 0xce
|
||||
#define IPMI_CC_CANT_RESP_DUPLI_REQ 0xcf
|
||||
#define IPMI_CC_CANT_RESP_SDRR_UPDATE 0xd0
|
||||
#define IPMI_CC_CANT_RESP_FIRM_UPDATE 0xd1
|
||||
#define IPMI_CC_CANT_RESP_BMC_INIT 0xd2
|
||||
#define IPMI_CC_DESTINATION_UNAVAILABLE 0xd3
|
||||
#define IPMI_CC_INSUFFICIENT_PRIVILEGES 0xd4
|
||||
#define IPMI_CC_NOT_SUPPORTED_PRESENT_STATE 0xd5
|
||||
#define IPMI_CC_ILLEGAL_COMMAND_DISABLED 0xd6
|
||||
#define IPMI_CC_UNSPECIFIED_ERROR 0xff
|
||||
|
||||
|
||||
#endif /*IPMI_CC_H*/
|
@ -51,6 +51,8 @@
|
||||
#define IPMI_SUSPEND_RESUME_PAYLOAD_ENCRYPTYION 0x55
|
||||
#define IPMI_GET_SEL_TIME 0x48
|
||||
#define IPMI_SET_SEL_TIME 0x49
|
||||
#define IPMI_SET_USER_PAYLOAD_ACCESS 0x4c
|
||||
#define IPMI_GET_USER_PAYLOAD_ACCESS 0x4d
|
||||
|
||||
#define IPMI_1_5_AUTH_TYPE_BIT_NONE 0x01
|
||||
#define IPMI_1_5_AUTH_TYPE_BIT_MD2 0x02
|
||||
@ -103,6 +105,15 @@
|
||||
#define IPMI_CHASSIS_POLICY_PREVIOUS 0x1
|
||||
#define IPMI_CHASSIS_POLICY_ALWAYS_OFF 0x0
|
||||
|
||||
#define IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS 0
|
||||
#define IPMI_CHASSIS_BOOTPARAM_SVCPART_SELECT 1
|
||||
#define IPMI_CHASSIS_BOOTPARAM_SVCPART_SCAN 2
|
||||
#define IPMI_CHASSIS_BOOTPARAM_FLAG_VALID 3
|
||||
#define IPMI_CHASSIS_BOOTPARAM_INFO_ACK 4
|
||||
#define IPMI_CHASSIS_BOOTPARAM_BOOT_FLAGS 5
|
||||
#define IPMI_CHASSIS_BOOTPARAM_INIT_INFO 6
|
||||
#define IPMI_CHASSIS_BOOTPARAM_INIT_MBOX 7
|
||||
|
||||
/* From table 13-17 of the IPMI v2 specification */
|
||||
#define IPMI_AUTH_RAKP_NONE 0x00
|
||||
#define IPMI_AUTH_RAKP_HMAC_SHA1 0x01
|
||||
|
@ -118,7 +118,7 @@ struct fru_multirec_header {
|
||||
#define FRU_RECORD_TYPE_MANAGEMENT_ACCESS 0x03
|
||||
#define FRU_RECORD_TYPE_BASE_COMPATIBILITY 0x04
|
||||
#define FRU_RECORD_TYPE_EXTENDED_COMPATIBILITY 0x05
|
||||
#define FRU_RECORD_TYPE_PICMG_EXTENSION 0xc0
|
||||
#define FRU_RECORD_TYPE_OEM_EXTENSION 0xc0
|
||||
uint8_t type;
|
||||
uint8_t format;
|
||||
uint8_t len;
|
||||
@ -207,7 +207,7 @@ struct fru_multirec_dcload {
|
||||
uint16_t max_current;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_multirec_picmgext_header {
|
||||
struct fru_multirec_oem_header {
|
||||
unsigned char mfg_id[3];
|
||||
#define FRU_PICMG_BACKPLANE_P2P 0x04
|
||||
#define FRU_PICMG_ADDRESS_TABLE 0x10
|
||||
@ -252,6 +252,57 @@ struct fru_picmgext_link_desc {
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
#define FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED 0x00
|
||||
#define FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED1 0x01
|
||||
#define FRU_PICMGEXT_AMC_LINK_TYPE_PCI_EXPRESS 0x02
|
||||
#define FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING1 0x03
|
||||
#define FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING2 0x04
|
||||
#define FRU_PICMGEXT_AMC_LINK_TYPE_ETHERNET 0x05
|
||||
#define FRU_PICMGEXT_AMC_LINK_TYPE_RAPIDIO 0x06
|
||||
#define FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE 0x07
|
||||
|
||||
/* This is used in command, not in FRU */
|
||||
struct fru_picmgext_amc_link_info {
|
||||
unsigned char linkInfo[3];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_picmgext_amc_link_desc_core {
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
unsigned int designator:12;
|
||||
unsigned int type:8;
|
||||
unsigned int ext:4;
|
||||
unsigned int grouping:8;
|
||||
#else
|
||||
unsigned int grouping:8;
|
||||
unsigned int ext:4;
|
||||
unsigned int type:8;
|
||||
unsigned int designator:12;
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_picmgext_amc_link_desc_extra {
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
unsigned char asymetricMatch:2;
|
||||
unsigned char reserved:6;
|
||||
#else
|
||||
unsigned char reserved:6;
|
||||
unsigned char asymetricMatch:2;
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct fru_picmgext_amc_link_desc {
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
struct fru_picmgext_amc_link_desc_core core;/* lsb */
|
||||
struct fru_picmgext_amc_link_desc_extra extra;
|
||||
#else
|
||||
struct fru_picmgext_amc_link_desc_extra extra;
|
||||
struct fru_picmgext_amc_link_desc_core core;/* lsb */
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct fru_picmgext_chn_desc {
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
unsigned char remote_slot:8;
|
||||
@ -272,11 +323,17 @@ struct fru_picmgext_slot_desc {
|
||||
unsigned char chn_count;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define FRU_PICMGEXT_DESIGN_IF_BASE 0x00
|
||||
#define FRU_PICMGEXT_DESIGN_IF_FABRIC 0x01
|
||||
#define FRU_PICMGEXT_DESIGN_IF_BASE 0x00
|
||||
#define FRU_PICMGEXT_DESIGN_IF_FABRIC 0x01
|
||||
#define FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL 0x02
|
||||
#define FRU_PICMGEXT_DESIGN_IF_RESERVED 0x03
|
||||
|
||||
struct fru_picmgext_carrier_activation_record {
|
||||
unsigned short max_internal_curr;
|
||||
unsigned char allowance_for_readiness;
|
||||
unsigned char module_activation_record_count;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_picmgext_activation_record {
|
||||
unsigned char ibmb_addr;
|
||||
unsigned char max_module_curr;
|
||||
@ -314,5 +371,7 @@ static const char *chassis_type_desc[] __attribute__ ((unused)) = {
|
||||
|
||||
int ipmi_fru_main(struct ipmi_intf *intf, int argc, char **argv);
|
||||
int ipmi_fru_print(struct ipmi_intf *intf, struct sdr_record_fru_locator *fru);
|
||||
int ipmi_spd_print(uint8_t *data, int len);
|
||||
int ipmi_spd_print_fru(struct ipmi_intf * intf, uint8_t id);
|
||||
|
||||
#endif /* IPMI_FRU_H */
|
||||
|
41
ipmitool/include/ipmitool/ipmi_hpmfwupg.h
Normal file
41
ipmitool/include/ipmitool/ipmi_hpmfwupg.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistribution of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistribution in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of Sun Microsystems, Inc. or the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* This software is provided "AS IS," without a warranty of any kind.
|
||||
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
|
||||
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
|
||||
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
|
||||
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
|
||||
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
|
||||
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
|
||||
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
|
||||
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
|
||||
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef IPMI_HPMFWUPG_H
|
||||
#define IPMI_HPMFWUPG_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
int ipmi_hpmfwupg_main(struct ipmi_intf *, int, char **);
|
||||
|
||||
#endif /* IPMI_KFWUM_H */
|
@ -106,6 +106,7 @@ struct ipmi_session {
|
||||
uint8_t integrity_alg;
|
||||
uint8_t crypt_alg;
|
||||
uint8_t max_priv_level;
|
||||
uint8_t lookupbit;
|
||||
|
||||
uint32_t console_id;
|
||||
uint32_t bmc_id;
|
||||
@ -173,6 +174,8 @@ struct ipmi_intf {
|
||||
uint8_t target_lun;
|
||||
uint8_t target_channel;
|
||||
|
||||
uint8_t devnum;
|
||||
|
||||
int (*setup)(struct ipmi_intf * intf);
|
||||
int (*open)(struct ipmi_intf * intf);
|
||||
void (*close)(struct ipmi_intf * intf);
|
||||
@ -190,6 +193,7 @@ void ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname);
|
||||
void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username);
|
||||
void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password);
|
||||
void ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t privlvl);
|
||||
void ipmi_intf_session_set_lookupbit(struct ipmi_intf * intf, uint8_t lookupbit);
|
||||
void ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id);
|
||||
void ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char);
|
||||
void ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey);
|
||||
|
@ -13,26 +13,30 @@
|
||||
#define PICMG_GET_ADDRESS_INFO_CMD 0x01
|
||||
#define PICMG_GET_SHELF_ADDRESS_INFO_CMD 0x02
|
||||
#define PICMG_SET_SHELF_ADDRESS_INFO_CMD 0x03
|
||||
#define PICMG_FRU_CONTROL_CMD 0x04
|
||||
#define PICMG_FRU_CONTROL_CMD 0x04
|
||||
#define PICMG_GET_FRU_LED_PROPERTIES_CMD 0x05
|
||||
#define PICMG_GET_LED_COLOR_CAPABILITIES_CMD 0x06
|
||||
#define PICMG_GET_LED_COLOR_CAPABILITIES_CMD 0x06
|
||||
#define PICMG_SET_FRU_LED_STATE_CMD 0x07
|
||||
#define PICMG_GET_FRU_LED_STATE_CMD 0x08
|
||||
#define PICMG_SET_IPMB_CMD 0x09
|
||||
#define PICMG_SET_FRU_POLICY_CMD 0x0A
|
||||
#define PICMG_GET_FRU_POLICY_CMD 0x0B
|
||||
#define PICMG_FRU_ACTIVATION_CMD 0x0C
|
||||
#define PICMG_GET_DEVICE_LOCATOR_RECORD_CMD 0x0D
|
||||
#define PICMG_SET_PORT_STATE_CMD 0x0E
|
||||
#define PICMG_GET_PORT_STATE_CMD 0x0F
|
||||
#define PICMG_COMPUTE_POWER_PROPERTIES_CMD 0x10
|
||||
#define PICMG_SET_IPMB_CMD 0x09
|
||||
#define PICMG_SET_FRU_POLICY_CMD 0x0A
|
||||
#define PICMG_GET_FRU_POLICY_CMD 0x0B
|
||||
#define PICMG_FRU_ACTIVATION_CMD 0x0C
|
||||
#define PICMG_GET_DEVICE_LOCATOR_RECORD_CMD 0x0D
|
||||
#define PICMG_SET_PORT_STATE_CMD 0x0E
|
||||
#define PICMG_GET_PORT_STATE_CMD 0x0F
|
||||
#define PICMG_COMPUTE_POWER_PROPERTIES_CMD 0x10
|
||||
#define PICMG_SET_POWER_LEVEL_CMD 0x11
|
||||
#define PICMG_GET_POWER_LEVEL_CMD 0x12
|
||||
#define PICMG_RENEGOTIATE_POWER_CMD 0x13
|
||||
#define PICMG_GET_FAN_SPEED_PROPERTIES_CMD 0x14
|
||||
#define PICMG_GET_FAN_SPEED_PROPERTIES_CMD 0x14
|
||||
#define PICMG_SET_FAN_LEVEL_CMD 0x15
|
||||
#define PICMG_GET_FAN_LEVEL_CMD 0x16
|
||||
#define PICMG_BUSED_RESOURCE_CMD 0x17
|
||||
#define PICMG_BUSED_RESOURCE_CMD 0x17
|
||||
|
||||
/* AMC.0 commands */
|
||||
#define PICMG_AMC_SET_PORT_STATE_CMD 0x19
|
||||
#define PICMG_AMC_GET_PORT_STATE_CMD 0x1A
|
||||
|
||||
/* Site Types */
|
||||
#define PICMG_ATCA_BOARD 0x00
|
||||
@ -42,9 +46,9 @@
|
||||
#define PICMG_FAN_TRAY 0x04
|
||||
#define PICMG_FAN_FILTER_TRAY 0x05
|
||||
#define PICMG_ALARM 0x06
|
||||
#define PICMG_AMC 0x07
|
||||
#define PICMG_PMC 0x08
|
||||
#define PICMG_RTM 0x09
|
||||
#define PICMG_AMC 0x07
|
||||
#define PICMG_PMC 0x08
|
||||
#define PICMG_RTM 0x09
|
||||
|
||||
|
||||
|
||||
@ -70,6 +74,17 @@ static const char* led_color_str[] __attribute__((unused)) = {
|
||||
|
||||
|
||||
|
||||
static const char* amc_link_type_str[] __attribute__((unused)) = {
|
||||
" FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED",
|
||||
" FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED1",
|
||||
" FRU_PICMGEXT_AMC_LINK_TYPE_PCI_EXPRESS",
|
||||
" FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING1",
|
||||
" FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING2",
|
||||
" FRU_PICMGEXT_AMC_LINK_TYPE_ETHERNET",
|
||||
" FRU_PICMGEXT_AMC_LINK_TYPE_RAPIDIO",
|
||||
" FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE",
|
||||
};
|
||||
|
||||
int ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv);
|
||||
|
||||
#endif
|
||||
|
@ -36,7 +36,9 @@
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
struct ipmi_rs * ipmi_master_write_read(struct ipmi_intf * intf, uint8_t addr, uint8_t * wdata, uint8_t wsize, uint8_t rsize);
|
||||
struct ipmi_rs * ipmi_master_write_read(struct ipmi_intf * intf, uint8_t bus, uint8_t addr,
|
||||
uint8_t * wdata, uint8_t wsize, uint8_t rsize);
|
||||
int ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
int ipmi_rawspd_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
|
||||
#endif /* IPMI_RAW_H */
|
||||
|
@ -159,7 +159,7 @@ struct sdr_record_mask {
|
||||
struct {
|
||||
uint16_t assert_event; /* assertion event mask */
|
||||
uint16_t deassert_event; /* de-assertion event mask */
|
||||
uint16_t read; /* discrete reaading mask */
|
||||
uint16_t read; /* discrete reading mask */
|
||||
} discrete;
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
@ -232,44 +232,52 @@ struct sdr_record_mask {
|
||||
uint16_t status_unr:1;
|
||||
uint16_t reserved_2:1;
|
||||
#endif
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN /* settable threshold mask */
|
||||
uint8_t reserved:2;
|
||||
uint8_t unr:1;
|
||||
uint8_t ucr:1;
|
||||
uint8_t unc:1;
|
||||
uint8_t lnr:1;
|
||||
uint8_t lcr:1;
|
||||
uint8_t lnc:1;
|
||||
union {
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN /* settable threshold mask */
|
||||
uint16_t reserved:2;
|
||||
uint16_t unr:1;
|
||||
uint16_t ucr:1;
|
||||
uint16_t unc:1;
|
||||
uint16_t lnr:1;
|
||||
uint16_t lcr:1;
|
||||
uint16_t lnc:1;
|
||||
/* padding lower 8 bits */
|
||||
uint16_t readable:8;
|
||||
#else
|
||||
uint8_t lnc:1;
|
||||
uint8_t lcr:1;
|
||||
uint8_t lnr:1;
|
||||
uint8_t unc:1;
|
||||
uint8_t ucr:1;
|
||||
uint8_t unr:1;
|
||||
uint8_t reserved:2;
|
||||
uint16_t readable:8;
|
||||
uint16_t lnc:1;
|
||||
uint16_t lcr:1;
|
||||
uint16_t lnr:1;
|
||||
uint16_t unc:1;
|
||||
uint16_t ucr:1;
|
||||
uint16_t unr:1;
|
||||
uint16_t reserved:2;
|
||||
#endif
|
||||
} set;
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN /* readable threshold mask */
|
||||
uint8_t reserved:2;
|
||||
uint8_t unr:1;
|
||||
uint8_t ucr:1;
|
||||
uint8_t unc:1;
|
||||
uint8_t lnr:1;
|
||||
uint8_t lcr:1;
|
||||
uint8_t lnc:1;
|
||||
} set;
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN /* readable threshold mask */
|
||||
/* padding upper 8 bits */
|
||||
uint16_t settable:8;
|
||||
uint16_t reserved:2;
|
||||
uint16_t unr:1;
|
||||
uint16_t ucr:1;
|
||||
uint16_t unc:1;
|
||||
uint16_t lnr:1;
|
||||
uint16_t lcr:1;
|
||||
uint16_t lnc:1;
|
||||
#else
|
||||
uint8_t lnc:1;
|
||||
uint8_t lcr:1;
|
||||
uint8_t lnr:1;
|
||||
uint8_t unc:1;
|
||||
uint8_t ucr:1;
|
||||
uint8_t unr:1;
|
||||
uint8_t reserved:2;
|
||||
uint16_t lnc:1;
|
||||
uint16_t lcr:1;
|
||||
uint16_t lnr:1;
|
||||
uint16_t unc:1;
|
||||
uint16_t ucr:1;
|
||||
uint16_t unr:1;
|
||||
uint16_t reserved:2;
|
||||
uint16_t settable:8;
|
||||
#endif
|
||||
} read;
|
||||
} read;
|
||||
};
|
||||
} threshold;
|
||||
} type;
|
||||
} __attribute__ ((packed));
|
||||
@ -763,8 +771,9 @@ static const char *unit_desc[] __attribute__ ((unused)) = {
|
||||
"overflow", "underrun", "collision", "packets", "messages",
|
||||
"characters", "error", "correctable error", "uncorrectable error",};
|
||||
|
||||
/* sensor type codes (IPMI v1.5 table 36.3) */
|
||||
#define SENSOR_TYPE_MAX 0x29
|
||||
/* sensor type codes (IPMI v1.5 table 36.3)
|
||||
/ Updated to v2.0 Table 42-3, Sensor Type Codes */
|
||||
#define SENSOR_TYPE_MAX 0x2C
|
||||
static const char *sensor_type_desc[] __attribute__ ((unused)) = {
|
||||
"reserved",
|
||||
"Temperature", "Voltage", "Current", "Fan",
|
||||
@ -779,7 +788,8 @@ static const char *sensor_type_desc[] __attribute__ ((unused)) = {
|
||||
"OS Boot", "OS Critical Stop", "Slot / Connector",
|
||||
"System ACPI Power State", "Watchdog", "Platform Alert",
|
||||
"Entity Presence", "Monitor ASIC", "LAN",
|
||||
"Management Subsystem Health", "Battery"};
|
||||
"Management Subsystem Health", "Battery","Session Audit",
|
||||
"Version Change","FRU State" };
|
||||
|
||||
struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf);
|
||||
struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf,
|
||||
@ -799,6 +809,8 @@ double sdr_convert_sensor_tolerance(struct sdr_record_full_sensor *sensor,
|
||||
uint8_t val);
|
||||
double sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor,
|
||||
uint8_t val);
|
||||
double sdr_convert_sensor_hysterisis(struct sdr_record_full_sensor *sensor,
|
||||
uint8_t val);
|
||||
uint8_t sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor *sensor,
|
||||
double val);
|
||||
struct ipmi_rs *ipmi_sdr_get_sensor_reading(struct ipmi_intf *intf,
|
||||
|
@ -115,6 +115,67 @@ struct ipmi_event_sensor_types {
|
||||
const char * desc;
|
||||
};
|
||||
|
||||
/* The sel module uses the "iana" number to select the appropriate array at run time
|
||||
This table if for iana number 15000 ( Kontron ), you can add you own OEM sensor types
|
||||
using a similar constuct, look for switch(iana) in ipmi_sel.c
|
||||
*/
|
||||
static struct ipmi_event_sensor_types oem_kontron_event_types[] __attribute__((unused)) = {
|
||||
|
||||
/* event type details uses an oem event type */
|
||||
{ 0xC0 , 0xFF , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info", NULL },
|
||||
{ 0xC0 , 0xFF , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info", NULL },
|
||||
|
||||
{ 0xC1 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Push Button" },
|
||||
{ 0xC1 , 0x01 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Bridge Reset" },
|
||||
{ 0xC1 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Backplane" },
|
||||
{ 0xC1 , 0x03 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Hotswap Fault" },
|
||||
{ 0xC1 , 0x04 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Hotswap Healty" },
|
||||
{ 0xC1 , 0x05 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Unknown" },
|
||||
{ 0xC1 , 0x06 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "ITP" },
|
||||
{ 0xC1 , 0x07 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Hardware Watchdog" },
|
||||
{ 0xC1 , 0x08 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Software Reset" },
|
||||
|
||||
/* Uses standard digital reading type */
|
||||
{ 0xC2 , 0xFF , 0xff, IPMI_EVENT_CLASS_DIGITAL , "SDRR Init Agent", NULL },
|
||||
|
||||
/* based on PICMG IPMB-0 Link state sensor */
|
||||
{ 0xC3 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "IPMB-L Link State", "IPMB L Disabled" },
|
||||
{ 0xC3 , 0x03 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "IPMB-L Link State", "IPMB L Enabled" },
|
||||
|
||||
{ 0xC4 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Push Button" },
|
||||
{ 0xC4 , 0x01 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Hardware Power Failure" },
|
||||
{ 0xC4 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Unknown" },
|
||||
{ 0xC4 , 0x03 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Hardware Watchdog" },
|
||||
{ 0xC4 , 0x04 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Soft Reset" },
|
||||
{ 0xC4 , 0x05 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Warm Reset" },
|
||||
{ 0xC4 , 0x06 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Cold Reset" },
|
||||
{ 0xC4 , 0x07 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "IPMI Command" },
|
||||
{ 0xC4 , 0x08 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Setup Reset (Save CMOS)" },
|
||||
{ 0xC4 , 0x09 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Power Up Reset" },
|
||||
|
||||
/* event type details uses a standard */
|
||||
{ 0xC5 , 0xFF , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FRU Information Agent", NULL },
|
||||
|
||||
{ 0xC6 , 0x0E , 0xff, IPMI_EVENT_CLASS_DISCRETE , "POST Value", "Post Error (see data2)" },
|
||||
|
||||
{ 0xC7 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FWUM Status", "First Boot After Upgrade" },
|
||||
{ 0xC7 , 0x01 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FWUM Status", "First Boot After Rollback(error)" },
|
||||
{ 0xC7 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FWUM Status", "First Boot After Errors (watchdog)" },
|
||||
{ 0xC7 , 0x03 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FWUM Status", "First Boot After Manual Rollback" },
|
||||
{ 0xC7 , 0x08 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FWUM Status", "Firmware Watchdog Bite, reset occured" },
|
||||
|
||||
{ 0xC8 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Switch Mngt Software Status", "Not Loaded" },
|
||||
{ 0xC8 , 0x01 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Switch Mngt Software Status", "Initializing" },
|
||||
{ 0xC8 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Switch Mngt Software Status", "Ready" },
|
||||
{ 0xC8 , 0x03 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Switch Mngt Software Status", "Failure (see data2)" },
|
||||
|
||||
{ 0xC9 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Diagnostic Status", "Started" },
|
||||
{ 0xC9 , 0x01 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Diagnostic Status", "Pass" },
|
||||
{ 0xC9 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Diagnostic Status", "Fail" },
|
||||
/* END */
|
||||
{ 0x00, 0x00, 0xff, 0x00, NULL, NULL },
|
||||
};
|
||||
|
||||
static struct ipmi_event_sensor_types generic_event_types[] __attribute__((unused)) = {
|
||||
/* Threshold Based States */
|
||||
{ 0x01, 0x00, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical going low " },
|
||||
@ -521,18 +582,6 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x00, 0x00, 0x00, 0x00, NULL, NULL },
|
||||
};
|
||||
|
||||
|
||||
/* These values are IANA numbers */
|
||||
typedef enum IPMI_OEM {
|
||||
IPMI_OEM_UNKNOWN = 0,
|
||||
IPMI_OEM_SUN = 42,
|
||||
IPMI_OEM_INTEL = 343,
|
||||
IPMI_OEM_TYAN = 6653,
|
||||
IPMI_OEM_NEWISYS = 9237,
|
||||
IPMI_OEM_SUPERMICRO = 10876,
|
||||
IPMI_OEM_KONTRON = 15000,
|
||||
} IPMI_OEM;
|
||||
|
||||
int ipmi_sel_main(struct ipmi_intf *, int, char **);
|
||||
void ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt);
|
||||
void ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
|
||||
|
@ -53,5 +53,8 @@ extern const struct valstr ipmi_integrity_algorithms[];
|
||||
extern const struct valstr ipmi_encryption_algorithms[];
|
||||
extern const struct valstr ipmi_oem_info[];
|
||||
|
||||
extern const struct oemvalstr ipmi_oem_sdr_type_vals[];
|
||||
|
||||
|
||||
|
||||
#endif /*IPMI_STRINGS_H*/
|
||||
|
@ -37,7 +37,8 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
|
||||
dimm_spd.c ipmi_sensor.c ipmi_channel.c ipmi_event.c \
|
||||
ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c \
|
||||
ipmi_oem.c ipmi_isol.c ipmi_sunoem.c ipmi_fwum.c ipmi_picmg.c \
|
||||
ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c
|
||||
ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c \
|
||||
ipmi_hpmfwupg.c
|
||||
|
||||
libipmitool_la_LDFLAGS = -export-dynamic
|
||||
libipmitool_la_LIBADD = -lm
|
||||
|
@ -669,13 +669,74 @@ const struct valstr jedec_id5_vals[] = {
|
||||
};
|
||||
|
||||
int
|
||||
ipmi_spd_print(struct ipmi_intf * intf, uint8_t id)
|
||||
ipmi_spd_print(uint8_t *spd_data, int len)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (len < 92)
|
||||
return -1; /* we need first 91 bytes to do our thing */
|
||||
|
||||
size = spd_data[5] * (spd_data[31] << 2);
|
||||
printf(" Memory Size : %d MB\n", size);
|
||||
printf(" Memory Type : %s\n",
|
||||
val2str(spd_data[2], spd_memtype_vals));
|
||||
printf(" Voltage Intf : %s\n",
|
||||
val2str(spd_data[8], spd_voltage_vals));
|
||||
printf(" Error Detect/Cor : %s\n",
|
||||
val2str(spd_data[11], spd_config_vals));
|
||||
|
||||
/* handle jedec table bank continuation values */
|
||||
printf(" Manufacturer : ");
|
||||
if (spd_data[64] != 0x7f)
|
||||
printf("%s\n",
|
||||
val2str(spd_data[64], jedec_id1_vals));
|
||||
else {
|
||||
if (spd_data[65] != 0x7f)
|
||||
printf("%s\n",
|
||||
val2str(spd_data[65], jedec_id2_vals));
|
||||
else {
|
||||
if (spd_data[66] != 0x7f)
|
||||
printf("%s\n",
|
||||
val2str(spd_data[66], jedec_id3_vals));
|
||||
else {
|
||||
if (spd_data[67] != 0x7f)
|
||||
printf("%s\n",
|
||||
val2str(spd_data[67],
|
||||
jedec_id4_vals));
|
||||
else
|
||||
printf("%s\n",
|
||||
val2str(spd_data[68],
|
||||
jedec_id5_vals));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (spd_data[73]) {
|
||||
char part[19];
|
||||
memcpy(part, spd_data+73, 18);
|
||||
part[18] = 0;
|
||||
printf(" Part Number : %s\n", part);
|
||||
}
|
||||
|
||||
printf(" Serial Number : %02x%02x%02x%02x\n",
|
||||
spd_data[95], spd_data[96], spd_data[97], spd_data[98]);
|
||||
|
||||
if (verbose) {
|
||||
printf("\n");
|
||||
printbuf(spd_data, len, "SPD DATA");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_spd_print_fru(struct ipmi_intf * intf, uint8_t id)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
struct fru_info fru;
|
||||
uint8_t spd_data[256], msg_data[4];
|
||||
int len, offset, size;
|
||||
int len, offset;
|
||||
|
||||
msg_data[0] = id;
|
||||
|
||||
@ -742,53 +803,8 @@ ipmi_spd_print(struct ipmi_intf * intf, uint8_t id)
|
||||
offset += len;
|
||||
} while (offset < fru.size);
|
||||
|
||||
if (verbose > 1)
|
||||
printbuf(spd_data, offset, "SPD DATA");
|
||||
|
||||
if (offset < 92)
|
||||
return -1; /* we need first 91 bytes to do our thing */
|
||||
|
||||
size = spd_data[5] * (spd_data[31] << 2);
|
||||
printf(" Memory Size : %d MB\n", size);
|
||||
printf(" Memory Type : %s\n",
|
||||
val2str(spd_data[2], spd_memtype_vals));
|
||||
printf(" Voltage Intf : %s\n",
|
||||
val2str(spd_data[8], spd_voltage_vals));
|
||||
printf(" Error Detect/Cor : %s\n",
|
||||
val2str(spd_data[11], spd_config_vals));
|
||||
|
||||
/* handle jedec table bank continuation values */
|
||||
printf(" Manufacturer : ");
|
||||
if (spd_data[64] != 0x7f)
|
||||
printf("%s\n",
|
||||
val2str(spd_data[64], jedec_id1_vals));
|
||||
else {
|
||||
if (spd_data[65] != 0x7f)
|
||||
printf("%s\n",
|
||||
val2str(spd_data[65], jedec_id2_vals));
|
||||
else {
|
||||
if (spd_data[66] != 0x7f)
|
||||
printf("%s\n",
|
||||
val2str(spd_data[66], jedec_id3_vals));
|
||||
else {
|
||||
if (spd_data[67] != 0x7f)
|
||||
printf("%s\n",
|
||||
val2str(spd_data[67],
|
||||
jedec_id4_vals));
|
||||
else
|
||||
printf("%s\n",
|
||||
val2str(spd_data[68],
|
||||
jedec_id5_vals));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (spd_data[73]) {
|
||||
char part[19];
|
||||
memcpy(part, spd_data+73, 18);
|
||||
part[18] = 0;
|
||||
printf(" Part Number : %s\n", part);
|
||||
}
|
||||
/* now print spd info */
|
||||
ipmi_spd_print(spd_data, offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -54,6 +54,8 @@
|
||||
# define _PATH_VARRUN "/var/run/"
|
||||
#endif
|
||||
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/log.h>
|
||||
|
||||
@ -97,13 +99,13 @@ void printbuf(const uint8_t * buf, int len, const char * desc)
|
||||
if (verbose < 1)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "%s (%d bytes)\n", desc, len);
|
||||
fprintf(stderr, "%s (%d bytes)\r\n", desc, len);
|
||||
for (i=0; i<len; i++) {
|
||||
if (((i%16) == 0) && (i != 0))
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\r\n");
|
||||
fprintf(stderr, " %2.2x", buf[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\r\n");
|
||||
}
|
||||
|
||||
const char * val2str(uint16_t val, const struct valstr *vs)
|
||||
@ -122,6 +124,35 @@ const char * val2str(uint16_t val, const struct valstr *vs)
|
||||
return un_str;
|
||||
}
|
||||
|
||||
const char * oemval2str(uint16_t oem, uint16_t val,
|
||||
const struct oemvalstr *vs)
|
||||
{
|
||||
static char un_str[32];
|
||||
int i;
|
||||
|
||||
for (i = 0; vs[i].oem != 0x00 && vs[i].str != NULL; i++) {
|
||||
/* FIXME: for now on we assume PICMG capability on all IANAs */
|
||||
if
|
||||
(
|
||||
(
|
||||
vs[i].oem == oem
|
||||
||
|
||||
vs[i].oem == IPMI_OEM_PICMG
|
||||
)
|
||||
&&
|
||||
vs[i].val == val
|
||||
)
|
||||
{
|
||||
return vs[i].str;
|
||||
}
|
||||
}
|
||||
|
||||
memset(un_str, 0, 32);
|
||||
snprintf(un_str, 32, "OEM reserved #%02x", val);
|
||||
|
||||
return un_str;
|
||||
}
|
||||
|
||||
uint16_t str2val(const char *str, const struct valstr *vs)
|
||||
{
|
||||
int i;
|
||||
@ -344,7 +375,7 @@ ipmi_open_file(const char * file, int rw)
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_start_daemon(void)
|
||||
ipmi_start_daemon(struct ipmi_intf *intf)
|
||||
{
|
||||
pid_t pid;
|
||||
int fd;
|
||||
@ -388,7 +419,7 @@ ipmi_start_daemon(void)
|
||||
close(fd);
|
||||
}
|
||||
#else
|
||||
if (setpgrp() == -1)
|
||||
if (setpgid(0, 0) == -1)
|
||||
exit(1);
|
||||
pid = (pid_t) fork();
|
||||
if (pid < 0 || pid > 0)
|
||||
@ -398,11 +429,12 @@ ipmi_start_daemon(void)
|
||||
chdir("/");
|
||||
umask(0);
|
||||
|
||||
for (fd=0; fd<64; fd++)
|
||||
close(fd);
|
||||
for (fd=0; fd<64; fd++) {
|
||||
if (fd != intf->fd)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
open("/dev/null", O_RDWR);
|
||||
dup(0);
|
||||
dup(0);
|
||||
}
|
||||
|
||||
|
@ -140,9 +140,9 @@ ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
|
||||
(auth_cap.kg_status) ? "non-zero" : "default (all zeroes)");
|
||||
|
||||
printf("Per message authentication : %sabled\n",
|
||||
(auth_cap.per_message_auth) ? "en" : "dis");
|
||||
(auth_cap.per_message_auth) ? "dis" : "en");
|
||||
printf("User level authentication : %sabled\n",
|
||||
(auth_cap.user_level_auth) ? "en" : "dis");
|
||||
(auth_cap.user_level_auth) ? "dis" : "en");
|
||||
|
||||
printf("Non-null user names exist : %s\n",
|
||||
(auth_cap.non_null_usernames) ? "yes" : "no");
|
||||
@ -593,12 +593,10 @@ ipmi_get_channel_cipher_suites(struct ipmi_intf * intf,
|
||||
if (rsp->data_len >= 1)
|
||||
channel = rsp->data[0];
|
||||
|
||||
|
||||
while ((rsp->data_len > 1) && (list_index < 0x3F))
|
||||
while ((rsp->data_len > 1) && (rsp->data_len == 17) && (list_index < 0x3F))
|
||||
{
|
||||
//
|
||||
//
|
||||
// We got back cipher suite data -- store it.
|
||||
//
|
||||
//printf("copying data to offset %d\n", offset);
|
||||
//printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data");
|
||||
memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1);
|
||||
@ -622,6 +620,16 @@ ipmi_get_channel_cipher_suites(struct ipmi_intf * intf,
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy last chunk */
|
||||
if(rsp->data_len > 1)
|
||||
{
|
||||
//
|
||||
// We got back cipher suite data -- store it.
|
||||
//printf("copying data to offset %d\n", offset);
|
||||
//printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data");
|
||||
memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1);
|
||||
offset += rsp->data_len - 1;
|
||||
}
|
||||
|
||||
//
|
||||
// We can chomp on all our data now.
|
||||
@ -842,7 +850,7 @@ ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
else
|
||||
{
|
||||
uint8_t ch = 0xe;
|
||||
if (argc == 4)
|
||||
if (argc == 3)
|
||||
ch = (uint8_t)strtol(argv[2], NULL, 0);
|
||||
retval = ipmi_get_channel_cipher_suites(intf,
|
||||
argv[1], // ipmi | sol
|
||||
@ -858,4 +866,3 @@ ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ ipmi_chassis_identify(struct ipmi_intf * intf, char * arg)
|
||||
printf("default (15 seconds)\n");
|
||||
} else {
|
||||
if (identify_data.force_on != 0) {
|
||||
printf("indefinate\n");
|
||||
printf("indefinite\n");
|
||||
} else {
|
||||
if (identify_data.interval == 0)
|
||||
printf("off\n");
|
||||
@ -448,8 +448,10 @@ ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * dat
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Set Chassis Boot Parameter %d failed: %s",
|
||||
param, val2str(rsp->ccode, completion_code_vals));
|
||||
if (param != 0) {
|
||||
lprintf(LOG_ERR, "Set Chassis Boot Parameter %d failed: %s",
|
||||
param, val2str(rsp->ccode, completion_code_vals));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -502,19 +504,44 @@ ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg, int clearcmos)
|
||||
ipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg, uint8_t *iflags)
|
||||
{
|
||||
uint8_t flags[5];
|
||||
int rc = 0;
|
||||
int use_progress = 1;
|
||||
|
||||
if (use_progress) {
|
||||
/* set set-in-progress flag */
|
||||
memset(flags, 0, 5);
|
||||
flags[0] = 0x01;
|
||||
rc = ipmi_chassis_set_bootparam(intf,
|
||||
IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS, flags, 1);
|
||||
if (rc < 0)
|
||||
use_progress = 0;
|
||||
}
|
||||
|
||||
memset(flags, 0, 5);
|
||||
flags[0] = 0x01;
|
||||
flags[1] = 0x01;
|
||||
rc = ipmi_chassis_set_bootparam(intf, 4, flags, 2);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_INFO_ACK,
|
||||
flags, 2);
|
||||
|
||||
if (rc < 0) {
|
||||
if (use_progress) {
|
||||
/* set-in-progress = set-complete */
|
||||
memset(flags, 0, 5);
|
||||
ipmi_chassis_set_bootparam(intf,
|
||||
IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
|
||||
flags, 1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iflags == NULL)
|
||||
memset(flags, 0, 5);
|
||||
else
|
||||
memcpy(flags, iflags, sizeof (flags));
|
||||
|
||||
memset(flags, 0, 5);
|
||||
if (arg == NULL)
|
||||
flags[1] = 0x00;
|
||||
else if (strncmp(arg, "none", 4) == 0)
|
||||
@ -542,17 +569,42 @@ ipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg, int clearcmos)
|
||||
flags[1] = 0x18;
|
||||
else {
|
||||
lprintf(LOG_ERR, "Invalid argument: %s", arg);
|
||||
if (use_progress) {
|
||||
/* set-in-progress = set-complete */
|
||||
memset(flags, 0, 5);
|
||||
ipmi_chassis_set_bootparam(intf,
|
||||
IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
|
||||
flags, 1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (clearcmos)
|
||||
flags[1] |= 0x80;
|
||||
|
||||
/* set flag valid bit */
|
||||
flags[0] = 0x80;
|
||||
rc = ipmi_chassis_set_bootparam(intf, 5, flags, 5);
|
||||
if (rc == 0)
|
||||
flags[0] |= 0x80;
|
||||
|
||||
rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_BOOT_FLAGS,
|
||||
flags, 5);
|
||||
if (rc == 0) {
|
||||
if (use_progress) {
|
||||
/* set-in-progress = commit-write */
|
||||
memset(flags, 0, 5);
|
||||
flags[0] = 0x02;
|
||||
ipmi_chassis_set_bootparam(intf,
|
||||
IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
|
||||
flags, 1);
|
||||
}
|
||||
|
||||
printf("Set Boot Device to %s\n", arg);
|
||||
}
|
||||
|
||||
if (use_progress) {
|
||||
/* set-in-progress = set-complete */
|
||||
memset(flags, 0, 5);
|
||||
ipmi_chassis_set_bootparam(intf,
|
||||
IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
|
||||
flags, 1);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -649,7 +701,7 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
int rc = 0;
|
||||
|
||||
if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0)) {
|
||||
lprintf(LOG_NOTICE, "Chassis Commands: status, power, identify, policy, restart_cause, poh, bootdev, selftest");
|
||||
lprintf(LOG_NOTICE, "Chassis Commands: status, power, identify, policy, restart_cause, poh, bootdev, bootparam, selftest");
|
||||
}
|
||||
else if (strncmp(argv[0], "status", 6) == 0) {
|
||||
rc = ipmi_chassis_status(intf);
|
||||
@ -750,7 +802,7 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
|
||||
} else {
|
||||
if (strncmp(argv[2], "bootflag", 8) == 0)
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[3], 0);
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[3], NULL);
|
||||
else
|
||||
lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
|
||||
}
|
||||
@ -762,6 +814,7 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
else if (strncmp(argv[0], "bootdev", 7) == 0) {
|
||||
if ((argc < 2) || (strncmp(argv[1], "help", 4) == 0)) {
|
||||
lprintf(LOG_NOTICE, "bootdev <device> [clear-cmos=yes|no]");
|
||||
lprintf(LOG_NOTICE, "bootdev <device> [options=help,...]");
|
||||
lprintf(LOG_NOTICE, " none : Do not change boot device order");
|
||||
lprintf(LOG_NOTICE, " pxe : Force PXE boot");
|
||||
lprintf(LOG_NOTICE, " disk : Force boot from default Hard-drive");
|
||||
@ -769,17 +822,116 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
lprintf(LOG_NOTICE, " diag : Force boot from Diagnostic Partition");
|
||||
lprintf(LOG_NOTICE, " cdrom : Force boot from CD/DVD");
|
||||
lprintf(LOG_NOTICE, " bios : Force boot into BIOS Setup");
|
||||
lprintf(LOG_NOTICE, " floppy: Force boot from Floppy/primary removable media");
|
||||
} else {
|
||||
if (argc < 3)
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], 0);
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], NULL);
|
||||
else if (strncmp(argv[2], "clear-cmos=", 11) == 0) {
|
||||
if (strncmp(argv[2]+11, "yes", 3) == 0)
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], 1);
|
||||
else
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], 0);
|
||||
if (strncmp(argv[2]+11, "yes", 3) == 0) {
|
||||
uint8_t flags[5] = {0, (1<<7), 0, 0, 0};
|
||||
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], flags);
|
||||
} else
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], NULL);
|
||||
}
|
||||
else if (strncmp(argv[2], "options=", 8) == 0) {
|
||||
char *token;
|
||||
char *saveptr = NULL;
|
||||
int optionError = 0;
|
||||
unsigned char flags[5];
|
||||
static struct {
|
||||
char *name;
|
||||
int i;
|
||||
unsigned char mask;
|
||||
unsigned char value;
|
||||
char *desc;
|
||||
} options[] = {
|
||||
/* data 1 */
|
||||
{"valid", 0, (1<<7), (1<<7),
|
||||
"Boot flags valid"},
|
||||
{"persistent", 0, (1<<6), (1<<6),
|
||||
"Changes are persistent for all future boots"},
|
||||
{"efiboot", 0, (1<<5), (1<<5),
|
||||
"Extensible Firmware Interface Boot (EFI)"},
|
||||
|
||||
/* data 2 */
|
||||
{"clear-cmos", 1, (1<<7), (1<<7),
|
||||
"CMOS clear"},
|
||||
{"lockkbd", 1, (1<<6), (1<<6),
|
||||
"Lock Keyboard"},
|
||||
/* data2[5:2] is parsed elsewhere */
|
||||
{"screenblank", 1, (1<<1), (1<<1),
|
||||
"Screen Blank"},
|
||||
{"lockoutreset", 1, (1<<0), (1<<0),
|
||||
"Lock out Resetbuttons"},
|
||||
|
||||
/* data 3 */
|
||||
{"lockout_power", 2, (1<<7), (1<<7),
|
||||
"Lock out (power off/sleep request) via Power Button"},
|
||||
{"verbose=default", 2, (3<<5), (0<<5),
|
||||
"Request quiet BIOS display"},
|
||||
{"verbose=no", 2, (3<<5), (1<<5),
|
||||
"Request quiet BIOS display"},
|
||||
{"verbose=yes", 2, (3<<5), (2<<5),
|
||||
"Request verbose BIOS display"},
|
||||
{"force_pet", 2, (1<<4), (1<<4),
|
||||
"Force progress event traps"},
|
||||
{"upw_bypass", 2, (1<<3), (1<<3),
|
||||
"User password bypass"},
|
||||
{"lockout_sleep", 2, (1<<2), (1<<2),
|
||||
"Log Out Sleep Button"},
|
||||
{"cons_redirect=default", 2, (3<<0), (0<<0),
|
||||
"Console redirection occurs per BIOS configuration setting"},
|
||||
{"cons_redirect=skip", 2, (3<<0), (1<<0),
|
||||
"Suppress (skip) console redirection if enabled"},
|
||||
{"cons_redirect=enable", 2, (3<<0), (2<<0),
|
||||
"Suppress (skip) console redirection if enabled"},
|
||||
|
||||
/* data 4 */
|
||||
/* data4[7:4] reserved */
|
||||
/* data4[3] BIOS Shared Mode Override, not implemented here */
|
||||
/* data4[2:0] BIOS Mux Control Override, not implemented here */
|
||||
|
||||
/* data5 reserved */
|
||||
|
||||
{NULL} /* End marker */
|
||||
}, *op;
|
||||
|
||||
memset(&flags[0], 0, sizeof(flags));
|
||||
token = strtok_r(argv[2] + 8, ",", &saveptr);
|
||||
while (token != NULL) {
|
||||
int i;
|
||||
|
||||
if (strcmp(token, "help") == 0) {
|
||||
optionError = 1;
|
||||
break;
|
||||
}
|
||||
for (op = options; op->name != NULL; ++op) {
|
||||
if (strcmp(token, op->name) == 0) {
|
||||
flags[op->i] &= op->mask;
|
||||
flags[op->i] |= op->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (op->name == NULL) {
|
||||
/* Option not found */
|
||||
optionError = 1;
|
||||
lprintf(LOG_ERR, "Invalid option: %s", token);
|
||||
}
|
||||
token = strtok_r(NULL, ",", &saveptr);
|
||||
}
|
||||
if (optionError) {
|
||||
lprintf(LOG_NOTICE, "Legal options are:");
|
||||
lprintf(LOG_NOTICE, "\thelp:\tprint this message");
|
||||
for (op = options; op->name != NULL; ++op) {
|
||||
lprintf(LOG_NOTICE, "\t%s:\t%s", op->name, op->desc);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], flags);
|
||||
}
|
||||
else
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], 0);
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -71,7 +71,7 @@ ipmi_event_msg_print(struct ipmi_intf * intf, struct platform_event_msg * pmsg)
|
||||
sel_event.sel_type.standard_type.event_data[0] = pmsg->event_data[0];
|
||||
sel_event.sel_type.standard_type.event_data[1] = pmsg->event_data[1];
|
||||
sel_event.sel_type.standard_type.event_data[2] = pmsg->event_data[2];
|
||||
|
||||
|
||||
if (verbose)
|
||||
ipmi_sel_print_extended_entry_verbose(intf, &sel_event);
|
||||
else
|
||||
@ -523,10 +523,10 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
|
||||
|
||||
/* clip off trailing and leading whitespace */
|
||||
ptr--;
|
||||
while (isspace(*ptr) && ptr >= buf)
|
||||
while (isspace((int)*ptr) && ptr >= buf)
|
||||
*ptr-- = '\0';
|
||||
ptr = buf;
|
||||
while (isspace(*ptr))
|
||||
while (isspace((int)*ptr))
|
||||
ptr++;
|
||||
if (strlen(ptr) == 0)
|
||||
continue;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,17 +37,26 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_fwum.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
|
||||
#include <ipmitool/ipmi_mc.h>
|
||||
|
||||
/******************************************************************************
|
||||
* HISTORY
|
||||
* ===========================================================================
|
||||
* 2007-01-11 [FI]
|
||||
* - Incremented to version 1.3
|
||||
* - Added lan packet size reduction mechanism to workaround fact
|
||||
* that lan iface will not return C7 on excessive length
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define VERSION_MAJ 1
|
||||
#define VERSION_MIN 1
|
||||
#define VERSION_MIN 3
|
||||
|
||||
|
||||
typedef enum eKFWUM_Task
|
||||
@ -123,17 +132,16 @@ typedef struct sKFWUM_SaveFirmwareInfo
|
||||
unsigned char overheadSize;
|
||||
}tKFWUM_SaveFirmwareInfo;
|
||||
|
||||
#define KFWUM_SMALL_BUFFER 28
|
||||
#define KFWUM_BIG_BUFFER 36
|
||||
#define KFWUM_OLD_CMD_OVERHEAD 6
|
||||
#define KFWUM_NEW_CMD_OVERHEAD 4
|
||||
#define KFWUM_SMALL_BUFFER 32 /* Minimum size (IPMB/IOL/old protocol) */
|
||||
#define KFWUM_BIG_BUFFER 32 /* Maximum size on KCS interface */
|
||||
|
||||
#define KFWUM_OLD_CMD_OVERHEAD 6 /*3 address + 1 size + 1 checksum + 1 command*/
|
||||
#define KFWUM_NEW_CMD_OVERHEAD 4 /*1 sequence+ 1 size + 1 checksum + 1 command*/
|
||||
#define KFWUM_PAGE_SIZE 256
|
||||
|
||||
extern int verbose;
|
||||
static unsigned char fileName[512];
|
||||
static unsigned char firmBuf[1024*512];
|
||||
static unsigned char firmMaj;
|
||||
static unsigned char firmMinSub;
|
||||
static tKFWUM_SaveFirmwareInfo saveFirmwareInfo;
|
||||
|
||||
static void KfwumOutputHelp(void);
|
||||
@ -157,7 +165,8 @@ static tKFWUM_Status KfwumManualRollback(struct ipmi_intf * intf);
|
||||
static tKFWUM_Status KfwumStartFirmwareImage(struct ipmi_intf * intf,
|
||||
unsigned long length,unsigned short padding);
|
||||
static tKFWUM_Status KfwumSaveFirmwareImage(struct ipmi_intf * intf,
|
||||
unsigned char sequenceNumber, unsigned long address, unsigned char *pFirmBuf, unsigned char inBufLength);
|
||||
unsigned char sequenceNumber, unsigned long address,
|
||||
unsigned char *pFirmBuf, unsigned char * pInBufLength);
|
||||
static tKFWUM_Status KfwumFinishFirmwareImage(struct ipmi_intf * intf,
|
||||
tKFWUM_InFirmwareInfo firmInfo);
|
||||
static tKFWUM_Status KfwumUploadFirmware(struct ipmi_intf * intf,
|
||||
@ -172,9 +181,19 @@ static tKFWUM_Status KfwumGetTraceLog(struct ipmi_intf * intf);
|
||||
|
||||
tKFWUM_Status KfwumValidFirmwareForBoard(tKFWUM_BoardInfo boardInfo,
|
||||
tKFWUM_InFirmwareInfo firmInfo);
|
||||
tKFWUM_Status KfwumOutputInfo(tKFWUM_BoardInfo boardInfo,
|
||||
static void KfwumOutputInfo(tKFWUM_BoardInfo boardInfo,
|
||||
tKFWUM_InFirmwareInfo firmInfo);
|
||||
|
||||
|
||||
/* ipmi_fwum_main - entry point for this ipmitool mode
|
||||
*
|
||||
* @intf: ipmi interface
|
||||
* @arc : number of arguments
|
||||
* @argv : point to argument array
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on error
|
||||
*/
|
||||
int ipmi_fwum_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
printf("FWUM extension Version %d.%d\n", VERSION_MAJ, VERSION_MIN);
|
||||
@ -203,7 +222,7 @@ int ipmi_fwum_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
/* There is a file name in the parameters */
|
||||
if(strlen(argv[1]) < 512)
|
||||
{
|
||||
strcpy(fileName, argv[1]);
|
||||
strcpy((char *)fileName, argv[1]);
|
||||
printf("Firmware File Name : %s\n", fileName);
|
||||
|
||||
KfwumMain(intf, KFWUM_TASK_DOWNLOAD);
|
||||
@ -225,7 +244,7 @@ int ipmi_fwum_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
/* There is a file name in the parameters */
|
||||
if(strlen(argv[1]) < 512)
|
||||
{
|
||||
strcpy(fileName, argv[1]);
|
||||
strcpy((char *)fileName, argv[1]);
|
||||
printf("Upgrading using file name %s\n", fileName);
|
||||
KfwumMain(intf, KFWUM_TASK_UPGRADE);
|
||||
}
|
||||
@ -314,8 +333,8 @@ static void KfwumMain(struct ipmi_intf * intf, tKFWUM_Task task)
|
||||
{
|
||||
tKFWUM_Status status = KFWUM_STATUS_OK;
|
||||
tKFWUM_BoardInfo boardInfo;
|
||||
tKFWUM_InFirmwareInfo firmInfo;
|
||||
unsigned long fileSize;
|
||||
tKFWUM_InFirmwareInfo firmInfo = { 0 };
|
||||
unsigned long fileSize = 0;
|
||||
static unsigned short padding;
|
||||
|
||||
if((status == KFWUM_STATUS_OK) && (task == KFWUM_TASK_INFO))
|
||||
@ -443,13 +462,20 @@ static void KfwumMain(struct ipmi_intf * intf, tKFWUM_Task task)
|
||||
|
||||
}
|
||||
|
||||
/* KfwumGetFileSize - gets the file size
|
||||
*
|
||||
* @pFileName : filename ptr
|
||||
* @pFileSize : output ptr for filesize
|
||||
*
|
||||
* returns KFWUM_STATUS_OK or KFWUM_STATUS_ERROR
|
||||
*/
|
||||
static tKFWUM_Status KfwumGetFileSize(unsigned char * pFileName,
|
||||
unsigned long * pFileSize)
|
||||
{
|
||||
tKFWUM_Status status = KFWUM_STATUS_ERROR;
|
||||
FILE * pFileHandle;
|
||||
|
||||
pFileHandle = fopen(pFileName, "rb");
|
||||
pFileHandle = fopen((const char *)pFileName, "rb");
|
||||
|
||||
if(pFileHandle)
|
||||
{
|
||||
@ -468,6 +494,13 @@ static tKFWUM_Status KfwumGetFileSize(unsigned char * pFileName,
|
||||
return(status);
|
||||
}
|
||||
|
||||
/* KfwumSetupBuffersFromFile - small buffers are used to store the file data
|
||||
*
|
||||
* @pFileName : filename ptr
|
||||
* unsigned long : filesize
|
||||
*
|
||||
* returns KFWUM_STATUS_OK or KFWUM_STATUS_ERROR
|
||||
*/
|
||||
#define MAX_BUFFER_SIZE 1024*16
|
||||
static tKFWUM_Status KfwumSetupBuffersFromFile(unsigned char * pFileName,
|
||||
unsigned long fileSize)
|
||||
@ -475,7 +508,7 @@ static tKFWUM_Status KfwumSetupBuffersFromFile(unsigned char * pFileName,
|
||||
tKFWUM_Status status = KFWUM_STATUS_OK;
|
||||
FILE * pFileHandle;
|
||||
|
||||
pFileHandle = fopen(pFileName, "rb");
|
||||
pFileHandle = fopen((const char *)pFileName, "rb");
|
||||
|
||||
if(pFileHandle)
|
||||
{
|
||||
@ -487,7 +520,7 @@ static tKFWUM_Status KfwumSetupBuffersFromFile(unsigned char * pFileName,
|
||||
|
||||
for(qty=0;qty<count;qty++)
|
||||
{
|
||||
KfwumShowProgress( "Reading Firmware from File", qty, count );
|
||||
KfwumShowProgress((const unsigned char *)"Reading Firmware from File", qty, count );
|
||||
if(fread(&firmBuf[qty*MAX_BUFFER_SIZE], 1, MAX_BUFFER_SIZE ,pFileHandle)
|
||||
== MAX_BUFFER_SIZE)
|
||||
{
|
||||
@ -503,12 +536,20 @@ static tKFWUM_Status KfwumSetupBuffersFromFile(unsigned char * pFileName,
|
||||
}
|
||||
if(status == KFWUM_STATUS_OK)
|
||||
{
|
||||
KfwumShowProgress( "Reading Firmware from File", 100, 100);
|
||||
KfwumShowProgress((const unsigned char *)"Reading Firmware from File", 100, 100);
|
||||
}
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
/* KfwumShowProgress - helper routine to display progress bar
|
||||
*
|
||||
* Converts current/total in percent
|
||||
*
|
||||
* *task : string identifying current operation
|
||||
* current: progress
|
||||
* total : limit
|
||||
*/
|
||||
#define PROG_LENGTH 42
|
||||
void KfwumShowProgress( const unsigned char * task, unsigned long current ,
|
||||
unsigned long total)
|
||||
@ -541,7 +582,7 @@ void KfwumShowProgress( const unsigned char * task, unsigned long current ,
|
||||
printf("%s", spaces );
|
||||
|
||||
|
||||
printf(" %3d %%\r",progress); /* total 7 bytes */
|
||||
printf(" %3ld %%\r",progress); /* total 7 bytes */
|
||||
|
||||
if( progress == 100 )
|
||||
{
|
||||
@ -551,7 +592,11 @@ void KfwumShowProgress( const unsigned char * task, unsigned long current ,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* KfwumCalculateChecksumPadding
|
||||
*
|
||||
* TBD
|
||||
*
|
||||
*/
|
||||
static unsigned short KfwumCalculateChecksumPadding(unsigned char * pBuffer,
|
||||
unsigned long totalSize)
|
||||
{
|
||||
@ -574,12 +619,24 @@ static unsigned short KfwumCalculateChecksumPadding(unsigned char * pBuffer,
|
||||
struct KfwumGetInfoResp {
|
||||
unsigned char protocolRevision;
|
||||
unsigned char controllerDeviceId;
|
||||
unsigned char mode;
|
||||
struct
|
||||
{
|
||||
unsigned char mode:1;
|
||||
unsigned char seqAdd:1;
|
||||
unsigned char res : 6;
|
||||
} byte;
|
||||
unsigned char firmRev1;
|
||||
unsigned char firmRev2;
|
||||
unsigned char numBank;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* KfwumGetInfo - Get Firmware Update Manager (FWUM) information
|
||||
*
|
||||
* * intf : IPMI interface
|
||||
* output : when set to non zero, queried information is displayed
|
||||
* pNumBank: output ptr for number of banks
|
||||
*/
|
||||
static tKFWUM_Status KfwumGetInfo(struct ipmi_intf * intf, unsigned char output,
|
||||
unsigned char *pNumBank)
|
||||
{
|
||||
@ -620,7 +677,7 @@ static tKFWUM_Status KfwumGetInfo(struct ipmi_intf * intf, unsigned char output,
|
||||
printf("Firmware Revision : %u.%u%u",
|
||||
pGetInfo->firmRev1, pGetInfo->firmRev2 >> 4,
|
||||
pGetInfo->firmRev2 & 0x0f);
|
||||
if(pGetInfo->mode != 0)
|
||||
if(pGetInfo->byte.mode != 0)
|
||||
{
|
||||
printf(" - DEBUG BUILD\n");
|
||||
}
|
||||
@ -633,12 +690,19 @@ static tKFWUM_Status KfwumGetInfo(struct ipmi_intf * intf, unsigned char output,
|
||||
* pNumBank = pGetInfo->numBank;
|
||||
|
||||
/* Determine wich type of download to use: */
|
||||
/* Old FWUM or Old IPMC fw (data_len < 7) --> Address with small buffer size */
|
||||
/* Old FWUM or Old IPMC fw (data_len < 7) -->
|
||||
Address with small buffer size */
|
||||
if ( (pGetInfo->protocolRevision) <= 0x05 || (rsp->data_len < 7 ) )
|
||||
{
|
||||
saveFirmwareInfo.downloadType = KFWUM_DOWNLOAD_TYPE_ADDRESS;
|
||||
saveFirmwareInfo.bufferSize = KFWUM_SMALL_BUFFER;
|
||||
saveFirmwareInfo.overheadSize = KFWUM_OLD_CMD_OVERHEAD;
|
||||
|
||||
if(verbose)
|
||||
{
|
||||
printf("Protocol Revision :");
|
||||
printf(" <= 5 detected, adjusting buffers\n");
|
||||
}
|
||||
}
|
||||
else /* Both fw are using the new protocol */
|
||||
{
|
||||
@ -646,20 +710,60 @@ static tKFWUM_Status KfwumGetInfo(struct ipmi_intf * intf, unsigned char output,
|
||||
saveFirmwareInfo.overheadSize = KFWUM_NEW_CMD_OVERHEAD;
|
||||
/* Buffer size depending on access type (Local or remote) */
|
||||
/* Look if we run remote or locally */
|
||||
if ( intf->target_addr != IPMI_BMC_SLAVE_ADDR )
|
||||
|
||||
if(verbose)
|
||||
{
|
||||
saveFirmwareInfo.bufferSize = KFWUM_SMALL_BUFFER;
|
||||
printf("Protocol Revision :");
|
||||
printf(" > 5 optimizing buffers\n");
|
||||
}
|
||||
|
||||
if(strstr(intf->name,"lan")!= NULL) /* also covers lanplus */
|
||||
{
|
||||
saveFirmwareInfo.bufferSize = KFWUM_SMALL_BUFFER;
|
||||
if(verbose)
|
||||
{
|
||||
printf("IOL payload size : %d\r\n" ,
|
||||
saveFirmwareInfo.bufferSize);
|
||||
}
|
||||
}
|
||||
else if
|
||||
(
|
||||
(strstr(intf->name,"open")!= NULL)
|
||||
&&
|
||||
intf->target_addr != IPMI_BMC_SLAVE_ADDR
|
||||
&&
|
||||
(
|
||||
intf->target_addr != intf->my_addr
|
||||
)
|
||||
)
|
||||
{
|
||||
saveFirmwareInfo.bufferSize = KFWUM_SMALL_BUFFER;
|
||||
if(verbose)
|
||||
{
|
||||
printf("IPMB payload size : %d\r\n" ,
|
||||
saveFirmwareInfo.bufferSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
saveFirmwareInfo.bufferSize = KFWUM_BIG_BUFFER;
|
||||
saveFirmwareInfo.bufferSize = KFWUM_BIG_BUFFER;
|
||||
if(verbose)
|
||||
{
|
||||
printf("SMI payload size : %d\r\n",
|
||||
saveFirmwareInfo.bufferSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* KfwumGetDeviceInfo - Get IPMC/Board information
|
||||
*
|
||||
* * intf : IPMI interface
|
||||
* output : when set to non zero, queried information is displayed
|
||||
* tKFWUM_BoardInfo: output ptr for IPMC/Board information
|
||||
*/
|
||||
static tKFWUM_Status KfwumGetDeviceInfo(struct ipmi_intf * intf,
|
||||
unsigned char output, tKFWUM_BoardInfo * pBoardInfo)
|
||||
{
|
||||
@ -689,24 +793,8 @@ static tKFWUM_Status KfwumGetDeviceInfo(struct ipmi_intf * intf,
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct ipm_devid_rsp {
|
||||
unsigned char device_id;
|
||||
unsigned char device_revision;
|
||||
unsigned char fw_rev1;
|
||||
unsigned char fw_rev2;
|
||||
unsigned char ipmi_version;
|
||||
unsigned char adtl_device_support;
|
||||
unsigned char manufacturer_id[3];
|
||||
unsigned char product_id[2];
|
||||
unsigned char aux_fw_rev[4];
|
||||
} __attribute__ ((packed));
|
||||
#endif
|
||||
|
||||
if(status == KFWUM_STATUS_OK)
|
||||
{
|
||||
unsigned long manufId;
|
||||
unsigned short boardId;
|
||||
pGetDevId = (struct ipm_devid_rsp *) rsp->data;
|
||||
pBoardInfo->iana = IPM_DEV_MANUFACTURER_ID(pGetDevId->manufacturer_id);
|
||||
pBoardInfo->boardId = buf2short(pGetDevId->product_id);
|
||||
@ -739,11 +827,6 @@ static tKFWUM_Status KfwumGetDeviceInfo(struct ipmi_intf * intf,
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct KfwumGetStatusResp {
|
||||
unsigned char bankState;
|
||||
unsigned char firmLengthLSB;
|
||||
@ -762,7 +845,10 @@ const struct valstr bankStateValS[] = {
|
||||
{ 0x04, "Previous Good" }
|
||||
};
|
||||
|
||||
|
||||
/* KfwumGetStatus - Get (and prints) FWUM banks information
|
||||
*
|
||||
* * intf : IPMI interface
|
||||
*/
|
||||
static tKFWUM_Status KfwumGetStatus(struct ipmi_intf * intf)
|
||||
{
|
||||
tKFWUM_Status status = KFWUM_STATUS_OK;
|
||||
@ -821,7 +907,7 @@ static tKFWUM_Status KfwumGetStatus(struct ipmi_intf * intf)
|
||||
firmLength = firmLength << 8;
|
||||
firmLength |= pGetStatus->firmLengthLSB;
|
||||
|
||||
printf("Firmware Length : %d bytes\n", firmLength);
|
||||
printf("Firmware Length : %ld bytes\n", firmLength);
|
||||
printf("Firmware Revision : %u.%u%u SDR %u\n",
|
||||
pGetStatus->firmRev1, pGetStatus->firmRev2 >> 4,
|
||||
pGetStatus->firmRev2 & 0x0f, pGetStatus->firmRev3);
|
||||
@ -836,6 +922,10 @@ struct KfwumManualRollbackReq{
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* KfwumManualRollback - Ask IPMC to rollback to previous version
|
||||
*
|
||||
* * intf : IPMI interface
|
||||
*/
|
||||
static tKFWUM_Status KfwumManualRollback(struct ipmi_intf * intf)
|
||||
{
|
||||
tKFWUM_Status status = KFWUM_STATUS_OK;
|
||||
@ -952,22 +1042,26 @@ struct KfwumSaveFirmwareAddressReq
|
||||
struct KfwumSaveFirmwareSequenceReq
|
||||
{
|
||||
unsigned char sequenceNumber;
|
||||
unsigned char txBuf[KFWUM_BIG_BUFFER-KFWUM_NEW_CMD_OVERHEAD];
|
||||
unsigned char txBuf[KFWUM_BIG_BUFFER];
|
||||
}__attribute__ ((packed));
|
||||
|
||||
|
||||
#define FWUM_SAVE_FIRMWARE_NO_RESPONSE_LIMIT ((unsigned char)6)
|
||||
|
||||
static tKFWUM_Status KfwumSaveFirmwareImage(struct ipmi_intf * intf,
|
||||
unsigned char sequenceNumber, unsigned long address, unsigned char *pFirmBuf,
|
||||
unsigned char inBufLength)
|
||||
unsigned char * pInBufLength)
|
||||
{
|
||||
tKFWUM_Status status = KFWUM_STATUS_OK;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char out = 0;
|
||||
unsigned char retry = 0;
|
||||
unsigned char counter;
|
||||
unsigned char noResponse = 0 ;
|
||||
|
||||
struct KfwumSaveFirmwareAddressReq addressReq;
|
||||
struct KfwumSaveFirmwareSequenceReq sequenceReq;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
memset(&req, 0, sizeof(req));
|
||||
@ -979,26 +1073,46 @@ static tKFWUM_Status KfwumSaveFirmwareImage(struct ipmi_intf * intf,
|
||||
addressReq.addressLSB = address & 0x000000ff;
|
||||
addressReq.addressMid = (address >> 8) & 0x000000ff;
|
||||
addressReq.addressMSB = (address >> 16) & 0x000000ff;
|
||||
addressReq.numBytes = inBufLength;
|
||||
memcpy(addressReq.txBuf, pFirmBuf, inBufLength);
|
||||
addressReq.numBytes = (* pInBufLength);
|
||||
memcpy(addressReq.txBuf, pFirmBuf, (* pInBufLength));
|
||||
req.msg.data = (unsigned char *) &addressReq;
|
||||
req.msg.data_len = inBufLength+4;
|
||||
req.msg.data_len = (* pInBufLength)+4;
|
||||
}
|
||||
else
|
||||
{
|
||||
sequenceReq.sequenceNumber = sequenceNumber;
|
||||
memcpy(sequenceReq.txBuf, pFirmBuf, inBufLength);
|
||||
memcpy(sequenceReq.txBuf, pFirmBuf, (* pInBufLength));
|
||||
req.msg.data = (unsigned char *) &sequenceReq;
|
||||
req.msg.data_len = inBufLength+sizeof(unsigned char); /* + 1 => sequenceNumber*/
|
||||
req.msg.data_len = (* pInBufLength)+sizeof(unsigned char); /* + 1 => sequenceNumber*/
|
||||
}
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp)
|
||||
{
|
||||
printf("Error in FWUM Firmware Save Firmware Image Download Command\n");
|
||||
status = KFWUM_STATUS_ERROR;
|
||||
|
||||
out = 0;
|
||||
status = KFWUM_STATUS_OK;
|
||||
|
||||
/* With IOL, we don't receive "C7" on errors, instead we receive
|
||||
nothing */
|
||||
if(strstr(intf->name,"lan")!= NULL)
|
||||
{
|
||||
noResponse++;
|
||||
|
||||
if(noResponse < FWUM_SAVE_FIRMWARE_NO_RESPONSE_LIMIT )
|
||||
{
|
||||
(* pInBufLength) -= 1;
|
||||
out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error, too many commands without response\n");
|
||||
(* pInBufLength) = 0 ;
|
||||
out = 1;
|
||||
}
|
||||
} /* For other interface keep trying */
|
||||
}
|
||||
else if (rsp->ccode)
|
||||
{
|
||||
@ -1007,6 +1121,19 @@ static tKFWUM_Status KfwumSaveFirmwareImage(struct ipmi_intf * intf,
|
||||
status = KFWUM_STATUS_OK;
|
||||
sleep(1);
|
||||
}
|
||||
else if(
|
||||
(rsp->ccode == 0xc7)
|
||||
||
|
||||
(
|
||||
(rsp->ccode == 0xC3) &&
|
||||
(sequenceNumber == 0)
|
||||
)
|
||||
)
|
||||
{
|
||||
(* pInBufLength) -= 1;
|
||||
status = KFWUM_STATUS_OK;
|
||||
retry = 1;
|
||||
}
|
||||
else if(rsp->ccode == 0x82)
|
||||
{
|
||||
/* Double sent, continue */
|
||||
@ -1030,7 +1157,21 @@ static tKFWUM_Status KfwumSaveFirmwareImage(struct ipmi_intf * intf,
|
||||
{
|
||||
retry = 1;
|
||||
status = KFWUM_STATUS_OK;
|
||||
}else
|
||||
}
|
||||
else if(rsp->ccode == 0xC3)
|
||||
{
|
||||
if(retry == 0)
|
||||
{
|
||||
retry = 1;
|
||||
status = KFWUM_STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = KFWUM_STATUS_ERROR;
|
||||
out = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("FWUM Firmware Save Firmware Image Download returned %x\n",
|
||||
rsp->ccode);
|
||||
@ -1100,15 +1241,14 @@ static tKFWUM_Status KfwumUploadFirmware(struct ipmi_intf * intf,
|
||||
tKFWUM_Status status = KFWUM_STATUS_ERROR;
|
||||
unsigned long address = 0x0;
|
||||
unsigned char writeSize;
|
||||
unsigned char oldWriteSize;
|
||||
unsigned long lastAddress = 0;
|
||||
unsigned char sequenceNumber = 0;
|
||||
unsigned char retry = FWUM_MAX_UPLOAD_RETRY;
|
||||
unsigned char isLengthValid = 1;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned char bytes;
|
||||
unsigned char chksum = 0;
|
||||
|
||||
writeSize = saveFirmwareInfo.bufferSize - saveFirmwareInfo.overheadSize;
|
||||
|
||||
/* Reach the end */
|
||||
@ -1122,16 +1262,27 @@ static tKFWUM_Status KfwumUploadFirmware(struct ipmi_intf * intf,
|
||||
writeSize = (KFWUM_PAGE_SIZE - (address % KFWUM_PAGE_SIZE));
|
||||
}
|
||||
|
||||
status = KfwumSaveFirmwareImage(intf, sequenceNumber, address, &pBuffer[address],
|
||||
writeSize);
|
||||
|
||||
oldWriteSize = writeSize;
|
||||
status = KfwumSaveFirmwareImage(intf, sequenceNumber, address,
|
||||
&pBuffer[address], &writeSize);
|
||||
|
||||
if((status != KFWUM_STATUS_OK) && (retry-- != 0))
|
||||
{
|
||||
address = lastAddress;
|
||||
status = KFWUM_STATUS_OK;
|
||||
}
|
||||
else if( writeSize == 0 )
|
||||
{
|
||||
status = KFWUM_STATUS_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(writeSize != oldWriteSize)
|
||||
{
|
||||
printf("Adjusting length to %d bytes \n", writeSize);
|
||||
saveFirmwareInfo.bufferSize -= (oldWriteSize - writeSize);
|
||||
}
|
||||
|
||||
retry = FWUM_MAX_UPLOAD_RETRY;
|
||||
lastAddress = address;
|
||||
address+= writeSize;
|
||||
@ -1141,7 +1292,8 @@ static tKFWUM_Status KfwumUploadFirmware(struct ipmi_intf * intf,
|
||||
{
|
||||
if((address % 1024) == 0)
|
||||
{
|
||||
KfwumShowProgress("Writting Firmware in Flash",address,totalSize);
|
||||
KfwumShowProgress((const unsigned char *)\
|
||||
"Writting Firmware in Flash",address,totalSize);
|
||||
}
|
||||
sequenceNumber++;
|
||||
}
|
||||
@ -1150,10 +1302,10 @@ static tKFWUM_Status KfwumUploadFirmware(struct ipmi_intf * intf,
|
||||
|
||||
if(status == KFWUM_STATUS_OK)
|
||||
{
|
||||
KfwumShowProgress( "Writting Firmware in Flash", 100 , 100 );
|
||||
KfwumShowProgress((const unsigned char *)\
|
||||
"Writting Firmware in Flash", 100 , 100 );
|
||||
}
|
||||
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
@ -1461,32 +1613,12 @@ tKFWUM_Status KfwumValidFirmwareForBoard(tKFWUM_BoardInfo boardInfo,
|
||||
}
|
||||
|
||||
|
||||
tKFWUM_Status KfwumOutputInfo(tKFWUM_BoardInfo boardInfo,
|
||||
static void KfwumOutputInfo(tKFWUM_BoardInfo boardInfo,
|
||||
tKFWUM_InFirmwareInfo firmInfo)
|
||||
{
|
||||
#if 0
|
||||
unsigned long fileSize;
|
||||
unsigned short checksum;
|
||||
unsigned short sumToRemoveFromChecksum;
|
||||
/* Since the checksum is added in the bin
|
||||
after the checksum is calculated, we
|
||||
need to remove the each byte value. This
|
||||
byte will contain the addition of both bytes*/
|
||||
tKFWUM_BoardList boardId;
|
||||
unsigned char deviceId;
|
||||
unsigned char tableVers;
|
||||
unsigned char implRev;
|
||||
unsigned char versMajor;
|
||||
unsigned char versMinor;
|
||||
unsigned char versSubMinor;
|
||||
unsigned char sdrRev;
|
||||
tKFWUM_IanaList iana;
|
||||
#endif
|
||||
|
||||
printf("Target Board Id : %u\n",boardInfo.boardId);
|
||||
printf("Target IANA number : %u\n",boardInfo.iana);
|
||||
printf("File Size : %u bytes\n",firmInfo.fileSize);
|
||||
printf("File Size : %lu bytes\n",firmInfo.fileSize);
|
||||
printf("Firmware Version : %d.%d%d SDR %d\n",firmInfo.versMajor,
|
||||
firmInfo.versMinor, firmInfo.versSubMinor, firmInfo.sdrRev);
|
||||
|
||||
}
|
||||
|
2398
ipmitool/lib/ipmi_hpmfwupg.c
Normal file
2398
ipmitool/lib/ipmi_hpmfwupg.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -148,9 +148,9 @@ ipmi_kontron_set_serial_number(struct ipmi_intf * intf)
|
||||
struct fru_header header;
|
||||
uint8_t msg_data[4];
|
||||
char *sn;
|
||||
uint8_t sn_size, checksum,prev_lun;
|
||||
int ret = 0;
|
||||
uint8_t *fru_data, *fru_area;
|
||||
uint8_t sn_size, checksum;
|
||||
uint8_t *fru_data;
|
||||
char *fru_area;
|
||||
uint32_t fru_data_offset, fru_data_offset_tmp, board_sec_len, prod_sec_len, i;
|
||||
|
||||
sn = NULL;
|
||||
@ -193,7 +193,7 @@ ipmi_kontron_set_serial_number(struct ipmi_intf * intf)
|
||||
if(sn == NULL)
|
||||
{
|
||||
printf("Out of memory!");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(sn, 0, sn_size + 1);
|
||||
@ -435,7 +435,6 @@ ipmi_kontron_set_mfg_date (struct ipmi_intf * intf)
|
||||
|
||||
uint32_t board_sec_len, i;
|
||||
uint8_t *fru_data, checksum;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
|
||||
@ -551,7 +550,7 @@ ipmi_kontron_set_mfg_date (struct ipmi_intf * intf)
|
||||
|
||||
if(fru_data == NULL)
|
||||
{
|
||||
lprintf("Out of memory!");
|
||||
printf("Out of memory!");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ __set_lan_param(struct ipmi_intf * intf, uint8_t chan,
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t msg_data[32];
|
||||
|
||||
|
||||
if (param < 0)
|
||||
return -1;
|
||||
|
||||
@ -394,9 +394,10 @@ ipmi_lanp_unlock(struct ipmi_intf * intf, uint8_t chan)
|
||||
rc = __set_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS, &val, 1, 0);
|
||||
if (rc < 0) {
|
||||
lprintf(LOG_DEBUG, "LAN Parameter Commit not supported");
|
||||
val = IPMI_LANP_WRITE_UNLOCK;
|
||||
__set_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS, &val, 0, 0);
|
||||
}
|
||||
|
||||
val = IPMI_LANP_WRITE_UNLOCK;
|
||||
__set_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS, &val, 1, 0);
|
||||
}
|
||||
|
||||
/* set_lan_param - Wrap LAN parameter write with set-in-progress lock
|
||||
@ -448,7 +449,7 @@ lan_set_arp_interval(struct ipmi_intf * intf,
|
||||
struct lan_param *lp;
|
||||
uint8_t interval;
|
||||
int rc = 0;
|
||||
|
||||
|
||||
lp = get_lan_param(intf, chan, IPMI_LANP_GRAT_ARP);
|
||||
if (lp == NULL)
|
||||
return -1;
|
||||
@ -520,7 +521,7 @@ lan_set_arp_respond(struct ipmi_intf * intf,
|
||||
static char priv_level_to_char(unsigned char priv_level)
|
||||
{
|
||||
char ret = 'X';
|
||||
|
||||
|
||||
switch (priv_level)
|
||||
{
|
||||
case IPMI_SESSION_PRIV_CALLBACK:
|
||||
@ -801,7 +802,7 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
|
||||
priv_level_to_char(p->data[7] & 0x0F),
|
||||
priv_level_to_char(p->data[7] >> 4),
|
||||
priv_level_to_char(p->data[8] & 0x0F));
|
||||
|
||||
|
||||
/* Now print a legend */
|
||||
printf("%-24s: %s\n", "", " X=Cipher Suite Unused");
|
||||
printf("%-24s: %s\n", "", " c=CALLBACK");
|
||||
@ -870,7 +871,7 @@ ipmi_lan_set_auth(struct ipmi_intf * intf, uint8_t chan, char * level, char * ty
|
||||
data[2] = authtype;
|
||||
else if (strncasecmp(p, "admin", 5) == 0)
|
||||
data[3] = authtype;
|
||||
else
|
||||
else
|
||||
lprintf(LOG_WARNING, "Invalid authentication level: %s", p);
|
||||
p = strchr(p, ',');
|
||||
if (p)
|
||||
@ -1003,37 +1004,90 @@ ipmi_set_channel_access(struct ipmi_intf * intf, uint8_t channel, uint8_t enable
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t rqdata[3];
|
||||
uint8_t byteEnable;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
/* RETREIVE VALUE IN NVRAM */
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = 0x40;
|
||||
req.msg.cmd = 0x41; /* Get Channel Access Command */
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 2;
|
||||
|
||||
memset(rqdata, 0, 2);
|
||||
rqdata[0] = channel & 0xf;
|
||||
rqdata[1] = 0x40; /* retreive NV */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel);
|
||||
return -1;
|
||||
} else if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s",
|
||||
channel, val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
} else {
|
||||
byteEnable = *(rsp->data + 0);
|
||||
}
|
||||
|
||||
/* SAVE TO NVRAM */
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = 0x40; /* Set Channel Access Command */
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
/* SAVE TO NVRAM */
|
||||
memset(rqdata, 0, 3);
|
||||
rqdata[0] = channel & 0xf;
|
||||
rqdata[1] = 0x40; /* set pef enabled, per-msg auth enabled */
|
||||
rqdata[1] = 0x40 | (byteEnable & 0x38); /* use previously set values */
|
||||
if (enable != 0)
|
||||
rqdata[1] |= 0x2; /* set always available if enable is set */
|
||||
rqdata[2] = 0x44; /* set channel privilege limit to ADMIN */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
} else if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s",
|
||||
channel, val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* RETREIVE VALUE IN NVRAM */
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = 0x41; /* Get Channel Access Command */
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 2;
|
||||
|
||||
memset(rqdata, 0, 2);
|
||||
rqdata[0] = channel & 0xf;
|
||||
rqdata[1] = 0x80; /* retreive NV */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel);
|
||||
return -1;
|
||||
} else if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s",
|
||||
channel, val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
} else {
|
||||
byteEnable = *(rsp->data + 0);
|
||||
}
|
||||
|
||||
/* SAVE TO CURRENT */
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = 0x40; /* Set Channel Access Command */
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
memset(rqdata, 0, 3);
|
||||
rqdata[0] = channel & 0xf;
|
||||
rqdata[1] = 0x80; /* set pef enabled, per-msg auth enabled */
|
||||
rqdata[1] = 0x80 | (byteEnable & 0x38); /* use previously set values */
|
||||
if (enable != 0)
|
||||
rqdata[1] |= 0x2; /* set always available if enable is set */
|
||||
rqdata[2] = 0x84; /* set channel privilege limit to ADMIN */
|
||||
@ -1042,8 +1096,7 @@ ipmi_set_channel_access(struct ipmi_intf * intf, uint8_t channel, uint8_t enable
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
} else if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s",
|
||||
channel, val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
@ -1068,7 +1121,7 @@ ipmi_set_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid)
|
||||
rqdata[1] = userid & 0x3f;
|
||||
rqdata[2] = 0x4;
|
||||
rqdata[3] = 0;
|
||||
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = 0x43;
|
||||
@ -1121,7 +1174,7 @@ get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf)
|
||||
}
|
||||
|
||||
/*
|
||||
* The first byte is reservered (0). The resst of the buffer is setup
|
||||
* The first byte is reserved (0). The rest of the buffer is setup
|
||||
* so that each nibble holds the maximum privilege level available for
|
||||
* that cipher suite number. The number of nibbles (15) matches the number
|
||||
* of fixed cipher suite IDs. This command documentation mentions 16 IDs
|
||||
@ -1136,7 +1189,7 @@ get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf)
|
||||
|
||||
for (i = 0; i < 15; ++i)
|
||||
{
|
||||
unsigned char priv_level;
|
||||
unsigned char priv_level = IPMI_SESSION_PRIV_ADMIN;
|
||||
|
||||
switch (arg[i])
|
||||
{
|
||||
@ -1164,7 +1217,7 @@ get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf)
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (ret != 0)
|
||||
break;
|
||||
else
|
||||
@ -1181,7 +1234,7 @@ get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1560,7 +1613,7 @@ ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
else {
|
||||
ipmi_lan_set_usage();
|
||||
}
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1950,18 +2003,16 @@ ipmi_lan_stats_get(struct ipmi_intf * intf, uint8_t chan)
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (verbose > 1)
|
||||
{
|
||||
|
||||
if (verbose > 1) {
|
||||
uint8_t counter;
|
||||
printf("--- Rx Stats ---\n");
|
||||
for(counter=0;counter<18;counter+=2)
|
||||
{
|
||||
printf("%02X", *(rsp->data + counter));
|
||||
printf(" %02X - ", *(rsp->data + counter+1));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("--- Rx Stats ---\n");
|
||||
for (counter=0; counter<18; counter+=2) {
|
||||
printf("%02X", *(rsp->data + counter));
|
||||
printf(" %02X - ", *(rsp->data + counter+1));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
statsTemp = ((*(rsp->data + 0)) << 8) | (*(rsp->data + 1));
|
||||
printf("IP Rx Packet : %d\n", statsTemp);
|
||||
@ -2099,8 +2150,8 @@ ipmi_lanp_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
}
|
||||
else if (argc > 2)
|
||||
chan = (uint8_t)strtol(argv[2], NULL, 0);
|
||||
|
||||
if (chan < 2 || chan > IPMI_CHANNEL_NUMBER_MAX)
|
||||
|
||||
if (chan < 1 || chan > IPMI_CHANNEL_NUMBER_MAX)
|
||||
{
|
||||
lprintf(LOG_ERR, "Invalid channel: %d", chan);
|
||||
return -1;
|
||||
@ -2115,6 +2166,7 @@ ipmi_lanp_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
else
|
||||
{
|
||||
lprintf(LOG_NOTICE, "Invalid LAN command: %s", argv[0]);
|
||||
rc = -1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -71,9 +71,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ALL_OPTIONS
|
||||
# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:C:L:A:t:m:S:l:b:e:k:O:"
|
||||
# define OPTION_STRING "I:hVvcgsEao:H:d:P:f:U:p:C:L:A:t:m:S:l:b:e:k:O:"
|
||||
#else
|
||||
# define OPTION_STRING "I:hVvcH:f:U:p:S:"
|
||||
# define OPTION_STRING "I:hVvcH:f:U:p:d:S:"
|
||||
#endif
|
||||
|
||||
extern int verbose;
|
||||
@ -216,6 +216,7 @@ ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_
|
||||
lprintf(LOG_NOTICE, " -V Show version information");
|
||||
lprintf(LOG_NOTICE, " -v Verbose (can use multiple times)");
|
||||
lprintf(LOG_NOTICE, " -c Display output in comma separated format");
|
||||
lprintf(LOG_NOTICE, " -d N Specify a /dev/ipmiN device to use (default=0)");
|
||||
lprintf(LOG_NOTICE, " -I intf Interface to use");
|
||||
lprintf(LOG_NOTICE, " -H hostname Remote host name for LAN interface");
|
||||
lprintf(LOG_NOTICE, " -p port Remote RMCP port [default=623]");
|
||||
@ -228,6 +229,7 @@ ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_
|
||||
lprintf(LOG_NOTICE, " -C ciphersuite Cipher suite to be used by lanplus interface");
|
||||
lprintf(LOG_NOTICE, " -k key Use Kg key for IPMIv2 authentication");
|
||||
lprintf(LOG_NOTICE, " -L level Remote session privilege level [default=ADMINISTRATOR]");
|
||||
lprintf(LOG_NOTICE, " Append a '+' to use name/privilege lookup in RAKP1");
|
||||
lprintf(LOG_NOTICE, " -A authtype Force use of auth type NONE, PASSWORD, MD2, MD5 or OEM");
|
||||
lprintf(LOG_NOTICE, " -P password Remote session password");
|
||||
lprintf(LOG_NOTICE, " -E Read password from IPMI_PASSWORD environment variable");
|
||||
@ -269,6 +271,7 @@ ipmi_main(int argc, char ** argv,
|
||||
uint8_t target_channel = 0;
|
||||
uint8_t target_lun = 0;
|
||||
uint8_t my_addr = 0;
|
||||
uint8_t lookupbit = 0x10; /* use name-only lookup by default */
|
||||
int authtype = -1;
|
||||
char * tmp = NULL;
|
||||
char * hostname = NULL;
|
||||
@ -281,6 +284,7 @@ ipmi_main(int argc, char ** argv,
|
||||
char * kgkey = NULL;
|
||||
char * seloem = NULL;
|
||||
int port = 0;
|
||||
int devnum = 0;
|
||||
int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */
|
||||
int argflag, i, found;
|
||||
int rc = -1;
|
||||
@ -323,6 +327,9 @@ ipmi_main(int argc, char ** argv,
|
||||
rc = 0;
|
||||
goto out_free;
|
||||
break;
|
||||
case 'd':
|
||||
devnum = atoi(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
@ -447,9 +454,15 @@ ipmi_main(int argc, char ** argv,
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
i = strlen(optarg);
|
||||
if ((i > 0) && (optarg[i-1] == '+')) {
|
||||
lookupbit = 0;
|
||||
optarg[i-1] = 0;
|
||||
}
|
||||
privlvl = str2val(optarg, ipmi_privlvl_vals);
|
||||
if (privlvl == 0xFF)
|
||||
if (privlvl == 0xFF) {
|
||||
lprintf(LOG_WARN, "Invalid privilege level %s", optarg);
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
authtype = str2val(optarg, ipmi_authtype_session_vals);
|
||||
@ -564,6 +577,7 @@ ipmi_main(int argc, char ** argv,
|
||||
ipmi_intf_session_set_privlvl(intf,
|
||||
IPMI_SESSION_PRIV_ADMIN); /* default */
|
||||
|
||||
ipmi_intf_session_set_lookupbit(intf, lookupbit);
|
||||
ipmi_intf_session_set_sol_escape_char(intf, sol_escape_char);
|
||||
ipmi_intf_session_set_cipher_suite_id(intf, cipher_suite_id);
|
||||
|
||||
@ -573,6 +587,8 @@ ipmi_main(int argc, char ** argv,
|
||||
/* setup destination channel if given */
|
||||
intf->target_channel = target_channel ;
|
||||
|
||||
intf->devnum = devnum;
|
||||
|
||||
/* setup IPMB local and target address if given */
|
||||
intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR;
|
||||
if (target_addr > 0) {
|
||||
|
@ -564,9 +564,13 @@ ipmi_mc_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
else if (strncmp(argv[0], "setenables", 10) == 0) {
|
||||
rc = ipmi_mc_set_enables(intf, argc-1, &(argv[1]));
|
||||
}
|
||||
else if (!strncmp(argv[0], "selftest", 8)) {
|
||||
else if (!strncmp(argv[0], "selftest", 8)) {
|
||||
rc = ipmi_mc_get_selftest(intf);
|
||||
}
|
||||
else {
|
||||
lprintf(LOG_ERR, "Invalid mc/bmc command: %s", argv[0]);
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ static struct ipmi_oem_handle ipmi_oem_list[] = {
|
||||
desc: "IBM OEM support",
|
||||
setup: ipmi_oem_ibm,
|
||||
},
|
||||
{ 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Supermicro IPMIv2 BMCs use OEM authtype */
|
||||
@ -110,7 +110,6 @@ int
|
||||
ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype)
|
||||
{
|
||||
struct ipmi_oem_handle * oem;
|
||||
int i;
|
||||
int rc = 0;
|
||||
|
||||
if (strncmp(oemtype, "help", 4) == 0 ||
|
||||
@ -120,18 +119,13 @@ ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype)
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (oem=ipmi_oem_list, i=0; i < sizeof(ipmi_oem_list)/sizeof(struct ipmi_oem_handle); oem++, i++) {
|
||||
if (oem->name == NULL)
|
||||
continue;
|
||||
for (oem=ipmi_oem_list; oem->name != NULL; oem++) {
|
||||
if (strncmp(oemtype, oem->name, strlen(oem->name)) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (oem->name == NULL) {
|
||||
/* nothing was found */
|
||||
lprintf(LOG_ERR, "OEM support not found for \"%s\"", oemtype);
|
||||
if (oem->name == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* save pointer for later use */
|
||||
intf->oem = oem;
|
||||
@ -164,4 +158,3 @@ ipmi_oem_active(struct ipmi_intf * intf, const char * oemtype)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -730,6 +730,7 @@ ipmi_pef_get_status(struct ipmi_intf * intf)
|
||||
struct ipmi_rq req;
|
||||
struct pef_cfgparm_selector psel;
|
||||
char tbuf[40];
|
||||
uint32_t timei;
|
||||
time_t ts;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
@ -741,11 +742,12 @@ ipmi_pef_get_status(struct ipmi_intf * intf)
|
||||
"Last S/W processed ID");
|
||||
return;
|
||||
}
|
||||
memcpy(&timei, rsp->data, sizeof(timei));
|
||||
#if WORDS_BIGENDIAN
|
||||
ts = (time_t)(rsp->data[0]<<24 + rsp->data[1]<<16 + rsp->data[2]<<8 + rsp->data[3]);
|
||||
#else
|
||||
ts = (time_t)(*(long *)rsp->data);
|
||||
timei = BSWAP_32(timei);
|
||||
#endif
|
||||
ts = (time_t)timei;
|
||||
|
||||
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", localtime(&ts));
|
||||
|
||||
ipmi_pef_print_str("Last SEL addition", tbuf);
|
||||
@ -843,6 +845,7 @@ int ipmi_pef_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
// PEF subcommand handling
|
||||
*/
|
||||
int help = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (!argc || !strncmp(argv[0], "info", 4))
|
||||
ipmi_pef_get_info(intf);
|
||||
@ -856,11 +859,14 @@ int ipmi_pef_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
ipmi_pef_list_entries(intf);
|
||||
else {
|
||||
help = 1;
|
||||
rc = -1;
|
||||
lprintf(LOG_ERR, "Invalid PEF command: '%s'\n", argv[0]);
|
||||
}
|
||||
|
||||
if (help)
|
||||
lprintf(LOG_NOTICE, "PEF commands: info status policy list");
|
||||
else if (!verbose)
|
||||
printf("\n");
|
||||
return 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -7,25 +7,42 @@
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_picmg.h>
|
||||
#include <ipmitool/ipmi_fru.h> /* for access to link descriptor defines */
|
||||
#include <ipmitool/log.h>
|
||||
|
||||
|
||||
#define PICMG_EKEY_MODE_QUERY 0
|
||||
#define PICMG_EKEY_MODE_PRINT_ALL 1
|
||||
#define PICMG_EKEY_MODE_PRINT_ENABLED 2
|
||||
#define PICMG_EKEY_MODE_PRINT_DISABLED 3
|
||||
|
||||
#define PICMG_EKEY_MAX_CHANNEL 16
|
||||
#define PICMG_EKEY_MAX_FABRIC_CHANNEL 15
|
||||
#define PICMG_EKEY_MAX_INTERFACE 3
|
||||
|
||||
#define PICMG_EKEY_AMC_MAX_CHANNEL 16
|
||||
#define PICMG_EKEY_AMC_MAX_DEVICE 15 /* 4 bits */
|
||||
|
||||
void
|
||||
ipmi_picmg_help (void)
|
||||
{
|
||||
printf(" properties - get PICMG properties\n");
|
||||
printf(" addrinfo - get address information\n");
|
||||
printf(" activate - activate a FRU\n");
|
||||
printf(" deactivate - deactivate a FRU\n");
|
||||
printf(" policy get - get the FRU activation policy\n");
|
||||
printf(" policy set - set the FRU activation policy\n");
|
||||
printf(" portstate get - get port state \n");
|
||||
printf(" portstate set - set port state \n");
|
||||
printf(" led prop - get led properties\n");
|
||||
printf(" led cap - get led color capabilities\n");
|
||||
printf(" led state get - get led state\n");
|
||||
printf(" led state set - set led state\n");
|
||||
printf(" power get - get power level info\n");
|
||||
printf(" power set - set power level\n");
|
||||
printf(" properties - get PICMG properties\n");
|
||||
printf(" addrinfo - get address information\n");
|
||||
printf(" activate - activate a FRU\n");
|
||||
printf(" deactivate - deactivate a FRU\n");
|
||||
printf(" policy get - get the FRU activation policy\n");
|
||||
printf(" policy set - set the FRU activation policy\n");
|
||||
printf(" portstate get - get port state \n");
|
||||
printf(" portstate getdenied - get all denied[disabled] port description\n");
|
||||
printf(" portstate getgranted - get all granted[enabled] port description\n");
|
||||
printf(" portstate getall - get all port state description\n");
|
||||
printf(" portstate set - set port state \n");
|
||||
printf(" amcportstate get - get port state \n");
|
||||
printf(" led prop - get led properties\n");
|
||||
printf(" led cap - get led color capabilities\n");
|
||||
printf(" led state get - get led state\n");
|
||||
printf(" led state set - set led state\n");
|
||||
printf(" power get - get power level info\n");
|
||||
printf(" power set - set power level\n");
|
||||
}
|
||||
|
||||
int
|
||||
@ -192,15 +209,20 @@ ipmi_picmg_fru_activation_policy_get(struct ipmi_intf * intf, int argc, char **
|
||||
}
|
||||
|
||||
printf("Activation Policy for FRU %x: ", atoi(argv[0]) );
|
||||
printf(" %s\n",(((*(rsp->data+3))&0x01) == 0x01)?"is locked":"is not locked");
|
||||
printf("%s, ", (rsp->data[1] & 0x01) ? "is locked" : "is not locked");
|
||||
printf("%s\n", (rsp->data[1] & 0x02) ? "deactivation locked"
|
||||
: "deactivation not locked");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PICMG_MAX_LINK_PER_CHANNEL 4
|
||||
|
||||
int
|
||||
ipmi_picmg_portstate_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
ipmi_picmg_portstate_get(struct ipmi_intf * intf, int interface,int channel,
|
||||
int mode)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rs * rsp = NULL;
|
||||
struct ipmi_rq req;
|
||||
|
||||
unsigned char msg_data[4];
|
||||
@ -215,8 +237,8 @@ ipmi_picmg_portstate_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
req.msg.data_len = 2;
|
||||
|
||||
msg_data[0] = 0x00; /* PICMG identifier */
|
||||
msg_data[1] = (atoi(argv[0]) & 0x3)<<6; /* interface */
|
||||
msg_data[1] |= (atoi(argv[1]) & 0x3F); /* channel number */
|
||||
msg_data[1] = (interface & 0x3)<<6; /* interface */
|
||||
msg_data[1] |= (channel & 0x3F); /* channel number */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
@ -226,53 +248,81 @@ ipmi_picmg_portstate_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
}
|
||||
|
||||
if (rsp->ccode) {
|
||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
||||
if( mode == PICMG_EKEY_MODE_QUERY ){
|
||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->data_len == 6) {
|
||||
d = (struct fru_picmgext_link_desc *) &(rsp->data[1]);
|
||||
if (rsp->data_len >= 6) {
|
||||
int index;
|
||||
|
||||
/* add support for more than one link per channel */
|
||||
for(index=0;index<PICMG_MAX_LINK_PER_CHANNEL;index++){
|
||||
|
||||
if( rsp->data_len > (1+ (index*5))){
|
||||
|
||||
printf(" Link Grouping ID: 0x%02x\n", d->grouping);
|
||||
printf(" Link Type Extension: 0x%02x\n", d->ext);
|
||||
printf(" Link Type: ");
|
||||
if (d->type == 0 || d->type == 0xff)
|
||||
{
|
||||
printf("Reserved\n");
|
||||
}
|
||||
else if (d->type >= 0x06 && d->type <= 0xef)
|
||||
{
|
||||
printf("Reserved\n");
|
||||
}
|
||||
else if (d->type >= 0xf0 && d->type <= 0xfe)
|
||||
{
|
||||
printf("OEM GUID Definition\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (d->type)
|
||||
{
|
||||
case FRU_PICMGEXT_LINK_TYPE_BASE:
|
||||
printf("PICMG 3.0 Base Interface 10/100/1000\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET:
|
||||
printf("PICMG 3.1 Ethernet Fabric Interface\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND:
|
||||
printf("PICMG 3.2 Infiniband Fabric Interface\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR:
|
||||
printf("PICMG 3.3 Star Fabric Interface\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_LINK_TYPE_PCIE:
|
||||
printf("PCI Express Fabric Interface\n");
|
||||
default:
|
||||
printf("Invalid\n");
|
||||
}
|
||||
}
|
||||
printf(" Link Designator: 0x%03x\n", d->designator);
|
||||
printf(" Port Flag: 0x%02x\n", d->designator >> 8);
|
||||
printf(" Interface: ");
|
||||
d = (struct fru_picmgext_link_desc *) &(rsp->data[1 + (index*5)]);
|
||||
|
||||
if
|
||||
(
|
||||
mode == PICMG_EKEY_MODE_PRINT_ALL
|
||||
||
|
||||
mode == PICMG_EKEY_MODE_QUERY
|
||||
||
|
||||
(
|
||||
mode == PICMG_EKEY_MODE_PRINT_ENABLED
|
||||
&&
|
||||
rsp->data[5 + (index*5) ] == 0x01
|
||||
)
|
||||
||
|
||||
(
|
||||
mode == PICMG_EKEY_MODE_PRINT_DISABLED
|
||||
&&
|
||||
rsp->data[5 + (index*5) ] == 0x00
|
||||
)
|
||||
)
|
||||
{
|
||||
printf(" Link Grouping ID: 0x%02x\n", d->grouping);
|
||||
printf(" Link Type Extension: 0x%02x\n", d->ext);
|
||||
printf(" Link Type: ");
|
||||
if (d->type == 0 || d->type == 0xff)
|
||||
{
|
||||
printf("Reserved %d\n",d->type);
|
||||
}
|
||||
else if (d->type >= 0x06 && d->type <= 0xef)
|
||||
{
|
||||
printf("Reserved\n",d->type);
|
||||
}
|
||||
else if (d->type >= 0xf0 && d->type <= 0xfe)
|
||||
{
|
||||
printf("OEM GUID Definition\n",d->type);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (d->type)
|
||||
{
|
||||
case FRU_PICMGEXT_LINK_TYPE_BASE:
|
||||
printf("PICMG 3.0 Base Interface 10/100/1000\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET:
|
||||
printf("PICMG 3.1 Ethernet Fabric Interface\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND:
|
||||
printf("PICMG 3.2 Infiniband Fabric Interface\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR:
|
||||
printf("PICMG 3.3 Star Fabric Interface\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_LINK_TYPE_PCIE:
|
||||
printf("PCI Express Fabric Interface\n");
|
||||
default:
|
||||
printf("Invalid\n");
|
||||
}
|
||||
}
|
||||
printf(" Link Designator: 0x%03x\n", d->designator);
|
||||
printf(" Port Flag: 0x%02x\n", d->designator >> 8);
|
||||
printf(" Interface: ");
|
||||
switch ((d->designator & 0xff) >> 6)
|
||||
{
|
||||
case FRU_PICMGEXT_DESIGN_IF_BASE:
|
||||
@ -289,17 +339,25 @@ ipmi_picmg_portstate_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
default:
|
||||
printf("Invalid");
|
||||
}
|
||||
printf(" Channel Number: 0x%02x\n", d->designator & 0x1f);
|
||||
printf("\n");
|
||||
printf(" STATE: %s\n", rsp->data[5] == 0x01?"enabled":"disabled");
|
||||
printf(" Channel Number: 0x%02x\n", d->designator & 0x1f);
|
||||
printf("\n");
|
||||
printf(" STATE: %s\n", rsp->data[5 +(index*5)] == 0x01?"enabled":"disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lprintf(LOG_NOTICE,"Unexpected answer, can't print result");
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_portstate_set(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
ipmi_picmg_portstate_set(struct ipmi_intf * intf, int interface, int channel,
|
||||
int port, int type, int typeext, int group, int enable)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
@ -318,15 +376,15 @@ ipmi_picmg_portstate_set(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
d = (struct fru_picmgext_link_desc*) &(msg_data[1]);
|
||||
|
||||
d->designator = (unsigned char) (atoi(argv[0]) & 0x1F); /* channel */
|
||||
d->designator = (unsigned char) ((atoi(argv[1]) & 0x03) << 6); /* interface */
|
||||
d->designator = (unsigned char) ((atoi(argv[2]) & 0x03) << 8); /* port */
|
||||
d->designator = (unsigned char) (channel & 0x1F); /* channel */
|
||||
d->designator = (unsigned char) ((interface & 0x03) << 6); /* interface */
|
||||
d->designator = (unsigned char) ((port & 0x03) << 8); /* port */
|
||||
|
||||
d->type = (unsigned char) (atoi(argv[3]) & 0xFF); /* link type */
|
||||
d->ext = (unsigned char) (atoi(argv[4]) & 0x03); /* type ext */
|
||||
d->grouping = (unsigned char) (atoi(argv[5]) & 0xFF); /* type ext */
|
||||
d->type = (unsigned char) (type & 0xFF); /* link type */
|
||||
d->ext = (unsigned char) (typeext & 0x03); /* type ext */
|
||||
d->grouping = (unsigned char) (group & 0xFF); /* type ext */
|
||||
|
||||
msg_data[5] = (unsigned char) (atoi(argv[6]) & 0x01); /* en/dis */
|
||||
msg_data[5] = (unsigned char) (enable & 0x01); /* en/dis */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
@ -343,6 +401,134 @@ ipmi_picmg_portstate_set(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* AMC.0 commands */
|
||||
|
||||
#define PICMG_AMC_MAX_LINK_PER_CHANNEL 4
|
||||
|
||||
int
|
||||
ipmi_picmg_amc_portstate_get(struct ipmi_intf * intf,int device,int channel,
|
||||
int mode)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
unsigned char msg_data[4];
|
||||
|
||||
struct fru_picmgext_amc_link_info* d; /* descriptor pointer for rec. data */
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_AMC_GET_PORT_STATE_CMD;
|
||||
req.msg.data = msg_data;
|
||||
|
||||
/* FIXME : add check for AMC or carrier device */
|
||||
req.msg.data_len = 3;
|
||||
|
||||
msg_data[0] = 0x00; /* PICMG identifier */
|
||||
msg_data[1] = channel ;
|
||||
msg_data[2] = device ;
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp) {
|
||||
printf("no response\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->ccode) {
|
||||
if( mode == PICMG_EKEY_MODE_QUERY ){
|
||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->data_len >= 5) {
|
||||
int index;
|
||||
|
||||
/* add support for more than one link per channel */
|
||||
for(index=0;index<PICMG_AMC_MAX_LINK_PER_CHANNEL;index++){
|
||||
|
||||
if( rsp->data_len > (1+ (index*4))){
|
||||
unsigned char type;
|
||||
unsigned char ext;
|
||||
unsigned char grouping;
|
||||
unsigned char port;
|
||||
unsigned char enabled;
|
||||
d = (struct fru_picmgext_amc_link_info *)&(rsp->data[1 + (index*4)]);
|
||||
|
||||
|
||||
/* Removed endianness check here, probably not required
|
||||
as we dont use bitfields */
|
||||
port = d->linkInfo[0] & 0x0F;
|
||||
type = ((d->linkInfo[0] & 0xF0) >> 4 )|(d->linkInfo[1] & 0x0F );
|
||||
ext = ((d->linkInfo[1] & 0xF0) >> 4 );
|
||||
grouping = d->linkInfo[2];
|
||||
|
||||
|
||||
enabled = rsp->data[4 + (index*4) ];
|
||||
|
||||
if
|
||||
(
|
||||
mode == PICMG_EKEY_MODE_PRINT_ALL
|
||||
||
|
||||
mode == PICMG_EKEY_MODE_QUERY
|
||||
||
|
||||
(
|
||||
mode == PICMG_EKEY_MODE_PRINT_ENABLED
|
||||
&&
|
||||
enabled == 0x01
|
||||
)
|
||||
||
|
||||
(
|
||||
mode == PICMG_EKEY_MODE_PRINT_DISABLED
|
||||
&&
|
||||
enabled == 0x00
|
||||
)
|
||||
)
|
||||
{
|
||||
printf(" Link device : 0x%02x\n", device );
|
||||
printf(" Link channel: 0x%02x\n", channel);
|
||||
|
||||
printf(" Link Grouping ID: 0x%02x\n", grouping);
|
||||
printf(" Link Type Extension: 0x%02x\n", ext);
|
||||
printf(" Link Type: ");
|
||||
if (type == 0 || type == 1 ||type == 0xff)
|
||||
{
|
||||
printf("Reserved\n");
|
||||
}
|
||||
else if (type >= 0xf0 && type <= 0xfe)
|
||||
{
|
||||
printf("OEM GUID Definition\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type <= FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE )
|
||||
{
|
||||
printf("%s\n",amc_link_type_str[type]);
|
||||
}
|
||||
else{
|
||||
printf("undefined\n");
|
||||
}
|
||||
}
|
||||
printf(" Port Flag: 0x%02x\n", port );
|
||||
printf(" STATE: %s\n",( enabled == 0x01 )?"enabled":"disabled");
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lprintf(LOG_NOTICE,"ipmi_picmg_amc_portstate_get"\
|
||||
"Unexpected answer, can't print result");
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_get_led_properties(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
@ -608,7 +794,7 @@ ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv)
|
||||
else if (!strncmp(argv[0], "policy", 6)) {
|
||||
if (argc > 2) {
|
||||
if (!strncmp(argv[1], "get", 3)) {
|
||||
rc = ipmi_picmg_fru_activation_policy_get(intf, argc-1, &(argv[2]));
|
||||
rc = ipmi_picmg_fru_activation_policy_get(intf, argc-2, &(argv[2]));
|
||||
}
|
||||
else if (!strncmp(argv[1], "set", 6)) {
|
||||
printf("tbd\n");
|
||||
@ -623,30 +809,172 @@ ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* portstate command */
|
||||
else if (!strncmp(argv[0], "portstate", 9)) {
|
||||
if (argc > 2) {
|
||||
if (!strncmp(argv[1], "get", 3)) {
|
||||
rc = ipmi_picmg_portstate_get(intf, argc-1, &(argv[2]));
|
||||
}
|
||||
|
||||
else {
|
||||
printf("portstate get <intf><chn>\n");
|
||||
}
|
||||
}
|
||||
lprintf(LOG_DEBUG,"PICMG: portstate API");
|
||||
|
||||
else if (!strncmp(argv[1], "set", 3)) {
|
||||
if (argc > 5) {
|
||||
rc = ipmi_picmg_portstate_set(intf, argc-1, &(argv[2]));
|
||||
}
|
||||
else {
|
||||
printf("portstate set <chn><intf><port><type><typeext><group><en|dis>\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (argc > 1) {
|
||||
if (!strncmp(argv[1], "get", 3)){
|
||||
|
||||
int iface;
|
||||
int channel ;
|
||||
|
||||
lprintf(LOG_DEBUG,"PICMG: get");
|
||||
|
||||
if(!strncmp(argv[1], "getall", 6)){
|
||||
for(iface=0;iface<=PICMG_EKEY_MAX_INTERFACE;iface++){
|
||||
for(channel=1;channel<=PICMG_EKEY_MAX_CHANNEL;channel++){
|
||||
if(
|
||||
!(( iface == FRU_PICMGEXT_DESIGN_IF_FABRIC )
|
||||
&&
|
||||
( channel > PICMG_EKEY_MAX_FABRIC_CHANNEL ) )
|
||||
){
|
||||
rc = ipmi_picmg_portstate_get(intf,iface,channel,
|
||||
PICMG_EKEY_MODE_PRINT_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!strncmp(argv[1], "getgranted", 10)){
|
||||
for(iface=0;iface<=PICMG_EKEY_MAX_INTERFACE;iface++){
|
||||
for(channel=1;channel<=PICMG_EKEY_MAX_CHANNEL;channel++){
|
||||
rc = ipmi_picmg_portstate_get(intf,iface,channel,
|
||||
PICMG_EKEY_MODE_PRINT_ENABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!strncmp(argv[1], "getdenied", 9)){
|
||||
for(iface=0;iface<=PICMG_EKEY_MAX_INTERFACE;iface++){
|
||||
for(channel=1;channel<=PICMG_EKEY_MAX_CHANNEL;channel++){
|
||||
rc = ipmi_picmg_portstate_get(intf,iface,channel,
|
||||
PICMG_EKEY_MODE_PRINT_DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (argc > 3){
|
||||
iface = atoi(argv[2]);
|
||||
channel = atoi(argv[3]);
|
||||
lprintf(LOG_DEBUG,"PICMG: requesting interface %d",iface);
|
||||
lprintf(LOG_DEBUG,"PICMG: requesting channel %d",channel);
|
||||
|
||||
rc = ipmi_picmg_portstate_get(intf,iface,channel,
|
||||
PICMG_EKEY_MODE_QUERY );
|
||||
}
|
||||
else {
|
||||
printf("<intf> <chn>|getall|getgranted|getdenied\n");
|
||||
}
|
||||
}
|
||||
else if (!strncmp(argv[1], "set", 3)) {
|
||||
if (argc > 5) {
|
||||
int interface= atoi(argv[2]);
|
||||
int channel = atoi(argv[3]);
|
||||
int port = atoi(argv[4]);
|
||||
int type = atoi(argv[5]);
|
||||
int typeext = atoi(argv[6]);
|
||||
int group = atoi(argv[7]);
|
||||
int enable = atoi(argv[8]);
|
||||
|
||||
lprintf(LOG_DEBUG,"PICMG: interface %d",interface);
|
||||
lprintf(LOG_DEBUG,"PICMG: channel %d",channel);
|
||||
lprintf(LOG_DEBUG,"PICMG: port %d",port);
|
||||
lprintf(LOG_DEBUG,"PICMG: type %d",type);
|
||||
lprintf(LOG_DEBUG,"PICMG: typeext %d",typeext);
|
||||
lprintf(LOG_DEBUG,"PICMG: group %d",group);
|
||||
lprintf(LOG_DEBUG,"PICMG: enable %d",enable);
|
||||
|
||||
rc = ipmi_picmg_portstate_set(intf, interface, channel, port ,
|
||||
type, typeext ,group ,enable);
|
||||
}
|
||||
else {
|
||||
printf("<intf> <chn> <port> <type> <ext> <group> <1|0>\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("<set>|<get>\n");
|
||||
printf("<set>|<get>|<getall>|<getgranted>|<getdenied>\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* amc portstate command */
|
||||
else if (!strncmp(argv[0], "amcportstate", 12)) {
|
||||
|
||||
lprintf(LOG_DEBUG,"PICMG: amcportstate API");
|
||||
|
||||
if (argc > 1) {
|
||||
if (!strncmp(argv[1], "get", 3)){
|
||||
int channel ;
|
||||
int device;
|
||||
|
||||
lprintf(LOG_DEBUG,"PICMG: get");
|
||||
|
||||
if(!strncmp(argv[1], "getall", 6)){
|
||||
for(device=0;device<=PICMG_EKEY_AMC_MAX_DEVICE;device++){
|
||||
for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){
|
||||
rc = ipmi_picmg_amc_portstate_get(intf,device,channel,
|
||||
PICMG_EKEY_MODE_PRINT_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!strncmp(argv[1], "getgranted", 10)){
|
||||
for(device=0;device<=PICMG_EKEY_AMC_MAX_DEVICE;device++){
|
||||
for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){
|
||||
rc = ipmi_picmg_amc_portstate_get(intf,device,channel,
|
||||
PICMG_EKEY_MODE_PRINT_ENABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!strncmp(argv[1], "getdenied", 9)){
|
||||
for(device=0;device<=PICMG_EKEY_AMC_MAX_DEVICE;device++){
|
||||
for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){
|
||||
rc = ipmi_picmg_amc_portstate_get(intf,device,channel,
|
||||
PICMG_EKEY_MODE_PRINT_DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (argc > 3){
|
||||
channel = atoi(argv[2]);
|
||||
device = atoi(argv[3]);
|
||||
lprintf(LOG_DEBUG,"PICMG: requesting device %d",device);
|
||||
lprintf(LOG_DEBUG,"PICMG: requesting channel %d",channel);
|
||||
|
||||
rc = ipmi_picmg_amc_portstate_get(intf,device,channel,
|
||||
PICMG_EKEY_MODE_QUERY );
|
||||
}
|
||||
else {
|
||||
printf("<chn> <device>|getall|getgranted|getdenied\n");
|
||||
}
|
||||
}
|
||||
else if (!strncmp(argv[1], "set", 3)) {
|
||||
if (argc > 5) {
|
||||
int interface= atoi(argv[2]);
|
||||
int channel = atoi(argv[3]);
|
||||
int port = atoi(argv[4]);
|
||||
int type = atoi(argv[5]);
|
||||
int typeext = atoi(argv[6]);
|
||||
int group = atoi(argv[7]);
|
||||
int enable = atoi(argv[8]);
|
||||
|
||||
lprintf(LOG_DEBUG,"PICMG: interface %d",interface);
|
||||
lprintf(LOG_DEBUG,"PICMG: channel %d",channel);
|
||||
lprintf(LOG_DEBUG,"PICMG: port %d",port);
|
||||
lprintf(LOG_DEBUG,"PICMG: type %d",type);
|
||||
lprintf(LOG_DEBUG,"PICMG: typeext %d",typeext);
|
||||
lprintf(LOG_DEBUG,"PICMG: group %d",group);
|
||||
lprintf(LOG_DEBUG,"PICMG: enable %d",enable);
|
||||
|
||||
rc = ipmi_picmg_portstate_set(intf, interface, channel, port ,
|
||||
type, typeext ,group ,enable);
|
||||
}
|
||||
else {
|
||||
printf("<intf> <chn> <port> <type> <ext> <group> <1|0>\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("<set>|<get>|<getall>|<getgranted>|<getdenied>\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -39,9 +39,10 @@
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_raw.h>
|
||||
#include <ipmitool/ipmi_fru.h>
|
||||
#include <ipmitool/ipmi_strings.h>
|
||||
|
||||
#define IPMI_I2C_MASTER_MAX_SIZE 0x40
|
||||
#define IPMI_I2C_MASTER_MAX_SIZE 0x40 /* 64 bytes */
|
||||
|
||||
/* ipmi_master_write_read - Perform I2C write/read transactions
|
||||
*
|
||||
@ -49,6 +50,7 @@
|
||||
* IPMI interface. It has a maximum transfer size of 32 bytes.
|
||||
*
|
||||
* @intf: ipmi interface
|
||||
* @bus: channel number, i2c bus id and type
|
||||
* @addr: i2c slave address
|
||||
* @wdata: data to write
|
||||
* @wsize: length of data to write (max 64 bytes)
|
||||
@ -57,7 +59,8 @@
|
||||
* Returns pointer to IPMI Response
|
||||
*/
|
||||
struct ipmi_rs *
|
||||
ipmi_master_write_read(struct ipmi_intf * intf, uint8_t addr, uint8_t * wdata, uint8_t wsize, uint8_t rsize)
|
||||
ipmi_master_write_read(struct ipmi_intf * intf, uint8_t bus, uint8_t addr,
|
||||
uint8_t * wdata, uint8_t wsize, uint8_t rsize)
|
||||
{
|
||||
struct ipmi_rq req;
|
||||
struct ipmi_rs * rsp;
|
||||
@ -79,7 +82,7 @@ ipmi_master_write_read(struct ipmi_intf * intf, uint8_t addr, uint8_t * wdata, u
|
||||
req.msg.data_len = 3;
|
||||
|
||||
memset(rqdata, 0, IPMI_I2C_MASTER_MAX_SIZE + 3);
|
||||
rqdata[0] = 0x00; /* channel number, bus id, bus type */
|
||||
rqdata[0] = bus; /* channel number, bus id, bus type */
|
||||
rqdata[1] = addr; /* slave address */
|
||||
rqdata[2] = rsize; /* number of bytes to read */
|
||||
|
||||
@ -124,9 +127,49 @@ ipmi_master_write_read(struct ipmi_intf * intf, uint8_t addr, uint8_t * wdata, u
|
||||
return rsp;
|
||||
}
|
||||
|
||||
#define RAW_SPD_SIZE 256
|
||||
|
||||
int
|
||||
ipmi_rawspd_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_rs *rsp;
|
||||
uint8_t i2cbus = 0;
|
||||
uint8_t i2caddr = 0;
|
||||
uint8_t spd_data[RAW_SPD_SIZE];
|
||||
int i;
|
||||
|
||||
memset(spd_data, 0, RAW_SPD_SIZE);
|
||||
|
||||
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
|
||||
lprintf(LOG_NOTICE, "usage: spd <i2cbus> <i2caddr>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
i2cbus = (uint8_t)strtoul(argv[0], NULL, 0);
|
||||
i2caddr = (uint8_t)strtoul(argv[1], NULL, 0);
|
||||
|
||||
i2cbus = ((i2cbus & 7) << 1) | 1;
|
||||
|
||||
for (i = 0; i < RAW_SPD_SIZE; i+= IPMI_I2C_MASTER_MAX_SIZE) {
|
||||
rsp = ipmi_master_write_read(intf, i2cbus, i2caddr,
|
||||
(uint8_t *)&i, 1, IPMI_I2C_MASTER_MAX_SIZE);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to perform I2C Master Write-Read");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(spd_data+i, rsp->data, IPMI_I2C_MASTER_MAX_SIZE);
|
||||
}
|
||||
|
||||
ipmi_spd_print(spd_data, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rawi2c_usage(void)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "usage: i2c <i2caddr> <read bytes> [write data]");
|
||||
lprintf(LOG_NOTICE, "usage: i2c [bus=public|# [chan=#]] <i2caddr> <read bytes> [write data]");
|
||||
lprintf(LOG_NOTICE, " bus=public is default");
|
||||
lprintf(LOG_NOTICE, " chan=0 is default, bus= must be specified to use chan=");
|
||||
}
|
||||
|
||||
int
|
||||
@ -137,20 +180,41 @@ ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
uint8_t i2caddr = 0;
|
||||
uint8_t rsize = 0;
|
||||
uint8_t wsize = 0;
|
||||
int i;
|
||||
unsigned int rbus = 0;
|
||||
uint8_t bus = 0;
|
||||
int i = 0;
|
||||
|
||||
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
|
||||
/* handle bus= argument */
|
||||
if (argc > 2 && strncmp(argv[0], "bus=", 4) == 0) {
|
||||
i = 1;
|
||||
if (strncmp(argv[0], "bus=public", 10) == 0)
|
||||
bus = 0;
|
||||
else if (sscanf(argv[0], "bus=%u", &rbus) == 1)
|
||||
bus = ((rbus & 7) << 1) | 1;
|
||||
else
|
||||
bus = 0;
|
||||
|
||||
/* handle channel= argument
|
||||
* the bus= argument must be supplied first on command line */
|
||||
if (argc > 3 && strncmp(argv[1], "chan=", 5) == 0) {
|
||||
i = 2;
|
||||
if (sscanf(argv[1], "chan=%u", &rbus) == 1)
|
||||
bus |= rbus << 4;
|
||||
}
|
||||
}
|
||||
|
||||
if ((argc-i) < 2 || strncmp(argv[0], "help", 4) == 0) {
|
||||
rawi2c_usage();
|
||||
return 0;
|
||||
}
|
||||
else if (argc-2 > IPMI_I2C_MASTER_MAX_SIZE) {
|
||||
else if (argc-i-2 > IPMI_I2C_MASTER_MAX_SIZE) {
|
||||
lprintf(LOG_ERR, "Raw command input limit (%d bytes) exceeded",
|
||||
IPMI_I2C_MASTER_MAX_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
i2caddr = (uint8_t)strtoul(argv[0], NULL, 0);
|
||||
rsize = (uint8_t)strtoul(argv[1], NULL, 0);
|
||||
i2caddr = (uint8_t)strtoul(argv[i++], NULL, 0);
|
||||
rsize = (uint8_t)strtoul(argv[i++], NULL, 0);
|
||||
|
||||
if (i2caddr == 0) {
|
||||
lprintf(LOG_ERR, "Invalid I2C address 0");
|
||||
@ -159,7 +223,7 @@ ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
}
|
||||
|
||||
memset(wdata, 0, IPMI_I2C_MASTER_MAX_SIZE);
|
||||
for (i=2; i<argc; i++) {
|
||||
for (; i < argc; i++) {
|
||||
uint8_t val = (uint8_t)strtol(argv[i], NULL, 0);
|
||||
wdata[i-2] = val;
|
||||
wsize++;
|
||||
@ -169,7 +233,7 @@ ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
i2caddr, rsize, wsize);
|
||||
printbuf(wdata, wsize, "WRITE DATA");
|
||||
|
||||
rsp = ipmi_master_write_read(intf, i2caddr, wdata, wsize, rsize);
|
||||
rsp = ipmi_master_write_read(intf, bus, i2caddr, wdata, wsize, rsize);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to perform I2C Master Write-Read");
|
||||
return -1;
|
||||
@ -184,6 +248,9 @@ ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
if (verbose || wsize == 0)
|
||||
printf("Read %d bytes from I2C device %02Xh\n", rsp->data_len, i2caddr);
|
||||
|
||||
if (rsp->data_len < rsize)
|
||||
return -1;
|
||||
|
||||
/* print the raw response buffer */
|
||||
for (i=0; i<rsp->data_len; i++) {
|
||||
if (((i%16) == 0) && (i != 0))
|
||||
@ -243,7 +310,7 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
memset(data, 0, sizeof(data));
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = netfn;
|
||||
req.msg.lun = lun;
|
||||
req.msg.lun = lun;
|
||||
req.msg.cmd = cmd;
|
||||
req.msg.data = data;
|
||||
|
||||
@ -288,4 +355,3 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ extern int verbose;
|
||||
static int use_built_in; /* Uses DeviceSDRs instead of SDRR */
|
||||
static int sdr_max_read_len = GET_SDR_ENTIRE_RECORD;
|
||||
static int sdr_extended = 0;
|
||||
static long sdriana = 0;
|
||||
|
||||
static struct sdr_record_list *sdr_list_head = NULL;
|
||||
static struct sdr_record_list *sdr_list_tail = NULL;
|
||||
@ -92,7 +93,6 @@ ipmi_sdr_get_unit_string(uint8_t type, uint8_t base, uint8_t modifier)
|
||||
|
||||
return unitstr;
|
||||
}
|
||||
|
||||
/* sdr_convert_sensor_reading - convert raw sensor reading
|
||||
*
|
||||
* @sensor: sensor record
|
||||
@ -169,6 +169,87 @@ sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor, uint8_t val)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/* sdr_convert_sensor_hysterisis - convert raw sensor hysterisis
|
||||
*
|
||||
* Even though spec says histerisis should be computed using Mx+B
|
||||
* formula, B is irrelevant when doing raw comparison
|
||||
*
|
||||
* threshold rearm point is computed using threshold +/- hysterisis
|
||||
* with the full formula however B can't be applied in raw comparisons
|
||||
*
|
||||
* @sensor: sensor record
|
||||
* @val: raw sensor reading
|
||||
*
|
||||
* returns floating-point sensor reading
|
||||
*/
|
||||
double
|
||||
sdr_convert_sensor_hysterisis(struct sdr_record_full_sensor *sensor, uint8_t val)
|
||||
{
|
||||
int m, k1, k2;
|
||||
double result;
|
||||
|
||||
m = __TO_M(sensor->mtol);
|
||||
|
||||
k1 = __TO_B_EXP(sensor->bacc);
|
||||
k2 = __TO_R_EXP(sensor->bacc);
|
||||
|
||||
switch (sensor->unit.analog) {
|
||||
case 0:
|
||||
result = (double) (((m * val)) * pow(10, k2));
|
||||
break;
|
||||
case 1:
|
||||
if (val & 0x80)
|
||||
val++;
|
||||
/* Deliberately fall through to case 2. */
|
||||
case 2:
|
||||
result = (double) (((m * (int8_t) val) ) * pow(10, k2));
|
||||
break;
|
||||
default:
|
||||
/* Oops! This isn't an analog sensor. */
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
switch (sensor->linearization & 0x7f) {
|
||||
case SDR_SENSOR_L_LN:
|
||||
result = log(result);
|
||||
break;
|
||||
case SDR_SENSOR_L_LOG10:
|
||||
result = log10(result);
|
||||
break;
|
||||
case SDR_SENSOR_L_LOG2:
|
||||
result = (double) (log(result) / log(2.0));
|
||||
break;
|
||||
case SDR_SENSOR_L_E:
|
||||
result = exp(result);
|
||||
break;
|
||||
case SDR_SENSOR_L_EXP10:
|
||||
result = pow(10.0, result);
|
||||
break;
|
||||
case SDR_SENSOR_L_EXP2:
|
||||
result = pow(2.0, result);
|
||||
break;
|
||||
case SDR_SENSOR_L_1_X:
|
||||
result = pow(result, -1.0); /*1/x w/o exception */
|
||||
break;
|
||||
case SDR_SENSOR_L_SQR:
|
||||
result = pow(result, 2.0);
|
||||
break;
|
||||
case SDR_SENSOR_L_CUBE:
|
||||
result = pow(result, 3.0);
|
||||
break;
|
||||
case SDR_SENSOR_L_SQRT:
|
||||
result = sqrt(result);
|
||||
break;
|
||||
case SDR_SENSOR_L_CUBERT:
|
||||
result = cbrt(result);
|
||||
break;
|
||||
case SDR_SENSOR_L_LINEAR:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* sdr_convert_sensor_tolerance - convert raw sensor reading
|
||||
*
|
||||
@ -438,7 +519,10 @@ ipmi_sdr_get_sensor_type_desc(const uint8_t type)
|
||||
if (type < 0xc0)
|
||||
snprintf(desc, 32, "reserved #%02x", type);
|
||||
else
|
||||
snprintf(desc, 32, "OEM reserved #%02x", type);
|
||||
{
|
||||
snprintf(desc, 32, oemval2str(sdriana,type,ipmi_oem_sdr_type_vals),
|
||||
type);
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
@ -545,7 +629,7 @@ ipmi_sdr_get_header(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr)
|
||||
continue;
|
||||
} else if (rsp->ccode == 0xc5) {
|
||||
/* lost reservation */
|
||||
lprintf(LOG_DEBUG, "SDR reserveration %04x cancelled. "
|
||||
lprintf(LOG_DEBUG, "SDR reservation %04x cancelled. "
|
||||
"Sleeping a bit and retrying...",
|
||||
itr->reservation);
|
||||
|
||||
@ -1038,14 +1122,6 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf *intf,
|
||||
} else if (IS_SCANNING_DISABLED(rsp->data[1])) {
|
||||
/* Sensor Scanning Disabled */
|
||||
validread = 0;
|
||||
if (rsp->data[0] != 0) {
|
||||
/* we might still get a valid reading */
|
||||
val =
|
||||
sdr_convert_sensor_reading(sensor,
|
||||
rsp->data[0]);
|
||||
if (val != 0.0)
|
||||
validread = 1;
|
||||
}
|
||||
} else if (rsp->data[0] != 0) {
|
||||
/* convert RAW reading into units */
|
||||
val = sdr_convert_sensor_reading(sensor, rsp->data[0]);
|
||||
@ -1281,7 +1357,7 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf *intf,
|
||||
SENSOR_PRINT_THRESH("Lower non-critical", lower.non_critical, lnc);
|
||||
|
||||
creading =
|
||||
sdr_convert_sensor_reading(sensor,
|
||||
sdr_convert_sensor_hysterisis(sensor,
|
||||
sensor->threshold.hysteresis.positive);
|
||||
if (sensor->threshold.hysteresis.positive == 0x00
|
||||
|| sensor->threshold.hysteresis.positive == 0xff || creading == 0)
|
||||
@ -1290,7 +1366,7 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf *intf,
|
||||
printf(" Positive Hysteresis : %.3f\n", creading);
|
||||
|
||||
creading =
|
||||
sdr_convert_sensor_reading(sensor,
|
||||
sdr_convert_sensor_hysterisis(sensor,
|
||||
sensor->threshold.hysteresis.negative);
|
||||
if (sensor->threshold.hysteresis.negative == 0x00
|
||||
|| sensor->threshold.hysteresis.negative == 0xff || creading == 0.0)
|
||||
@ -2397,7 +2473,7 @@ ipmi_sdr_get_reservation(struct ipmi_intf *intf, uint16_t * reserve_id)
|
||||
return -1;
|
||||
|
||||
*reserve_id = ((struct sdr_reserve_repo_rs *) &(rsp->data))->reserve_id;
|
||||
lprintf(LOG_DEBUG, "SDR reserveration ID %04x", *reserve_id);
|
||||
lprintf(LOG_DEBUG, "SDR reservation ID %04x", *reserve_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2439,6 +2515,8 @@ ipmi_sdr_start(struct ipmi_intf *intf)
|
||||
}
|
||||
devid = (struct ipm_devid_rsp *) rsp->data;
|
||||
|
||||
sdriana = (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id);
|
||||
|
||||
if (devid->device_revision & IPM_DEV_DEVICE_ID_SDR_MASK) {
|
||||
if ((devid->adtl_device_support & 0x02) == 0) {
|
||||
if ((devid->adtl_device_support & 0x01)) {
|
||||
@ -2590,7 +2668,7 @@ ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header,
|
||||
continue;
|
||||
case 0xc5:
|
||||
/* lost reservation */
|
||||
lprintf(LOG_DEBUG, "SDR reserveration cancelled. "
|
||||
lprintf(LOG_DEBUG, "SDR reservation cancelled. "
|
||||
"Sleeping a bit and retrying...");
|
||||
|
||||
sleep(rand() & 3);
|
||||
@ -3843,7 +3921,6 @@ ipmi_sdr_dump_bin(struct ipmi_intf *intf, const char *ofile)
|
||||
itr = ipmi_sdr_start(intf);
|
||||
if (itr == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to open SDR for reading");
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -4120,6 +4197,9 @@ ipmi_sdr_main(struct ipmi_intf *intf, int argc, char **argv)
|
||||
lprintf(LOG_ERR, " type [sensor type]");
|
||||
lprintf(LOG_ERR,
|
||||
" list Get a list of available sensor types");
|
||||
lprintf(LOG_ERR,
|
||||
" get Retrieve the state of a specified sensor");
|
||||
|
||||
lprintf(LOG_ERR, " info");
|
||||
lprintf(LOG_ERR,
|
||||
" Display information about the repository itself");
|
||||
|
@ -354,10 +354,10 @@ ipmi_sel_add_entries_fromfile(struct ipmi_intf * intf, const char * filename)
|
||||
|
||||
/* clip off trailing and leading whitespace */
|
||||
ptr--;
|
||||
while (isspace(*ptr) && ptr >= buf)
|
||||
while (isspace((int)*ptr) && ptr >= buf)
|
||||
*ptr-- = '\0';
|
||||
ptr = buf;
|
||||
while (isspace(*ptr))
|
||||
while (isspace((int)*ptr))
|
||||
ptr++;
|
||||
if (strlen(ptr) == 0)
|
||||
continue;
|
||||
@ -401,7 +401,36 @@ ipmi_sel_add_entries_fromfile(struct ipmi_intf * intf, const char * filename)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct ipmi_event_sensor_types oem_kontron_event_reading_types[] __attribute__((unused)) = {
|
||||
{ 0x70 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info 1", "Reserved" },
|
||||
{ 0x71 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info 2", "Reserved" },
|
||||
};
|
||||
|
||||
char *
|
||||
get_kontron_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
||||
{
|
||||
char * description = NULL;
|
||||
/*
|
||||
* Kontron OEM events are described in the product's user manual, but are limited in favor of
|
||||
* sensor specific
|
||||
*/
|
||||
|
||||
/* Only standard records are defined so far */
|
||||
if( rec->record_type < 0xC0 ){
|
||||
struct ipmi_event_sensor_types *st=NULL;
|
||||
for ( st=oem_kontron_event_reading_types ; st->type != NULL; st++){
|
||||
if (st->code == rec->sel_type.standard_type.event_type ){
|
||||
size_t len =strlen(st->desc);
|
||||
description = (char*)malloc( len + 1 );
|
||||
memcpy(description, st->desc , len);
|
||||
description[len] = 0;;
|
||||
return description;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "Unsupported event";
|
||||
}
|
||||
|
||||
char *
|
||||
get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
||||
@ -476,6 +505,14 @@ ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
||||
case IPMI_OEM_NEWISYS:
|
||||
desc = get_newisys_evt_desc(intf, rec);
|
||||
break;
|
||||
case IPMI_OEM_SUN:
|
||||
case IPMI_OEM_INTEL:
|
||||
case IPMI_OEM_TYAN:
|
||||
case IPMI_OEM_SUPERMICRO:
|
||||
case IPMI_OEM_KONTRON:
|
||||
desc = get_kontron_evt_desc(intf, rec);
|
||||
break;
|
||||
case IPMI_OEM_UNKNOWN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -488,7 +525,7 @@ void
|
||||
ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char ** desc)
|
||||
{
|
||||
uint8_t code, offset;
|
||||
struct ipmi_event_sensor_types *evt;
|
||||
struct ipmi_event_sensor_types *evt = NULL;
|
||||
|
||||
if (desc == NULL)
|
||||
return;
|
||||
@ -498,8 +535,29 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
|
||||
*desc = ipmi_get_oem_desc(intf, rec);
|
||||
return;
|
||||
} else if (rec->sel_type.standard_type.event_type == 0x6f) {
|
||||
evt = sensor_specific_types;
|
||||
code = rec->sel_type.standard_type.sensor_type;
|
||||
|
||||
if( rec->sel_type.standard_type.sensor_type >= 0xC0 && rec->sel_type.standard_type.sensor_type < 0xF0) {
|
||||
IPMI_OEM iana = ipmi_get_oem(intf);
|
||||
|
||||
switch(iana){
|
||||
case IPMI_OEM_KONTRON:
|
||||
lprintf(LOG_DEBUG, "oem sensor type %x %d using oem type supplied description",
|
||||
rec->sel_type.standard_type.sensor_type , iana);
|
||||
|
||||
evt = oem_kontron_event_types;
|
||||
code = rec->sel_type.standard_type.sensor_type;
|
||||
break;
|
||||
/* add your oem sensor assignation here */
|
||||
}
|
||||
if( evt == NULL ){
|
||||
lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description",
|
||||
rec->sel_type.standard_type.sensor_type );
|
||||
}
|
||||
}
|
||||
if( evt == NULL ){
|
||||
evt = sensor_specific_types;
|
||||
code = rec->sel_type.standard_type.sensor_type;
|
||||
}
|
||||
} else {
|
||||
evt = generic_event_types;
|
||||
code = rec->sel_type.standard_type.event_type;
|
||||
@ -521,11 +579,54 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
|
||||
memset(*desc, 0, strlen(evt->desc)+48);
|
||||
sprintf(*desc, "%s", evt->desc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
evt++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
ipmi_sel_get_oem_sensor_type(IPMI_OEM iana, uint8_t code)
|
||||
{
|
||||
struct ipmi_event_sensor_types *st = NULL;
|
||||
|
||||
switch(iana){
|
||||
case IPMI_OEM_KONTRON:
|
||||
st = oem_kontron_event_types;
|
||||
break;
|
||||
/* add you oem sensor type lookup assignement here */
|
||||
}
|
||||
|
||||
if( st != NULL )
|
||||
for (; st->type != NULL; st++)
|
||||
if (st->code == code)
|
||||
return st->type;
|
||||
|
||||
return ipmi_sel_get_sensor_type(code);
|
||||
}
|
||||
|
||||
const char *
|
||||
ipmi_sel_get_oem_sensor_type_offset(IPMI_OEM iana, uint8_t code, uint8_t offset)
|
||||
{
|
||||
struct ipmi_event_sensor_types *st = NULL;
|
||||
|
||||
switch(iana){
|
||||
case IPMI_OEM_KONTRON:
|
||||
st = oem_kontron_event_types;
|
||||
break;
|
||||
/* add you oem sensor type lookup assignement here */
|
||||
}
|
||||
|
||||
if( st != NULL )
|
||||
for (; st->type != NULL; st++)
|
||||
{
|
||||
if (st->code == code && st->offset == (offset&0xf))
|
||||
return st->type;
|
||||
}
|
||||
|
||||
return ipmi_sel_get_oem_sensor_type(iana,code);
|
||||
}
|
||||
|
||||
const char *
|
||||
ipmi_sel_get_sensor_type(uint8_t code)
|
||||
{
|
||||
@ -543,6 +644,7 @@ ipmi_sel_get_sensor_type_offset(uint8_t code, uint8_t offset)
|
||||
for (st = sensor_specific_types; st->type != NULL; st++)
|
||||
if (st->code == code && st->offset == (offset&0xf))
|
||||
return st->type;
|
||||
|
||||
return ipmi_sel_get_sensor_type(code);
|
||||
}
|
||||
|
||||
@ -779,7 +881,13 @@ ipmi_sel_print_event_file(struct ipmi_intf * intf, struct sel_event_record * evt
|
||||
evt->sel_type.standard_type.event_data[0],
|
||||
evt->sel_type.standard_type.event_data[1],
|
||||
evt->sel_type.standard_type.event_data[2],
|
||||
ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0]),
|
||||
(
|
||||
(evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
|
||||
?
|
||||
ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
|
||||
:
|
||||
ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
|
||||
),
|
||||
evt->sel_type.standard_type.sensor_num,
|
||||
(description != NULL) ? description : "Unknown");
|
||||
|
||||
@ -890,7 +998,15 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
|
||||
|
||||
/* lookup SDR entry based on sensor number and type */
|
||||
if (sdr != NULL) {
|
||||
printf("%s ", ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0]));
|
||||
printf("%s ",
|
||||
(
|
||||
(evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
|
||||
?
|
||||
ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
|
||||
:
|
||||
ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
|
||||
)
|
||||
);
|
||||
switch (sdr->type) {
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
printf("%s", sdr->record.full->id_string);
|
||||
@ -915,7 +1031,13 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printf("%s", ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0]));
|
||||
printf("%s",(
|
||||
(evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
|
||||
?
|
||||
ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
|
||||
:
|
||||
ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
|
||||
));
|
||||
if (evt->sel_type.standard_type.sensor_num != 0)
|
||||
printf(" #0x%02x", evt->sel_type.standard_type.sensor_num);
|
||||
}
|
||||
@ -1066,7 +1188,14 @@ ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_recor
|
||||
printf(" EvM Revision : %02x\n",
|
||||
evt->sel_type.standard_type.evm_rev);
|
||||
printf(" Sensor Type : %s\n",
|
||||
ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0]));
|
||||
(
|
||||
(evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
|
||||
?
|
||||
ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
|
||||
:
|
||||
ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
|
||||
)
|
||||
);
|
||||
printf(" Sensor Number : %02x\n",
|
||||
evt->sel_type.standard_type.sensor_num);
|
||||
printf(" Event Type : %s\n",
|
||||
@ -1236,6 +1365,11 @@ ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_
|
||||
evt->sel_type.standard_type.event_data[2] & 0x0f,
|
||||
(evt->sel_type.standard_type.event_data[2] & 0xf0) >> 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME : Add sensor specific discrete types */
|
||||
printf(" Event Interpretation Missing\n");
|
||||
}
|
||||
} else if (evt->sel_type.standard_type.event_type >= 0x70 && evt->sel_type.standard_type.event_type <= 0x7f) {
|
||||
/* OEM */
|
||||
} else {
|
||||
@ -1281,7 +1415,7 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav
|
||||
|
||||
if (rsp->data[1] == 0 && rsp->data[2] == 0) {
|
||||
lprintf(LOG_ERR, "SEL has no entries");
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
@ -1332,7 +1466,7 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav
|
||||
|
||||
if (savefile != NULL) {
|
||||
fp = ipmi_open_file_write(savefile);
|
||||
}
|
||||
}
|
||||
|
||||
while (next_id != 0xffff) {
|
||||
curr_id = next_id;
|
||||
@ -1498,12 +1632,13 @@ ipmi_sel_get_time(struct ipmi_intf * intf)
|
||||
"Invalid data length %d", rsp->data_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
memcpy(&timei, rsp->data, 4);
|
||||
#if WORDS_BIGENDIAN
|
||||
timei = BSWAP_32(time);
|
||||
#endif
|
||||
time = (time_t)(BSWAP_32(timei));
|
||||
#else
|
||||
time = (time_t)timei;
|
||||
#endif
|
||||
|
||||
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", localtime(&time));
|
||||
printf("%s\n", tbuf);
|
||||
@ -1551,7 +1686,7 @@ ipmi_sel_set_time(struct ipmi_intf * intf, const char * time_string)
|
||||
}
|
||||
|
||||
timei = (uint32_t)t;
|
||||
req.msg.data = (uint8_t *)&timei;
|
||||
req.msg.data = (uint8_t *)&timei;
|
||||
req.msg.data_len = 4;
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
@ -1879,7 +2014,7 @@ int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
} else {
|
||||
lprintf(LOG_ERR, "sel time commands: get set");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
lprintf(LOG_ERR, "Invalid SEL command: %s", argv[0]);
|
||||
rc = -1;
|
||||
@ -1887,4 +2022,3 @@ int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
|
||||
extern int verbose;
|
||||
|
||||
#define SCANNING_DISABLED 0x40
|
||||
#define READING_UNAVAILABLE 0x20
|
||||
|
||||
static
|
||||
@ -110,6 +111,8 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf *intf,
|
||||
return -1;
|
||||
} else if (rsp->ccode > 0 || (rsp->data[1] & READING_UNAVAILABLE)) {
|
||||
validread = 0;
|
||||
} else if (!(rsp->data[1] & SCANNING_DISABLED)) {
|
||||
validread = 0;
|
||||
} else {
|
||||
/* convert RAW reading into units */
|
||||
val = rsp->data[0];
|
||||
@ -143,16 +146,19 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf *intf,
|
||||
printf(" Sensor Type (Discrete): %s\n",
|
||||
ipmi_sdr_get_sensor_type_desc(sensor->sensor.
|
||||
type));
|
||||
ipmi_sdr_print_discrete_state("States Asserted",
|
||||
sensor->sensor.type,
|
||||
sensor->event_type,
|
||||
rsp->data[2],
|
||||
rsp->data[3]);
|
||||
printf("\n");
|
||||
if( validread )
|
||||
{
|
||||
ipmi_sdr_print_discrete_state("States Asserted",
|
||||
sensor->sensor.type,
|
||||
sensor->event_type,
|
||||
rsp->data[2],
|
||||
rsp->data[3]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (validread ? 0 : -1 );
|
||||
}
|
||||
|
||||
static int
|
||||
@ -190,6 +196,8 @@ ipmi_sensor_print_full_analog(struct ipmi_intf *intf,
|
||||
return -1;
|
||||
} else if (rsp->ccode || (rsp->data[1] & READING_UNAVAILABLE)) {
|
||||
validread = 0;
|
||||
} else if (!(rsp->data[1] & SCANNING_DISABLED)) {
|
||||
validread = 0;
|
||||
} else {
|
||||
/* convert RAW reading into units */
|
||||
val = (rsp->data[0] > 0)
|
||||
@ -385,7 +393,7 @@ ipmi_sensor_print_full_analog(struct ipmi_intf *intf,
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (validread ? 0 : -1 );
|
||||
}
|
||||
|
||||
int
|
||||
@ -427,6 +435,8 @@ ipmi_sensor_print_compact(struct ipmi_intf *intf,
|
||||
return -1;
|
||||
} else if (rsp->ccode || (rsp->data[1] & READING_UNAVAILABLE)) {
|
||||
validread = 0;
|
||||
} else if (!(rsp->data[1] & SCANNING_DISABLED)) {
|
||||
validread = 0;
|
||||
} else {
|
||||
/* convert RAW reading into units */
|
||||
val = rsp->data[0];
|
||||
@ -461,16 +471,20 @@ ipmi_sensor_print_compact(struct ipmi_intf *intf,
|
||||
printf(" Sensor Type (Discrete): %s\n",
|
||||
ipmi_sdr_get_sensor_type_desc(sensor->sensor.
|
||||
type));
|
||||
ipmi_sdr_print_discrete_state("States Asserted",
|
||||
sensor->sensor.type,
|
||||
sensor->event_type,
|
||||
rsp->data[2],
|
||||
rsp->data[3]);
|
||||
printf("\n");
|
||||
|
||||
if(validread)
|
||||
{
|
||||
ipmi_sdr_print_discrete_state("States Asserted",
|
||||
sensor->sensor.type,
|
||||
sensor->event_type,
|
||||
rsp->data[2],
|
||||
rsp->data[3]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (validread ? 0 : -1 );
|
||||
}
|
||||
|
||||
static int
|
||||
@ -771,6 +785,8 @@ ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv)
|
||||
continue;
|
||||
} else if (rsp->data[1] & READING_UNAVAILABLE) {
|
||||
continue;
|
||||
} else if (!(rsp->data[1] & SCANNING_DISABLED)) {
|
||||
continue;
|
||||
} else if (rsp->data[0] > 0) {
|
||||
/* convert RAW reading into units */
|
||||
val = sdr_convert_sensor_reading(sdr->record.full, rsp->data[0]);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -88,10 +88,58 @@ const struct valstr sol_parameter_vals[] = {
|
||||
static struct timeval _start_keepalive;
|
||||
static struct termios _saved_tio;
|
||||
static int _in_raw_mode = 0;
|
||||
static int _disable_keepalive = 0;
|
||||
static int _use_sol_for_keepalive = 0;
|
||||
|
||||
extern int verbose;
|
||||
|
||||
static uint8_t G_u8ActiveSOL = 0;
|
||||
/*
|
||||
* ipmi_sol_payload_access
|
||||
*/
|
||||
int
|
||||
ipmi_sol_payload_access(struct ipmi_intf * intf,
|
||||
uint8_t channel,
|
||||
uint8_t userid,
|
||||
int enable)
|
||||
{
|
||||
struct ipmi_rq req;
|
||||
struct ipmi_rs *rsp;
|
||||
uint8_t data[6];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = IPMI_SET_USER_PAYLOAD_ACCESS;
|
||||
req.msg.data = data;
|
||||
req.msg.data_len = 6;
|
||||
|
||||
memset(data, 0, 6);
|
||||
|
||||
data[0] = channel & 0xf; /* channel */
|
||||
data[1] = userid & 0x3f; /* user id */
|
||||
if (!enable)
|
||||
data[1] |= 0x40; /* disable */
|
||||
data[2] = 0x02; /* payload 1 is SOL */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
return 0;
|
||||
default:
|
||||
lprintf(LOG_ERR, "Error %sabling SOL payload for user %d on channel %d: %s",
|
||||
enable ? "en" : "dis", userid, channel,
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error %sabling SOL payload for user %d on channel %d",
|
||||
enable ? "en" : "dis", userid, channel);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ipmi_get_sol_info
|
||||
@ -104,9 +152,9 @@ ipmi_get_sol_info(
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t data[4];
|
||||
uint8_t data[4];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_TRANSPORT;
|
||||
req.msg.cmd = IMPI_GET_SOL_CONFIG_PARAMETERS;
|
||||
req.msg.data_len = 4;
|
||||
@ -121,12 +169,12 @@ ipmi_get_sol_info(
|
||||
data[1] = SOL_PARAMETER_SET_IN_PROGRESS; /* parameter selector */
|
||||
data[2] = 0x00; /* set selector */
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->set_in_progress = rsp->data[1];
|
||||
} else {
|
||||
@ -137,12 +185,12 @@ ipmi_get_sol_info(
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
break;
|
||||
default:
|
||||
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
|
||||
val2str(data[1], sol_parameter_vals),
|
||||
val2str(data[1], sol_parameter_vals),
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
@ -159,12 +207,12 @@ ipmi_get_sol_info(
|
||||
data[1] = SOL_PARAMETER_SOL_ENABLE; /* parameter selector */
|
||||
data[2] = 0x00; /* set selector */
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->enabled = rsp->data[1];
|
||||
} else {
|
||||
@ -175,7 +223,7 @@ ipmi_get_sol_info(
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
break;
|
||||
default:
|
||||
@ -197,11 +245,11 @@ ipmi_get_sol_info(
|
||||
data[1] = SOL_PARAMETER_SOL_AUTHENTICATION; /* parameter selector */
|
||||
data[2] = 0x00; /* set selector */
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->force_encryption = ((rsp->data[1] & 0x80)? 1 : 0);
|
||||
params->force_authentication = ((rsp->data[1] & 0x40)? 1 : 0);
|
||||
@ -214,7 +262,7 @@ ipmi_get_sol_info(
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
break;
|
||||
default:
|
||||
@ -236,11 +284,11 @@ ipmi_get_sol_info(
|
||||
data[1] = SOL_PARAMETER_CHARACTER_INTERVAL; /* parameter selector */
|
||||
data[2] = 0x00; /* set selector */
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
case 0x00:
|
||||
if (rsp->data_len == 3) {
|
||||
params->character_accumulate_level = rsp->data[1];
|
||||
params->character_send_threshold = rsp->data[2];
|
||||
@ -252,7 +300,7 @@ ipmi_get_sol_info(
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
break;
|
||||
default:
|
||||
@ -274,14 +322,14 @@ ipmi_get_sol_info(
|
||||
data[1] = SOL_PARAMETER_SOL_RETRY; /* parameter selector */
|
||||
data[2] = 0x00; /* set selector */
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
case 0x00:
|
||||
if (rsp->data_len == 3) {
|
||||
params->retry_count = rsp->data[1];
|
||||
params->retry_interval = rsp->data[2];
|
||||
params->retry_interval = rsp->data[2];
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL parameter '%s'",
|
||||
@ -290,7 +338,7 @@ ipmi_get_sol_info(
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
break;
|
||||
default:
|
||||
@ -312,11 +360,11 @@ ipmi_get_sol_info(
|
||||
data[1] = SOL_PARAMETER_SOL_NON_VOLATILE_BIT_RATE; /* parameter selector */
|
||||
data[2] = 0x00; /* set selector */
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->non_volatile_bit_rate = rsp->data[1] & 0x0F;
|
||||
} else {
|
||||
@ -327,7 +375,7 @@ ipmi_get_sol_info(
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
break;
|
||||
default:
|
||||
@ -349,11 +397,11 @@ ipmi_get_sol_info(
|
||||
data[1] = SOL_PARAMETER_SOL_VOLATILE_BIT_RATE; /* parameter selector */
|
||||
data[2] = 0x00; /* set selector */
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->volatile_bit_rate = rsp->data[1] & 0x0F;
|
||||
} else {
|
||||
@ -364,7 +412,7 @@ ipmi_get_sol_info(
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
break;
|
||||
default:
|
||||
@ -386,11 +434,11 @@ ipmi_get_sol_info(
|
||||
data[1] = SOL_PARAMETER_SOL_PAYLOAD_CHANNEL; /* parameter selector */
|
||||
data[2] = 0x00; /* set selector */
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->payload_channel = rsp->data[1];
|
||||
} else {
|
||||
@ -401,7 +449,7 @@ ipmi_get_sol_info(
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported - defaulting to 0x%02x",
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported - defaulting to 0x%02x",
|
||||
val2str(data[1], sol_parameter_vals), channel);
|
||||
params->payload_channel = channel;
|
||||
break;
|
||||
@ -424,11 +472,11 @@ ipmi_get_sol_info(
|
||||
data[1] = SOL_PARAMETER_SOL_PAYLOAD_PORT; /* parameter selector */
|
||||
data[2] = 0x00; /* set selector */
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
case 0x00:
|
||||
if (rsp->data_len == 3) {
|
||||
params->payload_port = (rsp->data[1]) | (rsp->data[2] << 8);
|
||||
} else {
|
||||
@ -439,7 +487,7 @@ ipmi_get_sol_info(
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported - defaulting to %d",
|
||||
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported - defaulting to %d",
|
||||
val2str(data[1], sol_parameter_vals), intf->session->port);
|
||||
params->payload_port = intf->session->port;
|
||||
break;
|
||||
@ -468,7 +516,7 @@ ipmi_print_sol_info(struct ipmi_intf * intf, uint8_t channel)
|
||||
struct sol_config_parameters params = {0};
|
||||
if (ipmi_get_sol_info(intf, channel, ¶ms))
|
||||
return -1;
|
||||
|
||||
|
||||
if (csv_output)
|
||||
{
|
||||
printf("%s,",
|
||||
@ -543,22 +591,22 @@ ipmi_print_sol_info(struct ipmi_intf * intf, uint8_t channel)
|
||||
*/
|
||||
static int
|
||||
ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
uint8_t channel,
|
||||
const char * param,
|
||||
const char * value)
|
||||
uint8_t channel,
|
||||
const char * param,
|
||||
const char * value,
|
||||
uint8_t guarded)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t data[4];
|
||||
int bGuarded = 1; /* Use set-in-progress indicator? */
|
||||
uint8_t data[4];
|
||||
int bGuarded = guarded; /* Use set-in-progress indicator? */
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_TRANSPORT; /* 0x0c */
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_TRANSPORT; /* 0x0c */
|
||||
req.msg.cmd = IMPI_SET_SOL_CONFIG_PARAMETERS; /* 0x21 */
|
||||
req.msg.data = data;
|
||||
|
||||
|
||||
data[0] = channel;
|
||||
|
||||
|
||||
/*
|
||||
* set-in-progress
|
||||
@ -638,11 +686,11 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
param);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
data[2] |= params.force_authentication? 0x40 : 0x00;
|
||||
data[2] |= params.privilege_level;
|
||||
data[2] |= params.privilege_level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* force-payload-authentication
|
||||
@ -676,9 +724,9 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
}
|
||||
|
||||
data[2] |= params.force_encryption? 0x80 : 0x00;
|
||||
data[2] |= params.privilege_level;
|
||||
data[2] |= params.privilege_level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* privilege-level
|
||||
@ -738,7 +786,7 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
param);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
data[3] = params.character_send_threshold;
|
||||
}
|
||||
|
||||
@ -764,7 +812,7 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
|
||||
data[2] = params.character_accumulate_level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* retry-count
|
||||
@ -807,11 +855,11 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
param);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
data[2] = params.retry_count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* non-volatile-bit-rate
|
||||
*/
|
||||
@ -853,7 +901,7 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* volatile-bit-rate
|
||||
@ -896,7 +944,6 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: invalid SOL parameter %s", param);
|
||||
@ -909,9 +956,10 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
*/
|
||||
if (bGuarded &&
|
||||
(ipmi_sol_set_param(intf,
|
||||
channel,
|
||||
"set-in-progress",
|
||||
"set-in-progress")))
|
||||
channel,
|
||||
"set-in-progress",
|
||||
"set-in-progress",
|
||||
bGuarded)))
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: set of parameter \"%s\" failed", param);
|
||||
return -1;
|
||||
@ -924,23 +972,45 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error setting SOL parameter '%s'", param);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Error setting SOL parameter '%s': %s",
|
||||
param, val2str(rsp->ccode, completion_code_vals));
|
||||
if (!(!strncmp(param, "set-in-progress", 15) && !strncmp(value, "commit-write", 12)) &&
|
||||
rsp->ccode > 0) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Error setting SOL parameter '%s': "
|
||||
"Parameter not supported", param);
|
||||
break;
|
||||
case 0x81:
|
||||
lprintf(LOG_ERR, "Error setting SOL parameter '%s': "
|
||||
"Attempt to set set-in-progress when not in set-complete state",
|
||||
param);
|
||||
break;
|
||||
case 0x82:
|
||||
lprintf(LOG_ERR, "Error setting SOL parameter '%s': "
|
||||
"Attempt to write read-only parameter", param);
|
||||
break;
|
||||
case 0x83:
|
||||
lprintf(LOG_ERR, "Error setting SOL parameter '%s': "
|
||||
"Attempt to read write-only parameter", param);
|
||||
break;
|
||||
default:
|
||||
lprintf(LOG_ERR, "Error setting SOL parameter '%s' to '%s': %s",
|
||||
param, value, val2str(rsp->ccode, completion_code_vals));
|
||||
break;
|
||||
}
|
||||
|
||||
if (bGuarded &&
|
||||
(ipmi_sol_set_param(intf,
|
||||
channel,
|
||||
"set-in-progress",
|
||||
"set-complete")))
|
||||
channel,
|
||||
"set-in-progress",
|
||||
"set-complete",
|
||||
bGuarded)))
|
||||
{
|
||||
lprintf(LOG_ERR, "Error could not set \"set-in-progress\" "
|
||||
"to \"set-complete\"");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -951,16 +1021,18 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
*/
|
||||
if (bGuarded)
|
||||
ipmi_sol_set_param(intf,
|
||||
channel,
|
||||
"set-in-progress",
|
||||
"commit-write");
|
||||
channel,
|
||||
"set-in-progress",
|
||||
"commit-write",
|
||||
bGuarded);
|
||||
|
||||
|
||||
if (bGuarded &&
|
||||
ipmi_sol_set_param(intf,
|
||||
channel,
|
||||
"set-in-progress",
|
||||
"set-complete"))
|
||||
channel,
|
||||
"set-in-progress",
|
||||
"set-complete",
|
||||
bGuarded))
|
||||
{
|
||||
lprintf(LOG_ERR, "Error could not set \"set-in-progress\" "
|
||||
"to \"set-complete\"");
|
||||
@ -995,8 +1067,7 @@ enter_raw_mode(void)
|
||||
}
|
||||
_saved_tio = tio;
|
||||
tio.c_iflag |= IGNPAR;
|
||||
tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF)\
|
||||
;
|
||||
tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
|
||||
tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
|
||||
// #ifdef IEXTEN
|
||||
tio.c_lflag &= ~IEXTEN;
|
||||
@ -1084,9 +1155,21 @@ printSolEscapeSequences(struct ipmi_intf * intf)
|
||||
static void
|
||||
output(struct ipmi_rs * rsp)
|
||||
{
|
||||
if (rsp)
|
||||
/* Add checks to make sure it is actually SOL data, in general I see
|
||||
* outside code mostly trying to guard against this happening, but
|
||||
* some places fail to do so, so I do so here to make sure nothing gets
|
||||
* through. If non-sol data comes through here, there is probably
|
||||
* a packet that won't get processed somewhere else, but the alternative
|
||||
* of outputting corrupt data is worse. Generally I see the get device
|
||||
* id response make it here somehow. I assume it is a heartbeat and the
|
||||
* other code will retry if it cares about the response and misses it.
|
||||
*/
|
||||
if (rsp &&
|
||||
(rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) &&
|
||||
(rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rsp->data_len; ++i)
|
||||
putc(rsp->data[i], stdout);
|
||||
|
||||
@ -1104,9 +1187,9 @@ ipmi_sol_deactivate(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t data[6];
|
||||
uint8_t data[6];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = IPMI_DEACTIVATE_PAYLOAD;
|
||||
req.msg.data_len = 6;
|
||||
@ -1126,7 +1209,7 @@ ipmi_sol_deactivate(struct ipmi_intf * intf)
|
||||
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
case 0x00:
|
||||
return 0;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL payload already de-activated");
|
||||
@ -1144,7 +1227,7 @@ ipmi_sol_deactivate(struct ipmi_intf * intf)
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1184,7 +1267,7 @@ processSolUserInput(
|
||||
|
||||
if (escape_pending){
|
||||
escape_pending = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Process a possible escape sequence.
|
||||
*/
|
||||
@ -1242,7 +1325,7 @@ processSolUserInput(
|
||||
last_was_cr = (ch == '\r' || ch == '\n');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* If there is anything left to process we dispatch it to the BMC,
|
||||
* send intf->session->sol_data.max_outbound_payload_size bytes
|
||||
@ -1254,8 +1337,9 @@ processSolUserInput(
|
||||
int try = 0;
|
||||
|
||||
while (try < intf->session->retry) {
|
||||
|
||||
|
||||
v2_payload.payload.sol_packet.character_count = length;
|
||||
|
||||
rsp = intf->send_sol(intf, &v2_payload);
|
||||
|
||||
if (rsp)
|
||||
@ -1284,23 +1368,53 @@ processSolUserInput(
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ipmi_sol_keepalive(struct ipmi_intf * intf)
|
||||
ipmi_sol_keepalive_using_sol(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_v2_payload v2_payload;
|
||||
struct ipmi_rs * rsp = NULL;
|
||||
struct timeval end;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (_disable_keepalive)
|
||||
return 0;
|
||||
|
||||
gettimeofday(&end, 0);
|
||||
|
||||
if (end.tv_sec - _start_keepalive.tv_sec > SOL_KEEPALIVE_TIMEOUT) {
|
||||
ret = intf->keepalive(intf);
|
||||
gettimeofday(&_start_keepalive, 0);
|
||||
}
|
||||
memset(&v2_payload, 0, sizeof(v2_payload));
|
||||
|
||||
v2_payload.payload.sol_packet.character_count = 0;
|
||||
|
||||
rsp = intf->send_sol(intf, &v2_payload);
|
||||
|
||||
gettimeofday(&_start_keepalive, 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_sol_keepalive_using_getdeviceid(struct ipmi_intf * intf)
|
||||
{
|
||||
struct timeval end;
|
||||
int ret = 0;
|
||||
|
||||
if (_disable_keepalive)
|
||||
return 0;
|
||||
|
||||
gettimeofday(&end, 0);
|
||||
|
||||
if (end.tv_sec - _start_keepalive.tv_sec > SOL_KEEPALIVE_TIMEOUT) {
|
||||
ret = intf->keepalive(intf);
|
||||
gettimeofday(&_start_keepalive, 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ipmi_sol_red_pill
|
||||
@ -1308,7 +1422,6 @@ ipmi_sol_keepalive(struct ipmi_intf * intf)
|
||||
static int
|
||||
ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
{
|
||||
|
||||
char * buffer;
|
||||
int numRead;
|
||||
int bShouldExit = 0;
|
||||
@ -1321,12 +1434,12 @@ ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
|
||||
buffer = (char*)malloc(buffer_size);
|
||||
if (buffer == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Initialize keepalive start time */
|
||||
gettimeofday(&_start_keepalive, 0);
|
||||
gettimeofday(&_start_keepalive, 0);
|
||||
|
||||
enter_raw_mode();
|
||||
|
||||
@ -1337,7 +1450,15 @@ ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
FD_SET(intf->fd, &read_fds);
|
||||
|
||||
/* Send periodic keepalive packet */
|
||||
keepAliveRet = ipmi_sol_keepalive(intf);
|
||||
if(_use_sol_for_keepalive == 0)
|
||||
{
|
||||
keepAliveRet = ipmi_sol_keepalive_using_getdeviceid(intf);
|
||||
}
|
||||
else
|
||||
{
|
||||
keepAliveRet = ipmi_sol_keepalive_using_sol(intf);
|
||||
}
|
||||
|
||||
if (keepAliveRet != 0)
|
||||
{
|
||||
/* no response to keepalive message */
|
||||
@ -1370,11 +1491,11 @@ ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
numRead = read(fileno(stdin),
|
||||
buffer,
|
||||
buffer_size);
|
||||
|
||||
|
||||
if (numRead > 0)
|
||||
{
|
||||
int rc = processSolUserInput(intf, (uint8_t *)buffer, numRead);
|
||||
|
||||
|
||||
if (rc)
|
||||
{
|
||||
if (rc < 0)
|
||||
@ -1401,10 +1522,12 @@ ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
bShouldExit = bBmcClosedSession = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
output(rs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ERROR in select
|
||||
*/
|
||||
@ -1414,7 +1537,7 @@ ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
bShouldExit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leave_raw_mode();
|
||||
|
||||
@ -1449,7 +1572,7 @@ ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval)
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
struct activate_payload_rsp ap_rsp;
|
||||
uint8_t data[6];
|
||||
uint8_t data[6];
|
||||
uint8_t bSolEncryption = 1;
|
||||
uint8_t bSolAuthentication = 1;
|
||||
|
||||
@ -1497,7 +1620,6 @@ ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval)
|
||||
data[4] = 0x00; /* reserved */
|
||||
data[5] = 0x00; /* reserved */
|
||||
|
||||
G_u8ActiveSOL = 1;
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (NULL != rsp) {
|
||||
@ -1539,7 +1661,7 @@ ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval)
|
||||
|
||||
|
||||
memcpy(&ap_rsp, rsp->data, sizeof(struct activate_payload_rsp));
|
||||
|
||||
|
||||
intf->session->sol_data.max_inbound_payload_size =
|
||||
(ap_rsp.inbound_payload_size[1] << 8) |
|
||||
ap_rsp.inbound_payload_size[0];
|
||||
@ -1551,7 +1673,6 @@ ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval)
|
||||
intf->session->sol_data.port =
|
||||
(ap_rsp.payload_udp_port[1] << 8) |
|
||||
ap_rsp.payload_udp_port[0];
|
||||
|
||||
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
@ -1564,7 +1685,7 @@ ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval)
|
||||
#endif
|
||||
|
||||
|
||||
intf->session->timeout = 3;
|
||||
intf->session->timeout = 1;
|
||||
|
||||
|
||||
/* NOTE: the spec does allow for SOL traffic to be sent on
|
||||
@ -1582,7 +1703,6 @@ ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("[SOL Session operational. Use %c? for help]\r\n",
|
||||
intf->session->sol_escape_char);
|
||||
@ -1592,7 +1712,7 @@ ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval)
|
||||
ipmi_sol_deactivate(intf);
|
||||
usleep(interval*1000);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point we are good to go with our SOL session. We
|
||||
@ -1619,7 +1739,8 @@ print_sol_usage(void)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "SOL Commands: info [<channel number>]");
|
||||
lprintf(LOG_NOTICE, " set <parameter> <value> [channel]");
|
||||
lprintf(LOG_NOTICE, " activate");
|
||||
lprintf(LOG_NOTICE, " payload <enable|disable> [channel] [userid]");
|
||||
lprintf(LOG_NOTICE, " activate [<usesolforkeepalive|nokeepalive>]");
|
||||
lprintf(LOG_NOTICE, " deactivate");
|
||||
lprintf(LOG_NOTICE, " looptest [<loop times>] [<loop interval(in ms)>]");
|
||||
}
|
||||
@ -1678,49 +1799,104 @@ ipmi_sol_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
channel = (uint8_t)strtol(argv[1], NULL, 0);
|
||||
else
|
||||
{
|
||||
print_sol_usage();
|
||||
print_sol_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = ipmi_print_sol_info(intf, channel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Payload enable or disable
|
||||
*/
|
||||
else if (!strncmp(argv[0], "payload", 7)) {
|
||||
uint8_t channel = 0xe;
|
||||
uint8_t userid = 1;
|
||||
int enable = -1;
|
||||
|
||||
if (!strncmp(argv[1], "enable", 6))
|
||||
{
|
||||
enable = 1;
|
||||
}
|
||||
else if (!strncmp(argv[1], "disable", 7))
|
||||
{
|
||||
enable = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
print_sol_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc >= 3)
|
||||
{
|
||||
channel = (uint8_t)strtol(argv[2], NULL, 0);
|
||||
}
|
||||
if (argc >= 4)
|
||||
{
|
||||
userid = (uint8_t)strtol(argv[3], NULL, 0);
|
||||
}
|
||||
|
||||
retval = ipmi_sol_payload_access(intf, channel, userid, enable);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set a parameter value
|
||||
*/
|
||||
else if (!strncmp(argv[0], "set", 3)) {
|
||||
uint8_t channel;
|
||||
uint8_t channel = 0xe;
|
||||
uint8_t guard = 1;
|
||||
|
||||
if (argc == 3)
|
||||
channel = 0x0E; /* Ask about the current channel */
|
||||
{
|
||||
channel = 0xe;
|
||||
}
|
||||
else if (argc == 4)
|
||||
{
|
||||
if (!strncmp(argv[3], "noguard", 7))
|
||||
guard = 0;
|
||||
else
|
||||
channel = (uint8_t)strtol(argv[3], NULL, 0);
|
||||
}
|
||||
else if (argc == 5)
|
||||
{
|
||||
channel = (uint8_t)strtol(argv[3], NULL, 0);
|
||||
if (!strncmp(argv[4], "noguard", 7))
|
||||
guard = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
print_sol_set_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = ipmi_sol_set_param(intf,
|
||||
channel,
|
||||
argv[1],
|
||||
argv[2]);
|
||||
|
||||
retval = ipmi_sol_set_param(intf, channel, argv[1], argv[2], guard);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Activate
|
||||
*/
|
||||
else if (!strncmp(argv[0], "activate", 8))
|
||||
else if (!strncmp(argv[0], "activate", 8)) {
|
||||
|
||||
if (argc > 1) {
|
||||
if (!strncmp(argv[1], "usesolkeepalive", 11))
|
||||
_use_sol_for_keepalive = 1;
|
||||
else if (!strncmp(argv[1], "nokeepalive", 11))
|
||||
_disable_keepalive = 1;
|
||||
}
|
||||
|
||||
retval = ipmi_sol_activate(intf, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Dectivate
|
||||
*/
|
||||
else if (!strncmp(argv[0], "deactivate", 10))
|
||||
retval = ipmi_sol_deactivate(intf);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* SOL loop test: Activate and then Dectivate
|
||||
@ -1730,9 +1906,9 @@ ipmi_sol_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
int cnt = 200;
|
||||
int interval = 100; /* Unit is: ms */
|
||||
|
||||
if(argc > 3)
|
||||
if (argc > 3)
|
||||
{
|
||||
print_sol_usage();
|
||||
print_sol_usage();
|
||||
return -1;
|
||||
}
|
||||
if (argc != 1) /* at least 2 */
|
||||
@ -1745,12 +1921,12 @@ ipmi_sol_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
interval = strtol(argv[2], NULL, 10);
|
||||
if(interval < 0) interval = 0;
|
||||
}
|
||||
|
||||
while(cnt > 0)
|
||||
|
||||
while (cnt > 0)
|
||||
{
|
||||
printf("remain loop test counter: %d\n", cnt);
|
||||
retval = ipmi_sol_activate(intf, 1, interval);
|
||||
if(retval)
|
||||
if (retval)
|
||||
{
|
||||
printf("SOL looptest failed: %d\n", retval);
|
||||
break;
|
||||
|
@ -44,10 +44,29 @@ const struct valstr ipmi_oem_info[] = {
|
||||
{ IPMI_OEM_TYAN, "Tyan Computer Corporation" },
|
||||
{ IPMI_OEM_NEWISYS, "Newisys" },
|
||||
{ IPMI_OEM_SUPERMICRO, "Supermicro" },
|
||||
{ IPMI_OEM_GOOGLE, "Google" },
|
||||
{ IPMI_OEM_KONTRON, "Kontron" },
|
||||
{ IPMI_OEM_NOKIA, "Nokia" },
|
||||
{ 0xffff , NULL },
|
||||
};
|
||||
|
||||
const struct oemvalstr ipmi_oem_sdr_type_vals[] = {
|
||||
/* Keep OEM grouped together */
|
||||
{ IPMI_OEM_KONTRON , 0xC0 , "OEM Firmware Info" },
|
||||
{ IPMI_OEM_KONTRON , 0xC2 , "OEM Init Agent" },
|
||||
{ IPMI_OEM_KONTRON , 0xC3 , "OEM IPMBL Link State" },
|
||||
{ IPMI_OEM_KONTRON , 0xC4 , "OEM Board Reset" },
|
||||
{ IPMI_OEM_KONTRON , 0xC5 , "OEM FRU Information Agent" },
|
||||
{ IPMI_OEM_KONTRON , 0xC6 , "OEM POST Value Sensor" },
|
||||
{ IPMI_OEM_KONTRON , 0xC7 , "OEM FWUM Status" },
|
||||
{ IPMI_OEM_KONTRON , 0xC8 , "OEM Switch Mngt Software Status" },
|
||||
|
||||
{ IPMI_OEM_PICMG , 0xF0 , "PICMG FRU Hotswap" },
|
||||
{ IPMI_OEM_PICMG , 0xF1 , "PICMG IPMB0 Link State" },
|
||||
|
||||
{ 0xffff, 0x00, NULL }
|
||||
};
|
||||
|
||||
const struct valstr ipmi_netfn_vals[] = {
|
||||
{ IPMI_NETFN_CHASSIS, "Chassis" },
|
||||
{ IPMI_NETFN_BRIDGE, "Bridge" },
|
||||
@ -161,18 +180,26 @@ const struct valstr entity_id_vals[] = {
|
||||
{ 0x26, "Remote Management Device" },
|
||||
{ 0x27, "External Environment" },
|
||||
{ 0x28, "Battery" },
|
||||
{ 0x29, "Processing Blade" },
|
||||
{ 0x2A, "Connectivity Switch" },
|
||||
{ 0x2B, "Processor/Memory Module" },
|
||||
{ 0x2C, "I/O Module" },
|
||||
{ 0x2D, "Processor/IO Module" },
|
||||
{ 0x2E, "Management Controller Firmware" },
|
||||
{ 0x2F, "IPMI Channel" },
|
||||
{ 0x30, "PCI Bus" },
|
||||
{ 0x31, "PCI Express Bus" },
|
||||
{ 0x32, "SCSI Bus (parallel)" },
|
||||
{ 0x33, "SATA/SAS Bus" },
|
||||
{ 0x34, "Processor/Front-Side Bus" },
|
||||
{ 0x29, "Processing Blade" },
|
||||
{ 0x2A, "Connectivity Switch" },
|
||||
{ 0x2B, "Processor/Memory Module" },
|
||||
{ 0x2C, "I/O Module" },
|
||||
{ 0x2D, "Processor/IO Module" },
|
||||
{ 0x2E, "Management Controller Firmware" },
|
||||
{ 0x2F, "IPMI Channel" },
|
||||
{ 0x30, "PCI Bus" },
|
||||
{ 0x31, "PCI Express Bus" },
|
||||
{ 0x32, "SCSI Bus (parallel)" },
|
||||
{ 0x33, "SATA/SAS Bus" },
|
||||
{ 0x34, "Processor/Front-Side Bus" },
|
||||
/* PICMG */
|
||||
{ 0xA0, "PICMG Front Board" },
|
||||
{ 0xC0, "PICMG Rear Transition Module" },
|
||||
{ 0xC1, "PICMG AdvancedMC Module" },
|
||||
{ 0xF0, "PICMG Shelf Management Controller" },
|
||||
{ 0xF1, "PICMG Filtration Unit" },
|
||||
{ 0xF2, "PICMG Shelf FRU Information" },
|
||||
{ 0xF3, "PICMG Alarm Panel" },
|
||||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
|
@ -72,11 +72,10 @@ extern int csv_output;
|
||||
*/
|
||||
static int
|
||||
ipmi_get_user_access(
|
||||
struct ipmi_intf * intf,
|
||||
uint8_t channel_number,
|
||||
uint8_t user_id,
|
||||
struct user_access_rsp * user_access)
|
||||
|
||||
struct ipmi_intf *intf,
|
||||
uint8_t channel_number,
|
||||
uint8_t user_id,
|
||||
struct user_access_rsp *user_access)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
@ -92,7 +91,7 @@ ipmi_get_user_access(
|
||||
/* The channel number will remain constant throughout this function */
|
||||
msg_data[0] = channel_number;
|
||||
msg_data[1] = user_id;
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (rsp == NULL) {
|
||||
@ -129,10 +128,9 @@ ipmi_get_user_access(
|
||||
*/
|
||||
static int
|
||||
ipmi_get_user_name(
|
||||
struct ipmi_intf * intf,
|
||||
uint8_t user_id,
|
||||
char * user_name)
|
||||
|
||||
struct ipmi_intf *intf,
|
||||
uint8_t user_id,
|
||||
char *user_name)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
@ -141,13 +139,13 @@ ipmi_get_user_name(
|
||||
memset(user_name, 0, 17);
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
|
||||
req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */
|
||||
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
|
||||
req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 1;
|
||||
|
||||
msg_data[0] = user_id;
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (rsp == NULL) {
|
||||
@ -185,7 +183,6 @@ dump_user_access(
|
||||
"Channel Priv Limit\n");
|
||||
printed_header = 1;
|
||||
}
|
||||
|
||||
|
||||
printf("%-4d%-17s%-8s%-11s%-11s%-s\n",
|
||||
user_id,
|
||||
@ -201,9 +198,9 @@ dump_user_access(
|
||||
|
||||
static void
|
||||
dump_user_access_csv(
|
||||
uint8_t user_id,
|
||||
const char * user_name,
|
||||
struct user_access_rsp * user_access)
|
||||
uint8_t user_id,
|
||||
const char *user_name,
|
||||
struct user_access_rsp *user_access)
|
||||
{
|
||||
printf("%d,%s,%s,%s,%s,%s\n",
|
||||
user_id,
|
||||
@ -219,8 +216,8 @@ dump_user_access_csv(
|
||||
|
||||
static int
|
||||
ipmi_print_user_list(
|
||||
struct ipmi_intf * intf,
|
||||
uint8_t channel_number)
|
||||
struct ipmi_intf *intf,
|
||||
uint8_t channel_number)
|
||||
{
|
||||
/* This is where you were! */
|
||||
char user_name[17];
|
||||
@ -241,8 +238,7 @@ ipmi_print_user_list(
|
||||
current_user_id,
|
||||
user_name))
|
||||
return -1;
|
||||
|
||||
|
||||
|
||||
if ((current_user_id == 0) ||
|
||||
user_access.link_auth_access ||
|
||||
user_access.ipmi_messaging_access ||
|
||||
@ -308,9 +304,9 @@ ipmi_print_user_summary(
|
||||
*/
|
||||
static int
|
||||
ipmi_user_set_username(
|
||||
struct ipmi_intf * intf,
|
||||
uint8_t user_id,
|
||||
const char * name)
|
||||
struct ipmi_intf *intf,
|
||||
uint8_t user_id,
|
||||
const char *name)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
@ -343,49 +339,48 @@ ipmi_user_set_username(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ipmi_user_set_userpriv(
|
||||
struct ipmi_intf * intf,
|
||||
uint8_t channel,
|
||||
uint8_t user_id,
|
||||
const unsigned char privLevel)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t msg_data[3];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
|
||||
req.msg.cmd = IPMI_SET_USER_ACCESS; /* 0x43 */
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
|
||||
/* The channel number will remain constant throughout this function */
|
||||
msg_data[0] = (channel & 0x0f); /* Do not change any bytes */
|
||||
msg_data[1] = (user_id & 0x3f);
|
||||
msg_data[2] = (privLevel & 0x0f);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (rsp == NULL)
|
||||
{
|
||||
lprintf(LOG_ERR, "Set Privilege Level command failed (user %d)",
|
||||
user_id);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0)
|
||||
{
|
||||
lprintf(LOG_ERR, "Set Privilege Level command failed (user %d)",
|
||||
user_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_user_set_userpriv(
|
||||
struct ipmi_intf *intf,
|
||||
uint8_t channel,
|
||||
uint8_t user_id,
|
||||
const unsigned char privLevel)
|
||||
{
|
||||
struct ipmi_rs *rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t msg_data[4];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
|
||||
req.msg.cmd = IPMI_SET_USER_ACCESS; /* 0x43 */
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 4;
|
||||
|
||||
/* The channel number will remain constant throughout this function */
|
||||
msg_data[0] = (channel & 0x0f);
|
||||
msg_data[0] |= 0x90; /* enable ipmi messaging */
|
||||
msg_data[1] = (user_id & 0x3f);
|
||||
msg_data[2] = (privLevel & 0x0f);
|
||||
msg_data[3] = 0;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (rsp == NULL)
|
||||
{
|
||||
lprintf(LOG_ERR, "Set Privilege Level command failed (user %d)",
|
||||
user_id);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0)
|
||||
{
|
||||
lprintf(LOG_ERR, "Set Privilege Level command failed (user %d): %s",
|
||||
user_id, val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ipmi_user_set_password
|
||||
@ -396,11 +391,11 @@ ipmi_user_set_userpriv(
|
||||
*/
|
||||
static int
|
||||
ipmi_user_set_password(
|
||||
struct ipmi_intf * intf,
|
||||
uint8_t user_id,
|
||||
uint8_t operation,
|
||||
const char * password,
|
||||
int is_twenty_byte_password)
|
||||
struct ipmi_intf * intf,
|
||||
uint8_t user_id,
|
||||
uint8_t operation,
|
||||
const char *password,
|
||||
int is_twenty_byte_password)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
@ -420,10 +415,10 @@ ipmi_user_set_password(
|
||||
|
||||
/* The channel number will remain constant throughout this function */
|
||||
msg_data[0] = user_id;
|
||||
|
||||
|
||||
if (is_twenty_byte_password)
|
||||
msg_data[0] |= 0x80;
|
||||
|
||||
|
||||
msg_data[1] = operation;
|
||||
|
||||
memset(msg_data + 2, 0, password_length);
|
||||
@ -486,7 +481,6 @@ ipmi_user_test_password(
|
||||
return ((ret == 0) ? 0 : -1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* print_user_usage
|
||||
@ -500,7 +494,7 @@ print_user_usage(void)
|
||||
lprintf(LOG_NOTICE, " set password <user id> [<password>]");
|
||||
lprintf(LOG_NOTICE, " disable <user id>");
|
||||
lprintf(LOG_NOTICE, " enable <user id>");
|
||||
lprintf(LOG_NOTICE, " priv <user id> <privile level> [<channel number>]");
|
||||
lprintf(LOG_NOTICE, " priv <user id> <privilege level> [<channel number>]");
|
||||
lprintf(LOG_NOTICE, " test <user id> <16|20> [<password]>\n");
|
||||
}
|
||||
|
||||
@ -547,7 +541,7 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
channel = (uint8_t)strtol(argv[1], NULL, 0);
|
||||
else
|
||||
{
|
||||
print_user_usage();
|
||||
print_user_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -568,7 +562,7 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
channel = (uint8_t)strtol(argv[1], NULL, 0);
|
||||
else
|
||||
{
|
||||
print_user_usage();
|
||||
print_user_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -590,8 +584,8 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
char * password = NULL;
|
||||
int password_length = atoi(argv[2]);
|
||||
uint8_t user_id = (uint8_t)strtol(argv[1],
|
||||
NULL,
|
||||
0);
|
||||
NULL,
|
||||
0);
|
||||
if (user_id == 0)
|
||||
{
|
||||
lprintf(LOG_ERR, "Invalid user ID: %d", user_id);
|
||||
@ -606,7 +600,6 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
char * tmp;
|
||||
const char * password_prompt =
|
||||
ipmi_user_build_password_prompt(user_id);
|
||||
|
||||
#ifdef HAVE_GETPASSPHRASE
|
||||
tmp = getpassphrase (password_prompt);
|
||||
#else
|
||||
@ -637,7 +630,6 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set
|
||||
*/
|
||||
@ -647,12 +639,12 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
* Set Password
|
||||
*/
|
||||
if ((argc >= 3) &&
|
||||
(strncmp("password", argv[1], 8) == 0))
|
||||
(strncmp("password", argv[1], 8) == 0))
|
||||
{
|
||||
char * password = NULL;
|
||||
uint8_t user_id = (uint8_t)strtol(argv[2],
|
||||
NULL,
|
||||
0);
|
||||
NULL,
|
||||
0);
|
||||
if (user_id == 0)
|
||||
{
|
||||
lprintf(LOG_ERR, "Invalid user ID: %d", user_id);
|
||||
@ -709,7 +701,6 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
lprintf(LOG_ERR, "Password is too long (> 20 bytes)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
retval = ipmi_user_set_password(intf,
|
||||
user_id,
|
||||
@ -717,7 +708,6 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
password,
|
||||
strlen(password) > 16);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set Name
|
||||
@ -733,8 +723,8 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
retval = ipmi_user_set_username(intf,
|
||||
(uint8_t)strtol(argv[2],
|
||||
NULL,
|
||||
0),
|
||||
NULL,
|
||||
0),
|
||||
argv[3]);
|
||||
}
|
||||
else
|
||||
@ -742,40 +732,38 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
print_user_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (strncmp(argv[0], "priv", 4) == 0)
|
||||
{
|
||||
uint8_t user_id;
|
||||
uint8_t priv_level;
|
||||
uint8_t channel = 0x0e; /* Use channel running on */
|
||||
|
||||
if (
|
||||
(argc != 3) &&
|
||||
(argc != 4)
|
||||
)
|
||||
|
||||
|
||||
if (argc == 4)
|
||||
{
|
||||
channel = (uint8_t)strtol(argv[3], NULL, 0);
|
||||
channel = (channel & 0x0f);
|
||||
}
|
||||
|
||||
user_id = (uint8_t)strtol(argv[1], NULL, 0);
|
||||
|
||||
priv_level = (uint8_t)strtol(argv[2], NULL, 0);
|
||||
priv_level = (priv_level & 0x0f);
|
||||
|
||||
if (user_id == 0)
|
||||
{
|
||||
lprintf(LOG_ERR, "Invalid user ID: %d", user_id);
|
||||
{
|
||||
uint8_t user_id;
|
||||
uint8_t priv_level;
|
||||
uint8_t channel = 0x0e; /* Use channel running on */
|
||||
|
||||
if (argc != 3 && argc != 4)
|
||||
{
|
||||
print_user_usage();
|
||||
return -1;
|
||||
}
|
||||
if (argc == 4)
|
||||
{
|
||||
channel = (uint8_t)strtol(argv[3], NULL, 0);
|
||||
channel = (channel & 0x0f);
|
||||
}
|
||||
|
||||
user_id = (uint8_t)strtol(argv[1], NULL, 0);
|
||||
|
||||
priv_level = (uint8_t)strtol(argv[2], NULL, 0);
|
||||
priv_level = (priv_level & 0x0f);
|
||||
|
||||
if (user_id == 0)
|
||||
{
|
||||
lprintf(LOG_ERR, "Invalid user ID: %d", user_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = ipmi_user_set_userpriv(intf,channel,user_id,priv_level);
|
||||
}
|
||||
retval = ipmi_user_set_userpriv(intf,channel,user_id,priv_level);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable / Enable
|
||||
@ -796,8 +784,8 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
}
|
||||
|
||||
user_id = (uint8_t)strtol(argv[1],
|
||||
NULL,
|
||||
0);
|
||||
NULL,
|
||||
0);
|
||||
if (user_id == 0)
|
||||
{
|
||||
lprintf(LOG_ERR, "Invalid user ID: %d", user_id);
|
||||
@ -814,11 +802,10 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
null_password,
|
||||
0); /* This field is ignored */
|
||||
}
|
||||
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
retval = -1;
|
||||
lprintf(LOG_ERR, "Invalid user command: '%s'\n", argv[0]);
|
||||
print_user_usage();
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,9 @@
|
||||
|
||||
#ifdef IPMI_INTF_OPEN
|
||||
# if defined(HAVE_OPENIPMI_H)
|
||||
# include <linux/compiler.h>
|
||||
# if defined(HAVE_LINUX_COMPILER_H)
|
||||
# include <linux/compiler.h>
|
||||
# endif
|
||||
# include <linux/ipmi.h>
|
||||
# elif defined(HAVE_FREEBSD_IPMI_H)
|
||||
# include <sys/ipmi.h>
|
||||
@ -87,6 +89,7 @@ int selwatch_timeout = 10; /* default to 10 seconds */
|
||||
struct ipmi_event_intf {
|
||||
char name[16];
|
||||
char desc[128];
|
||||
char prefix[72];
|
||||
int (*setup)(struct ipmi_event_intf * eintf);
|
||||
int (*wait)(struct ipmi_event_intf * eintf);
|
||||
int (*read)(struct ipmi_event_intf * eintf);
|
||||
@ -105,6 +108,7 @@ static int openipmi_read(struct ipmi_event_intf * eintf);
|
||||
static struct ipmi_event_intf openipmi_event_intf = {
|
||||
name: "open",
|
||||
desc: "OpenIPMI asyncronous notification of events",
|
||||
prefix: "",
|
||||
setup: openipmi_setup,
|
||||
wait: openipmi_wait,
|
||||
read: openipmi_read,
|
||||
@ -193,27 +197,34 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)
|
||||
return;
|
||||
|
||||
if (evt->record_type == 0xf0) {
|
||||
lprintf(LOG_ALERT, "Linux kernel panic: %.11s", (char *) evt + 5);
|
||||
lprintf(LOG_ALERT, "%sLinux kernel panic: %.11s",
|
||||
eintf->prefix, (char *) evt + 5);
|
||||
return;
|
||||
}
|
||||
else if (evt->record_type >= 0xc0) {
|
||||
lprintf(LOG_NOTICE, "IPMI Event OEM Record %02x", evt->record_type);
|
||||
lprintf(LOG_NOTICE, "%sIPMI Event OEM Record %02x",
|
||||
eintf->prefix, evt->record_type);
|
||||
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_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type,
|
||||
evt->sel_type.standard_type.event_data[0]);
|
||||
|
||||
ipmi_get_event_desc(intf, evt, &desc);
|
||||
|
||||
sdr = ipmi_sdr_find_sdr_bynumtype(intf, evt->sel_type.standard_type.sensor_num, evt->sel_type.standard_type.sensor_type);
|
||||
sdr = ipmi_sdr_find_sdr_bynumtype(intf, evt->sel_type.standard_type.sensor_num,
|
||||
evt->sel_type.standard_type.sensor_type);
|
||||
|
||||
if (sdr == NULL) {
|
||||
/* could not find matching SDR record */
|
||||
if (desc) {
|
||||
lprintf(LOG_NOTICE, "%s sensor - %s",
|
||||
type, desc);
|
||||
lprintf(LOG_NOTICE, "%s%s sensor - %s",
|
||||
eintf->prefix, type, desc);
|
||||
free(desc);
|
||||
} else {
|
||||
lprintf(LOG_NOTICE, "%s sensor %02x",
|
||||
type, evt->sel_type.standard_type.sensor_num);
|
||||
lprintf(LOG_NOTICE, "%s%s sensor %02x",
|
||||
eintf->prefix, type,
|
||||
evt->sel_type.standard_type.sensor_num);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -237,7 +248,8 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)
|
||||
sdr->record.full, evt->sel_type.standard_type.event_data[2]);
|
||||
}
|
||||
|
||||
lprintf(LOG_NOTICE, "%s sensor %s %s (Reading %.*f %s Threshold %.*f %s)",
|
||||
lprintf(LOG_NOTICE, "%s%s sensor %s %s (Reading %.*f %s Threshold %.*f %s)",
|
||||
eintf->prefix,
|
||||
type,
|
||||
sdr->record.full->id_string,
|
||||
desc ? : "",
|
||||
@ -255,8 +267,8 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)
|
||||
/*
|
||||
* Discrete Event
|
||||
*/
|
||||
lprintf(LOG_NOTICE, "%s sensor %s %s",
|
||||
type, sdr->record.full->id_string, desc ? : "");
|
||||
lprintf(LOG_NOTICE, "%s%s sensor %s %s",
|
||||
eintf->prefix, type, sdr->record.full->id_string, desc ? : "");
|
||||
if (((evt->sel_type.standard_type.event_data[0] >> 6) & 3) == 1) {
|
||||
/* previous state and/or severity in event data byte 2 */
|
||||
}
|
||||
@ -265,26 +277,29 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)
|
||||
/*
|
||||
* OEM Event
|
||||
*/
|
||||
lprintf(LOG_NOTICE, "%s sensor %s %s",
|
||||
type, sdr->record.full->id_string, desc ? : "");
|
||||
lprintf(LOG_NOTICE, "%s%s sensor %s %s",
|
||||
eintf->prefix, type, sdr->record.full->id_string, desc ? : "");
|
||||
}
|
||||
break;
|
||||
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
if (evt->sel_type.standard_type.event_type == 0x6f) {
|
||||
lprintf(LOG_NOTICE, "%s sensor %s - %s %s",
|
||||
lprintf(LOG_NOTICE, "%s%s sensor %s - %s %s",
|
||||
eintf->prefix,
|
||||
type, sdr->record.compact->id_string,
|
||||
desc ? : "",
|
||||
evt->sel_type.standard_type.event_dir ? "Deasserted" : "Asserted");
|
||||
} else {
|
||||
lprintf(LOG_NOTICE, "%s sensor %s - %s",
|
||||
type, sdr->record.compact->id_string, desc ? : "");
|
||||
lprintf(LOG_NOTICE, "%s%s sensor %s - %s",
|
||||
eintf->prefix, type,
|
||||
sdr->record.compact->id_string, desc ? : "");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
lprintf(LOG_NOTICE, "%s sensor - %s",
|
||||
type, evt->sel_type.standard_type.sensor_num, desc ? : "");
|
||||
lprintf(LOG_NOTICE, "%s%s sensor - %s",
|
||||
eintf->prefix, type,
|
||||
evt->sel_type.standard_type.sensor_num, desc ? : "");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -609,7 +624,8 @@ ipmievd_main(struct ipmi_event_intf * eintf, int argc, char ** argv)
|
||||
struct sigaction act;
|
||||
|
||||
memset(pidfile, 0, 64);
|
||||
strncpy(pidfile, DEFAULT_PIDFILE, strlen(DEFAULT_PIDFILE));
|
||||
sprintf(pidfile, "%s%d", DEFAULT_PIDFILE, eintf->intf->devnum);
|
||||
lprintf(LOG_NOTICE, "ipmievd: using pidfile %s", pidfile);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strncasecmp(argv[i], "help", 4) == 0) {
|
||||
@ -654,7 +670,7 @@ ipmievd_main(struct ipmi_event_intf * eintf, int argc, char ** argv)
|
||||
FILE *fp;
|
||||
struct stat st1;
|
||||
|
||||
ipmi_start_daemon();
|
||||
ipmi_start_daemon(eintf->intf);
|
||||
|
||||
if (lstat(pidfile, &st1) == 0) {
|
||||
/* already exists, erase first */
|
||||
@ -723,6 +739,12 @@ ipmievd_sel_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
eintf->intf = intf;
|
||||
|
||||
if (intf->session != NULL) {
|
||||
snprintf(eintf->prefix,
|
||||
strlen((const char *)intf->session->hostname) + 3,
|
||||
"%s: ", intf->session->hostname);
|
||||
}
|
||||
|
||||
return ipmievd_main(eintf, argc, argv);
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,11 @@ extern const struct valstr ipmi_authtype_session_vals[];
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
|
||||
/* avoid warnings errors due to non-ANSI type declarations in readline.h */
|
||||
#define _FUNCTION_DEF
|
||||
#define USE_VARARGS
|
||||
#define PREFER_STDARG
|
||||
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#define RL_PROMPT "ipmitool> "
|
||||
@ -107,7 +112,7 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
shell_intf = intf;
|
||||
rl_event_hook = rl_event_keepalive;
|
||||
#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0402
|
||||
/* There is a bug in readline 4.2 and later (at least on FreeBSD):
|
||||
/* There is a bug in readline 4.2 and later (at least on FreeBSD and NetBSD):
|
||||
* timeout equal or greater than 1 second causes an infinite loop. */
|
||||
rl_set_keyboard_input_timeout(1000 * 1000 - 1);
|
||||
#endif
|
||||
@ -132,14 +137,14 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
/* for the all-important up arrow :) */
|
||||
add_history(pbuf);
|
||||
|
||||
|
||||
/* change "" and '' with spaces in the middle to ~ */
|
||||
ptr = pbuf;
|
||||
while (*ptr != '\0') {
|
||||
if (*ptr == '"') {
|
||||
ptr++;
|
||||
while (*ptr != '"') {
|
||||
if (isspace(*ptr))
|
||||
if (isspace((int)*ptr))
|
||||
*ptr = '~';
|
||||
ptr++;
|
||||
}
|
||||
@ -147,7 +152,7 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
if (*ptr == '\'') {
|
||||
ptr++;
|
||||
while (*ptr != '\'') {
|
||||
if (isspace(*ptr))
|
||||
if (isspace((int)*ptr))
|
||||
*ptr = '~';
|
||||
ptr++;
|
||||
}
|
||||
@ -196,7 +201,8 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
&(__argv[1]));
|
||||
|
||||
free(pbuf);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -211,7 +217,7 @@ ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
#endif /* HAVE_READLINE */
|
||||
|
||||
void ipmi_echo_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
int ipmi_echo_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -219,6 +225,8 @@ void ipmi_echo_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
printf("%s ", argv[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -355,7 +363,7 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
if (*ptr == '"') {
|
||||
ptr++;
|
||||
while (*ptr != '"') {
|
||||
if (isspace(*ptr))
|
||||
if (isspace((int)*ptr))
|
||||
*ptr = '~';
|
||||
ptr++;
|
||||
}
|
||||
@ -363,7 +371,7 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
if (*ptr == '\'') {
|
||||
ptr++;
|
||||
while (*ptr != '\'') {
|
||||
if (isspace(*ptr))
|
||||
if (isspace((int)*ptr))
|
||||
*ptr = '~';
|
||||
ptr++;
|
||||
}
|
||||
@ -373,10 +381,10 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
/* clip off trailing and leading whitespace */
|
||||
ptr--;
|
||||
while (isspace(*ptr) && ptr >= buf)
|
||||
while (isspace((int)*ptr) && ptr >= buf)
|
||||
*ptr-- = '\0';
|
||||
ptr = buf;
|
||||
while (isspace(*ptr))
|
||||
while (isspace((int)*ptr))
|
||||
ptr++;
|
||||
if (strlen(ptr) == 0)
|
||||
continue;
|
||||
@ -429,4 +437,3 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
fclose(fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,8 @@
|
||||
#include <ipmitool/ipmi_fwum.h>
|
||||
#include <ipmitool/ipmi_picmg.h>
|
||||
#include <ipmitool/ipmi_kontronoem.h>
|
||||
#include <ipmitool/ipmi_firewall.h>
|
||||
#include <ipmitool/ipmi_hpmfwupg.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
@ -77,6 +79,7 @@ int verbose = 0;
|
||||
struct ipmi_cmd ipmitool_cmd_list[] = {
|
||||
{ ipmi_raw_main, "raw", "Send a RAW IPMI request and print response" },
|
||||
{ ipmi_rawi2c_main, "i2c", "Send an I2C Master Write-Read command and print response" },
|
||||
{ ipmi_rawspd_main, "spd", "Print SPD info from remote I2C device" },
|
||||
{ ipmi_lanp_main, "lan", "Configure LAN Channels" },
|
||||
{ ipmi_chassis_main, "chassis", "Get chassis status and set power state" },
|
||||
{ ipmi_power_main, "power", "Shortcut to chassis power commands" },
|
||||
@ -98,12 +101,14 @@ struct ipmi_cmd ipmitool_cmd_list[] = {
|
||||
{ ipmi_kontronoem_main, "kontronoem", "OEM Commands for Kontron devices"},
|
||||
{ ipmi_picmg_main, "picmg", "Run a PICMG/ATCA extended cmd"},
|
||||
{ ipmi_fwum_main, "fwum", "Update IPMC using Kontron OEM Firmware Update Manager" },
|
||||
{ ipmi_firewall_main,"firewall","Configure Firmware Firewall" },
|
||||
#ifdef HAVE_READLINE
|
||||
{ ipmi_shell_main, "shell", "Launch interactive IPMI shell" },
|
||||
#endif
|
||||
{ ipmi_exec_main, "exec", "Run list of commands from file" },
|
||||
{ ipmi_set_main, "set", "Set runtime variable for shell and exec" },
|
||||
{ ipmi_echo_main, "echo", NULL }, /* for echoing lines to stdout in scripts */
|
||||
{ ipmi_hpmfwupg_main,"hpm", "Update HPM components using PICMG HPM.1 file"},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
@ -32,8 +32,8 @@ MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@
|
||||
DIST_SUBDIRS = lan lanplus open lipmi imb bmc
|
||||
SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@
|
||||
DIST_SUBDIRS = lan lanplus open lipmi imb bmc free
|
||||
|
||||
noinst_LTLIBRARIES = libintf.la
|
||||
libintf_la_SOURCES = ipmi_intf.c
|
||||
|
9
ipmitool/src/plugins/free/Makefile.am
Normal file
9
ipmitool/src/plugins/free/Makefile.am
Normal file
@ -0,0 +1,9 @@
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
EXTRA_LTLIBRARIES = libintf_free.la
|
||||
noinst_LTLIBRARIES = @INTF_FREE_LIB@
|
||||
libintf_free_la_LIBADD = $(top_builddir)/lib/libipmitool.la
|
||||
libintf_free_la_SOURCES = free.c
|
||||
libintf_free_la_LDFLAGS = -lfreeipmi
|
157
ipmitool/src/plugins/free/free.c
Normal file
157
ipmitool/src/plugins/free/free.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistribution of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistribution in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of Sun Microsystems, Inc. or the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* This software is provided "AS IS," without a warranty of any kind.
|
||||
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
|
||||
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
|
||||
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
|
||||
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
|
||||
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
|
||||
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
|
||||
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
|
||||
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
|
||||
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* You acknowledge that this software is not designed or intended for use
|
||||
* in the design, construction, operation or maintenance of any nuclear
|
||||
* facility.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
|
||||
#include <freeipmi/freeipmi.h>
|
||||
#include <freeipmi/udm/ipmi-udm.h>
|
||||
|
||||
#include <config.h>
|
||||
|
||||
ipmi_device_t dev = NULL;
|
||||
|
||||
extern int verbose;
|
||||
|
||||
static int ipmi_free_open(struct ipmi_intf * intf)
|
||||
{
|
||||
if (getuid() != 0) {
|
||||
fprintf(stderr, "Permission denied, must be root\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(dev = ipmi_open_inband (IPMI_DEVICE_KCS,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
IPMI_FLAGS_DEFAULT))) {
|
||||
if (!(dev = ipmi_open_inband (IPMI_DEVICE_SSIF,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
IPMI_FLAGS_DEFAULT))) {
|
||||
perror("ipmi_open_inband()");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
intf->opened = 1;
|
||||
return 0;
|
||||
cleanup:
|
||||
if (dev)
|
||||
ipmi_close_device(dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void ipmi_free_close(struct ipmi_intf * intf)
|
||||
{
|
||||
if (dev)
|
||||
ipmi_close_device(dev);
|
||||
intf->opened = 0;
|
||||
}
|
||||
|
||||
static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
{
|
||||
u_int8_t lun = 0;
|
||||
u_int8_t cmd = req->msg.cmd;
|
||||
u_int8_t netfn = req->msg.netfn;
|
||||
u_int8_t rq_buf[IPMI_BUF_SIZE];
|
||||
u_int8_t rs_buf[IPMI_BUF_SIZE];
|
||||
u_int32_t rs_buf_len = IPMI_BUF_SIZE;
|
||||
int32_t rs_len;
|
||||
|
||||
static struct ipmi_rs rsp;
|
||||
|
||||
/* achu: FreeIPMI requests have the cmd as the first byte of
|
||||
* the data. Responses have cmd as the first byte and
|
||||
* completion code as the second byte. This differs from some
|
||||
* other APIs, so it must be compensated for within the ipmitool
|
||||
* interface.
|
||||
*/
|
||||
|
||||
if (!intf || !req)
|
||||
return NULL;
|
||||
|
||||
if (!intf->opened && intf->open && intf->open(intf) < 0)
|
||||
return NULL;
|
||||
|
||||
if (req->msg.data_len > IPMI_BUF_SIZE)
|
||||
return NULL;
|
||||
|
||||
memset(rq_buf, '\0', IPMI_BUF_SIZE);
|
||||
memset(rs_buf, '\0', IPMI_BUF_SIZE);
|
||||
memcpy(rq_buf, &cmd, 1);
|
||||
|
||||
if (req->msg.data)
|
||||
memcpy(rq_buf + 1, req->msg.data, req->msg.data_len);
|
||||
|
||||
if ((rs_len = ipmi_cmd_raw(dev,
|
||||
lun,
|
||||
netfn,
|
||||
rq_buf,
|
||||
req->msg.data_len + 1,
|
||||
rs_buf,
|
||||
rs_buf_len)) < 0) {
|
||||
perror("ipmi_cmd_raw");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(&rsp, 0, sizeof(struct ipmi_rs));
|
||||
rsp.ccode = (unsigned char)rs_buf[1];
|
||||
rsp.data_len = (int)rs_len - 2;
|
||||
|
||||
if (!rsp.ccode && rsp.data_len)
|
||||
memcpy(rsp.data, rs_buf + 2, rsp.data_len);
|
||||
|
||||
return &rsp;
|
||||
}
|
||||
|
||||
struct ipmi_intf ipmi_free_intf = {
|
||||
name: "free",
|
||||
desc: "FreeIPMI IPMI Interface",
|
||||
open: ipmi_free_open,
|
||||
close: ipmi_free_close,
|
||||
sendrecv: ipmi_free_send_cmd,
|
||||
target_addr: IPMI_BMC_SLAVE_ADDR,
|
||||
};
|
||||
|
@ -59,6 +59,9 @@ extern struct ipmi_intf ipmi_lan_intf;
|
||||
#ifdef IPMI_INTF_LANPLUS
|
||||
extern struct ipmi_intf ipmi_lanplus_intf;
|
||||
#endif
|
||||
#ifdef IPMI_INTF_FREE
|
||||
extern struct ipmi_intf ipmi_free_intf;
|
||||
#endif
|
||||
|
||||
struct ipmi_intf * ipmi_intf_table[] = {
|
||||
#ifdef IPMI_INTF_OPEN
|
||||
@ -78,6 +81,9 @@ struct ipmi_intf * ipmi_intf_table[] = {
|
||||
#endif
|
||||
#ifdef IPMI_INTF_LANPLUS
|
||||
&ipmi_lanplus_intf,
|
||||
#endif
|
||||
#ifdef IPMI_INTF_FREE
|
||||
&ipmi_free_intf,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
@ -212,6 +218,15 @@ ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t level)
|
||||
intf->session->privlvl = level;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_intf_session_set_lookupbit(struct ipmi_intf * intf, uint8_t lookupbit)
|
||||
{
|
||||
if (intf->session == NULL)
|
||||
return;
|
||||
|
||||
intf->session->v2_data.lookupbit = lookupbit;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id)
|
||||
{
|
||||
|
@ -40,8 +40,6 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@ -63,23 +61,29 @@
|
||||
#include "asf.h"
|
||||
#include "auth.h"
|
||||
|
||||
#define IPMI_LAN_TIMEOUT 2
|
||||
#define IPMI_LAN_RETRY 4
|
||||
#define IPMI_LAN_PORT 0x26f
|
||||
#define IPMI_LAN_CHANNEL_E 0x0e
|
||||
|
||||
extern const struct valstr ipmi_privlvl_vals[];
|
||||
extern const struct valstr ipmi_authtype_session_vals[];
|
||||
extern int verbose;
|
||||
|
||||
struct ipmi_rq_entry * ipmi_req_entries;
|
||||
static struct ipmi_rq_entry * ipmi_req_entries_tail;
|
||||
|
||||
extern int verbose;
|
||||
|
||||
static uint8_t bridgePossible = 0;
|
||||
|
||||
static sigjmp_buf jmpbuf;
|
||||
static uint8_t bridge_possible = 0;
|
||||
|
||||
static int ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len);
|
||||
static struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf);
|
||||
static struct ipmi_rs * ipmi_lan_poll_recv(struct ipmi_intf * intf);
|
||||
static int ipmi_lan_setup(struct ipmi_intf * intf);
|
||||
static int ipmi_lan_keepalive(struct ipmi_intf * intf);
|
||||
static struct ipmi_rs * ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req);
|
||||
static int ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp);
|
||||
static int ipmi_lan_open(struct ipmi_intf * intf);
|
||||
static void ipmi_lan_close(struct ipmi_intf * intf);
|
||||
static int ipmi_lan_ping(struct ipmi_intf * intf);
|
||||
|
||||
struct ipmi_intf ipmi_lan_intf = {
|
||||
name: "lan",
|
||||
@ -93,13 +97,6 @@ struct ipmi_intf ipmi_lan_intf = {
|
||||
target_addr: IPMI_BMC_SLAVE_ADDR,
|
||||
};
|
||||
|
||||
static void
|
||||
query_alarm(int signo)
|
||||
{
|
||||
siglongjmp(jmpbuf, 1);
|
||||
}
|
||||
|
||||
|
||||
static struct ipmi_rq_entry *
|
||||
ipmi_req_add_entry(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
{
|
||||
@ -208,7 +205,8 @@ get_random(void *data, int len)
|
||||
return rv;
|
||||
}
|
||||
|
||||
int ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len)
|
||||
static int
|
||||
ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len)
|
||||
{
|
||||
if (verbose > 2)
|
||||
printbuf(data, data_len, "send_packet");
|
||||
@ -216,20 +214,26 @@ int ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len)
|
||||
return send(intf->fd, data, data_len, 0);
|
||||
}
|
||||
|
||||
struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf)
|
||||
static struct ipmi_rs *
|
||||
ipmi_lan_recv_packet(struct ipmi_intf * intf)
|
||||
{
|
||||
static struct ipmi_rs rsp;
|
||||
int rc;
|
||||
fd_set read_set, err_set;
|
||||
struct timeval tmout;
|
||||
int ret;
|
||||
|
||||
/* setup alarm timeout */
|
||||
if (sigsetjmp(jmpbuf, 1) != 0) {
|
||||
alarm(0);
|
||||
FD_ZERO(&read_set);
|
||||
FD_SET(intf->fd, &read_set);
|
||||
|
||||
FD_ZERO(&err_set);
|
||||
FD_SET(intf->fd, &err_set);
|
||||
|
||||
tmout.tv_sec = intf->session->timeout;
|
||||
tmout.tv_usec = 0;
|
||||
|
||||
ret = select(intf->fd + 1, &read_set, NULL, &err_set, &tmout);
|
||||
if (ret < 0 || FD_ISSET(intf->fd, &err_set) || !FD_ISSET(intf->fd, &read_set))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
alarm(intf->session->timeout);
|
||||
rc = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
|
||||
alarm(0);
|
||||
|
||||
/* the first read may return ECONNREFUSED because the rmcp ping
|
||||
* packet--sent to UDP port 623--will be processed by both the
|
||||
@ -241,17 +245,37 @@ struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf)
|
||||
* regardless of the order they were sent out. (unless the
|
||||
* response is read before the connection refused is returned)
|
||||
*/
|
||||
if (rc < 0) {
|
||||
alarm(intf->session->timeout);
|
||||
rc = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
|
||||
alarm(0);
|
||||
if (rc < 0) {
|
||||
perror("recv failed");
|
||||
return NULL;
|
||||
ret = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
FD_ZERO(&read_set);
|
||||
FD_SET(intf->fd, &read_set);
|
||||
|
||||
FD_ZERO(&err_set);
|
||||
FD_SET(intf->fd, &err_set);
|
||||
|
||||
tmout.tv_sec = intf->session->timeout;
|
||||
tmout.tv_usec = 0;
|
||||
|
||||
ret = select(intf->fd + 1, &read_set, NULL, &err_set, &tmout);
|
||||
if (ret < 0) {
|
||||
if (FD_ISSET(intf->fd, &err_set) || !FD_ISSET(intf->fd, &read_set))
|
||||
return NULL;
|
||||
|
||||
ret = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
rsp.data[rc] = '\0';
|
||||
rsp.data_len = rc;
|
||||
|
||||
if (ret == 0)
|
||||
return NULL;
|
||||
|
||||
rsp.data[ret] = '\0';
|
||||
rsp.data_len = ret;
|
||||
|
||||
if (verbose > 2)
|
||||
printbuf(rsp.data, rsp.data_len, "recv_packet");
|
||||
|
||||
return &rsp;
|
||||
}
|
||||
@ -328,7 +352,7 @@ ipmi_handle_pong(struct ipmi_intf * intf, struct ipmi_rs * rsp)
|
||||
* asf.len = 0x00
|
||||
*
|
||||
*/
|
||||
int
|
||||
static int
|
||||
ipmi_lan_ping(struct ipmi_intf * intf)
|
||||
{
|
||||
struct asf_hdr asf_ping = {
|
||||
@ -375,7 +399,8 @@ ipmi_lan_ping(struct ipmi_intf * intf)
|
||||
* request message. This may kick-start some BMCs that get confused with
|
||||
* bad passwords or operate poorly under heavy network load.
|
||||
*/
|
||||
static void ipmi_lan_thump_first(struct ipmi_intf * intf)
|
||||
static void
|
||||
ipmi_lan_thump_first(struct ipmi_intf * intf)
|
||||
{
|
||||
/* is this random data? */
|
||||
uint8_t data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@ -383,7 +408,8 @@ static void ipmi_lan_thump_first(struct ipmi_intf * intf)
|
||||
ipmi_lan_send_packet(intf, data, 16);
|
||||
}
|
||||
|
||||
static void ipmi_lan_thump(struct ipmi_intf * intf)
|
||||
static void
|
||||
ipmi_lan_thump(struct ipmi_intf * intf)
|
||||
{
|
||||
uint8_t data[10] = "thump";
|
||||
ipmi_lan_send_packet(intf, data, 10);
|
||||
@ -396,10 +422,10 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq_entry * entry;
|
||||
int x=0, rv;
|
||||
uint8_t ourAddress = intf->my_addr;
|
||||
uint8_t our_address = intf->my_addr;
|
||||
|
||||
if (ourAddress == 0)
|
||||
ourAddress = IPMI_BMC_SLAVE_ADDR;
|
||||
if (our_address == 0)
|
||||
our_address = IPMI_BMC_SLAVE_ADDR;
|
||||
|
||||
rsp = ipmi_lan_recv_packet(intf);
|
||||
|
||||
@ -441,7 +467,7 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
||||
rsp->payload.ipmi_response.rs_addr = rsp->data[x++];
|
||||
rsp->payload.ipmi_response.rq_seq = rsp->data[x] >> 2;
|
||||
rsp->payload.ipmi_response.rs_lun = rsp->data[x++] & 0x3;
|
||||
rsp->payload.ipmi_response.cmd = rsp->data[x++];
|
||||
rsp->payload.ipmi_response.cmd = rsp->data[x++];
|
||||
rsp->ccode = rsp->data[x++];
|
||||
|
||||
if (verbose > 2)
|
||||
@ -454,7 +480,6 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
||||
(long)rsp->session.seq);
|
||||
lprintf(LOG_DEBUG+1, "<< Session ID : 0x%08lx",
|
||||
(long)rsp->session.id);
|
||||
|
||||
lprintf(LOG_DEBUG+1, "<< IPMI Response Message Header");
|
||||
lprintf(LOG_DEBUG+1, "<< Rq Addr : %02x",
|
||||
rsp->payload.ipmi_response.rq_addr);
|
||||
@ -478,7 +503,7 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
||||
rsp->payload.ipmi_response.cmd);
|
||||
if (entry) {
|
||||
lprintf(LOG_DEBUG+2, "IPMI Request Match found");
|
||||
if ((intf->target_addr != ourAddress) && bridgePossible) {
|
||||
if ((intf->target_addr != our_address) && bridge_possible) {
|
||||
if ((rsp->data_len) &&
|
||||
(rsp->payload.ipmi_response.cmd != 0x34)) {
|
||||
printbuf(&rsp->data[x], rsp->data_len-x,
|
||||
@ -564,11 +589,11 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
struct ipmi_rq_entry * entry;
|
||||
struct ipmi_session * s = intf->session;
|
||||
static int curr_seq = 0;
|
||||
uint8_t ourAddress = intf->my_addr;
|
||||
uint8_t bridgedRequest = 0;
|
||||
uint8_t our_address = intf->my_addr;
|
||||
uint8_t bridge_request = 0;
|
||||
|
||||
if (ourAddress == 0)
|
||||
ourAddress = IPMI_BMC_SLAVE_ADDR;
|
||||
if (our_address == 0)
|
||||
our_address = IPMI_BMC_SLAVE_ADDR;
|
||||
|
||||
if (curr_seq >= 64)
|
||||
curr_seq = 0;
|
||||
@ -609,12 +634,12 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
}
|
||||
|
||||
/* message length */
|
||||
if ((intf->target_addr == ourAddress) || !bridgePossible) {
|
||||
if ((intf->target_addr == our_address) || !bridge_possible) {
|
||||
msg[len++] = req->msg.data_len + 7;
|
||||
cs = mp = len;
|
||||
} else {
|
||||
/* bridged request: encapsulate w/in Send Message */
|
||||
bridgedRequest = 1;
|
||||
bridge_request = 1;
|
||||
msg[len++] = req->msg.data_len + 15;
|
||||
cs = mp = len;
|
||||
msg[len++] = IPMI_BMC_SLAVE_ADDR;
|
||||
@ -638,7 +663,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||
cs = len;
|
||||
|
||||
if (!bridgedRequest)
|
||||
if (!bridge_request)
|
||||
msg[len++] = IPMI_REMOTE_SWID;
|
||||
else /* Bridged message */
|
||||
msg[len++] = intf->my_addr;
|
||||
@ -672,7 +697,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||
|
||||
/* bridged request: 2nd checksum */
|
||||
if (bridgedRequest) {
|
||||
if (bridge_request) {
|
||||
tmp = len - cs2;
|
||||
msg[len++] = ipmi_csum(msg+cs2, tmp);
|
||||
}
|
||||
@ -707,7 +732,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
return entry;
|
||||
}
|
||||
|
||||
struct ipmi_rs *
|
||||
static struct ipmi_rs *
|
||||
ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
{
|
||||
struct ipmi_rq_entry * entry;
|
||||
@ -719,21 +744,20 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
|
||||
if (intf->opened == 0 && intf->open != NULL) {
|
||||
if (intf->open(intf) < 0) {
|
||||
lprintf(LOG_ERR,
|
||||
"ipmi_lan_send_cmd failed to open intf");
|
||||
lprintf(LOG_DEBUG, "Failed to open LAN interface");
|
||||
return NULL;
|
||||
}
|
||||
lprintf(LOG_DEBUG, "\topened=[%d], open=[%d]",
|
||||
intf->opened, intf->open);
|
||||
}
|
||||
|
||||
entry = ipmi_lan_build_cmd(intf, req);
|
||||
if (entry == NULL) {
|
||||
lprintf(LOG_ERR, "Aborting send command, unable to build");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
entry = ipmi_lan_build_cmd(intf, req);
|
||||
if (entry == NULL) {
|
||||
lprintf(LOG_ERR, "Aborting send command, unable to build");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ipmi_lan_send_packet(intf, entry->msg_data, entry->msg_len) < 0) {
|
||||
try++;
|
||||
usleep(5000);
|
||||
@ -763,7 +787,8 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
return rsp;
|
||||
}
|
||||
|
||||
uint8_t * ipmi_lan_build_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp, int * llen)
|
||||
static uint8_t *
|
||||
ipmi_lan_build_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp, int * llen)
|
||||
{
|
||||
struct rmcp_hdr rmcp = {
|
||||
.ver = RMCP_VERSION_1,
|
||||
@ -848,17 +873,19 @@ uint8_t * ipmi_lan_build_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp, int
|
||||
d = ipmi_auth_md2(s, msg+mp, msg[mp-1]);
|
||||
memcpy(msg+ap, d, 16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*llen = len;
|
||||
return msg;
|
||||
}
|
||||
|
||||
int ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp)
|
||||
static int
|
||||
ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp)
|
||||
{
|
||||
uint8_t * msg;
|
||||
int len, rv;
|
||||
int len = 0;
|
||||
int rv;
|
||||
|
||||
msg = ipmi_lan_build_rsp(intf, rsp, &len);
|
||||
if (len <= 0 || msg == NULL) {
|
||||
@ -1069,7 +1096,7 @@ ipmi_get_session_challenge_cmd(struct ipmi_intf * intf)
|
||||
lprintf(LOG_DEBUG, "Opening Session");
|
||||
lprintf(LOG_DEBUG, " Session ID : %08lx", (long)s->session_id);
|
||||
lprintf(LOG_DEBUG, " Challenge : %s", buf2str(s->challenge, 16));
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1171,8 +1198,8 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
bridgePossible = 1;
|
||||
|
||||
bridge_possible = 1;
|
||||
|
||||
lprintf(LOG_DEBUG, "\nSession Activated");
|
||||
lprintf(LOG_DEBUG, " Auth Type : %s",
|
||||
val2str(rsp->data[0], ipmi_authtype_session_vals));
|
||||
@ -1194,7 +1221,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t privlvl = intf->session->privlvl;
|
||||
uint8_t backupBridgePossible = bridgePossible;
|
||||
uint8_t backup_bridge_possible = bridge_possible;
|
||||
|
||||
if (privlvl <= IPMI_SESSION_PRIV_USER)
|
||||
return 0; /* no need to set higher */
|
||||
@ -1205,12 +1232,10 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
|
||||
req.msg.data = &privlvl;
|
||||
req.msg.data_len = 1;
|
||||
|
||||
bridgePossible = 0;
|
||||
|
||||
bridge_possible = 0;
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
bridgePossible = backupBridgePossible;
|
||||
|
||||
bridge_possible = backup_bridge_possible;
|
||||
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Set Session Privilege Level to %s failed",
|
||||
val2str(privlvl, ipmi_privlvl_vals));
|
||||
@ -1244,7 +1269,7 @@ ipmi_close_session_cmd(struct ipmi_intf * intf)
|
||||
return -1;
|
||||
|
||||
intf->target_addr = IPMI_BMC_SLAVE_ADDR;
|
||||
bridgePossible = 0; /* Not a bridge message */
|
||||
bridge_possible = 0; /* Not a bridge message */
|
||||
|
||||
memcpy(&msg_data, &session_id, 4);
|
||||
|
||||
@ -1340,7 +1365,8 @@ ipmi_lan_activate_session(struct ipmi_intf * intf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ipmi_lan_close(struct ipmi_intf * intf)
|
||||
static void
|
||||
ipmi_lan_close(struct ipmi_intf * intf)
|
||||
{
|
||||
if (intf->abort == 0)
|
||||
ipmi_close_session_cmd(intf);
|
||||
@ -1359,10 +1385,10 @@ void ipmi_lan_close(struct ipmi_intf * intf)
|
||||
intf = NULL;
|
||||
}
|
||||
|
||||
int ipmi_lan_open(struct ipmi_intf * intf)
|
||||
static int
|
||||
ipmi_lan_open(struct ipmi_intf * intf)
|
||||
{
|
||||
int rc;
|
||||
struct sigaction act;
|
||||
struct ipmi_session *s;
|
||||
|
||||
if (intf == NULL || intf->session == NULL)
|
||||
@ -1420,16 +1446,6 @@ int ipmi_lan_open(struct ipmi_intf * intf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* setup alarm handler */
|
||||
act.sa_handler = query_alarm;
|
||||
act.sa_flags = 0;
|
||||
if (sigemptyset(&act.sa_mask) == 0 &&
|
||||
sigaction(SIGALRM, &act, NULL) < 0) {
|
||||
lperror(LOG_ERR, "Alarm signal setup failed");
|
||||
intf->close(intf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
intf->opened = 1;
|
||||
|
||||
/* try to open session */
|
||||
@ -1443,7 +1459,8 @@ int ipmi_lan_open(struct ipmi_intf * intf)
|
||||
return intf->fd;
|
||||
}
|
||||
|
||||
static int ipmi_lan_setup(struct ipmi_intf * intf)
|
||||
static int
|
||||
ipmi_lan_setup(struct ipmi_intf * intf)
|
||||
{
|
||||
intf->session = malloc(sizeof(struct ipmi_session));
|
||||
if (intf->session == NULL) {
|
||||
|
@ -36,22 +36,6 @@
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
|
||||
#define IPMI_LAN_CHANNEL_1 0x07
|
||||
#define IPMI_LAN_CHANNEL_2 0x06
|
||||
#define IPMI_LAN_CHANNEL_E 0x0e
|
||||
#define IPMI_LAN_PORT 0x26f
|
||||
|
||||
#define IPMI_LAN_TIMEOUT 2
|
||||
#define IPMI_LAN_RETRY 4
|
||||
|
||||
|
||||
struct ipmi_rs * ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req);
|
||||
int ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp);
|
||||
int ipmi_lan_open(struct ipmi_intf * intf);
|
||||
void ipmi_lan_close(struct ipmi_intf * intf);
|
||||
void ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel);
|
||||
int ipmi_lan_ping(struct ipmi_intf * intf);
|
||||
|
||||
extern struct ipmi_intf ipmi_lan_intf;
|
||||
|
||||
#endif /*IPMI_LAN_H*/
|
||||
|
76
ipmitool/src/plugins/lanplus/README.sol
Normal file
76
ipmitool/src/plugins/lanplus/README.sol
Normal file
@ -0,0 +1,76 @@
|
||||
This document was last updated for release 1.8.8.
|
||||
|
||||
This document explains how Serial Over Lan is implemented on in the
|
||||
impitool IPMI client. Obviously, the code itself is authoritative, but
|
||||
this document should serve as a good starting point.
|
||||
|
||||
Serial Over Lan (SOL) is defined in the IPMI v2 specification published by
|
||||
Intel and available at http://www.intel.com/design/servers/ipmi/. SOL
|
||||
functionality is built on top of the RMCP+ protocol as an additional
|
||||
payload type (type 1).
|
||||
|
||||
The high end SOL logic is implemented in src/ipmitool/lib/ipmi_sol.c. SOL
|
||||
sessions are begun in ipmitool using the "sol activate" command. This
|
||||
command maps directly to the IPMI Activate Payload command. It first
|
||||
verifies that an RMCP+ session (lanplus interface) is being used to
|
||||
establish the session. Although the spec allows for a SOL connection to be
|
||||
established on a port different than the RMCP+ port that the "activate
|
||||
payload" command issued, impitool does not support this.
|
||||
|
||||
Once a session has been established (the activate payload command
|
||||
succeeds), impitool simply loops over a select() on user input and data
|
||||
returned from the BMC. All user input is first filtered so that special
|
||||
escape sequences can suspend or deactivate the SOL session and so that data
|
||||
can be broken into chunks no greater than N bytes. This maximum is
|
||||
specified by the BMC in the response to the Activate Payload command.
|
||||
|
||||
User input to the BMC is handled in ipmitool/src/plugins/lanplus/lanplus.c.
|
||||
Every SOL packet (with one exception) traveling in either direction causes
|
||||
the recipient to return an acknowledgement packet, though acks themself are
|
||||
not acknowledged. The transport layer in lanplus.c handles the logic
|
||||
regarding acks, partial acks, sequence numbers. SOL acknowledgements
|
||||
packets be acks, partial acks (the remote destination processed only some
|
||||
of the data), and nacks (requests to stop sending packets). Nacks are not
|
||||
honored by ipmitool.
|
||||
|
||||
Note that one way that SOL communication differs from standard IPMI
|
||||
commands, is that it is not simply a request response protocol. Packets
|
||||
may be returned asyncrhonously from the BMC. When establishing a SOL
|
||||
session, impitool registers a callback for asynchonously received data.
|
||||
This call back simply prints text returned from the BMC.
|
||||
|
||||
Once a user has chosen to exit the SOL session (with ~.) ipmitool sends the
|
||||
IPMI SOL Deactivate command to the BMC.
|
||||
|
||||
The standard code path for SOL logic follows:
|
||||
ipmi_sol_main (ipmi_sol.c):
|
||||
|
||||
ipmi_sol_activate (ipmi_sol.c):
|
||||
Argument validation
|
||||
Creation and dispatch of IPMI Activate Payload command
|
||||
|
||||
ipmi_sol_red_pill (ipmi_sol.c):
|
||||
Loop on select() for user input and data returned from the BMC
|
||||
Periodic dispatch of "keep alive" packet to the BMC.
|
||||
Send user input to the BMC and BMC data to the console.
|
||||
|
||||
processSolUserInput (ipmi_sol.c):
|
||||
Process possible escape sequences (~., ~B, etc.)
|
||||
Send (with retries) user data to the BMC
|
||||
Partial creation of packet payload
|
||||
|
||||
ipmi_lanplus_send_sol (lanplus.c):
|
||||
Completion of packet payload
|
||||
Send (with retries) of SOL packet
|
||||
|
||||
ipmi_lanplus_send_payload (lanplus.c):
|
||||
Creation of RMCP+ packet
|
||||
Details general to all V2 packet processing, as
|
||||
well as a some logic to handle ack reception.
|
||||
|
||||
is_sol_partial_ack (lanplus.c):
|
||||
Determine whether a data needs to be resent
|
||||
|
||||
ipmi_lanplus_recv_sol (lanplus.c):
|
||||
Handle data received by the BMC. Ack as appropriate.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -66,7 +66,7 @@
|
||||
#define IPMI_LAN_CHANNEL_2 0x06
|
||||
#define IPMI_LAN_CHANNEL_E 0x0e
|
||||
|
||||
#define IPMI_LAN_TIMEOUT 2
|
||||
#define IPMI_LAN_TIMEOUT 1
|
||||
#define IPMI_LAN_RETRY 4
|
||||
|
||||
#define IPMI_PRIV_CALLBACK 1
|
||||
|
@ -226,16 +226,15 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
|
||||
/* Intel BMC responds with the integrity Algorithm in RAKP4 */
|
||||
if (session->v2_data.integrity_alg == IPMI_INTEGRITY_NONE)
|
||||
return 1;
|
||||
|
||||
|
||||
/* We don't yet support other algorithms */
|
||||
assert(session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_SHA1_96);
|
||||
|
||||
} else {
|
||||
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
/* We don't yet support other algorithms */
|
||||
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
|
||||
/* We don't yet support other algorithms */
|
||||
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
|
||||
}
|
||||
|
||||
bufferLength =
|
||||
@ -905,4 +904,3 @@ int lanplus_decrypt_payload(uint8_t crypt_alg,
|
||||
free(decrypted_payload);
|
||||
return (bytes_decrypted == 0);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#include "ipmitool/log.h"
|
||||
#include "ipmitool/ipmi_constants.h"
|
||||
#include "lanplus.h"
|
||||
#include "lanplus_crypt_impl.h"
|
||||
@ -117,18 +118,16 @@ lanplus_HMAC(uint8_t mac,
|
||||
uint8_t *md,
|
||||
uint32_t *md_len)
|
||||
{
|
||||
|
||||
const EVP_MD *evp_md;
|
||||
const EVP_MD *evp_md = NULL;
|
||||
|
||||
if ((mac == IPMI_AUTH_RAKP_HMAC_SHA1) ||
|
||||
(mac == IPMI_INTEGRITY_HMAC_SHA1_96))
|
||||
evp_md = EVP_sha1();
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Invalid mac type 0x%x in lanplus_HMAC\n", mac);
|
||||
lprintf(LOG_DEBUG, "Invalid mac type 0x%x in lanplus_HMAC\n", mac);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
return HMAC(evp_md, key, key_len, d, n, md, (unsigned int *)md_len);
|
||||
}
|
||||
@ -167,7 +166,7 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
|
||||
if (input_length == 0)
|
||||
return;
|
||||
|
||||
if (verbose > 2)
|
||||
if (verbose >= 5)
|
||||
{
|
||||
printbuf(iv, 16, "encrypting with this IV");
|
||||
printbuf(key, 16, "encrypting with this key");
|
||||
@ -235,10 +234,9 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
|
||||
EVP_CIPHER_CTX_set_padding(&ctx, 0);
|
||||
|
||||
|
||||
|
||||
if (verbose > 2)
|
||||
if (verbose >= 5)
|
||||
{
|
||||
printbuf(iv, 16, "decrypting with this IV");
|
||||
printbuf(key, 16, "decrypting with this key");
|
||||
@ -262,7 +260,7 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
|
||||
if (!EVP_DecryptUpdate(&ctx, output, (int *)bytes_written, input, input_length))
|
||||
{
|
||||
/* Error */
|
||||
fprintf(stderr, "ERROR: decrypt update failed");
|
||||
lprintf(LOG_DEBUG, "ERROR: decrypt update failed");
|
||||
*bytes_written = 0;
|
||||
return;
|
||||
}
|
||||
@ -274,8 +272,8 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
|
||||
{
|
||||
char buffer[1000];
|
||||
ERR_error_string(ERR_get_error(), buffer);
|
||||
fprintf(stderr, "the ERR error %s", buffer);
|
||||
fprintf(stderr, "ERROR: decrypt final failed");
|
||||
lprintf(LOG_DEBUG, "the ERR error %s", buffer);
|
||||
lprintf(LOG_DEBUG, "ERROR: decrypt final failed");
|
||||
*bytes_written = 0;
|
||||
return; /* Error */
|
||||
}
|
||||
@ -287,10 +285,9 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose > 1)
|
||||
if (verbose >= 5)
|
||||
{
|
||||
fprintf(stderr, "Decrypted %d encrypted bytes", input_length);
|
||||
lprintf(LOG_DEBUG, "Decrypted %d encrypted bytes", input_length);
|
||||
printbuf(output, *bytes_written, "Decrypted this data");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,9 @@
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OPENIPMI_H)
|
||||
# include <linux/compiler.h>
|
||||
# if defined(HAVE_LINUX_COMPILER_H)
|
||||
# include <linux/compiler.h>
|
||||
# endif
|
||||
# include <linux/ipmi.h>
|
||||
#elif defined(HAVE_FREEBSD_IPMI_H)
|
||||
/* FreeBSD OpenIPMI-compatible header */
|
||||
@ -61,10 +63,6 @@
|
||||
|
||||
extern int verbose;
|
||||
|
||||
#define IPMI_OPENIPMI_DEV "/dev/ipmi0"
|
||||
#define IPMI_OPENIPMI_DEVFS "/dev/ipmi/0"
|
||||
#define IPMI_OPENIPMI_DEVFS2 "/dev/ipmidev/0"
|
||||
|
||||
static int
|
||||
ipmi_openipmi_open(struct ipmi_intf * intf)
|
||||
{
|
||||
@ -74,17 +72,28 @@ ipmi_openipmi_open(struct ipmi_intf * intf)
|
||||
struct ipmi_rs *rsp;
|
||||
char msg_data;
|
||||
#endif
|
||||
char ipmi_dev[16];
|
||||
char ipmi_devfs[16];
|
||||
char ipmi_devfs2[16];
|
||||
int devnum = 0;
|
||||
|
||||
intf->fd = open(IPMI_OPENIPMI_DEV, O_RDWR);
|
||||
devnum = intf->devnum;
|
||||
|
||||
sprintf(ipmi_dev, "/dev/ipmi%d", devnum);
|
||||
sprintf(ipmi_devfs, "/dev/ipmi/%d", devnum);
|
||||
sprintf(ipmi_devfs2, "/dev/ipmidev/%d", devnum);
|
||||
lprintf(LOG_DEBUG, "Using ipmi device %d", devnum);
|
||||
|
||||
intf->fd = open(ipmi_dev, O_RDWR);
|
||||
|
||||
if (intf->fd < 0) {
|
||||
intf->fd = open(IPMI_OPENIPMI_DEVFS, O_RDWR);
|
||||
intf->fd = open(ipmi_devfs, O_RDWR);
|
||||
if (intf->fd < 0) {
|
||||
intf->fd = open(IPMI_OPENIPMI_DEVFS2, O_RDWR);
|
||||
intf->fd = open(ipmi_devfs2, O_RDWR);
|
||||
}
|
||||
if (intf->fd < 0) {
|
||||
lperror(LOG_ERR, "Could not open device at %s or %s or %s",
|
||||
IPMI_OPENIPMI_DEV, IPMI_OPENIPMI_DEVFS , IPMI_OPENIPMI_DEVFS2);
|
||||
ipmi_dev, ipmi_devfs , ipmi_devfs2);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -274,4 +283,3 @@ struct ipmi_intf ipmi_open_intf = {
|
||||
my_addr: IPMI_BMC_SLAVE_ADDR,
|
||||
target_addr: IPMI_BMC_SLAVE_ADDR,
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user